@fluixi-ui/fx 0.1.0-alpha.2 → 0.1.0-alpha.4
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/README.md +57 -3
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/lib/animations.d.ts +55 -0
- package/dist/lib/animations.d.ts.map +1 -0
- package/dist/lib/animations.js +73 -0
- package/dist/lib/keyframes.d.ts +70 -0
- package/dist/lib/keyframes.d.ts.map +1 -0
- package/dist/lib/keyframes.js +63 -0
- package/dist/lib/merge.d.ts +1 -1
- package/dist/lib/merge.js +1 -1
- package/dist/lib/presets.d.ts +67 -0
- package/dist/lib/presets.d.ts.map +1 -0
- package/dist/lib/presets.js +111 -0
- package/dist/lib/resolve.d.ts.map +1 -1
- package/dist/lib/resolve.js +23 -0
- package/dist/lib/scales.d.ts.map +1 -1
- package/dist/lib/scales.js +9 -1
- package/dist/lib/selectors.d.ts +9 -0
- package/dist/lib/selectors.d.ts.map +1 -1
- package/dist/lib/selectors.js +4 -0
- package/dist/lib/sheet.d.ts +7 -0
- package/dist/lib/sheet.d.ts.map +1 -1
- package/dist/lib/sheet.js +30 -1
- package/dist/lib/slots.d.ts +19 -0
- package/dist/lib/slots.d.ts.map +1 -0
- package/dist/lib/slots.js +29 -0
- package/dist/lib/types.d.ts +13 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utilities.d.ts +98 -0
- package/dist/lib/utilities.d.ts.map +1 -0
- package/dist/lib/utilities.js +114 -0
- package/dist/lib/variants.d.ts +41 -0
- package/dist/lib/variants.d.ts.map +1 -0
- package/dist/lib/variants.js +16 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/vite.d.ts +41 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +182 -0
- package/package.json +12 -2
package/dist/lib/scales.js
CHANGED
|
@@ -118,6 +118,10 @@ export const PROP_SCALE = (() => {
|
|
|
118
118
|
map['fontFamily'] = 'fontFamily';
|
|
119
119
|
map['transitionDuration'] = 'duration';
|
|
120
120
|
map['animationDuration'] = 'duration';
|
|
121
|
+
// Delays are the same kind of value as durations — without this a bare `100` would
|
|
122
|
+
// serialize unitless, which CSS drops.
|
|
123
|
+
map['transitionDelay'] = 'duration';
|
|
124
|
+
map['animationDelay'] = 'duration';
|
|
121
125
|
map['transitionTimingFunction'] = 'easing';
|
|
122
126
|
map['animationTimingFunction'] = 'easing';
|
|
123
127
|
map['opacity'] = 'opacity';
|
|
@@ -218,5 +222,9 @@ export function resolveValue(property, value) {
|
|
|
218
222
|
export function cssProperty(name) {
|
|
219
223
|
if (name.startsWith('--'))
|
|
220
224
|
return name;
|
|
221
|
-
|
|
225
|
+
// A vendor prefix keeps its leading dash: `webkitLineClamp` is `-webkit-line-clamp`,
|
|
226
|
+
// and camel-to-kebab alone would emit `webkit-line-clamp`, which no browser reads.
|
|
227
|
+
return name
|
|
228
|
+
.replace(/^(webkit|moz|ms|o)(?=[A-Z])/, '-$1')
|
|
229
|
+
.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
|
|
222
230
|
}
|
package/dist/lib/selectors.d.ts
CHANGED
|
@@ -63,6 +63,15 @@ export declare const SELECTORS: {
|
|
|
63
63
|
_selection: {
|
|
64
64
|
selector: string;
|
|
65
65
|
};
|
|
66
|
+
_scrollbar: {
|
|
67
|
+
selector: string;
|
|
68
|
+
};
|
|
69
|
+
_scrollbarThumb: {
|
|
70
|
+
selector: string;
|
|
71
|
+
};
|
|
72
|
+
_scrollbarTrack: {
|
|
73
|
+
selector: string;
|
|
74
|
+
};
|
|
66
75
|
_first: {
|
|
67
76
|
selector: string;
|
|
68
77
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../src/lib/selectors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../src/lib/selectors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCmB,CAAC;AAE1C,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,SAAS,CAAC;AAEjD,KAAK,MAAM,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;AAEhC;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,SAAS,WAAW,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC;AAEtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,WAAW,CAE7D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAE7D;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAe3D;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAO3E"}
|
package/dist/lib/selectors.js
CHANGED
|
@@ -22,6 +22,10 @@ export const SELECTORS = {
|
|
|
22
22
|
_after: { selector: '&::after' },
|
|
23
23
|
_placeholder: { selector: '&::placeholder' },
|
|
24
24
|
_selection: { selector: '&::selection' },
|
|
25
|
+
// Scrollbar styling has no standard selector, and the closed set is the only way in.
|
|
26
|
+
_scrollbar: { selector: '&::-webkit-scrollbar' },
|
|
27
|
+
_scrollbarThumb: { selector: '&::-webkit-scrollbar-thumb' },
|
|
28
|
+
_scrollbarTrack: { selector: '&::-webkit-scrollbar-track' },
|
|
25
29
|
_first: { selector: '&:first-child' },
|
|
26
30
|
_last: { selector: '&:last-child' },
|
|
27
31
|
_odd: { selector: '&:nth-child(odd)' },
|
package/dist/lib/sheet.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ import type { FxResult } from './types.js';
|
|
|
4
4
|
* fitted entirely inline never reach the stylesheet at all.
|
|
5
5
|
*/
|
|
6
6
|
export declare function insertFx(result: FxResult): void;
|
|
7
|
+
/**
|
|
8
|
+
* Register an `@keyframes` rule. Kept apart from the per-render rules because it has a
|
|
9
|
+
* different lifetime: `keyframes()` is called once at module scope, while `insertFx`
|
|
10
|
+
* runs per element. Held in a map so a server that resets between requests still emits
|
|
11
|
+
* the animation — see `resetFx`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerKeyframes(name: string, body: string): void;
|
|
7
14
|
/**
|
|
8
15
|
* Everything inserted so far, for a server render to emit into `<head>`. Render
|
|
9
16
|
* the result as `<style data-fx-sheet data-fx-tokens="…">`; the client adopts it.
|
package/dist/lib/sheet.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../src/lib/sheet.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../src/lib/sheet.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAoC3C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAgB/C;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAelE;AAMD;;;GAGG;AACH,wBAAgB,SAAS,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAO3D;AAED,uFAAuF;AACvF,wBAAgB,OAAO,IAAI,IAAI,CAQ9B"}
|
package/dist/lib/sheet.js
CHANGED
|
@@ -3,6 +3,7 @@ const SHEET_ATTRIBUTE = 'data-fx-sheet';
|
|
|
3
3
|
const TOKENS_ATTRIBUTE = 'data-fx-tokens';
|
|
4
4
|
const inserted = new Set();
|
|
5
5
|
const collected = [];
|
|
6
|
+
const keyframeRules = new Map();
|
|
6
7
|
let sheet = null;
|
|
7
8
|
/**
|
|
8
9
|
* Find or create the sheet. A server-rendered sheet is adopted rather than
|
|
@@ -51,6 +52,28 @@ export function insertFx(result) {
|
|
|
51
52
|
element.appendChild(document.createTextNode(wrap(result.rules)));
|
|
52
53
|
element.setAttribute(TOKENS_ATTRIBUTE, [...inserted].join(','));
|
|
53
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Register an `@keyframes` rule. Kept apart from the per-render rules because it has a
|
|
57
|
+
* different lifetime: `keyframes()` is called once at module scope, while `insertFx`
|
|
58
|
+
* runs per element. Held in a map so a server that resets between requests still emits
|
|
59
|
+
* the animation — see `resetFx`.
|
|
60
|
+
*/
|
|
61
|
+
export function registerKeyframes(name, body) {
|
|
62
|
+
if (keyframeRules.has(name))
|
|
63
|
+
return;
|
|
64
|
+
keyframeRules.set(name, `@keyframes ${name}{${body}}`);
|
|
65
|
+
if (typeof document === 'undefined') {
|
|
66
|
+
inserted.add(name);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Adopt first: the server sheet's token list may already name this animation.
|
|
70
|
+
const element = styleElement();
|
|
71
|
+
if (inserted.has(name))
|
|
72
|
+
return;
|
|
73
|
+
inserted.add(name);
|
|
74
|
+
element.appendChild(document.createTextNode(wrap(keyframeRules.get(name))));
|
|
75
|
+
element.setAttribute(TOKENS_ATTRIBUTE, [...inserted].join(','));
|
|
76
|
+
}
|
|
54
77
|
function wrap(rules) {
|
|
55
78
|
return `@layer flx.fx{${rules}}`;
|
|
56
79
|
}
|
|
@@ -59,8 +82,10 @@ function wrap(rules) {
|
|
|
59
82
|
* the result as `<style data-fx-sheet data-fx-tokens="…">`; the client adopts it.
|
|
60
83
|
*/
|
|
61
84
|
export function collectFx() {
|
|
85
|
+
const animations = [...keyframeRules.values()].map(wrap).join('');
|
|
86
|
+
const body = `${animations}${collected.join('')}`;
|
|
62
87
|
return {
|
|
63
|
-
css:
|
|
88
|
+
css: body ? `${LAYER_ORDER}${body}` : '',
|
|
64
89
|
tokens: [...inserted].join(','),
|
|
65
90
|
};
|
|
66
91
|
}
|
|
@@ -68,6 +93,10 @@ export function collectFx() {
|
|
|
68
93
|
export function resetFx() {
|
|
69
94
|
inserted.clear();
|
|
70
95
|
collected.length = 0;
|
|
96
|
+
// Keyframes survive: they are registered once at module scope, so dropping them
|
|
97
|
+
// would leave every request after the first naming an animation nobody emits.
|
|
98
|
+
for (const name of keyframeRules.keys())
|
|
99
|
+
inserted.add(name);
|
|
71
100
|
if (sheet && sheet.isConnected)
|
|
72
101
|
sheet.remove();
|
|
73
102
|
sheet = null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FxProp } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reaching a compound component's parts.
|
|
4
|
+
*
|
|
5
|
+
* `sp={{ header: { sticky: true, fx: { gap: 2 } } }}` a part's full props
|
|
6
|
+
* `fx={{ p: 4, sp: { header: { gap: 2 } } }}` only its styles
|
|
7
|
+
*
|
|
8
|
+
* `fx.sp` keeps styling a whole component in one object; `sp` is the general
|
|
9
|
+
* channel, since a part takes props and styling is one of them.
|
|
10
|
+
*/
|
|
11
|
+
/** The styles `fx.sp` addresses to one part. */
|
|
12
|
+
export declare function slotFx(fx: FxProp, slot: string): FxProp;
|
|
13
|
+
/**
|
|
14
|
+
* What a part is spread with: its `sp` entry, with the `fx.sp` shorthand merged
|
|
15
|
+
* under its own `fx`. `sp.<part>.fx` wins — it names the part exactly. A
|
|
16
|
+
* component's own defaults merge in at the call site.
|
|
17
|
+
*/
|
|
18
|
+
export declare function slot(name: string, fx: FxProp, sp: object | undefined): Record<string, unknown>;
|
|
19
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../src/lib/slots.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,YAAY,CAAC;AAElD;;;;;;;;GAQG;AAEH,gDAAgD;AAChD,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO9F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mergeFx } from './merge.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reaching a compound component's parts.
|
|
4
|
+
*
|
|
5
|
+
* `sp={{ header: { sticky: true, fx: { gap: 2 } } }}` a part's full props
|
|
6
|
+
* `fx={{ p: 4, sp: { header: { gap: 2 } } }}` only its styles
|
|
7
|
+
*
|
|
8
|
+
* `fx.sp` keeps styling a whole component in one object; `sp` is the general
|
|
9
|
+
* channel, since a part takes props and styling is one of them.
|
|
10
|
+
*/
|
|
11
|
+
/** The styles `fx.sp` addresses to one part. */
|
|
12
|
+
export function slotFx(fx, slot) {
|
|
13
|
+
const slots = mergeFx(fx).sp;
|
|
14
|
+
return slots?.[slot];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* What a part is spread with: its `sp` entry, with the `fx.sp` shorthand merged
|
|
18
|
+
* under its own `fx`. `sp.<part>.fx` wins — it names the part exactly. A
|
|
19
|
+
* component's own defaults merge in at the call site.
|
|
20
|
+
*/
|
|
21
|
+
export function slot(name, fx, sp) {
|
|
22
|
+
// A slots type is an interface of named optional parts, not a Record, so it is read
|
|
23
|
+
// positionally. The user-facing typing is on the component's own `sp` prop.
|
|
24
|
+
const own = sp?.[name];
|
|
25
|
+
const shorthand = slotFx(fx, name);
|
|
26
|
+
if (!shorthand)
|
|
27
|
+
return own ?? {};
|
|
28
|
+
return { ...own, fx: mergeFx(shorthand, own?.['fx']) };
|
|
29
|
+
}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type RadiusValue = RadiusToken | number | Raw;
|
|
|
21
21
|
export type ShadowValue = ShadowToken | Raw;
|
|
22
22
|
export type BorderWidthValue = BorderWidthToken | number | Raw;
|
|
23
23
|
/** The value type a property accepts, decided by the scale it belongs to. */
|
|
24
|
-
type ValueFor<K> = K extends SpaceProp ? SpaceValue : K extends SizeProp ? SizeValue : K extends ColorProp ? ColorValue : K extends RadiusProp ? RadiusValue : K extends BorderWidthProp ? BorderWidthValue : K extends UnitlessProp ? number | Raw : K extends 'boxShadow' ? ShadowValue : K extends 'fontSize' ? FontSizeToken | number | Raw : K extends 'fontWeight' ? FontWeightToken | number | Raw : K extends 'lineHeight' ? LineHeightToken | number | Raw : K extends 'letterSpacing' ? LetterSpacingToken | number | Raw : K extends 'fontFamily' ? FontFamilyToken | Raw : K extends 'transitionDuration' | 'animationDuration' ? DurationToken | number | Raw : K extends 'transitionTimingFunction' | 'animationTimingFunction' ? EasingToken | Raw : K extends 'opacity' ? OpacityToken | number | Raw : K extends 'zIndex' ? ZIndexToken | number | Raw : string | number;
|
|
24
|
+
type ValueFor<K> = K extends SpaceProp ? SpaceValue : K extends SizeProp ? SizeValue : K extends ColorProp ? ColorValue : K extends RadiusProp ? RadiusValue : K extends BorderWidthProp ? BorderWidthValue : K extends UnitlessProp ? number | Raw : K extends 'boxShadow' ? ShadowValue : K extends 'fontSize' ? FontSizeToken | number | Raw : K extends 'fontWeight' ? FontWeightToken | number | Raw : K extends 'lineHeight' ? LineHeightToken | number | Raw : K extends 'letterSpacing' ? LetterSpacingToken | number | Raw : K extends 'fontFamily' ? FontFamilyToken | Raw : K extends 'transitionDuration' | 'animationDuration' | 'transitionDelay' | 'animationDelay' ? DurationToken | number | Raw : K extends 'transitionTimingFunction' | 'animationTimingFunction' ? EasingToken | Raw : K extends 'opacity' ? OpacityToken | number | Raw : K extends 'zIndex' ? ZIndexToken | number | Raw : string | number;
|
|
25
25
|
/**
|
|
26
26
|
* Every writable CSS property, taken from `CSSStyleDeclaration` — the string-valued
|
|
27
27
|
* members are exactly the properties, which drops its methods and `length`.
|
|
@@ -75,11 +75,23 @@ export type ContainerQuery = {
|
|
|
75
75
|
} & {
|
|
76
76
|
[K in `(${string}`]?: FxObject;
|
|
77
77
|
};
|
|
78
|
+
/**
|
|
79
|
+
* Styles for a compound component's parts, keyed by the slot names that component
|
|
80
|
+
* documents. It carries styles only — a part's other props go through the `sp` prop.
|
|
81
|
+
*/
|
|
82
|
+
export type FxSlots = {
|
|
83
|
+
[slot: string]: FxProp;
|
|
84
|
+
};
|
|
78
85
|
/** A style object: declarations plus nested selector blocks, arbitrarily deep. */
|
|
79
86
|
export type FxObject = FxDeclarations & {
|
|
80
87
|
[K in SelectorKey]?: FxObject;
|
|
81
88
|
} & {
|
|
82
89
|
_container?: ContainerQuery;
|
|
90
|
+
/**
|
|
91
|
+
* Styles addressed to a compound component's parts, so one `fx` can dress the
|
|
92
|
+
* whole thing. Stripped before resolution — it never reaches CSS.
|
|
93
|
+
*/
|
|
94
|
+
sp?: FxSlots;
|
|
83
95
|
};
|
|
84
96
|
/**
|
|
85
97
|
* What an `fx` prop accepts. The array form composes conditionally
|
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,aAAa,EACb,WAAW,EACX,eAAe,EACf,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IAAE,IAAI,CAAC,EAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,oFAAoF;AACpF,KAAK,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC;AAEvB,KAAK,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACpE,KAAK,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;AAErD,kFAAkF;AAClF,MAAM,MAAM,UAAU,GAClB,UAAU,WAAW,EAAE,GACvB,QAAQ,WAAW,EAAE,GACrB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;AAExD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,iBAAiB,GAAG,GAAG,CAAC;AAC7D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,GAAG,CAAC;AACrC,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,GAAG,CAAC;AACvD,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,GAAG,CAAC;AACrD,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,GAAG,CAAC;AAC5C,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,MAAM,GAAG,GAAG,CAAC;AAE/D,6EAA6E;AAC7E,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAClC,UAAU,GACV,CAAC,SAAS,QAAQ,GAChB,SAAS,GACT,CAAC,SAAS,SAAS,GACjB,UAAU,GACV,CAAC,SAAS,UAAU,GAClB,WAAW,GACX,CAAC,SAAS,eAAe,GACvB,gBAAgB,GAChB,CAAC,SAAS,YAAY,GACpB,MAAM,GAAG,GAAG,GACZ,CAAC,SAAS,WAAW,GACnB,WAAW,GACX,CAAC,SAAS,UAAU,GAClB,aAAa,GAAG,MAAM,GAAG,GAAG,GAC5B,CAAC,SAAS,YAAY,GACpB,eAAe,GAAG,MAAM,GAAG,GAAG,GAC9B,CAAC,SAAS,YAAY,GACpB,eAAe,GAAG,MAAM,GAAG,GAAG,GAC9B,CAAC,SAAS,eAAe,GACvB,kBAAkB,GAAG,MAAM,GAAG,GAAG,GACjC,CAAC,SAAS,YAAY,GACpB,eAAe,GAAG,GAAG,GACrB,CAAC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,aAAa,EACb,WAAW,EACX,eAAe,EACf,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IAAE,IAAI,CAAC,EAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,oFAAoF;AACpF,KAAK,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC;AAEvB,KAAK,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACpE,KAAK,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;AAErD,kFAAkF;AAClF,MAAM,MAAM,UAAU,GAClB,UAAU,WAAW,EAAE,GACvB,QAAQ,WAAW,EAAE,GACrB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;AAExD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,iBAAiB,GAAG,GAAG,CAAC;AAC7D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,GAAG,CAAC;AACrC,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,GAAG,CAAC;AACvD,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,GAAG,CAAC;AACrD,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,GAAG,CAAC;AAC5C,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,MAAM,GAAG,GAAG,CAAC;AAE/D,6EAA6E;AAC7E,KAAK,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAClC,UAAU,GACV,CAAC,SAAS,QAAQ,GAChB,SAAS,GACT,CAAC,SAAS,SAAS,GACjB,UAAU,GACV,CAAC,SAAS,UAAU,GAClB,WAAW,GACX,CAAC,SAAS,eAAe,GACvB,gBAAgB,GAChB,CAAC,SAAS,YAAY,GACpB,MAAM,GAAG,GAAG,GACZ,CAAC,SAAS,WAAW,GACnB,WAAW,GACX,CAAC,SAAS,UAAU,GAClB,aAAa,GAAG,MAAM,GAAG,GAAG,GAC5B,CAAC,SAAS,YAAY,GACpB,eAAe,GAAG,MAAM,GAAG,GAAG,GAC9B,CAAC,SAAS,YAAY,GACpB,eAAe,GAAG,MAAM,GAAG,GAAG,GAC9B,CAAC,SAAS,eAAe,GACvB,kBAAkB,GAAG,MAAM,GAAG,GAAG,GACjC,CAAC,SAAS,YAAY,GACpB,eAAe,GAAG,GAAG,GACrB,CAAC,SACK,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,GACpB,aAAa,GAAG,MAAM,GAAG,GAAG,GAC5B,CAAC,SAAS,0BAA0B,GAAG,yBAAyB,GAC9D,WAAW,GAAG,GAAG,GACjB,CAAC,SAAS,SAAS,GACjB,YAAY,GAAG,MAAM,GAAG,GAAG,GAC3B,CAAC,SAAS,QAAQ,GAChB,WAAW,GAAG,MAAM,GAAG,GAAG,GAC1B,MAAM,GAAG,MAAM,CAAC;AAElD;;;;GAIG;AACH,KAAK,UAAU,GAAG;KACf,CAAC,IAAI,MAAM,mBAAmB,IAAI,mBAAmB,CAAC,CAAC,CAAC,SAAS,MAAM,GACpE,CAAC,SAAS,MAAM,GACd,CAAC,GACD,KAAK,GACP,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,gBAAgB;IAChB,CAAC,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC3B,uBAAuB;IACvB,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,sBAAsB;IACtB,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,eAAe;IACf,CAAC,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC3B,sBAAsB;IACtB,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,qBAAqB;IACrB,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,yBAAyB;IACzB,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,sBAAsB;IACtB,MAAM,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACjC,mBAAmB;IACnB,MAAM,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;CAClC;AAED,KAAK,gBAAgB,GAAG;KACrB,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,gBAAgB,CAAC;AAEvE;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG;KAAG,CAAC,IAAI,UAAU,CAAC,CAAC,EAAE,QAAQ;CAAE,GAAG;KAAG,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC,EAAE,QAAQ;CAAE,CAAC;AAE1E;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAAC;AAEjD,kFAAkF;AAClF,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG;KACrC,CAAC,IAAI,WAAW,CAAC,CAAC,EAAE,QAAQ;CAC9B,GAAG;IACF,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,CAAC;CACd,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,CAAC,QAAQ,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;AAEzE,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AAE1E,uFAAuF;AACvF,MAAM,WAAW,QAAQ;IACvB,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { FxObject } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Everyday `fx` objects, ready to import and merge.
|
|
4
|
+
*
|
|
5
|
+
* An `fx` value is a plain object, so a utility is just a named one — nothing is
|
|
6
|
+
* generated, nothing is resolved until it reaches an element, and anything merged
|
|
7
|
+
* after it wins:
|
|
8
|
+
*
|
|
9
|
+
* fx={mergeFx(flexBetween, gapped(3), { p: 4 })}
|
|
10
|
+
* fx={{ ...card, ...muted }}
|
|
11
|
+
*
|
|
12
|
+
* The line for including one: it's typed several times a week, or it carries a
|
|
13
|
+
* decision — a token, a browser trap, the `min-width: 0` that flex needs before
|
|
14
|
+
* text will truncate. `{ display: 'flex' }` is here because it's typed constantly;
|
|
15
|
+
* a name for every CSS property is not, since that's a second vocabulary for the
|
|
16
|
+
* same thing.
|
|
17
|
+
*
|
|
18
|
+
* Multi-declaration recipes live next door in `presets` (`truncate`, `lineClamp`,
|
|
19
|
+
* `visuallyHidden`, `stack`, `scrollY`, …).
|
|
20
|
+
*/
|
|
21
|
+
export declare const flex: FxObject;
|
|
22
|
+
export declare const inlineFlex: FxObject;
|
|
23
|
+
export declare const grid: FxObject;
|
|
24
|
+
export declare const block: FxObject;
|
|
25
|
+
export declare const inlineBlock: FxObject;
|
|
26
|
+
export declare const hidden: FxObject;
|
|
27
|
+
/** Out of sight but still laid out — unlike `hidden`, which collapses the box. */
|
|
28
|
+
export declare const invisible: FxObject;
|
|
29
|
+
export declare const flexRow: FxObject;
|
|
30
|
+
export declare const flexColumn: FxObject;
|
|
31
|
+
export declare const flexWrap: FxObject;
|
|
32
|
+
export declare const flexCenter: FxObject;
|
|
33
|
+
export declare const flexBetween: FxObject;
|
|
34
|
+
export declare const flexEnd: FxObject;
|
|
35
|
+
export declare const flexStart: FxObject;
|
|
36
|
+
export declare const alignCenter: FxObject;
|
|
37
|
+
/**
|
|
38
|
+
* Take the free space. `minWidth: 0` because a flex child defaults to `min-width:
|
|
39
|
+
* auto`, which refuses to shrink below its content — the reason a long string blows
|
|
40
|
+
* out a row instead of truncating.
|
|
41
|
+
*/
|
|
42
|
+
export declare const flexFill: FxObject;
|
|
43
|
+
/** The same shrink fix on its own, for a child you don't want to grow. */
|
|
44
|
+
export declare const minW0: FxObject;
|
|
45
|
+
/** Hold your size while siblings take the space. */
|
|
46
|
+
export declare const flexNone: FxObject;
|
|
47
|
+
export declare const fullWidth: FxObject;
|
|
48
|
+
export declare const fullHeight: FxObject;
|
|
49
|
+
export declare const fullSize: FxObject;
|
|
50
|
+
export declare const fillViewport: FxObject;
|
|
51
|
+
export declare const relative: FxObject;
|
|
52
|
+
export declare const absolute: FxObject;
|
|
53
|
+
export declare const fixed: FxObject;
|
|
54
|
+
/** Sticks to the top of its scroll container, above the content it passes. */
|
|
55
|
+
export declare const stickyTop: FxObject;
|
|
56
|
+
export declare const textCenter: FxObject;
|
|
57
|
+
export declare const textStart: FxObject;
|
|
58
|
+
export declare const textEnd: FxObject;
|
|
59
|
+
export declare const nowrap: FxObject;
|
|
60
|
+
export declare const medium: FxObject;
|
|
61
|
+
export declare const semibold: FxObject;
|
|
62
|
+
export declare const bold: FxObject;
|
|
63
|
+
export declare const uppercase: FxObject;
|
|
64
|
+
export declare const capitalize: FxObject;
|
|
65
|
+
/** Secondary text, on the token rather than a hand-picked grey. */
|
|
66
|
+
export declare const muted: FxObject;
|
|
67
|
+
/** Break anywhere rather than let a URL or an ID push the layout wide. */
|
|
68
|
+
export declare const breakWords: FxObject;
|
|
69
|
+
/**
|
|
70
|
+
* Fixed-width digits, so numbers in a column line up and a live counter stops
|
|
71
|
+
* jittering as its digits change.
|
|
72
|
+
*/
|
|
73
|
+
export declare const tabularNums: FxObject;
|
|
74
|
+
export declare const bordered: FxObject;
|
|
75
|
+
export declare const borderTop: FxObject;
|
|
76
|
+
export declare const borderBottom: FxObject;
|
|
77
|
+
export declare const rounded: FxObject;
|
|
78
|
+
export declare const pill: FxObject;
|
|
79
|
+
export declare const circle: FxObject;
|
|
80
|
+
/** A full-window scrim, at the layer overlays expect. */
|
|
81
|
+
export declare const scrim: FxObject;
|
|
82
|
+
export declare const pointer: FxObject;
|
|
83
|
+
export declare const notAllowed: FxObject;
|
|
84
|
+
/** Nothing here reacts — clicks pass through to whatever is behind. */
|
|
85
|
+
export declare const inert: FxObject;
|
|
86
|
+
/**
|
|
87
|
+
* The clickable-but-not-a-button recipe: pointer, no text selection on a
|
|
88
|
+
* double-click, and no grey flash on iOS.
|
|
89
|
+
*/
|
|
90
|
+
export declare const clickable: FxObject;
|
|
91
|
+
/**
|
|
92
|
+
* The library's focus ring, for something you've made focusable yourself.
|
|
93
|
+
* `:focus-visible`, so a mouse click doesn't ring it — only keyboard focus does.
|
|
94
|
+
*/
|
|
95
|
+
export declare const focusRing: FxObject;
|
|
96
|
+
/** Reads as unavailable and stops responding, without the `disabled` attribute. */
|
|
97
|
+
export declare const disabled: FxObject;
|
|
98
|
+
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/lib/utilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everyday `fx` objects, ready to import and merge.
|
|
3
|
+
*
|
|
4
|
+
* An `fx` value is a plain object, so a utility is just a named one — nothing is
|
|
5
|
+
* generated, nothing is resolved until it reaches an element, and anything merged
|
|
6
|
+
* after it wins:
|
|
7
|
+
*
|
|
8
|
+
* fx={mergeFx(flexBetween, gapped(3), { p: 4 })}
|
|
9
|
+
* fx={{ ...card, ...muted }}
|
|
10
|
+
*
|
|
11
|
+
* The line for including one: it's typed several times a week, or it carries a
|
|
12
|
+
* decision — a token, a browser trap, the `min-width: 0` that flex needs before
|
|
13
|
+
* text will truncate. `{ display: 'flex' }` is here because it's typed constantly;
|
|
14
|
+
* a name for every CSS property is not, since that's a second vocabulary for the
|
|
15
|
+
* same thing.
|
|
16
|
+
*
|
|
17
|
+
* Multi-declaration recipes live next door in `presets` (`truncate`, `lineClamp`,
|
|
18
|
+
* `visuallyHidden`, `stack`, `scrollY`, …).
|
|
19
|
+
*/
|
|
20
|
+
/* Display */
|
|
21
|
+
export const flex = { display: 'flex' };
|
|
22
|
+
export const inlineFlex = { display: 'inline-flex' };
|
|
23
|
+
export const grid = { display: 'grid' };
|
|
24
|
+
export const block = { display: 'block' };
|
|
25
|
+
export const inlineBlock = { display: 'inline-block' };
|
|
26
|
+
export const hidden = { display: 'none' };
|
|
27
|
+
/** Out of sight but still laid out — unlike `hidden`, which collapses the box. */
|
|
28
|
+
export const invisible = { visibility: 'hidden' };
|
|
29
|
+
/* Flex arrangement */
|
|
30
|
+
export const flexRow = { display: 'flex', flexDirection: 'row' };
|
|
31
|
+
export const flexColumn = { display: 'flex', flexDirection: 'column' };
|
|
32
|
+
export const flexWrap = { display: 'flex', flexWrap: 'wrap' };
|
|
33
|
+
export const flexCenter = { display: 'flex', alignItems: 'center', justifyContent: 'center' };
|
|
34
|
+
export const flexBetween = { display: 'flex', alignItems: 'center', justifyContent: 'space-between' };
|
|
35
|
+
export const flexEnd = { display: 'flex', alignItems: 'center', justifyContent: 'flex-end' };
|
|
36
|
+
export const flexStart = { display: 'flex', alignItems: 'flex-start' };
|
|
37
|
+
export const alignCenter = { alignItems: 'center' };
|
|
38
|
+
/**
|
|
39
|
+
* Take the free space. `minWidth: 0` because a flex child defaults to `min-width:
|
|
40
|
+
* auto`, which refuses to shrink below its content — the reason a long string blows
|
|
41
|
+
* out a row instead of truncating.
|
|
42
|
+
*/
|
|
43
|
+
export const flexFill = { flexGrow: 1, flexBasis: 0, minWidth: 0 };
|
|
44
|
+
/** The same shrink fix on its own, for a child you don't want to grow. */
|
|
45
|
+
export const minW0 = { minWidth: 0 };
|
|
46
|
+
/** Hold your size while siblings take the space. */
|
|
47
|
+
export const flexNone = { flexShrink: 0 };
|
|
48
|
+
/* Size */
|
|
49
|
+
export const fullWidth = { width: '100%' };
|
|
50
|
+
export const fullHeight = { height: '100%' };
|
|
51
|
+
export const fullSize = { width: '100%', height: '100%' };
|
|
52
|
+
export const fillViewport = { minHeight: '100dvh' };
|
|
53
|
+
/* Position */
|
|
54
|
+
export const relative = { position: 'relative' };
|
|
55
|
+
export const absolute = { position: 'absolute' };
|
|
56
|
+
export const fixed = { position: 'fixed' };
|
|
57
|
+
/** Sticks to the top of its scroll container, above the content it passes. */
|
|
58
|
+
export const stickyTop = { position: 'sticky', top: 0, zIndex: 'sticky' };
|
|
59
|
+
/* Text */
|
|
60
|
+
export const textCenter = { textAlign: 'center' };
|
|
61
|
+
export const textStart = { textAlign: 'start' };
|
|
62
|
+
export const textEnd = { textAlign: 'end' };
|
|
63
|
+
export const nowrap = { whiteSpace: 'nowrap' };
|
|
64
|
+
export const medium = { fontWeight: 'medium' };
|
|
65
|
+
export const semibold = { fontWeight: 'semibold' };
|
|
66
|
+
export const bold = { fontWeight: 'bold' };
|
|
67
|
+
export const uppercase = { textTransform: 'uppercase' };
|
|
68
|
+
export const capitalize = { textTransform: 'capitalize' };
|
|
69
|
+
/** Secondary text, on the token rather than a hand-picked grey. */
|
|
70
|
+
export const muted = { color: 'fgMuted' };
|
|
71
|
+
/** Break anywhere rather than let a URL or an ID push the layout wide. */
|
|
72
|
+
export const breakWords = { overflowWrap: 'anywhere', wordBreak: 'break-word' };
|
|
73
|
+
/**
|
|
74
|
+
* Fixed-width digits, so numbers in a column line up and a live counter stops
|
|
75
|
+
* jittering as its digits change.
|
|
76
|
+
*/
|
|
77
|
+
export const tabularNums = { fontVariantNumeric: 'tabular-nums' };
|
|
78
|
+
/* Surface */
|
|
79
|
+
export const bordered = { borderWidth: 'thin', borderStyle: 'solid', borderColor: 'border' };
|
|
80
|
+
export const borderTop = { borderTopWidth: 'thin', borderTopStyle: 'solid', borderTopColor: 'border' };
|
|
81
|
+
export const borderBottom = { borderBottomWidth: 'thin', borderBottomStyle: 'solid', borderBottomColor: 'border' };
|
|
82
|
+
export const rounded = { borderRadius: 'md' };
|
|
83
|
+
export const pill = { borderRadius: 'full' };
|
|
84
|
+
export const circle = { borderRadius: 'full', aspectRatio: '1' };
|
|
85
|
+
/** A full-window scrim, at the layer overlays expect. */
|
|
86
|
+
export const scrim = { position: 'fixed', inset: 0, backgroundColor: 'overlay', zIndex: 'overlay' };
|
|
87
|
+
/* Interaction */
|
|
88
|
+
export const pointer = { cursor: 'pointer' };
|
|
89
|
+
export const notAllowed = { cursor: 'not-allowed' };
|
|
90
|
+
/** Nothing here reacts — clicks pass through to whatever is behind. */
|
|
91
|
+
export const inert = { pointerEvents: 'none' };
|
|
92
|
+
/**
|
|
93
|
+
* The clickable-but-not-a-button recipe: pointer, no text selection on a
|
|
94
|
+
* double-click, and no grey flash on iOS.
|
|
95
|
+
*/
|
|
96
|
+
export const clickable = {
|
|
97
|
+
cursor: 'pointer',
|
|
98
|
+
userSelect: 'none',
|
|
99
|
+
webkitTapHighlightColor: 'transparent',
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* The library's focus ring, for something you've made focusable yourself.
|
|
103
|
+
* `:focus-visible`, so a mouse click doesn't ring it — only keyboard focus does.
|
|
104
|
+
*/
|
|
105
|
+
export const focusRing = {
|
|
106
|
+
_focusVisible: {
|
|
107
|
+
outlineWidth: 'thick',
|
|
108
|
+
outlineStyle: 'solid',
|
|
109
|
+
outlineColor: 'focusRing',
|
|
110
|
+
outlineOffset: '2px',
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
/** Reads as unavailable and stops responding, without the `disabled` attribute. */
|
|
114
|
+
export const disabled = { opacity: 0.5, pointerEvents: 'none', cursor: 'not-allowed' };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { FxObject, FxProp } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Map a component's props to `fx`.
|
|
4
|
+
*
|
|
5
|
+
* A component with a `tone` and a `size` ends up writing the same lookup by hand every
|
|
6
|
+
* time, usually as a ternary chain that is hard to extend and easy to get out of sync
|
|
7
|
+
* with the prop type. This is that lookup, once:
|
|
8
|
+
*
|
|
9
|
+
* const panel = variants({
|
|
10
|
+
* base: { p: 3, radius: 'md' },
|
|
11
|
+
* variants: {
|
|
12
|
+
* tone: { neutral: { bg: 'surface' }, danger: { bg: 'dangerSubtle' } },
|
|
13
|
+
* size: { sm: { p: 2 }, lg: { p: 4 } },
|
|
14
|
+
* },
|
|
15
|
+
* defaults: { tone: 'neutral' },
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* panel({ tone: 'danger' }); // FxObject
|
|
19
|
+
*
|
|
20
|
+
* Later groups win over earlier ones, and `base` loses to all of them — declaration
|
|
21
|
+
* order in the config is the precedence. The result is an ordinary `FxObject`, so a
|
|
22
|
+
* caller's own `fx` still merges over it at the element.
|
|
23
|
+
*/
|
|
24
|
+
/** A group of mutually exclusive options, e.g. `{ sm: …, md: … }`. */
|
|
25
|
+
export type VariantGroup = Record<string, FxProp>;
|
|
26
|
+
export interface VariantConfig<G extends Record<string, VariantGroup>> {
|
|
27
|
+
/** Applied first, under every selected variant. */
|
|
28
|
+
base?: FxProp;
|
|
29
|
+
/** The groups themselves, in precedence order. */
|
|
30
|
+
variants: G;
|
|
31
|
+
/** Used for any group the caller leaves out. */
|
|
32
|
+
defaults?: {
|
|
33
|
+
[K in keyof G]?: keyof G[K] & string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** What a variant function accepts: one option per group, or nothing. */
|
|
37
|
+
export type VariantSelection<G extends Record<string, VariantGroup>> = {
|
|
38
|
+
[K in keyof G]?: (keyof G[K] & string) | false | null | undefined;
|
|
39
|
+
};
|
|
40
|
+
export declare function variants<G extends Record<string, VariantGroup>>(config: VariantConfig<G>): (selection?: VariantSelection<G>) => FxObject;
|
|
41
|
+
//# sourceMappingURL=variants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variants.d.ts","sourceRoot":"","sources":["../../src/lib/variants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,sEAAsE;AACtE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElD,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;IACnE,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,EAAE,CAAC,CAAC;IACZ,gDAAgD;IAChD,QAAQ,CAAC,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM;KAAE,CAAC;CACrD;AAED,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI;KACpE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS;CAClE,CAAC;AAEF,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EAC7D,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GACvB,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,QAAQ,CAgB/C"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { mergeFx } from './merge.js';
|
|
2
|
+
export function variants(config) {
|
|
3
|
+
const groups = Object.keys(config.variants);
|
|
4
|
+
return (selection) => {
|
|
5
|
+
const parts = [config.base];
|
|
6
|
+
for (const group of groups) {
|
|
7
|
+
const chosen = selection?.[group] ?? config.defaults?.[group];
|
|
8
|
+
// `false` selects nothing on purpose — it is how a caller turns a defaulted
|
|
9
|
+
// group off without knowing which option the default was.
|
|
10
|
+
if (chosen == null || chosen === false)
|
|
11
|
+
continue;
|
|
12
|
+
parts.push(config.variants[group][chosen]);
|
|
13
|
+
}
|
|
14
|
+
return mergeFx(...parts);
|
|
15
|
+
};
|
|
16
|
+
}
|