@greese/ui 0.0.0-stage → 1.0.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 +55 -2
- package/bin/greese-utilities.mjs +56 -0
- package/dist/_layers.scss +2 -0
- package/dist/_maps.scss +1884 -0
- package/dist/_tokens-base.scss +174 -0
- package/dist/_tokens.scss +2140 -0
- package/dist/base.css +67 -0
- package/dist/colorScheme.d.ts +16 -0
- package/dist/colorScheme.js +13 -0
- package/dist/contrast.d.ts +15 -0
- package/dist/contrast.js +43 -0
- package/dist/css/Accordion.css +9 -0
- package/dist/css/ActionSelect.css +6 -0
- package/dist/css/Alert.css +84 -0
- package/dist/css/AppBar.css +35 -0
- package/dist/css/AspectRatio.css +40 -0
- package/dist/css/AutoLayout.css +508 -0
- package/dist/css/Avatar.css +88 -0
- package/dist/css/Badge.css +66 -0
- package/dist/css/Box.css +640 -0
- package/dist/css/Breadcrumbs.css +57 -0
- package/dist/css/Button.css +275 -0
- package/dist/css/ButtonGroup.css +40 -0
- package/dist/css/Card.css +101 -0
- package/dist/css/Carousel.css +170 -0
- package/dist/css/Center.css +11 -0
- package/dist/css/ChatBubble.css +128 -0
- package/dist/css/Checkbox.css +65 -0
- package/dist/css/Chip.css +124 -0
- package/dist/css/ChoiceGroup.css +57 -0
- package/dist/css/Code.css +29 -0
- package/dist/css/Collapsible.css +126 -0
- package/dist/css/ColorPicker.css +191 -0
- package/dist/css/Combobox.css +90 -0
- package/dist/css/Container.css +30 -0
- package/dist/css/Countdown.css +25 -0
- package/dist/css/DateField.css +15 -0
- package/dist/css/Dialog.css +640 -0
- package/dist/css/Diff.css +103 -0
- package/dist/css/Divider.css +19 -0
- package/dist/css/Dock.css +91 -0
- package/dist/css/Field.css +33 -0
- package/dist/css/Fieldset.css +54 -0
- package/dist/css/FileInput.css +65 -0
- package/dist/css/Footer.css +72 -0
- package/dist/css/Grid.css +998 -0
- package/dist/css/Header.css +89 -0
- package/dist/css/Heading.css +6 -0
- package/dist/css/Icon.css +12 -0
- package/dist/css/IconButton.css +7 -0
- package/dist/css/Image.css +69 -0
- package/dist/css/Indicator.css +41 -0
- package/dist/css/Input.css +115 -0
- package/dist/css/Key.css +42 -0
- package/dist/css/Link.css +72 -0
- package/dist/css/List.css +52 -0
- package/dist/css/Media.css +8 -0
- package/dist/css/Menu.css +161 -0
- package/dist/css/Motion.css +1356 -0
- package/dist/css/NumberField.css +49 -0
- package/dist/css/OtpField.css +90 -0
- package/dist/css/PageTransition.css +979 -0
- package/dist/css/Pagination.css +43 -0
- package/dist/css/Popover.css +93 -0
- package/dist/css/Progress.css +101 -0
- package/dist/css/RadialProgress.css +44 -0
- package/dist/css/Radio.css +41 -0
- package/dist/css/Rating.css +100 -0
- package/dist/css/ScrollSpy.css +6 -0
- package/dist/css/SegmentedControl.css +101 -0
- package/dist/css/Select.css +115 -0
- package/dist/css/Sidebar.css +207 -0
- package/dist/css/Skeleton.css +48 -0
- package/dist/css/Slider.css +75 -0
- package/dist/css/Spacer.css +34 -0
- package/dist/css/SpeedDial.css +165 -0
- package/dist/css/Spinner.css +44 -0
- package/dist/css/Stack.css +528 -0
- package/dist/css/Stat.css +107 -0
- package/dist/css/Status.css +86 -0
- package/dist/css/Steps.css +201 -0
- package/dist/css/Swap.css +49 -0
- package/dist/css/Switch.css +66 -0
- package/dist/css/Table.css +269 -0
- package/dist/css/Tabs.css +119 -0
- package/dist/css/Text.css +60 -0
- package/dist/css/TextRotate.css +147 -0
- package/dist/css/Textarea.css +107 -0
- package/dist/css/ThemeProvider.css +6 -0
- package/dist/css/Tile.css +18 -0
- package/dist/css/Toast.css +110 -0
- package/dist/css/ToggleButton.css +20 -0
- package/dist/css/Tooltip.css +94 -0
- package/dist/css/Type.css +211 -0
- package/dist/css/Visibility.css +78 -0
- package/dist/css/VisuallyHidden.css +15 -0
- package/dist/css/core.css +251 -0
- package/dist/css.d.ts +29 -0
- package/dist/css.js +28 -0
- package/dist/effect-classes.d.ts +8 -0
- package/dist/effect-classes.js +5 -0
- package/dist/effects/css.d.ts +71 -0
- package/dist/effects/css.js +184 -0
- package/dist/effects/definitions.d.ts +555 -0
- package/dist/effects/definitions.js +379 -0
- package/dist/effects/frames.d.ts +18 -0
- package/dist/effects/frames.js +68 -0
- package/dist/effects/sequence.d.ts +33 -0
- package/dist/effects/sequence.js +106 -0
- package/dist/effects.d.ts +30 -0
- package/dist/effects.js +30 -0
- package/dist/greese.css +11907 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/kebab.d.ts +2 -0
- package/dist/kebab.js +2 -0
- package/dist/palette.css +249 -0
- package/dist/palette.d.ts +599 -0
- package/dist/palette.js +334 -0
- package/dist/shapes.d.ts +193 -0
- package/dist/shapes.js +852 -0
- package/dist/storage.d.ts +47 -0
- package/dist/storage.js +118 -0
- package/dist/style-manifest.json +3010 -0
- package/dist/theme.d.ts +71 -0
- package/dist/theme.js +180 -0
- package/dist/tokens.css +253 -0
- package/dist/tokens.d.ts +343 -0
- package/dist/tokens.js +179 -0
- package/dist/typography.d.ts +55 -0
- package/dist/typography.js +144 -0
- package/dist/utilities.css +6975 -0
- package/dist/utilities.d.ts +82 -0
- package/dist/utilities.js +636 -0
- package/dist/utilitiesFiles.d.ts +18 -0
- package/dist/utilitiesFiles.js +26 -0
- package/dist/vite.d.ts +40 -0
- package/dist/vite.js +43 -0
- package/package.json +131 -4
- package/src/components/Accordion/Accordion.scss +9 -0
- package/src/components/ActionSelect/ActionSelect.scss +6 -0
- package/src/components/Alert/Alert.scss +71 -0
- package/src/components/AppBar/AppBar.scss +43 -0
- package/src/components/AspectRatio/AspectRatio.scss +22 -0
- package/src/components/AutoLayout/AutoLayout.scss +90 -0
- package/src/components/Avatar/Avatar.scss +91 -0
- package/src/components/Badge/Badge.scss +52 -0
- package/src/components/Box/Box.scss +63 -0
- package/src/components/Breadcrumbs/Breadcrumbs.scss +59 -0
- package/src/components/Button/Button.scss +231 -0
- package/src/components/ButtonGroup/ButtonGroup.scss +56 -0
- package/src/components/Card/Card.scss +99 -0
- package/src/components/Carousel/Carousel.scss +161 -0
- package/src/components/Center/Center.scss +11 -0
- package/src/components/ChatBubble/ChatBubble.scss +119 -0
- package/src/components/Checkbox/Checkbox.scss +66 -0
- package/src/components/Chip/Chip.scss +119 -0
- package/src/components/ChoiceGroup/ChoiceGroup.scss +69 -0
- package/src/components/Code/Code.scss +28 -0
- package/src/components/Collapsible/Collapsible.scss +136 -0
- package/src/components/ColorPicker/ColorPicker.scss +235 -0
- package/src/components/Combobox/Combobox.scss +83 -0
- package/src/components/Container/Container.scss +28 -0
- package/src/components/Countdown/Countdown.scss +28 -0
- package/src/components/DateField/DateField.scss +19 -0
- package/src/components/Dialog/Dialog.scss +268 -0
- package/src/components/Diff/Diff.scss +125 -0
- package/src/components/Divider/Divider.scss +22 -0
- package/src/components/Dock/Dock.scss +86 -0
- package/src/components/Field/Field.scss +38 -0
- package/src/components/Fieldset/Fieldset.scss +63 -0
- package/src/components/FileInput/FileInput.scss +66 -0
- package/src/components/Footer/Footer.scss +79 -0
- package/src/components/Grid/Grid.scss +86 -0
- package/src/components/Header/Header.scss +111 -0
- package/src/components/Heading/Heading.scss +7 -0
- package/src/components/Icon/Icon.scss +12 -0
- package/src/components/IconButton/IconButton.scss +6 -0
- package/src/components/Image/Image.scss +46 -0
- package/src/components/Indicator/Indicator.scss +48 -0
- package/src/components/Input/Input.scss +58 -0
- package/src/components/Key/Key.scss +48 -0
- package/src/components/Link/Link.scss +50 -0
- package/src/components/List/List.scss +62 -0
- package/src/components/Media/Media.scss +7 -0
- package/src/components/Menu/Menu.scss +91 -0
- package/src/components/Motion/Motion.scss +106 -0
- package/src/components/NumberField/NumberField.scss +44 -0
- package/src/components/OtpField/OtpField.scss +91 -0
- package/src/components/PageTransition/PageTransition.scss +168 -0
- package/src/components/Pagination/Pagination.scss +55 -0
- package/src/components/Popover/Popover.scss +13 -0
- package/src/components/Progress/Progress.scss +126 -0
- package/src/components/RadialProgress/RadialProgress.scss +65 -0
- package/src/components/Radio/Radio.scss +36 -0
- package/src/components/Rating/Rating.scss +121 -0
- package/src/components/ScrollSpy/ScrollSpy.scss +6 -0
- package/src/components/SegmentedControl/SegmentedControl.scss +107 -0
- package/src/components/Select/Select.scss +59 -0
- package/src/components/Sidebar/Sidebar.scss +88 -0
- package/src/components/Skeleton/Skeleton.scss +60 -0
- package/src/components/Slider/Slider.scss +96 -0
- package/src/components/Spacer/Spacer.scss +15 -0
- package/src/components/SpeedDial/SpeedDial.scss +109 -0
- package/src/components/Spinner/Spinner.scss +43 -0
- package/src/components/Stack/Stack.scss +57 -0
- package/src/components/Stat/Stat.scss +96 -0
- package/src/components/Status/Status.scss +60 -0
- package/src/components/Steps/Steps.scss +216 -0
- package/src/components/Swap/Swap.scss +62 -0
- package/src/components/Switch/Switch.scss +63 -0
- package/src/components/Table/Table.scss +183 -0
- package/src/components/Tabs/Tabs.scss +108 -0
- package/src/components/Text/Text.scss +34 -0
- package/src/components/TextRotate/TextRotate.scss +51 -0
- package/src/components/Textarea/Textarea.scss +56 -0
- package/src/components/ThemeProvider/ThemeProvider.scss +7 -0
- package/src/components/Tile/Tile.scss +23 -0
- package/src/components/Toast/Toast.scss +93 -0
- package/src/components/ToggleButton/ToggleButton.scss +23 -0
- package/src/components/Tooltip/Tooltip.scss +21 -0
- package/src/components/Type/Type.scss +35 -0
- package/src/components/Visibility/Visibility.scss +39 -0
- package/src/components/VisuallyHidden/VisuallyHidden.scss +17 -0
- package/src/styles/_breakpoint-vars.scss +16 -0
- package/src/styles/_config.scss +48 -0
- package/src/styles/_controls.scss +88 -0
- package/src/styles/_core.scss +4 -0
- package/src/styles/_effect.scss +51 -0
- package/src/styles/_floating.scss +141 -0
- package/src/styles/_kit.scss +1548 -0
- package/src/styles/_manifest.scss +670 -0
- package/src/styles/_mixins.scss +261 -0
- package/src/styles/_tones.scss +63 -0
- package/src/styles/_type-emit.scss +76 -0
- package/src/styles/_typography-vars.scss +8 -0
- package/src/styles/base.scss +80 -0
- package/src/styles/breakpoints.test.ts +73 -0
- package/src/styles/entryPoints.test.ts +68 -0
- package/src/styles/index.scss +93 -0
- package/src/styles/kit.test.ts +754 -0
- package/src/styles/public/_controls.scss +3 -0
- package/src/styles/public/_floating.scss +3 -0
- package/src/styles/public/_mixins.scss +5 -0
- package/src/styles/public/_tones.scss +4 -0
- package/themes/bevel.css +1077 -0
- package/themes/bevel.scss +1166 -0
- package/themes/depth.css +123 -0
- package/themes/depth.scss +46 -0
- package/themes/extrude.css +219 -0
- package/themes/extrude.scss +255 -0
- package/themes/folio.css +986 -0
- package/themes/folio.scss +1047 -0
- package/themes/gentle.css +66 -0
- package/themes/gentle.scss +39 -0
- package/themes/outline.css +127 -0
- package/themes/outline.scss +126 -0
- package/themes/pebble.css +65 -0
- package/themes/pebble.scss +69 -0
- package/themes/pocket.css +137 -0
- package/themes/pocket.scss +45 -0
- package/themes/ridge.css +927 -0
- package/themes/ridge.scss +998 -0
- package/themes/snappy.css +82 -0
- package/themes/snappy.scss +40 -0
- package/themes/soft.css +79 -0
- package/themes/soft.scss +84 -0
- package/themes/ticket.css +960 -0
- package/themes/ticket.scss +1031 -0
- package/themes/tilt.css +148 -0
- package/themes/tilt.scss +169 -0
- package/themes/wipe.css +186 -0
- package/themes/wipe.scss +46 -0
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { type TypeSpec, type TypeVariant } from './typography.ts';
|
|
2
|
+
import { scalarTokens, type ColorRole, type ScalarGroup, type TokenPair } from './tokens.ts';
|
|
3
|
+
/** A color override: one value for both schemes, or a light/dark pair. */
|
|
4
|
+
export type ColorValue = string | TokenPair;
|
|
5
|
+
/** Tokens the system doesn't have, by group: `{ color: { 'brand-ink': '#1b1340' } }`. */
|
|
6
|
+
export type ExtendTokens = {
|
|
7
|
+
/** A new color role: one value, or a light/dark pair. */
|
|
8
|
+
color?: Record<string, ColorValue>;
|
|
9
|
+
} & {
|
|
10
|
+
[G in ScalarGroup]?: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
export type ThemeOptions = {
|
|
13
|
+
/** Scopes the theme: `[data-greese-theme="<name>"]`. Letters, digits, `-`. */
|
|
14
|
+
name: string;
|
|
15
|
+
color?: Partial<Record<ColorRole, ColorValue>>;
|
|
16
|
+
/**
|
|
17
|
+
* Adds tokens that don't exist yet, each declared as
|
|
18
|
+
* `--greese-<group>-<key>` in this theme (in both schemes, for a color).
|
|
19
|
+
* Names that already exist, and groups that don't, throw: set an existing
|
|
20
|
+
* token through its group above.
|
|
21
|
+
*/
|
|
22
|
+
extend?: ExtendTokens;
|
|
23
|
+
/**
|
|
24
|
+
* Type system values by variant, then `base` or a breakpoint, then property
|
|
25
|
+
* (`{ h1: { base: { size: '2rem' }, lg: { size: '4rem' } } }`). What you set
|
|
26
|
+
* replaces the default at that point and the rest stays. The breakpoints are
|
|
27
|
+
* the defaults' widths; a build with its own uses the SCSS kit's
|
|
28
|
+
* `typography()` instead.
|
|
29
|
+
*/
|
|
30
|
+
typography?: Partial<Record<TypeVariant, TypeSpec>>;
|
|
31
|
+
} & {
|
|
32
|
+
[G in ScalarGroup]?: Partial<Record<keyof (typeof scalarTokens)[G], string>>;
|
|
33
|
+
};
|
|
34
|
+
export interface Theme {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
/**
|
|
37
|
+
* Static CSS for this theme, in `@layer greese.theme`. Generated once, here;
|
|
38
|
+
* nothing is computed per render. ThemeProvider injects it, or serve it
|
|
39
|
+
* yourself and set `data-greese-theme` on any element (`<html>` included).
|
|
40
|
+
*/
|
|
41
|
+
readonly css: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Fills in what follows a brand color the theme set: its `Content` color,
|
|
45
|
+
* the more readable of white and near-black (WCAG AA), measured per scheme,
|
|
46
|
+
* and its `Strong` shade, mixed by the browser from the color itself
|
|
47
|
+
* (darker in light, lighter in dark). Anything the theme sets wins, and a
|
|
48
|
+
* color that can't be measured (not a hex) keeps the default content.
|
|
49
|
+
*/
|
|
50
|
+
export declare const deriveColors: (overrides: Partial<Record<ColorRole, ColorValue>>) => Partial<Record<ColorRole, ColorValue>>;
|
|
51
|
+
/**
|
|
52
|
+
* Builds a theme: the default tokens with your overrides applied. Setting a
|
|
53
|
+
* brand color (`primary`, `secondary`, `tertiary`, `accent`, `negative`)
|
|
54
|
+
* also sets its `Content` and `Strong` colors unless you set them: see
|
|
55
|
+
* {@link deriveColors}.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* export const brand = createTheme({
|
|
59
|
+
* name: 'brand',
|
|
60
|
+
* color: { primary: { light: '#7c3aed', dark: '#c4b5fd' } },
|
|
61
|
+
* radius: { md: '12px' },
|
|
62
|
+
* })
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* A theme is complete, not a delta: its CSS declares every token, so a
|
|
66
|
+
* ThemeProvider renders exactly that theme whatever its ancestors are. Themes
|
|
67
|
+
* do not stack; to extend one, create another with more overrides.
|
|
68
|
+
*
|
|
69
|
+
* Call it at module scope, not during render: the result is meant to be static.
|
|
70
|
+
*/
|
|
71
|
+
export declare const createTheme: (options: ThemeOptions) => Theme;
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { allDurationKeys, cssVar, decls, kebab, LAYER_ORDER, reducedMotionDecls, SCHEME_ATTR, THEME_ATTR, } from "./css.js";
|
|
2
|
+
import { contentColor } from "./contrast.js";
|
|
3
|
+
import { mergeTypography, typography as defaultTypography, typographyByBreakpoint, } from "./typography.js";
|
|
4
|
+
import { color, scalarTokens, } from "./tokens.js";
|
|
5
|
+
const NAME = /^[a-z][a-z0-9-]*$/i;
|
|
6
|
+
// Theme values land inside a <style> element: refuse anything that could end a
|
|
7
|
+
// declaration, a rule, or the element itself.
|
|
8
|
+
const UNSAFE_VALUE = /[;{}<>]/;
|
|
9
|
+
const check = (property, value) => {
|
|
10
|
+
if (UNSAFE_VALUE.test(value)) {
|
|
11
|
+
throw new Error(`createTheme: invalid value for ${property}: ${JSON.stringify(value)}`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
};
|
|
15
|
+
/** Colors whose `Content` (and, where it exists, `Strong`) follow them. */
|
|
16
|
+
const DERIVED = ['primary', 'secondary', 'tertiary', 'accent', 'negative'];
|
|
17
|
+
const toPair = (value) => typeof value === 'string' ? { light: value, dark: value } : value;
|
|
18
|
+
/**
|
|
19
|
+
* Fills in what follows a brand color the theme set: its `Content` color,
|
|
20
|
+
* the more readable of white and near-black (WCAG AA), measured per scheme,
|
|
21
|
+
* and its `Strong` shade, mixed by the browser from the color itself
|
|
22
|
+
* (darker in light, lighter in dark). Anything the theme sets wins, and a
|
|
23
|
+
* color that can't be measured (not a hex) keeps the default content.
|
|
24
|
+
*/
|
|
25
|
+
export const deriveColors = (overrides) => {
|
|
26
|
+
const out = { ...overrides };
|
|
27
|
+
for (const role of DERIVED) {
|
|
28
|
+
const main = overrides[role];
|
|
29
|
+
if (main === undefined)
|
|
30
|
+
continue;
|
|
31
|
+
const pair = toPair(main);
|
|
32
|
+
const content = `${role}Content`;
|
|
33
|
+
if (overrides[content] === undefined) {
|
|
34
|
+
const fallback = color[content];
|
|
35
|
+
out[content] = {
|
|
36
|
+
light: contentColor(pair.light) ?? fallback.light,
|
|
37
|
+
dark: contentColor(pair.dark) ?? fallback.dark,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const strong = `${role}Strong`;
|
|
41
|
+
if (strong in color && overrides[strong] === undefined) {
|
|
42
|
+
const self = `var(${cssVar('color', role)})`;
|
|
43
|
+
out[strong] = {
|
|
44
|
+
light: `color-mix(in oklab, ${self} 80%, #000)`,
|
|
45
|
+
dark: `color-mix(in oklab, ${self} 70%, #fff)`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Builds a theme: the default tokens with your overrides applied. Setting a
|
|
53
|
+
* brand color (`primary`, `secondary`, `tertiary`, `accent`, `negative`)
|
|
54
|
+
* also sets its `Content` and `Strong` colors unless you set them: see
|
|
55
|
+
* {@link deriveColors}.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* export const brand = createTheme({
|
|
59
|
+
* name: 'brand',
|
|
60
|
+
* color: { primary: { light: '#7c3aed', dark: '#c4b5fd' } },
|
|
61
|
+
* radius: { md: '12px' },
|
|
62
|
+
* })
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* A theme is complete, not a delta: its CSS declares every token, so a
|
|
66
|
+
* ThemeProvider renders exactly that theme whatever its ancestors are. Themes
|
|
67
|
+
* do not stack; to extend one, create another with more overrides.
|
|
68
|
+
*
|
|
69
|
+
* Call it at module scope, not during render: the result is meant to be static.
|
|
70
|
+
*/
|
|
71
|
+
export const createTheme = (options) => {
|
|
72
|
+
const { name, color: colorOverrides = {}, extend = {}, typography: typeChanges, ...scalarOverrides } = options;
|
|
73
|
+
if (!NAME.test(name)) {
|
|
74
|
+
throw new Error(`createTheme: name must match ${NAME}, got ${JSON.stringify(name)}`);
|
|
75
|
+
}
|
|
76
|
+
const light = [];
|
|
77
|
+
const dark = [];
|
|
78
|
+
const colors = deriveColors(colorOverrides);
|
|
79
|
+
for (const [role, fallback] of Object.entries(color)) {
|
|
80
|
+
const prop = cssVar('color', role);
|
|
81
|
+
const pair = toPair(colors[role] ?? fallback);
|
|
82
|
+
light.push([prop, check(prop, pair.light)]);
|
|
83
|
+
dark.push([prop, check(prop, pair.dark)]);
|
|
84
|
+
}
|
|
85
|
+
const base = [];
|
|
86
|
+
for (const [group, defaults] of Object.entries(scalarTokens)) {
|
|
87
|
+
const overrides = scalarOverrides[group] ?? {};
|
|
88
|
+
for (const [key, fallback] of Object.entries(defaults)) {
|
|
89
|
+
const prop = cssVar(group, key);
|
|
90
|
+
base.push([prop, check(prop, overrides[key] ?? fallback)]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
addExtended(extend, base, light, dark);
|
|
94
|
+
// Complete like the rest: every variant, the smallest screen's values with
|
|
95
|
+
// the theme's tokens and the changes in media queries.
|
|
96
|
+
const steps = typographyByBreakpoint(mergeTypography(defaultTypography, typeChanges));
|
|
97
|
+
for (const [, list] of steps)
|
|
98
|
+
for (const [prop, value] of list)
|
|
99
|
+
check(prop, value);
|
|
100
|
+
base.push(...steps.filter(([min]) => min === 0).flatMap(([, list]) => list));
|
|
101
|
+
return {
|
|
102
|
+
name,
|
|
103
|
+
css: themeCss(name, base, light, dark, steps.filter(([min]) => min > 0)),
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
const TOKEN_KEY = /^[a-z0-9][a-z0-9-]*$/;
|
|
107
|
+
/** Declares `extend`'s new tokens, refusing names that exist or groups that don't. */
|
|
108
|
+
const addExtended = (extend, base, light, dark) => {
|
|
109
|
+
for (const [group, values] of Object.entries(extend)) {
|
|
110
|
+
const known = group === 'color'
|
|
111
|
+
? color
|
|
112
|
+
: scalarTokens[group];
|
|
113
|
+
if (!known)
|
|
114
|
+
throw new Error(`createTheme: no token group ${group} to extend`);
|
|
115
|
+
for (const [key, value] of Object.entries(values ?? {})) {
|
|
116
|
+
const name = kebab(key);
|
|
117
|
+
if (!TOKEN_KEY.test(name) || Object.keys(known).some((k) => kebab(k) === name)) {
|
|
118
|
+
throw new Error(`createTheme: ${group} token ${key} is invalid or already exists`);
|
|
119
|
+
}
|
|
120
|
+
const prop = cssVar(group, name);
|
|
121
|
+
if (group === 'color') {
|
|
122
|
+
const pair = toPair(value);
|
|
123
|
+
light.push([prop, check(prop, pair.light)]);
|
|
124
|
+
dark.push([prop, check(prop, pair.dark)]);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
base.push([prop, check(prop, value)]);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
/*
|
|
133
|
+
* Every scheme boundary inside a ThemeProvider stamps both attributes on one
|
|
134
|
+
* element, so these rules only need compound selectors on that element. The
|
|
135
|
+
* `:root[scheme] T:not([scheme])` rules cover a scheme forced on <html> (by
|
|
136
|
+
* useColorScheme) above a theme that sets none itself.
|
|
137
|
+
*
|
|
138
|
+
* Layer `greese.theme` sits above `greese.tokens`, so a theme beats the default
|
|
139
|
+
* scheme rules on the same element regardless of specificity.
|
|
140
|
+
*/
|
|
141
|
+
const themeCss = (name, base, light, dark, media) => {
|
|
142
|
+
const T = `[${THEME_ATTR}='${name}']`;
|
|
143
|
+
const S = (scheme) => `[${SCHEME_ATTR}='${scheme}']`;
|
|
144
|
+
return `${LAYER_ORDER}
|
|
145
|
+
@layer greese.theme {
|
|
146
|
+
${T} {
|
|
147
|
+
${decls([...base, ...light], ' ')}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@media (prefers-color-scheme: dark) {
|
|
151
|
+
${T}:not(${S('light')}) {
|
|
152
|
+
${decls(dark, ' ')}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
${T}${S('dark')},
|
|
157
|
+
:root${S('dark')} ${T}:not([${SCHEME_ATTR}]) {
|
|
158
|
+
${decls(dark, ' ')}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
:root${S('light')} ${T}:not([${SCHEME_ATTR}]) {
|
|
162
|
+
${decls(light, ' ')}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@media (prefers-reduced-motion: reduce) {
|
|
166
|
+
${T} {
|
|
167
|
+
${decls(reducedMotionDecls(allDurationKeys), ' ')}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
${media
|
|
171
|
+
.map(([min, list]) => `
|
|
172
|
+
@media (width >= ${min}px) {
|
|
173
|
+
${T} {
|
|
174
|
+
${decls(list, ' ')}
|
|
175
|
+
}
|
|
176
|
+
}`)
|
|
177
|
+
.join('\n')}
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
};
|
package/dist/tokens.css
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/* GENERATED by @greese/ui from src/tokens.ts - do not edit. */
|
|
2
|
+
@layer greese.reset, greese.tokens, greese.theme, greese.base, greese.components, greese.overrides, greese.utilities;
|
|
3
|
+
@layer greese.tokens {
|
|
4
|
+
:root {
|
|
5
|
+
--greese-loaded: 1;
|
|
6
|
+
--greese-space-0: 0;
|
|
7
|
+
--greese-space-1: 0.25rem;
|
|
8
|
+
--greese-space-2: 0.5rem;
|
|
9
|
+
--greese-space-3: 0.75rem;
|
|
10
|
+
--greese-space-4: 1rem;
|
|
11
|
+
--greese-space-5: 1.5rem;
|
|
12
|
+
--greese-space-6: 2rem;
|
|
13
|
+
--greese-space-7: 3rem;
|
|
14
|
+
--greese-space-8: 4rem;
|
|
15
|
+
--greese-radius-none: 0;
|
|
16
|
+
--greese-radius-sm: 4px;
|
|
17
|
+
--greese-radius-md: 8px;
|
|
18
|
+
--greese-radius-lg: 16px;
|
|
19
|
+
--greese-radius-xl: 24px;
|
|
20
|
+
--greese-radius-pill: 999px;
|
|
21
|
+
--greese-radius-round: 50%;
|
|
22
|
+
--greese-corner-control: var(--greese-radius-md);
|
|
23
|
+
--greese-corner-field: var(--greese-radius-md);
|
|
24
|
+
--greese-corner-surface: var(--greese-radius-lg);
|
|
25
|
+
--greese-corner-panel: var(--greese-radius-md);
|
|
26
|
+
--greese-corner-inset: var(--greese-radius-sm);
|
|
27
|
+
--greese-corner-pill: var(--greese-radius-pill);
|
|
28
|
+
--greese-corner-round: var(--greese-radius-round);
|
|
29
|
+
--greese-font-body: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
|
|
30
|
+
--greese-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
31
|
+
--greese-font-weight-regular: 400;
|
|
32
|
+
--greese-font-weight-medium: 500;
|
|
33
|
+
--greese-font-weight-semibold: 600;
|
|
34
|
+
--greese-font-weight-bold: 700;
|
|
35
|
+
--greese-line-height-tight: 1.25;
|
|
36
|
+
--greese-line-height-snug: 1.375;
|
|
37
|
+
--greese-line-height-normal: 1.5;
|
|
38
|
+
--greese-shadow-sm: 0 1px 2px color-mix(in srgb, var(--greese-color-black) 8%, transparent);
|
|
39
|
+
--greese-shadow-md: 0 4px 12px color-mix(in srgb, var(--greese-color-black) 12%, transparent);
|
|
40
|
+
--greese-shadow-lg: 0 12px 32px color-mix(in srgb, var(--greese-color-black) 18%, transparent);
|
|
41
|
+
--greese-z-index-dropdown: 1000;
|
|
42
|
+
--greese-z-index-sticky: 1100;
|
|
43
|
+
--greese-z-index-overlay: 1300;
|
|
44
|
+
--greese-z-index-modal: 1400;
|
|
45
|
+
--greese-z-index-popover: 1500;
|
|
46
|
+
--greese-z-index-toast: 1600;
|
|
47
|
+
--greese-z-index-tooltip: 1700;
|
|
48
|
+
--greese-duration-fast: 120ms;
|
|
49
|
+
--greese-duration-normal: 200ms;
|
|
50
|
+
--greese-duration-slow: 320ms;
|
|
51
|
+
--greese-easing-standard: cubic-bezier(0.2, 0, 0, 1);
|
|
52
|
+
--greese-easing-enter: cubic-bezier(0, 0, 0, 1);
|
|
53
|
+
--greese-easing-exit: cubic-bezier(0.3, 0, 1, 1);
|
|
54
|
+
--greese-breakpoint-xs: 0px;
|
|
55
|
+
--greese-breakpoint-sm: 600px;
|
|
56
|
+
--greese-breakpoint-md: 900px;
|
|
57
|
+
--greese-breakpoint-lg: 1200px;
|
|
58
|
+
--greese-breakpoint-xl: 1536px;
|
|
59
|
+
--greese-type-p1-font-size: 1.125rem;
|
|
60
|
+
--greese-type-p1-font-weight: 400;
|
|
61
|
+
--greese-type-p1-line-height: 1.6;
|
|
62
|
+
--greese-type-p1-letter-spacing: 0;
|
|
63
|
+
--greese-type-p2-font-size: 1rem;
|
|
64
|
+
--greese-type-p2-font-weight: 400;
|
|
65
|
+
--greese-type-p2-line-height: 1.55;
|
|
66
|
+
--greese-type-p2-letter-spacing: 0;
|
|
67
|
+
--greese-type-p3-font-size: 0.875rem;
|
|
68
|
+
--greese-type-p3-font-weight: 400;
|
|
69
|
+
--greese-type-p3-line-height: 1.5;
|
|
70
|
+
--greese-type-p3-letter-spacing: 0;
|
|
71
|
+
--greese-type-h1-font-size: 2.25rem;
|
|
72
|
+
--greese-type-h1-font-weight: 700;
|
|
73
|
+
--greese-type-h1-line-height: 1.15;
|
|
74
|
+
--greese-type-h1-letter-spacing: -0.02em;
|
|
75
|
+
--greese-type-h1-text-wrap: balance;
|
|
76
|
+
--greese-type-h2-font-size: 1.875rem;
|
|
77
|
+
--greese-type-h2-font-weight: 700;
|
|
78
|
+
--greese-type-h2-line-height: 1.2;
|
|
79
|
+
--greese-type-h2-letter-spacing: -0.015em;
|
|
80
|
+
--greese-type-h2-text-wrap: balance;
|
|
81
|
+
--greese-type-h3-font-size: 1.5rem;
|
|
82
|
+
--greese-type-h3-font-weight: 600;
|
|
83
|
+
--greese-type-h3-line-height: 1.25;
|
|
84
|
+
--greese-type-h3-letter-spacing: -0.01em;
|
|
85
|
+
--greese-type-h3-text-wrap: balance;
|
|
86
|
+
--greese-type-h4-font-size: 1.25rem;
|
|
87
|
+
--greese-type-h4-font-weight: 600;
|
|
88
|
+
--greese-type-h4-line-height: 1.3;
|
|
89
|
+
--greese-type-h4-letter-spacing: 0;
|
|
90
|
+
--greese-type-h4-text-wrap: balance;
|
|
91
|
+
--greese-type-h5-font-size: 1.125rem;
|
|
92
|
+
--greese-type-h5-font-weight: 600;
|
|
93
|
+
--greese-type-h5-line-height: 1.35;
|
|
94
|
+
--greese-type-h5-letter-spacing: 0;
|
|
95
|
+
--greese-type-h5-text-wrap: balance;
|
|
96
|
+
--greese-type-h6-font-size: 1rem;
|
|
97
|
+
--greese-type-h6-font-weight: 600;
|
|
98
|
+
--greese-type-h6-line-height: 1.4;
|
|
99
|
+
--greese-type-h6-letter-spacing: 0;
|
|
100
|
+
--greese-type-h6-text-wrap: balance;
|
|
101
|
+
--greese-type-s1-font-size: 1.25rem;
|
|
102
|
+
--greese-type-s1-font-weight: 500;
|
|
103
|
+
--greese-type-s1-line-height: 1.4;
|
|
104
|
+
--greese-type-s1-letter-spacing: 0;
|
|
105
|
+
--greese-type-s2-font-size: 1.125rem;
|
|
106
|
+
--greese-type-s2-font-weight: 500;
|
|
107
|
+
--greese-type-s2-line-height: 1.45;
|
|
108
|
+
--greese-type-s2-letter-spacing: 0;
|
|
109
|
+
--greese-type-caption-font-size: 0.75rem;
|
|
110
|
+
--greese-type-caption-font-weight: 400;
|
|
111
|
+
--greese-type-caption-line-height: 1.4;
|
|
112
|
+
--greese-type-caption-letter-spacing: 0.02em;
|
|
113
|
+
--greese-type-button-font-size: 0.9375rem;
|
|
114
|
+
--greese-type-button-font-weight: 600;
|
|
115
|
+
--greese-type-button-line-height: 1.25;
|
|
116
|
+
--greese-type-button-letter-spacing: 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@media (width >= 900px) {
|
|
120
|
+
:root {
|
|
121
|
+
--greese-type-p1-font-size: 1.25rem;
|
|
122
|
+
--greese-type-h1-font-size: 2.75rem;
|
|
123
|
+
--greese-type-h2-font-size: 2.25rem;
|
|
124
|
+
--greese-type-h3-font-size: 1.75rem;
|
|
125
|
+
--greese-type-h4-font-size: 1.375rem;
|
|
126
|
+
--greese-type-h5-font-size: 1.25rem;
|
|
127
|
+
--greese-type-h6-font-size: 1.0625rem;
|
|
128
|
+
--greese-type-s1-font-size: 1.375rem;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@media (width >= 1200px) {
|
|
133
|
+
:root {
|
|
134
|
+
--greese-type-h1-font-size: 3.5rem;
|
|
135
|
+
--greese-type-h1-line-height: 1.1;
|
|
136
|
+
--greese-type-h2-font-size: 2.75rem;
|
|
137
|
+
--greese-type-h3-font-size: 2rem;
|
|
138
|
+
--greese-type-h4-font-size: 1.5rem;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
:root,
|
|
143
|
+
[data-greese-scheme='light'],
|
|
144
|
+
[data-greese-scheme='system'] {
|
|
145
|
+
color-scheme: light;
|
|
146
|
+
--greese-color-canvas: #ffffff;
|
|
147
|
+
--greese-color-surface: #f5f7f9;
|
|
148
|
+
--greese-color-surface-overlay: #ffffff;
|
|
149
|
+
--greese-color-fg: #11171c;
|
|
150
|
+
--greese-color-fg-muted: #505e6d;
|
|
151
|
+
--greese-color-border: #d7dfe7;
|
|
152
|
+
--greese-color-border-strong: #a3b3c4;
|
|
153
|
+
--greese-color-track: #d7dfe7;
|
|
154
|
+
--greese-color-primary: #2771e0;
|
|
155
|
+
--greese-color-primary-strong: #1356b8;
|
|
156
|
+
--greese-color-primary-content: #ffffff;
|
|
157
|
+
--greese-color-secondary: #7e5bd0;
|
|
158
|
+
--greese-color-secondary-strong: #6443ab;
|
|
159
|
+
--greese-color-secondary-content: #ffffff;
|
|
160
|
+
--greese-color-tertiary: #007069;
|
|
161
|
+
--greese-color-tertiary-strong: #00544f;
|
|
162
|
+
--greese-color-tertiary-content: #ffffff;
|
|
163
|
+
--greese-color-accent: #c13b7b;
|
|
164
|
+
--greese-color-accent-strong: #9c2661;
|
|
165
|
+
--greese-color-accent-content: #ffffff;
|
|
166
|
+
--greese-color-focus-ring: var(--greese-color-primary);
|
|
167
|
+
--greese-color-positive: #007231;
|
|
168
|
+
--greese-color-negative: #ae0914;
|
|
169
|
+
--greese-color-negative-content: #ffffff;
|
|
170
|
+
--greese-color-warning: #8a5f00;
|
|
171
|
+
--greese-color-info: #00668f;
|
|
172
|
+
--greese-color-white: #ffffff;
|
|
173
|
+
--greese-color-black: #000000;
|
|
174
|
+
--greese-color-scrim: color-mix(in srgb, var(--greese-color-black) 45%, transparent);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@media (prefers-color-scheme: dark) {
|
|
178
|
+
:root:not([data-greese-scheme='light']),
|
|
179
|
+
[data-greese-scheme='system'] {
|
|
180
|
+
color-scheme: dark;
|
|
181
|
+
--greese-color-canvas: #11171c;
|
|
182
|
+
--greese-color-surface: #2a333c;
|
|
183
|
+
--greese-color-surface-overlay: #3c4854;
|
|
184
|
+
--greese-color-fg: #e9edf2;
|
|
185
|
+
--greese-color-fg-muted: #a3b3c4;
|
|
186
|
+
--greese-color-border: #3c4854;
|
|
187
|
+
--greese-color-border-strong: #505e6d;
|
|
188
|
+
--greese-color-track: #687889;
|
|
189
|
+
--greese-color-primary: #81b2ff;
|
|
190
|
+
--greese-color-primary-strong: #aaccff;
|
|
191
|
+
--greese-color-primary-content: #11171c;
|
|
192
|
+
--greese-color-secondary: #b69fff;
|
|
193
|
+
--greese-color-secondary-strong: #cdbfff;
|
|
194
|
+
--greese-color-secondary-content: #11171c;
|
|
195
|
+
--greese-color-tertiary: #5dcec5;
|
|
196
|
+
--greese-color-tertiary-strong: #94e1da;
|
|
197
|
+
--greese-color-tertiary-content: #11171c;
|
|
198
|
+
--greese-color-accent: #ff81b6;
|
|
199
|
+
--greese-color-accent-strong: #ffaecd;
|
|
200
|
+
--greese-color-accent-content: #11171c;
|
|
201
|
+
--greese-color-focus-ring: var(--greese-color-primary-strong);
|
|
202
|
+
--greese-color-positive: #61cf7e;
|
|
203
|
+
--greese-color-negative: #ff8b7f;
|
|
204
|
+
--greese-color-negative-content: #11171c;
|
|
205
|
+
--greese-color-warning: #feb93d;
|
|
206
|
+
--greese-color-info: #5ac0f7;
|
|
207
|
+
--greese-color-white: #ffffff;
|
|
208
|
+
--greese-color-black: #000000;
|
|
209
|
+
--greese-color-scrim: color-mix(in srgb, var(--greese-color-black) 60%, transparent);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
[data-greese-scheme='dark'] {
|
|
214
|
+
color-scheme: dark;
|
|
215
|
+
--greese-color-canvas: #11171c;
|
|
216
|
+
--greese-color-surface: #2a333c;
|
|
217
|
+
--greese-color-surface-overlay: #3c4854;
|
|
218
|
+
--greese-color-fg: #e9edf2;
|
|
219
|
+
--greese-color-fg-muted: #a3b3c4;
|
|
220
|
+
--greese-color-border: #3c4854;
|
|
221
|
+
--greese-color-border-strong: #505e6d;
|
|
222
|
+
--greese-color-track: #687889;
|
|
223
|
+
--greese-color-primary: #81b2ff;
|
|
224
|
+
--greese-color-primary-strong: #aaccff;
|
|
225
|
+
--greese-color-primary-content: #11171c;
|
|
226
|
+
--greese-color-secondary: #b69fff;
|
|
227
|
+
--greese-color-secondary-strong: #cdbfff;
|
|
228
|
+
--greese-color-secondary-content: #11171c;
|
|
229
|
+
--greese-color-tertiary: #5dcec5;
|
|
230
|
+
--greese-color-tertiary-strong: #94e1da;
|
|
231
|
+
--greese-color-tertiary-content: #11171c;
|
|
232
|
+
--greese-color-accent: #ff81b6;
|
|
233
|
+
--greese-color-accent-strong: #ffaecd;
|
|
234
|
+
--greese-color-accent-content: #11171c;
|
|
235
|
+
--greese-color-focus-ring: var(--greese-color-primary-strong);
|
|
236
|
+
--greese-color-positive: #61cf7e;
|
|
237
|
+
--greese-color-negative: #ff8b7f;
|
|
238
|
+
--greese-color-negative-content: #11171c;
|
|
239
|
+
--greese-color-warning: #feb93d;
|
|
240
|
+
--greese-color-info: #5ac0f7;
|
|
241
|
+
--greese-color-white: #ffffff;
|
|
242
|
+
--greese-color-black: #000000;
|
|
243
|
+
--greese-color-scrim: color-mix(in srgb, var(--greese-color-black) 60%, transparent);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@media (prefers-reduced-motion: reduce) {
|
|
247
|
+
:root {
|
|
248
|
+
--greese-duration-fast: 0.01ms;
|
|
249
|
+
--greese-duration-normal: 0.01ms;
|
|
250
|
+
--greese-duration-slow: 0.01ms;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|