@sveltier/ui 0.0.0-stage → 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +82 -2
- package/dist/components/Alert/Alert.svelte +88 -0
- package/dist/components/Alert/Alert.svelte.d.ts +4 -0
- package/dist/components/Alert/alert.css +78 -0
- package/dist/components/Alert/index.d.ts +2 -0
- package/dist/components/Alert/index.js +1 -0
- package/dist/components/Alert/types.d.ts +67 -0
- package/dist/components/Alert/types.js +1 -0
- package/dist/components/Avatar/Avatar.svelte +47 -0
- package/dist/components/Avatar/Avatar.svelte.d.ts +4 -0
- package/dist/components/Avatar/avatar.css +34 -0
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Avatar/index.js +1 -0
- package/dist/components/Avatar/types.d.ts +47 -0
- package/dist/components/Avatar/types.js +1 -0
- package/dist/components/Badge/Badge.svelte +53 -0
- package/dist/components/Badge/Badge.svelte.d.ts +4 -0
- package/dist/components/Badge/badge.css +57 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Badge/index.js +1 -0
- package/dist/components/Badge/types.d.ts +43 -0
- package/dist/components/Badge/types.js +1 -0
- package/dist/components/Button/Button.svelte +85 -0
- package/dist/components/Button/Button.svelte.d.ts +4 -0
- package/dist/components/Button/button.css +132 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Button/index.js +1 -0
- package/dist/components/Button/types.d.ts +76 -0
- package/dist/components/Button/types.js +1 -0
- package/dist/components/ButtonGroup/ButtonGroup.svelte +61 -0
- package/dist/components/ButtonGroup/ButtonGroup.svelte.d.ts +4 -0
- package/dist/components/ButtonGroup/button-group.css +39 -0
- package/dist/components/ButtonGroup/index.d.ts +2 -0
- package/dist/components/ButtonGroup/index.js +1 -0
- package/dist/components/ButtonGroup/types.d.ts +48 -0
- package/dist/components/ButtonGroup/types.js +1 -0
- package/dist/components/Card/Card.svelte +53 -0
- package/dist/components/Card/Card.svelte.d.ts +4 -0
- package/dist/components/Card/card.css +62 -0
- package/dist/components/Card/index.d.ts +2 -0
- package/dist/components/Card/index.js +1 -0
- package/dist/components/Card/types.d.ts +56 -0
- package/dist/components/Card/types.js +1 -0
- package/dist/components/Checkbox/Checkbox.svelte +105 -0
- package/dist/components/Checkbox/Checkbox.svelte.d.ts +4 -0
- package/dist/components/Checkbox/checkbox.css +138 -0
- package/dist/components/Checkbox/index.d.ts +2 -0
- package/dist/components/Checkbox/index.js +1 -0
- package/dist/components/Checkbox/types.d.ts +76 -0
- package/dist/components/Checkbox/types.js +1 -0
- package/dist/components/Chip/Chip.svelte +109 -0
- package/dist/components/Chip/Chip.svelte.d.ts +4 -0
- package/dist/components/Chip/chip.css +101 -0
- package/dist/components/Chip/index.d.ts +2 -0
- package/dist/components/Chip/index.js +1 -0
- package/dist/components/Chip/types.d.ts +69 -0
- package/dist/components/Chip/types.js +1 -0
- package/dist/components/Choice/Choice.svelte +60 -0
- package/dist/components/Choice/Choice.svelte.d.ts +4 -0
- package/dist/components/Choice/choice.css +75 -0
- package/dist/components/Choice/types.d.ts +43 -0
- package/dist/components/Choice/types.js +1 -0
- package/dist/components/Divider/Divider.svelte +19 -0
- package/dist/components/Divider/Divider.svelte.d.ts +4 -0
- package/dist/components/Divider/divider.css +23 -0
- package/dist/components/Divider/index.d.ts +2 -0
- package/dist/components/Divider/index.js +1 -0
- package/dist/components/Divider/types.d.ts +10 -0
- package/dist/components/Divider/types.js +1 -0
- package/dist/components/Field/Field.svelte +95 -0
- package/dist/components/Field/Field.svelte.d.ts +4 -0
- package/dist/components/Field/field.css +210 -0
- package/dist/components/Field/index.d.ts +3 -0
- package/dist/components/Field/index.js +2 -0
- package/dist/components/Field/types.d.ts +109 -0
- package/dist/components/Field/types.js +2 -0
- package/dist/components/Form/Form.svelte +93 -0
- package/dist/components/Form/Form.svelte.d.ts +8 -0
- package/dist/components/Form/form.css +16 -0
- package/dist/components/Form/index.d.ts +2 -0
- package/dist/components/Form/index.js +1 -0
- package/dist/components/Form/types.d.ts +38 -0
- package/dist/components/Form/types.js +1 -0
- package/dist/components/Icon/Icon.svelte +38 -0
- package/dist/components/Icon/Icon.svelte.d.ts +4 -0
- package/dist/components/Icon/icon.css +33 -0
- package/dist/components/Icon/index.d.ts +2 -0
- package/dist/components/Icon/index.js +1 -0
- package/dist/components/Icon/types.d.ts +34 -0
- package/dist/components/Icon/types.js +1 -0
- package/dist/components/List/List.svelte +39 -0
- package/dist/components/List/List.svelte.d.ts +4 -0
- package/dist/components/List/ListItem.svelte +57 -0
- package/dist/components/List/ListItem.svelte.d.ts +4 -0
- package/dist/components/List/index.d.ts +3 -0
- package/dist/components/List/index.js +2 -0
- package/dist/components/List/list.css +127 -0
- package/dist/components/List/types.d.ts +67 -0
- package/dist/components/List/types.js +1 -0
- package/dist/components/NativeSelect/NativeSelect.svelte +110 -0
- package/dist/components/NativeSelect/NativeSelect.svelte.d.ts +25 -0
- package/dist/components/NativeSelect/index.d.ts +2 -0
- package/dist/components/NativeSelect/index.js +1 -0
- package/dist/components/NativeSelect/native-select.css +45 -0
- package/dist/components/NativeSelect/types.d.ts +58 -0
- package/dist/components/NativeSelect/types.js +1 -0
- package/dist/components/NumberField/NumberField.svelte +246 -0
- package/dist/components/NumberField/NumberField.svelte.d.ts +4 -0
- package/dist/components/NumberField/index.d.ts +2 -0
- package/dist/components/NumberField/index.js +1 -0
- package/dist/components/NumberField/number-field.css +74 -0
- package/dist/components/NumberField/types.d.ts +73 -0
- package/dist/components/NumberField/types.js +1 -0
- package/dist/components/Progress/ProgressCircular.svelte +61 -0
- package/dist/components/Progress/ProgressCircular.svelte.d.ts +4 -0
- package/dist/components/Progress/ProgressLinear.svelte +44 -0
- package/dist/components/Progress/ProgressLinear.svelte.d.ts +4 -0
- package/dist/components/Progress/index.d.ts +3 -0
- package/dist/components/Progress/index.js +2 -0
- package/dist/components/Progress/progress-circular.css +61 -0
- package/dist/components/Progress/progress-linear.css +67 -0
- package/dist/components/Progress/types.d.ts +53 -0
- package/dist/components/Progress/types.js +1 -0
- package/dist/components/RadioGroup/RadioGroup.svelte +149 -0
- package/dist/components/RadioGroup/RadioGroup.svelte.d.ts +25 -0
- package/dist/components/RadioGroup/index.d.ts +2 -0
- package/dist/components/RadioGroup/index.js +1 -0
- package/dist/components/RadioGroup/radio-group.css +139 -0
- package/dist/components/RadioGroup/types.d.ts +93 -0
- package/dist/components/RadioGroup/types.js +1 -0
- package/dist/components/SegmentedControl/SegmentedControl.svelte +70 -0
- package/dist/components/SegmentedControl/SegmentedControl.svelte.d.ts +25 -0
- package/dist/components/SegmentedControl/index.d.ts +2 -0
- package/dist/components/SegmentedControl/index.js +1 -0
- package/dist/components/SegmentedControl/segmented-control.css +68 -0
- package/dist/components/SegmentedControl/types.d.ts +60 -0
- package/dist/components/SegmentedControl/types.js +1 -0
- package/dist/components/Skeleton/Skeleton.svelte +33 -0
- package/dist/components/Skeleton/Skeleton.svelte.d.ts +4 -0
- package/dist/components/Skeleton/index.d.ts +2 -0
- package/dist/components/Skeleton/index.js +1 -0
- package/dist/components/Skeleton/skeleton.css +70 -0
- package/dist/components/Skeleton/types.d.ts +25 -0
- package/dist/components/Skeleton/types.js +1 -0
- package/dist/components/Slider/Slider.svelte +153 -0
- package/dist/components/Slider/Slider.svelte.d.ts +4 -0
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/Slider/index.js +1 -0
- package/dist/components/Slider/slider.css +206 -0
- package/dist/components/Slider/types.d.ts +102 -0
- package/dist/components/Slider/types.js +1 -0
- package/dist/components/Switch/Switch.svelte +94 -0
- package/dist/components/Switch/Switch.svelte.d.ts +4 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Switch/index.js +1 -0
- package/dist/components/Switch/switch.css +118 -0
- package/dist/components/Switch/types.d.ts +67 -0
- package/dist/components/Switch/types.js +1 -0
- package/dist/components/Tabs/Tabs.svelte +93 -0
- package/dist/components/Tabs/Tabs.svelte.d.ts +25 -0
- package/dist/components/Tabs/index.d.ts +2 -0
- package/dist/components/Tabs/index.js +1 -0
- package/dist/components/Tabs/tabs.css +73 -0
- package/dist/components/Tabs/types.d.ts +59 -0
- package/dist/components/Tabs/types.js +1 -0
- package/dist/components/TextField/TextField.svelte +115 -0
- package/dist/components/TextField/TextField.svelte.d.ts +4 -0
- package/dist/components/TextField/index.d.ts +2 -0
- package/dist/components/TextField/index.js +1 -0
- package/dist/components/TextField/types.d.ts +57 -0
- package/dist/components/TextField/types.js +1 -0
- package/dist/components/Textarea/Textarea.svelte +116 -0
- package/dist/components/Textarea/Textarea.svelte.d.ts +4 -0
- package/dist/components/Textarea/index.d.ts +2 -0
- package/dist/components/Textarea/index.js +1 -0
- package/dist/components/Textarea/textarea.css +35 -0
- package/dist/components/Textarea/types.d.ts +60 -0
- package/dist/components/Textarea/types.js +1 -0
- package/dist/core/defaults/DefaultsProvider.svelte +30 -0
- package/dist/core/defaults/DefaultsProvider.svelte.d.ts +13 -0
- package/dist/core/defaults/context.d.ts +45 -0
- package/dist/core/defaults/context.js +38 -0
- package/dist/core/display/display.d.ts +39 -0
- package/dist/core/display/display.js +53 -0
- package/dist/core/errors/codes.d.ts +112 -0
- package/dist/core/errors/codes.js +96 -0
- package/dist/core/errors/errors.d.ts +8 -0
- package/dist/core/errors/errors.js +7 -0
- package/dist/core/form/constraints.d.ts +15 -0
- package/dist/core/form/constraints.js +42 -0
- package/dist/core/form/context.d.ts +19 -0
- package/dist/core/form/context.js +4 -0
- package/dist/core/form/field.svelte.d.ts +34 -0
- package/dist/core/form/field.svelte.js +66 -0
- package/dist/core/form/number.d.ts +24 -0
- package/dist/core/form/number.js +71 -0
- package/dist/core/form/types.d.ts +22 -0
- package/dist/core/form/types.js +1 -0
- package/dist/core/locale/locale.d.ts +55 -0
- package/dist/core/locale/locale.js +80 -0
- package/dist/core/props/classes.d.ts +21 -0
- package/dist/core/props/classes.js +44 -0
- package/dist/core/props/element.d.ts +18 -0
- package/dist/core/props/element.js +1 -0
- package/dist/core/props/types.d.ts +47 -0
- package/dist/core/props/types.js +16 -0
- package/dist/core/provider/UIProvider.svelte +60 -0
- package/dist/core/provider/UIProvider.svelte.d.ts +29 -0
- package/dist/core/theme/ThemeProvider.svelte +178 -0
- package/dist/core/theme/ThemeProvider.svelte.d.ts +25 -0
- package/dist/core/theme/color.d.ts +23 -0
- package/dist/core/theme/color.js +54 -0
- package/dist/core/theme/context.d.ts +25 -0
- package/dist/core/theme/context.js +14 -0
- package/dist/core/theme/css.d.ts +25 -0
- package/dist/core/theme/css.js +69 -0
- package/dist/core/theme/define.d.ts +11 -0
- package/dist/core/theme/define.js +21 -0
- package/dist/core/theme/resolve.d.ts +6 -0
- package/dist/core/theme/resolve.js +18 -0
- package/dist/core/theme/theme-provider.css +13 -0
- package/dist/core/theme/types.d.ts +35 -0
- package/dist/core/theme/types.js +61 -0
- package/dist/dev/off.d.ts +4 -0
- package/dist/dev/off.js +3 -0
- package/dist/dev/on.d.ts +8 -0
- package/dist/dev/on.js +33 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +72 -0
- package/dist/primitives/anchored/anchored.d.ts +39 -0
- package/dist/primitives/anchored/anchored.js +104 -0
- package/dist/primitives/anchored/fallback.d.ts +31 -0
- package/dist/primitives/anchored/fallback.js +73 -0
- package/dist/primitives/focus/focus-trap.d.ts +25 -0
- package/dist/primitives/focus/focus-trap.js +86 -0
- package/dist/primitives/focus/roving-focus.d.ts +22 -0
- package/dist/primitives/focus/roving-focus.js +86 -0
- package/dist/primitives/focus/tabbable.d.ts +9 -0
- package/dist/primitives/focus/tabbable.js +75 -0
- package/dist/primitives/inert/inert-others.d.ts +12 -0
- package/dist/primitives/inert/inert-others.js +44 -0
- package/dist/primitives/keyboard/keymap.d.ts +17 -0
- package/dist/primitives/keyboard/keymap.js +39 -0
- package/dist/primitives/keyboard/typeahead.d.ts +18 -0
- package/dist/primitives/keyboard/typeahead.js +50 -0
- package/dist/primitives/layer/dismissable.d.ts +26 -0
- package/dist/primitives/layer/dismissable.js +84 -0
- package/dist/primitives/motion/easing.d.ts +9 -0
- package/dist/primitives/motion/easing.js +46 -0
- package/dist/primitives/motion/motion.d.ts +59 -0
- package/dist/primitives/motion/motion.js +80 -0
- package/dist/primitives/portal/Portal.svelte +37 -0
- package/dist/primitives/portal/Portal.svelte.d.ts +9 -0
- package/dist/primitives/portal/PortalContent.svelte +15 -0
- package/dist/primitives/portal/PortalContent.svelte.d.ts +9 -0
- package/dist/primitives/portal/portal.css +8 -0
- package/dist/primitives/scroll-lock/scroll-lock.d.ts +10 -0
- package/dist/primitives/scroll-lock/scroll-lock.js +33 -0
- package/dist/primitives/virtual/virtual-list.svelte.d.ts +65 -0
- package/dist/primitives/virtual/virtual-list.svelte.js +291 -0
- package/dist/styles/base.css +44 -0
- package/dist/styles/props.css +137 -0
- package/dist/styles/tokens.css +84 -0
- package/dist/styles/visually-hidden.css +16 -0
- package/dist/themes/aurora.d.ts +13 -0
- package/dist/themes/aurora.js +103 -0
- package/dist/themes/heritage.d.ts +13 -0
- package/dist/themes/heritage.js +102 -0
- package/dist/themes/maison.d.ts +13 -0
- package/dist/themes/maison.js +99 -0
- package/dist/themes/milano.d.ts +13 -0
- package/dist/themes/milano.js +101 -0
- package/dist/themes/monolith.d.ts +13 -0
- package/dist/themes/monolith.js +101 -0
- package/package.json +87 -5
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Minimal oklch maths: enough to pick readable "on" colours and to check WCAG contrast.
|
|
2
|
+
// Conversion from Björn Ottosson's OKLab reference (https://bottosson.github.io/posts/oklab/).
|
|
3
|
+
const OKLCH = /^oklch\(\s*([\d.]+)(%?)\s+([\d.]+)(%?)\s+([\d.]+)(?:deg)?\s*(?:\/\s*([\d.]+)(%?))?\s*\)$/i;
|
|
4
|
+
/** Parses `oklch(L C H)` or `oklch(L C H / A)` with numbers or percentages. */
|
|
5
|
+
export function parseOklch(value) {
|
|
6
|
+
const match = OKLCH.exec(value.trim());
|
|
7
|
+
if (!match)
|
|
8
|
+
return undefined;
|
|
9
|
+
const [, l = '0', lPct, c = '0', cPct, h = '0', a, aPct] = match;
|
|
10
|
+
return {
|
|
11
|
+
l: lPct ? +l / 100 : +l,
|
|
12
|
+
c: cPct ? (+c / 100) * 0.4 : +c,
|
|
13
|
+
h: +h,
|
|
14
|
+
alpha: a === undefined ? 1 : aPct ? +a / 100 : +a
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const clamp01 = (value) => Math.min(1, Math.max(0, value));
|
|
18
|
+
/** Linear-light sRGB channels, clamped to the sRGB gamut. */
|
|
19
|
+
export function toLinearSrgb({ l, c, h }) {
|
|
20
|
+
const rad = (h * Math.PI) / 180;
|
|
21
|
+
const a = c * Math.cos(rad);
|
|
22
|
+
const b = c * Math.sin(rad);
|
|
23
|
+
const l3 = (l + 0.3963377774 * a + 0.2158037573 * b) ** 3;
|
|
24
|
+
const m3 = (l - 0.1055613458 * a - 0.0638541728 * b) ** 3;
|
|
25
|
+
const s3 = (l - 0.0894841775 * a - 1.291485548 * b) ** 3;
|
|
26
|
+
return [
|
|
27
|
+
clamp01(4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3),
|
|
28
|
+
clamp01(-1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3),
|
|
29
|
+
clamp01(-0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3)
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
/** WCAG relative luminance of an opaque colour. */
|
|
33
|
+
export function luminance(color) {
|
|
34
|
+
const [r, g, b] = toLinearSrgb(color);
|
|
35
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
36
|
+
}
|
|
37
|
+
/** WCAG 2 contrast ratio between two opaque oklch colours (1–21). */
|
|
38
|
+
export function contrast(a, b) {
|
|
39
|
+
const [hi, lo] = [luminance(a), luminance(b)].sort((x, y) => y - x);
|
|
40
|
+
return (hi + 0.05) / (lo + 0.05);
|
|
41
|
+
}
|
|
42
|
+
const format = ({ l, c, h }) => `oklch(${l} ${c} ${h})`;
|
|
43
|
+
/**
|
|
44
|
+
* Picks a readable text colour for a filled background: a deep ink or a near-white, both
|
|
45
|
+
* tinted with the background's hue, whichever contrasts more.
|
|
46
|
+
*/
|
|
47
|
+
export function onColor(background) {
|
|
48
|
+
const bg = parseOklch(background);
|
|
49
|
+
if (!bg)
|
|
50
|
+
return undefined;
|
|
51
|
+
const dark = { l: 0.2, c: 0.02, h: bg.h, alpha: 1 };
|
|
52
|
+
const light = { l: 0.985, c: 0.005, h: bg.h, alpha: 1 };
|
|
53
|
+
return format(contrast(bg, dark) >= contrast(bg, light) ? dark : light);
|
|
54
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ThemeChoice, ThemeDefinition } from './types.js';
|
|
2
|
+
/** The nearest `<ThemeProvider>`, as seen by `useTheme()`. All fields are reactive. */
|
|
3
|
+
export interface ThemeInstance {
|
|
4
|
+
/** "system" or a theme name. */
|
|
5
|
+
readonly choice: ThemeChoice;
|
|
6
|
+
/**
|
|
7
|
+
* The theme in effect. With "system" it follows `prefers-color-scheme`; during server
|
|
8
|
+
* rendering, where the preference is unknown, it is the `light` theme.
|
|
9
|
+
*/
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly current: ThemeDefinition;
|
|
12
|
+
readonly isDark: boolean;
|
|
13
|
+
readonly themes: Readonly<Record<string, ThemeDefinition>>;
|
|
14
|
+
/** Theme names that "system" and `toggle()` switch between. */
|
|
15
|
+
readonly light: string;
|
|
16
|
+
readonly dark: string;
|
|
17
|
+
/** Selects a theme name or "system". The root provider remembers it. */
|
|
18
|
+
set(choice: ThemeChoice): void;
|
|
19
|
+
/** Switches between the `light` and `dark` themes. */
|
|
20
|
+
toggle(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare const hasThemeContext: () => boolean;
|
|
23
|
+
export declare const setThemeContext: (theme: ThemeInstance) => ThemeInstance;
|
|
24
|
+
/** Returns the nearest theme. Must be called during component initialisation. */
|
|
25
|
+
export declare function useTheme(): ThemeInstance;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getContext, hasContext, setContext } from 'svelte';
|
|
2
|
+
import { sveltierError } from '../errors/errors.js';
|
|
3
|
+
// A private symbol key instead of createContext(): its `has` function only exists from
|
|
4
|
+
// Svelte 5.57, and the supported range starts at 5.40.
|
|
5
|
+
const KEY = Symbol('sveltier.theme');
|
|
6
|
+
export const hasThemeContext = () => hasContext(KEY);
|
|
7
|
+
export const setThemeContext = (theme) => setContext(KEY, theme);
|
|
8
|
+
/** Returns the nearest theme. Must be called during component initialisation. */
|
|
9
|
+
export function useTheme() {
|
|
10
|
+
if (!hasContext(KEY)) {
|
|
11
|
+
throw sveltierError('SV1007', 'useTheme() was called outside a <ThemeProvider>. Call it in a component inside <UIProvider> or <ThemeProvider>.');
|
|
12
|
+
}
|
|
13
|
+
return getContext(KEY);
|
|
14
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ThemeChoice, ThemeDefinition } from './types.js';
|
|
2
|
+
export declare const THEME_ATTRIBUTE = "data-sv-theme";
|
|
3
|
+
export interface ThemeCssOptions {
|
|
4
|
+
themes: Record<string, ThemeDefinition>;
|
|
5
|
+
/** Theme used by "system" when the OS prefers light. */
|
|
6
|
+
light: string;
|
|
7
|
+
/** Theme used by "system" when the OS prefers dark. */
|
|
8
|
+
dark: string;
|
|
9
|
+
/** What `<html>` shows before any attribute is set (no JavaScript, nothing stored). */
|
|
10
|
+
fallback: ThemeChoice;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* One stylesheet for every theme, keyed by `data-sv-theme`. "system" is pure CSS
|
|
14
|
+
* (`prefers-color-scheme`), so the right theme paints before any JavaScript runs.
|
|
15
|
+
* It also holds a `.sv-color-<name>` class for every colour with an `on-` colour (intents
|
|
16
|
+
* and custom colours), which a component's `color` prop sets.
|
|
17
|
+
*/
|
|
18
|
+
export declare function themeCss({ themes, light, dark, fallback }: ThemeCssOptions): string;
|
|
19
|
+
/**
|
|
20
|
+
* Render-blocking script for `<head>`: applies a stored choice to `<html>` before the body
|
|
21
|
+
* is parsed, if it is one of `choices`. Exposed so a Content Security Policy can hash it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function themeScript(storageKey: string, choices: string[]): string;
|
|
24
|
+
/** Markup for `<svelte:head>`: the theme stylesheet, then the optional script. */
|
|
25
|
+
export declare function themeHead(css: string, script: string, nonce?: string): string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { sveltierError } from '../errors/errors.js';
|
|
2
|
+
export const THEME_ATTRIBUTE = 'data-sv-theme';
|
|
3
|
+
const NAME = /^(?!system$)[a-z][\w-]*$/i;
|
|
4
|
+
const KEY = /^[a-z][\w-]*$/i;
|
|
5
|
+
const UNSAFE = /[<>{};]/;
|
|
6
|
+
const NONCE = /^[\w+/=-]+$/;
|
|
7
|
+
function check(ok, code, message) {
|
|
8
|
+
if (!ok)
|
|
9
|
+
throw sveltierError(code, message);
|
|
10
|
+
}
|
|
11
|
+
/** `{color-scheme:…;--sv-color-x:…;--sv-on-x:…;--sv-var:…}` for one theme. */
|
|
12
|
+
function block(theme, name, registered) {
|
|
13
|
+
check(theme, 'SV1002', `Unknown theme "${name}". Registered: ${registered}.`);
|
|
14
|
+
let out = `color-scheme:${theme.dark ? 'dark' : 'light'}`;
|
|
15
|
+
const entries = [
|
|
16
|
+
...Object.entries(theme.colors).map(([k, v]) => [k.startsWith('on-') ? k : `color-${k}`, v]),
|
|
17
|
+
...Object.entries(theme.variables)
|
|
18
|
+
];
|
|
19
|
+
for (const [key, value] of entries) {
|
|
20
|
+
check(KEY.test(key), 'SV1003', `Invalid colour or variable name "${key}". Use letters, digits, - and _, starting with a letter.`);
|
|
21
|
+
check(!UNSAFE.test(String(value)), 'SV1004', `Unsafe value for "${key}": it contains <, >, {, } or ;. Use a plain CSS value.`);
|
|
22
|
+
out += `;--sv-${key}:${value}`;
|
|
23
|
+
}
|
|
24
|
+
return `{${out}}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* One stylesheet for every theme, keyed by `data-sv-theme`. "system" is pure CSS
|
|
28
|
+
* (`prefers-color-scheme`), so the right theme paints before any JavaScript runs.
|
|
29
|
+
* It also holds a `.sv-color-<name>` class for every colour with an `on-` colour (intents
|
|
30
|
+
* and custom colours), which a component's `color` prop sets.
|
|
31
|
+
*/
|
|
32
|
+
export function themeCss({ themes, light, dark, fallback }) {
|
|
33
|
+
const attr = (name) => `[${THEME_ATTRIBUTE}="${name}"]`;
|
|
34
|
+
const bare = `:root:not([${THEME_ATTRIBUTE}])`;
|
|
35
|
+
const system = attr('system') + (fallback === 'system' ? `,${bare}` : '');
|
|
36
|
+
const colors = new Set();
|
|
37
|
+
const registered = Object.keys(themes).join(', ');
|
|
38
|
+
let css = '';
|
|
39
|
+
for (const [name, theme] of Object.entries(themes)) {
|
|
40
|
+
check(NAME.test(name), 'SV1005', `Invalid theme name "${name}". Use letters, digits, - and _, starting with a letter; "system" is reserved.`);
|
|
41
|
+
css += attr(name) + block(theme, name, registered);
|
|
42
|
+
for (const key in theme.colors)
|
|
43
|
+
if (key.startsWith('on-'))
|
|
44
|
+
colors.add(key.slice(3));
|
|
45
|
+
}
|
|
46
|
+
css += `@media (prefers-color-scheme:light){${system}${block(themes[light], light, registered)}}`;
|
|
47
|
+
css += `@media (prefers-color-scheme:dark){${system}${block(themes[dark], dark, registered)}}`;
|
|
48
|
+
if (fallback !== 'system')
|
|
49
|
+
css += bare + block(themes[fallback], fallback, registered);
|
|
50
|
+
let classes = '';
|
|
51
|
+
for (const color of colors) {
|
|
52
|
+
classes += `.sv-color-${color}{--sv-color:var(--sv-color-${color});--sv-on-color:var(--sv-on-${color})}`;
|
|
53
|
+
}
|
|
54
|
+
return `@layer sv.tokens,sv.base,sv.components,sv.utilities;@layer sv.tokens{${css}}@layer sv.base{${classes}}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Render-blocking script for `<head>`: applies a stored choice to `<html>` before the body
|
|
58
|
+
* is parsed, if it is one of `choices`. Exposed so a Content Security Policy can hash it.
|
|
59
|
+
*/
|
|
60
|
+
export function themeScript(storageKey, choices) {
|
|
61
|
+
const json = (data) => JSON.stringify(data).replace(/</g, '\\u003c');
|
|
62
|
+
return `(function(){try{var t=localStorage.getItem(${json(storageKey)});if(${json(choices)}.indexOf(t)>-1)document.documentElement.setAttribute("${THEME_ATTRIBUTE}",t)}catch(e){}})()`;
|
|
63
|
+
}
|
|
64
|
+
/** Markup for `<svelte:head>`: the theme stylesheet, then the optional script. */
|
|
65
|
+
export function themeHead(css, script, nonce) {
|
|
66
|
+
check(nonce === undefined || NONCE.test(nonce), 'SV1006', 'Invalid nonce. Pass the base64 nonce of your Content Security Policy as it is.');
|
|
67
|
+
const attr = nonce ? ` nonce="${nonce}"` : '';
|
|
68
|
+
return `<style id="sv-theme"${attr}>${css}</style>${script && `<script${attr}>${script}</script>`}`;
|
|
69
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ThemeDefinition, ThemeInput } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a complete theme from the parts you change over `base`, the theme you extend.
|
|
4
|
+
* Missing colours and variables come from `base`. `on-` colours are recomputed for every
|
|
5
|
+
* colour you override, unless you pass them yourself. `base` is never mutated.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { monolithDark } from '@sveltier/ui/themes/monolith';
|
|
9
|
+
* const midnight = defineTheme({ colors: { primary: 'oklch(0.78 0.11 260)' } }, monolithDark);
|
|
10
|
+
*/
|
|
11
|
+
export declare function defineTheme(input: ThemeInput, base: ThemeDefinition): ThemeDefinition;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { withOnColors } from './resolve.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a complete theme from the parts you change over `base`, the theme you extend.
|
|
4
|
+
* Missing colours and variables come from `base`. `on-` colours are recomputed for every
|
|
5
|
+
* colour you override, unless you pass them yourself. `base` is never mutated.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* import { monolithDark } from '@sveltier/ui/themes/monolith';
|
|
9
|
+
* const midnight = defineTheme({ colors: { primary: 'oklch(0.78 0.11 260)' } }, monolithDark);
|
|
10
|
+
*/
|
|
11
|
+
export function defineTheme(input, base) {
|
|
12
|
+
const overrides = input.colors ?? {};
|
|
13
|
+
const colors = { ...base.colors };
|
|
14
|
+
for (const name of Object.keys(overrides))
|
|
15
|
+
delete colors[`on-${name}`];
|
|
16
|
+
return withOnColors({
|
|
17
|
+
dark: input.dark ?? base.dark,
|
|
18
|
+
colors: { ...colors, ...overrides },
|
|
19
|
+
variables: { ...base.variables, ...input.variables }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ThemeDefinition } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns a copy of the theme where every non-neutral colour without an explicit `on-`
|
|
4
|
+
* colour gets a computed one (a deep ink or a near-white, whichever contrasts more).
|
|
5
|
+
*/
|
|
6
|
+
export declare function withOnColors(theme: ThemeDefinition): ThemeDefinition;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { onColor } from './color.js';
|
|
2
|
+
import { NEUTRAL_COLORS } from './types.js';
|
|
3
|
+
const NEUTRAL = new Set(NEUTRAL_COLORS);
|
|
4
|
+
/**
|
|
5
|
+
* Returns a copy of the theme where every non-neutral colour without an explicit `on-`
|
|
6
|
+
* colour gets a computed one (a deep ink or a near-white, whichever contrasts more).
|
|
7
|
+
*/
|
|
8
|
+
export function withOnColors(theme) {
|
|
9
|
+
const colors = { ...theme.colors };
|
|
10
|
+
for (const [name, value] of Object.entries(theme.colors)) {
|
|
11
|
+
if (NEUTRAL.has(name) || name.startsWith('on-') || colors[`on-${name}`])
|
|
12
|
+
continue;
|
|
13
|
+
const on = onColor(value);
|
|
14
|
+
if (on)
|
|
15
|
+
colors[`on-${name}`] = on;
|
|
16
|
+
}
|
|
17
|
+
return { ...theme, colors };
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@layer sv.tokens, sv.base, sv.components, sv.utilities;
|
|
2
|
+
|
|
3
|
+
@layer sv.components {
|
|
4
|
+
/* A theme scope only re-declares custom properties, which inherit through display: contents. */
|
|
5
|
+
.sv-theme-provider {
|
|
6
|
+
display: contents;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.sv-theme-provider--background {
|
|
10
|
+
display: block;
|
|
11
|
+
background-color: var(--sv-color-background);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Neutral roles: page, surfaces, rules and text. They have no `on-` colour. */
|
|
2
|
+
export declare const NEUTRAL_COLORS: readonly ["background", "surface", "surface-raised", "border", "border-soft", "border-strong", "text", "text-muted", "text-subtle"];
|
|
3
|
+
/**
|
|
4
|
+
* Intent colours, usable as a component's `color`. Each gets an `on-` colour for text on a
|
|
5
|
+
* filled background. `up` / `down` are price direction and are kept separate from
|
|
6
|
+
* `success` / `error`, because some markets show rising prices in red.
|
|
7
|
+
*/
|
|
8
|
+
export declare const INTENT_COLORS: readonly ["primary", "success", "warning", "error", "info", "up", "down"];
|
|
9
|
+
export type NeutralColor = (typeof NEUTRAL_COLORS)[number];
|
|
10
|
+
export type IntentColor = (typeof INTENT_COLORS)[number];
|
|
11
|
+
/** Every colour value is an `oklch()` string. */
|
|
12
|
+
export type ThemeColors = Record<NeutralColor | IntentColor, string> & Partial<Record<`on-${IntentColor}`, string>> & Record<string, string>;
|
|
13
|
+
/**
|
|
14
|
+
* The theme contract: every theme sets all of these, so one theme switch restyles type,
|
|
15
|
+
* shape, depth and motion as well as colour. Emitted as `--sv-<name>`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const THEME_VARIABLES: readonly ["font-display", "font-ui", "font-data", "weight-display", "tracking-display", "label-size", "label-transform", "label-tracking", "button-transform", "button-tracking", "radius-sm", "radius-md", "radius-lg", "radius-xl", "radius-full", "surface-alpha", "surface-blur", "backdrop", "ornament", "bevel", "shadow", "ease", "duration-fast", "duration-normal", "duration-slow"];
|
|
18
|
+
export type ThemeVariable = (typeof THEME_VARIABLES)[number];
|
|
19
|
+
export type ThemeVariables = Record<ThemeVariable, string | number>;
|
|
20
|
+
export interface ThemeDefinition {
|
|
21
|
+
/** Dark themes set `color-scheme: dark` and are the `dark` target of "system". */
|
|
22
|
+
dark: boolean;
|
|
23
|
+
/** Emitted as `--sv-color-<name>`, and `on-<name>` keys as `--sv-on-<name>`. */
|
|
24
|
+
colors: ThemeColors;
|
|
25
|
+
/** The theme contract plus any extra custom properties, emitted as `--sv-<name>`. */
|
|
26
|
+
variables: ThemeVariables & Record<string, string | number>;
|
|
27
|
+
}
|
|
28
|
+
/** Partial theme accepted by `defineTheme()`; missing values come from the base theme. */
|
|
29
|
+
export interface ThemeInput {
|
|
30
|
+
dark?: boolean;
|
|
31
|
+
colors?: Partial<ThemeColors>;
|
|
32
|
+
variables?: Partial<ThemeVariables> & Record<string, string | number>;
|
|
33
|
+
}
|
|
34
|
+
/** A user choice: a theme name, or "system" to follow `prefers-color-scheme`. */
|
|
35
|
+
export type ThemeChoice = 'system' | (string & {});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Neutral roles: page, surfaces, rules and text. They have no `on-` colour. */
|
|
2
|
+
export const NEUTRAL_COLORS = [
|
|
3
|
+
'background',
|
|
4
|
+
'surface',
|
|
5
|
+
'surface-raised',
|
|
6
|
+
'border',
|
|
7
|
+
'border-soft',
|
|
8
|
+
'border-strong',
|
|
9
|
+
'text',
|
|
10
|
+
'text-muted',
|
|
11
|
+
'text-subtle'
|
|
12
|
+
];
|
|
13
|
+
/**
|
|
14
|
+
* Intent colours, usable as a component's `color`. Each gets an `on-` colour for text on a
|
|
15
|
+
* filled background. `up` / `down` are price direction and are kept separate from
|
|
16
|
+
* `success` / `error`, because some markets show rising prices in red.
|
|
17
|
+
*/
|
|
18
|
+
export const INTENT_COLORS = [
|
|
19
|
+
'primary',
|
|
20
|
+
'success',
|
|
21
|
+
'warning',
|
|
22
|
+
'error',
|
|
23
|
+
'info',
|
|
24
|
+
'up',
|
|
25
|
+
'down'
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* The theme contract: every theme sets all of these, so one theme switch restyles type,
|
|
29
|
+
* shape, depth and motion as well as colour. Emitted as `--sv-<name>`.
|
|
30
|
+
*/
|
|
31
|
+
export const THEME_VARIABLES = [
|
|
32
|
+
// Type
|
|
33
|
+
'font-display',
|
|
34
|
+
'font-ui',
|
|
35
|
+
'font-data',
|
|
36
|
+
'weight-display',
|
|
37
|
+
'tracking-display',
|
|
38
|
+
'label-size',
|
|
39
|
+
'label-transform',
|
|
40
|
+
'label-tracking',
|
|
41
|
+
'button-transform',
|
|
42
|
+
'button-tracking',
|
|
43
|
+
// Shape
|
|
44
|
+
'radius-sm',
|
|
45
|
+
'radius-md',
|
|
46
|
+
'radius-lg',
|
|
47
|
+
'radius-xl',
|
|
48
|
+
'radius-full',
|
|
49
|
+
// Depth
|
|
50
|
+
'surface-alpha',
|
|
51
|
+
'surface-blur',
|
|
52
|
+
'backdrop',
|
|
53
|
+
'ornament',
|
|
54
|
+
'bevel',
|
|
55
|
+
'shadow',
|
|
56
|
+
// Motion (collapsed to near zero when the user prefers reduced motion)
|
|
57
|
+
'ease',
|
|
58
|
+
'duration-fast',
|
|
59
|
+
'duration-normal',
|
|
60
|
+
'duration-slow'
|
|
61
|
+
];
|
package/dist/dev/off.js
ADDED
package/dist/dev/on.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const DEV: boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Warns when a prop that takes one of a fixed set of values got another one. `hint` names the
|
|
4
|
+
* likely intent, for example the prop the value belongs to.
|
|
5
|
+
*/
|
|
6
|
+
export declare function checkValue(component: string, prop: string, value: unknown, valid: readonly unknown[], hint?: string): void;
|
|
7
|
+
/** Warns when a form control has no accessible name: no label with text, and no ARIA name. */
|
|
8
|
+
export declare function warnUnnamed(component: string, control: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null | undefined): void;
|
package/dist/dev/on.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ERRORS_URL } from '../core/errors/errors.js';
|
|
2
|
+
export const DEV = true;
|
|
3
|
+
const warned = new Set();
|
|
4
|
+
/** Warns once per message, in the format of thrown errors. */
|
|
5
|
+
function warn(code, message) {
|
|
6
|
+
const text = `[sveltier ${code}] ${message} ${ERRORS_URL}#${code}`;
|
|
7
|
+
if (warned.has(text))
|
|
8
|
+
return;
|
|
9
|
+
warned.add(text);
|
|
10
|
+
console.warn(text);
|
|
11
|
+
}
|
|
12
|
+
const show = (value) => (typeof value === 'string' ? `'${value}'` : String(value));
|
|
13
|
+
/**
|
|
14
|
+
* Warns when a prop that takes one of a fixed set of values got another one. `hint` names the
|
|
15
|
+
* likely intent, for example the prop the value belongs to.
|
|
16
|
+
*/
|
|
17
|
+
export function checkValue(component, prop, value, valid, hint) {
|
|
18
|
+
if (value == null || valid.includes(value))
|
|
19
|
+
return;
|
|
20
|
+
const got = typeof value === 'string' ? `"${value}"` : `{${String(value)}}`;
|
|
21
|
+
warn('SV2002', `<${component}> got ${prop}=${got}. Valid values: ${valid.map(show).join(' | ')}.${hint ? ` ${hint}` : ''}`);
|
|
22
|
+
}
|
|
23
|
+
/** Warns when a form control has no accessible name: no label with text, and no ARIA name. */
|
|
24
|
+
export function warnUnnamed(component, control) {
|
|
25
|
+
if (!control)
|
|
26
|
+
return;
|
|
27
|
+
// A label that wraps the control but holds no text names nothing.
|
|
28
|
+
if ([...(control.labels ?? [])].some((label) => label.textContent?.trim()))
|
|
29
|
+
return;
|
|
30
|
+
if (control.getAttribute('aria-label') || control.getAttribute('aria-labelledby'))
|
|
31
|
+
return;
|
|
32
|
+
warn('SV5001', `<${component}> has no accessible name. Give it a label, or name it with aria-label or aria-labelledby.`);
|
|
33
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export { default as UIProvider, type UIProviderProps } from './core/provider/UIProvider.svelte';
|
|
2
|
+
export { default as ThemeProvider, type ThemeProviderProps } from './core/theme/ThemeProvider.svelte';
|
|
3
|
+
export { useTheme, type ThemeInstance } from './core/theme/context.js';
|
|
4
|
+
export { defineTheme } from './core/theme/define.js';
|
|
5
|
+
export { themeCss, themeScript, type ThemeCssOptions } from './core/theme/css.js';
|
|
6
|
+
export { contrast, onColor, parseOklch, type Oklch } from './core/theme/color.js';
|
|
7
|
+
export { INTENT_COLORS, NEUTRAL_COLORS, THEME_VARIABLES, type IntentColor, type NeutralColor, type ThemeChoice, type ThemeColors, type ThemeDefinition, type ThemeInput, type ThemeVariable, type ThemeVariables } from './core/theme/types.js';
|
|
8
|
+
export { monolith, monolithDark, monolithLight } from './themes/monolith.js';
|
|
9
|
+
export { heritage, heritageDark, heritageLight } from './themes/heritage.js';
|
|
10
|
+
export { aurora, auroraDark, auroraLight } from './themes/aurora.js';
|
|
11
|
+
export { maison, maisonDark, maisonLight } from './themes/maison.js';
|
|
12
|
+
export { milano, milanoDark, milanoLight } from './themes/milano.js';
|
|
13
|
+
export { DENSITIES, ROUNDED, SIZES, VARIANTS, type Color, type CustomColors, type Density, type Rounded, type SharedProps, type Size, type Variant } from './core/props/types.js';
|
|
14
|
+
export { sharedClasses, type SharedClassProps } from './core/props/classes.js';
|
|
15
|
+
export type { ElementProps } from './core/props/element.js';
|
|
16
|
+
export { default as DefaultsProvider, type DefaultsProviderProps } from './core/defaults/DefaultsProvider.svelte';
|
|
17
|
+
export { useDefaults, type ComponentDefaults, type DefaultsConfig, type GlobalDefaults } from './core/defaults/context.js';
|
|
18
|
+
export { BREAKPOINTS, useDisplay, type Breakpoint, type DisplayInstance, type DisplayOptions, type DisplayThresholds } from './core/display/display.js';
|
|
19
|
+
export { MESSAGES, useLocale, type LocaleInstance, type LocaleOptions, type MessageKey, type Messages } from './core/locale/locale.js';
|
|
20
|
+
export { ERROR_CODES, type ErrorCode, type ErrorEntry } from './core/errors/codes.js';
|
|
21
|
+
export type { FieldError, Rule, ValidateOn } from './core/form/types.js';
|
|
22
|
+
export { focusTrap, type FocusTrapOptions } from './primitives/focus/focus-trap.js';
|
|
23
|
+
export { rovingFocus, type RovingFocusOptions } from './primitives/focus/roving-focus.js';
|
|
24
|
+
export { isTabbable, tabbable, type FocusableElement } from './primitives/focus/tabbable.js';
|
|
25
|
+
export { dismissable, type DismissableOptions, type DismissReason } from './primitives/layer/dismissable.js';
|
|
26
|
+
export { default as Portal, type PortalProps } from './primitives/portal/Portal.svelte';
|
|
27
|
+
export { inertOthers } from './primitives/inert/inert-others.js';
|
|
28
|
+
export { scrollLock } from './primitives/scroll-lock/scroll-lock.js';
|
|
29
|
+
export { anchored, type Align, type AnchoredOptions, type Side } from './primitives/anchored/anchored.js';
|
|
30
|
+
export { combination, keymap, type KeyHandler } from './primitives/keyboard/keymap.js';
|
|
31
|
+
export { typeahead, type TypeaheadOptions } from './primitives/keyboard/typeahead.js';
|
|
32
|
+
export { cubicBezier } from './primitives/motion/easing.js';
|
|
33
|
+
export { easing, fade, motion, pop, rise, spring, SPRINGS, type Motion, type SpringPreset, type TransitionOptions } from './primitives/motion/motion.js';
|
|
34
|
+
export { virtualList, type ScrollToIndexOptions, type VirtualItem, type VirtualKey, type VirtualList, type VirtualListOptions } from './primitives/virtual/virtual-list.svelte.js';
|
|
35
|
+
export { Alert, type AlertDefaults, type AlertProps } from './components/Alert/index.js';
|
|
36
|
+
export { Avatar, type AvatarDefaults, type AvatarProps } from './components/Avatar/index.js';
|
|
37
|
+
export { Badge, type BadgeDefaults, type BadgeProps } from './components/Badge/index.js';
|
|
38
|
+
export { Button, type ButtonDefaults, type ButtonProps } from './components/Button/index.js';
|
|
39
|
+
export { ButtonGroup, type ButtonGroupDefaults, type ButtonGroupProps } from './components/ButtonGroup/index.js';
|
|
40
|
+
export { Card, type CardDefaults, type CardProps } from './components/Card/index.js';
|
|
41
|
+
export { Checkbox, type CheckboxDefaults, type CheckboxProps } from './components/Checkbox/index.js';
|
|
42
|
+
export { Chip, type ChipDefaults, type ChipProps } from './components/Chip/index.js';
|
|
43
|
+
export { Divider, type DividerProps } from './components/Divider/index.js';
|
|
44
|
+
export { Field, FIELD_VARIANTS, type FieldContentProps, type FieldControlAttributes, type FieldDefaults, type FieldProps, type FieldVariant } from './components/Field/index.js';
|
|
45
|
+
export { Form, type FormProps } from './components/Form/index.js';
|
|
46
|
+
export { Icon, type IconProps } from './components/Icon/index.js';
|
|
47
|
+
export { List, ListItem, type ListDefaults, type ListItemProps, type ListProps } from './components/List/index.js';
|
|
48
|
+
export { NativeSelect, type NativeSelectDefaults, type NativeSelectOption, type NativeSelectProps } from './components/NativeSelect/index.js';
|
|
49
|
+
export { NumberField, type NumberFieldDefaults, type NumberFieldProps } from './components/NumberField/index.js';
|
|
50
|
+
export { ProgressCircular, ProgressLinear, type ProgressCircularDefaults, type ProgressCircularProps, type ProgressLinearDefaults, type ProgressLinearProps } from './components/Progress/index.js';
|
|
51
|
+
export { RadioGroup, type RadioGroupDefaults, type RadioGroupOption, type RadioGroupProps } from './components/RadioGroup/index.js';
|
|
52
|
+
export { SegmentedControl, type SegmentedControlDefaults, type SegmentedControlOption, type SegmentedControlProps } from './components/SegmentedControl/index.js';
|
|
53
|
+
export { Skeleton, type SkeletonProps } from './components/Skeleton/index.js';
|
|
54
|
+
export { Slider, type SliderDefaults, type SliderProps, type SliderTick } from './components/Slider/index.js';
|
|
55
|
+
export { Switch, type SwitchDefaults, type SwitchProps } from './components/Switch/index.js';
|
|
56
|
+
export { Tabs, type TabsDefaults, type TabsItem, type TabsProps } from './components/Tabs/index.js';
|
|
57
|
+
export { Textarea, type TextareaDefaults, type TextareaProps } from './components/Textarea/index.js';
|
|
58
|
+
export { TextField, type TextFieldDefaults, type TextFieldProps, type TextFieldType } from './components/TextField/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Root provider
|
|
2
|
+
export { default as UIProvider } from './core/provider/UIProvider.svelte';
|
|
3
|
+
// Theme engine
|
|
4
|
+
export { default as ThemeProvider } from './core/theme/ThemeProvider.svelte';
|
|
5
|
+
export { useTheme } from './core/theme/context.js';
|
|
6
|
+
export { defineTheme } from './core/theme/define.js';
|
|
7
|
+
export { themeCss, themeScript } from './core/theme/css.js';
|
|
8
|
+
export { contrast, onColor, parseOklch } from './core/theme/color.js';
|
|
9
|
+
export { INTENT_COLORS, NEUTRAL_COLORS, THEME_VARIABLES } from './core/theme/types.js';
|
|
10
|
+
// Built-in themes, also importable one by one from '@sveltier/ui/themes/<name>'
|
|
11
|
+
export { monolith, monolithDark, monolithLight } from './themes/monolith.js';
|
|
12
|
+
export { heritage, heritageDark, heritageLight } from './themes/heritage.js';
|
|
13
|
+
export { aurora, auroraDark, auroraLight } from './themes/aurora.js';
|
|
14
|
+
export { maison, maisonDark, maisonLight } from './themes/maison.js';
|
|
15
|
+
export { milano, milanoDark, milanoLight } from './themes/milano.js';
|
|
16
|
+
// Shared props
|
|
17
|
+
export { DENSITIES, ROUNDED, SIZES, VARIANTS } from './core/props/types.js';
|
|
18
|
+
export { sharedClasses } from './core/props/classes.js';
|
|
19
|
+
// Defaults
|
|
20
|
+
export { default as DefaultsProvider } from './core/defaults/DefaultsProvider.svelte';
|
|
21
|
+
export { useDefaults } from './core/defaults/context.js';
|
|
22
|
+
// Display
|
|
23
|
+
export { BREAKPOINTS, useDisplay } from './core/display/display.js';
|
|
24
|
+
// Locale
|
|
25
|
+
export { MESSAGES, useLocale } from './core/locale/locale.js';
|
|
26
|
+
// Errors
|
|
27
|
+
export { ERROR_CODES } from './core/errors/codes.js';
|
|
28
|
+
// Primitives: focus
|
|
29
|
+
export { focusTrap } from './primitives/focus/focus-trap.js';
|
|
30
|
+
export { rovingFocus } from './primitives/focus/roving-focus.js';
|
|
31
|
+
export { isTabbable, tabbable } from './primitives/focus/tabbable.js';
|
|
32
|
+
// Primitives: layers
|
|
33
|
+
export { dismissable } from './primitives/layer/dismissable.js';
|
|
34
|
+
// Primitives: portal and modality
|
|
35
|
+
export { default as Portal } from './primitives/portal/Portal.svelte';
|
|
36
|
+
export { inertOthers } from './primitives/inert/inert-others.js';
|
|
37
|
+
export { scrollLock } from './primitives/scroll-lock/scroll-lock.js';
|
|
38
|
+
// Primitives: positioning
|
|
39
|
+
export { anchored } from './primitives/anchored/anchored.js';
|
|
40
|
+
// Primitives: keyboard
|
|
41
|
+
export { combination, keymap } from './primitives/keyboard/keymap.js';
|
|
42
|
+
export { typeahead } from './primitives/keyboard/typeahead.js';
|
|
43
|
+
// Primitives: motion
|
|
44
|
+
export { cubicBezier } from './primitives/motion/easing.js';
|
|
45
|
+
export { easing, fade, motion, pop, rise, spring, SPRINGS } from './primitives/motion/motion.js';
|
|
46
|
+
// Primitives: virtual lists
|
|
47
|
+
export { virtualList } from './primitives/virtual/virtual-list.svelte.js';
|
|
48
|
+
// Components
|
|
49
|
+
export { Alert } from './components/Alert/index.js';
|
|
50
|
+
export { Avatar } from './components/Avatar/index.js';
|
|
51
|
+
export { Badge } from './components/Badge/index.js';
|
|
52
|
+
export { Button } from './components/Button/index.js';
|
|
53
|
+
export { ButtonGroup } from './components/ButtonGroup/index.js';
|
|
54
|
+
export { Card } from './components/Card/index.js';
|
|
55
|
+
export { Checkbox } from './components/Checkbox/index.js';
|
|
56
|
+
export { Chip } from './components/Chip/index.js';
|
|
57
|
+
export { Divider } from './components/Divider/index.js';
|
|
58
|
+
export { Field, FIELD_VARIANTS } from './components/Field/index.js';
|
|
59
|
+
export { Form } from './components/Form/index.js';
|
|
60
|
+
export { Icon } from './components/Icon/index.js';
|
|
61
|
+
export { List, ListItem } from './components/List/index.js';
|
|
62
|
+
export { NativeSelect } from './components/NativeSelect/index.js';
|
|
63
|
+
export { NumberField } from './components/NumberField/index.js';
|
|
64
|
+
export { ProgressCircular, ProgressLinear } from './components/Progress/index.js';
|
|
65
|
+
export { RadioGroup } from './components/RadioGroup/index.js';
|
|
66
|
+
export { SegmentedControl } from './components/SegmentedControl/index.js';
|
|
67
|
+
export { Skeleton } from './components/Skeleton/index.js';
|
|
68
|
+
export { Slider } from './components/Slider/index.js';
|
|
69
|
+
export { Switch } from './components/Switch/index.js';
|
|
70
|
+
export { Tabs } from './components/Tabs/index.js';
|
|
71
|
+
export { Textarea } from './components/Textarea/index.js';
|
|
72
|
+
export { TextField } from './components/TextField/index.js';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Attachment } from 'svelte/attachments';
|
|
2
|
+
export declare const SIDES: readonly ["top", "bottom", "start", "end"];
|
|
3
|
+
export declare const ALIGNS: readonly ["start", "center", "end"];
|
|
4
|
+
export declare const PHYSICAL_SIDES: readonly ["top", "bottom", "left", "right"];
|
|
5
|
+
/** Side of the anchor. `start` and `end` follow the writing direction. */
|
|
6
|
+
export type Side = (typeof SIDES)[number];
|
|
7
|
+
/** Alignment along that side, following the writing direction. */
|
|
8
|
+
export type Align = (typeof ALIGNS)[number];
|
|
9
|
+
export type PhysicalSide = (typeof PHYSICAL_SIDES)[number];
|
|
10
|
+
export interface AnchoredOptions {
|
|
11
|
+
/** The element to place against. Nothing happens until it exists. */
|
|
12
|
+
anchor: Element | null | undefined;
|
|
13
|
+
/** Defaults to `'bottom'`. */
|
|
14
|
+
side?: Side;
|
|
15
|
+
/** Defaults to `'start'`. */
|
|
16
|
+
align?: Align;
|
|
17
|
+
/** Gap between the anchor and the floating element, in px. Defaults to 5. */
|
|
18
|
+
offset?: number;
|
|
19
|
+
/** Move to the opposite side when there is not enough room. Defaults to `true`. */
|
|
20
|
+
flip?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The physical side, and the alignment in physical terms (start is left or top), of a
|
|
24
|
+
* logical placement in the element's direction. Both placement paths use it, so they agree.
|
|
25
|
+
*/
|
|
26
|
+
export declare function physical(side: Side, align: Align, rtl: boolean): [PhysicalSide, Align];
|
|
27
|
+
/** `position-area` in physical keywords: `bottom span-right` is below, from the left edge. */
|
|
28
|
+
export declare function positionArea(side: PhysicalSide, align: Align): string;
|
|
29
|
+
/**
|
|
30
|
+
* Places the element next to `anchor` and keeps it there on scroll and resize, flipping to
|
|
31
|
+
* the opposite side when there is not enough room. Uses CSS anchor positioning where the
|
|
32
|
+
* browser has it, otherwise loads a small script. The element must be positioned against the
|
|
33
|
+
* viewport: a popover in the top layer, or `position: fixed`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* <button bind:this={trigger}>Account</button>
|
|
37
|
+
* <div popover="manual" {@attach anchored({ anchor: trigger, side: 'bottom', align: 'end' })}>…</div>
|
|
38
|
+
*/
|
|
39
|
+
export declare function anchored({ anchor, side, align, offset, flip }: AnchoredOptions): Attachment<HTMLElement>;
|