@tenphi/tasty 0.0.0-snapshot.bbd10c7 → 0.0.0-snapshot.bbd36bd
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 +196 -140
- package/dist/astro-CeYENy2x.js +301 -0
- package/dist/astro-CeYENy2x.js.map +1 -0
- package/dist/{ssr/async-storage.js → async-storage-DKK-wTD4.js} +16 -6
- package/dist/async-storage-DKK-wTD4.js.map +1 -0
- package/dist/babel-DWCsafYw.d.ts +83 -0
- package/dist/collector-B3OsM252.js +327 -0
- package/dist/collector-B3OsM252.js.map +1 -0
- package/dist/collector-BTVXj2hS.d.ts +163 -0
- package/dist/config-B3gPdCqd.js +12421 -0
- package/dist/config-B3gPdCqd.js.map +1 -0
- package/dist/config-LfIDmVHx.d.ts +1363 -0
- package/dist/context-CA8YKeMn.js +24 -0
- package/dist/context-CA8YKeMn.js.map +1 -0
- package/dist/core/index.d.ts +5 -34
- package/dist/core/index.js +6 -27
- package/dist/core-DGm0CFHP.js +1732 -0
- package/dist/core-DGm0CFHP.js.map +1 -0
- package/dist/css-resources-Cyl_axbI.js +149 -0
- package/dist/css-resources-Cyl_axbI.js.map +1 -0
- package/dist/{zero/extractor.js → css-writer-Bgowobbx.js} +148 -24
- package/dist/css-writer-Bgowobbx.js.map +1 -0
- package/dist/{ssr/format-global-rules.js → format-global-rules-DklyaXv-.js} +2 -2
- package/dist/format-global-rules-DklyaXv-.js.map +1 -0
- package/dist/{ssr/format-rules.js → format-rules-XRw9u7d4.js} +33 -2
- package/dist/format-rules-XRw9u7d4.js.map +1 -0
- package/dist/hydrate-CNOmZprz.js +37 -0
- package/dist/hydrate-CNOmZprz.js.map +1 -0
- package/dist/index-Bm9ltvdH.d.ts +1933 -0
- package/dist/index-BmogEzTo.d.ts +1575 -0
- package/dist/index.d.ts +5 -51
- package/dist/index.js +922 -36
- package/dist/index.js.map +1 -0
- package/dist/keyframes-DE-OE76F.js +535 -0
- package/dist/keyframes-DE-OE76F.js.map +1 -0
- package/dist/{utils/merge-styles.d.ts → merge-styles-BcLl1u_d.d.ts} +3 -3
- package/dist/{utils/merge-styles.js → merge-styles-DuoZEsm9.js} +3 -4
- package/dist/merge-styles-DuoZEsm9.js.map +1 -0
- package/dist/{utils/resolve-recipes.js → resolve-recipes-H9NqOQuP.js} +4 -6
- package/dist/resolve-recipes-H9NqOQuP.js.map +1 -0
- package/dist/ssr/astro-client.js +19 -0
- package/dist/ssr/astro-client.js.map +1 -0
- package/dist/ssr/astro-middleware-extract-static.d.ts +11 -0
- package/dist/ssr/astro-middleware-extract-static.js +9 -0
- package/dist/ssr/astro-middleware-extract-static.js.map +1 -0
- package/dist/ssr/astro-middleware-extract.d.ts +11 -0
- package/dist/ssr/astro-middleware-extract.js +9 -0
- package/dist/ssr/astro-middleware-extract.js.map +1 -0
- package/dist/ssr/astro-middleware-static.d.ts +18 -0
- package/dist/ssr/astro-middleware-static.js +18 -0
- package/dist/ssr/astro-middleware-static.js.map +1 -0
- package/dist/ssr/astro-middleware.d.ts +19 -0
- package/dist/ssr/astro-middleware.js +19 -0
- package/dist/ssr/astro-middleware.js.map +1 -0
- package/dist/ssr/astro.d.ts +117 -11
- package/dist/ssr/astro.js +2 -64
- package/dist/ssr/index.d.ts +37 -4
- package/dist/ssr/index.js +6 -6
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next-config.d.ts +66 -0
- package/dist/ssr/next-config.js +115 -0
- package/dist/ssr/next-config.js.map +1 -0
- package/dist/ssr/next.d.ts +14 -5
- package/dist/ssr/next.js +32 -15
- package/dist/ssr/next.js.map +1 -1
- package/dist/ssr-collector-ref-COs_ioWl.js +29 -0
- package/dist/ssr-collector-ref-COs_ioWl.js.map +1 -0
- package/dist/static/index.d.ts +91 -5
- package/dist/static/index.js +49 -3
- package/dist/static/index.js.map +1 -0
- package/dist/static/inject.js.map +1 -1
- package/dist/zero/babel.d.ts +2 -182
- package/dist/zero/babel.js +80 -40
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +81 -3
- package/dist/zero/index.js +2 -3
- package/dist/zero/next.d.ts +1 -1
- package/dist/zero/next.js +1 -1
- package/dist/zero/next.js.map +1 -1
- package/docs/README.md +20 -12
- package/docs/adoption.md +59 -32
- package/docs/ai-agents.md +224 -0
- package/docs/comparison.md +76 -48
- package/docs/configuration.md +566 -69
- package/docs/debug.md +35 -18
- package/docs/design-system.md +63 -32
- package/docs/dsl.md +527 -179
- package/docs/getting-started.md +62 -41
- package/docs/injector.md +157 -51
- package/docs/methodology.md +69 -37
- package/docs/migration-v3.md +285 -0
- package/docs/pipeline.md +741 -0
- package/docs/plugins.md +353 -0
- package/docs/{runtime.md → react-api.md} +176 -67
- package/docs/runtime-benchmarks.md +351 -0
- package/docs/ssr.md +350 -94
- package/docs/styles.md +65 -16
- package/docs/tasty-static.md +149 -87
- package/package.json +78 -23
- package/tasty.config.ts +6 -0
- package/dist/_virtual/_rolldown/runtime.js +0 -7
- package/dist/chunks/cacheKey.js +0 -77
- package/dist/chunks/cacheKey.js.map +0 -1
- package/dist/chunks/definitions.d.ts +0 -37
- package/dist/chunks/definitions.js +0 -258
- package/dist/chunks/definitions.js.map +0 -1
- package/dist/chunks/index.d.ts +0 -1
- package/dist/chunks/renderChunk.d.ts +0 -1
- package/dist/chunks/renderChunk.js +0 -59
- package/dist/chunks/renderChunk.js.map +0 -1
- package/dist/compute-styles.d.ts +0 -31
- package/dist/compute-styles.js +0 -356
- package/dist/compute-styles.js.map +0 -1
- package/dist/config.d.ts +0 -372
- package/dist/config.js +0 -507
- package/dist/config.js.map +0 -1
- package/dist/counter-style/index.js +0 -51
- package/dist/counter-style/index.js.map +0 -1
- package/dist/debug.d.ts +0 -89
- package/dist/debug.js +0 -453
- package/dist/debug.js.map +0 -1
- package/dist/font-face/index.js +0 -63
- package/dist/font-face/index.js.map +0 -1
- package/dist/hooks/index.d.ts +0 -7
- package/dist/hooks/useCounterStyle.d.ts +0 -50
- package/dist/hooks/useCounterStyle.js +0 -45
- package/dist/hooks/useCounterStyle.js.map +0 -1
- package/dist/hooks/useFontFace.d.ts +0 -43
- package/dist/hooks/useFontFace.js +0 -69
- package/dist/hooks/useFontFace.js.map +0 -1
- package/dist/hooks/useGlobalStyles.d.ts +0 -30
- package/dist/hooks/useGlobalStyles.js +0 -77
- package/dist/hooks/useGlobalStyles.js.map +0 -1
- package/dist/hooks/useKeyframes.d.ts +0 -56
- package/dist/hooks/useKeyframes.js +0 -63
- package/dist/hooks/useKeyframes.js.map +0 -1
- package/dist/hooks/useProperty.d.ts +0 -79
- package/dist/hooks/useProperty.js +0 -108
- package/dist/hooks/useProperty.js.map +0 -1
- package/dist/hooks/useRawCSS.d.ts +0 -53
- package/dist/hooks/useRawCSS.js +0 -34
- package/dist/hooks/useRawCSS.js.map +0 -1
- package/dist/hooks/useStyles.d.ts +0 -40
- package/dist/hooks/useStyles.js +0 -29
- package/dist/hooks/useStyles.js.map +0 -1
- package/dist/injector/index.d.ts +0 -166
- package/dist/injector/index.js +0 -166
- package/dist/injector/index.js.map +0 -1
- package/dist/injector/injector.d.ts +0 -166
- package/dist/injector/injector.js +0 -464
- package/dist/injector/injector.js.map +0 -1
- package/dist/injector/sheet-manager.d.ts +0 -136
- package/dist/injector/sheet-manager.js +0 -733
- package/dist/injector/sheet-manager.js.map +0 -1
- package/dist/injector/types.d.ts +0 -204
- package/dist/keyframes/index.js +0 -206
- package/dist/keyframes/index.js.map +0 -1
- package/dist/parser/classify.js +0 -319
- package/dist/parser/classify.js.map +0 -1
- package/dist/parser/const.js +0 -60
- package/dist/parser/const.js.map +0 -1
- package/dist/parser/lru.js +0 -109
- package/dist/parser/lru.js.map +0 -1
- package/dist/parser/parser.d.ts +0 -25
- package/dist/parser/parser.js +0 -115
- package/dist/parser/parser.js.map +0 -1
- package/dist/parser/tokenizer.js +0 -69
- package/dist/parser/tokenizer.js.map +0 -1
- package/dist/parser/types.d.ts +0 -51
- package/dist/parser/types.js +0 -46
- package/dist/parser/types.js.map +0 -1
- package/dist/pipeline/conditions.d.ts +0 -134
- package/dist/pipeline/conditions.js +0 -406
- package/dist/pipeline/conditions.js.map +0 -1
- package/dist/pipeline/exclusive.js +0 -230
- package/dist/pipeline/exclusive.js.map +0 -1
- package/dist/pipeline/index.d.ts +0 -55
- package/dist/pipeline/index.js +0 -708
- package/dist/pipeline/index.js.map +0 -1
- package/dist/pipeline/materialize.js +0 -1103
- package/dist/pipeline/materialize.js.map +0 -1
- package/dist/pipeline/parseStateKey.d.ts +0 -15
- package/dist/pipeline/parseStateKey.js +0 -446
- package/dist/pipeline/parseStateKey.js.map +0 -1
- package/dist/pipeline/simplify.js +0 -515
- package/dist/pipeline/simplify.js.map +0 -1
- package/dist/pipeline/warnings.js +0 -18
- package/dist/pipeline/warnings.js.map +0 -1
- package/dist/plugins/index.d.ts +0 -2
- package/dist/plugins/okhsl-plugin.d.ts +0 -35
- package/dist/plugins/okhsl-plugin.js +0 -97
- package/dist/plugins/okhsl-plugin.js.map +0 -1
- package/dist/plugins/types.d.ts +0 -76
- package/dist/properties/index.js +0 -222
- package/dist/properties/index.js.map +0 -1
- package/dist/properties/property-type-resolver.d.ts +0 -24
- package/dist/properties/property-type-resolver.js +0 -90
- package/dist/properties/property-type-resolver.js.map +0 -1
- package/dist/ssr/astro.js.map +0 -1
- package/dist/ssr/async-storage.d.ts +0 -17
- package/dist/ssr/async-storage.js.map +0 -1
- package/dist/ssr/collect-auto-properties.js +0 -39
- package/dist/ssr/collect-auto-properties.js.map +0 -1
- package/dist/ssr/collector.d.ts +0 -102
- package/dist/ssr/collector.js +0 -219
- package/dist/ssr/collector.js.map +0 -1
- package/dist/ssr/format-global-rules.js.map +0 -1
- package/dist/ssr/format-keyframes.js +0 -69
- package/dist/ssr/format-keyframes.js.map +0 -1
- package/dist/ssr/format-property.js +0 -49
- package/dist/ssr/format-property.js.map +0 -1
- package/dist/ssr/format-rules.js.map +0 -1
- package/dist/ssr/hydrate.d.ts +0 -22
- package/dist/ssr/hydrate.js +0 -49
- package/dist/ssr/hydrate.js.map +0 -1
- package/dist/ssr/ssr-collector-ref.js +0 -12
- package/dist/ssr/ssr-collector-ref.js.map +0 -1
- package/dist/states/index.d.ts +0 -49
- package/dist/states/index.js +0 -170
- package/dist/states/index.js.map +0 -1
- package/dist/static/tastyStatic.d.ts +0 -46
- package/dist/static/tastyStatic.js +0 -30
- package/dist/static/tastyStatic.js.map +0 -1
- package/dist/static/types.d.ts +0 -49
- package/dist/static/types.js +0 -24
- package/dist/static/types.js.map +0 -1
- package/dist/styles/border.d.ts +0 -25
- package/dist/styles/border.js +0 -120
- package/dist/styles/border.js.map +0 -1
- package/dist/styles/color.d.ts +0 -14
- package/dist/styles/color.js +0 -26
- package/dist/styles/color.js.map +0 -1
- package/dist/styles/const.js +0 -17
- package/dist/styles/const.js.map +0 -1
- package/dist/styles/createStyle.js +0 -79
- package/dist/styles/createStyle.js.map +0 -1
- package/dist/styles/dimension.js +0 -109
- package/dist/styles/dimension.js.map +0 -1
- package/dist/styles/directional.js +0 -133
- package/dist/styles/directional.js.map +0 -1
- package/dist/styles/display.d.ts +0 -30
- package/dist/styles/display.js +0 -73
- package/dist/styles/display.js.map +0 -1
- package/dist/styles/fade.d.ts +0 -15
- package/dist/styles/fade.js +0 -62
- package/dist/styles/fade.js.map +0 -1
- package/dist/styles/fill.d.ts +0 -42
- package/dist/styles/fill.js +0 -51
- package/dist/styles/fill.js.map +0 -1
- package/dist/styles/flow.d.ts +0 -16
- package/dist/styles/flow.js +0 -12
- package/dist/styles/flow.js.map +0 -1
- package/dist/styles/gap.d.ts +0 -31
- package/dist/styles/gap.js +0 -38
- package/dist/styles/gap.js.map +0 -1
- package/dist/styles/height.d.ts +0 -17
- package/dist/styles/height.js +0 -19
- package/dist/styles/height.js.map +0 -1
- package/dist/styles/index.d.ts +0 -1
- package/dist/styles/index.js +0 -8
- package/dist/styles/index.js.map +0 -1
- package/dist/styles/inset.d.ts +0 -24
- package/dist/styles/inset.js +0 -34
- package/dist/styles/inset.js.map +0 -1
- package/dist/styles/list.d.ts +0 -16
- package/dist/styles/list.js +0 -100
- package/dist/styles/list.js.map +0 -1
- package/dist/styles/margin.d.ts +0 -24
- package/dist/styles/margin.js +0 -32
- package/dist/styles/margin.js.map +0 -1
- package/dist/styles/outline.d.ts +0 -29
- package/dist/styles/outline.js +0 -55
- package/dist/styles/outline.js.map +0 -1
- package/dist/styles/padding.d.ts +0 -24
- package/dist/styles/padding.js +0 -32
- package/dist/styles/padding.js.map +0 -1
- package/dist/styles/placement.d.ts +0 -37
- package/dist/styles/placement.js +0 -74
- package/dist/styles/placement.js.map +0 -1
- package/dist/styles/predefined.d.ts +0 -71
- package/dist/styles/predefined.js +0 -237
- package/dist/styles/predefined.js.map +0 -1
- package/dist/styles/preset.d.ts +0 -52
- package/dist/styles/preset.js +0 -127
- package/dist/styles/preset.js.map +0 -1
- package/dist/styles/radius.d.ts +0 -12
- package/dist/styles/radius.js +0 -83
- package/dist/styles/radius.js.map +0 -1
- package/dist/styles/scrollMargin.d.ts +0 -24
- package/dist/styles/scrollMargin.js +0 -32
- package/dist/styles/scrollMargin.js.map +0 -1
- package/dist/styles/scrollbar.d.ts +0 -25
- package/dist/styles/scrollbar.js +0 -51
- package/dist/styles/scrollbar.js.map +0 -1
- package/dist/styles/shadow.d.ts +0 -14
- package/dist/styles/shadow.js +0 -25
- package/dist/styles/shadow.js.map +0 -1
- package/dist/styles/shared.js +0 -17
- package/dist/styles/shared.js.map +0 -1
- package/dist/styles/transition.d.ts +0 -14
- package/dist/styles/transition.js +0 -159
- package/dist/styles/transition.js.map +0 -1
- package/dist/styles/types.d.ts +0 -564
- package/dist/styles/width.d.ts +0 -17
- package/dist/styles/width.js +0 -19
- package/dist/styles/width.js.map +0 -1
- package/dist/tasty.d.ts +0 -134
- package/dist/tasty.js +0 -240
- package/dist/tasty.js.map +0 -1
- package/dist/types.d.ts +0 -184
- package/dist/utils/cache-wrapper.js +0 -21
- package/dist/utils/cache-wrapper.js.map +0 -1
- package/dist/utils/case-converter.js +0 -8
- package/dist/utils/case-converter.js.map +0 -1
- package/dist/utils/color-math.d.ts +0 -46
- package/dist/utils/color-math.js +0 -749
- package/dist/utils/color-math.js.map +0 -1
- package/dist/utils/color-space.d.ts +0 -5
- package/dist/utils/color-space.js +0 -228
- package/dist/utils/color-space.js.map +0 -1
- package/dist/utils/colors.d.ts +0 -5
- package/dist/utils/colors.js +0 -10
- package/dist/utils/colors.js.map +0 -1
- package/dist/utils/css-types.d.ts +0 -7
- package/dist/utils/dotize.d.ts +0 -26
- package/dist/utils/dotize.js +0 -122
- package/dist/utils/dotize.js.map +0 -1
- package/dist/utils/filter-base-props.d.ts +0 -15
- package/dist/utils/filter-base-props.js +0 -45
- package/dist/utils/filter-base-props.js.map +0 -1
- package/dist/utils/get-display-name.d.ts +0 -7
- package/dist/utils/get-display-name.js +0 -10
- package/dist/utils/get-display-name.js.map +0 -1
- package/dist/utils/has-keys.js +0 -13
- package/dist/utils/has-keys.js.map +0 -1
- package/dist/utils/is-dev-env.js +0 -19
- package/dist/utils/is-dev-env.js.map +0 -1
- package/dist/utils/is-valid-element-type.js +0 -15
- package/dist/utils/is-valid-element-type.js.map +0 -1
- package/dist/utils/merge-styles.js.map +0 -1
- package/dist/utils/mod-attrs.d.ts +0 -6
- package/dist/utils/mod-attrs.js +0 -20
- package/dist/utils/mod-attrs.js.map +0 -1
- package/dist/utils/process-tokens.d.ts +0 -17
- package/dist/utils/process-tokens.js +0 -83
- package/dist/utils/process-tokens.js.map +0 -1
- package/dist/utils/resolve-recipes.d.ts +0 -17
- package/dist/utils/resolve-recipes.js.map +0 -1
- package/dist/utils/selector-transform.js +0 -32
- package/dist/utils/selector-transform.js.map +0 -1
- package/dist/utils/string.js +0 -8
- package/dist/utils/string.js.map +0 -1
- package/dist/utils/styles.d.ts +0 -99
- package/dist/utils/styles.js +0 -220
- package/dist/utils/styles.js.map +0 -1
- package/dist/utils/typography.d.ts +0 -47
- package/dist/utils/typography.js +0 -51
- package/dist/utils/typography.js.map +0 -1
- package/dist/utils/warnings.d.ts +0 -16
- package/dist/utils/warnings.js +0 -16
- package/dist/utils/warnings.js.map +0 -1
- package/dist/zero/css-writer.d.ts +0 -45
- package/dist/zero/css-writer.js +0 -73
- package/dist/zero/css-writer.js.map +0 -1
- package/dist/zero/extractor.d.ts +0 -24
- package/dist/zero/extractor.js.map +0 -1
- package/docs/PIPELINE.md +0 -519
- /package/dist/{chunks/cacheKey.d.ts → ssr/astro-client.d.ts} +0 -0
package/dist/font-face/index.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
//#region src/font-face/index.ts
|
|
2
|
-
const FONT_FACE_KEY = "@fontFace";
|
|
3
|
-
/**
|
|
4
|
-
* Check if styles object has local @fontFace definition.
|
|
5
|
-
*/
|
|
6
|
-
function hasLocalFontFace(styles) {
|
|
7
|
-
return FONT_FACE_KEY in styles;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Extract local @fontFace from styles object.
|
|
11
|
-
* Returns null if no local font faces (fast path).
|
|
12
|
-
*/
|
|
13
|
-
function extractLocalFontFace(styles) {
|
|
14
|
-
const fontFace = styles[FONT_FACE_KEY];
|
|
15
|
-
if (!fontFace || typeof fontFace !== "object") return null;
|
|
16
|
-
return fontFace;
|
|
17
|
-
}
|
|
18
|
-
const FONT_FACE_DESCRIPTOR_MAP = {
|
|
19
|
-
fontWeight: "font-weight",
|
|
20
|
-
fontStyle: "font-style",
|
|
21
|
-
fontStretch: "font-stretch",
|
|
22
|
-
fontDisplay: "font-display",
|
|
23
|
-
unicodeRange: "unicode-range",
|
|
24
|
-
ascentOverride: "ascent-override",
|
|
25
|
-
descentOverride: "descent-override",
|
|
26
|
-
lineGapOverride: "line-gap-override",
|
|
27
|
-
sizeAdjust: "size-adjust",
|
|
28
|
-
fontFeatureSettings: "font-feature-settings",
|
|
29
|
-
fontVariationSettings: "font-variation-settings"
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Format the inner declarations of a @font-face rule (no wrapper).
|
|
33
|
-
* Used by the injector which needs selector and declarations separately.
|
|
34
|
-
*/
|
|
35
|
-
function formatFontFaceDeclarations(family, descriptors) {
|
|
36
|
-
const parts = [];
|
|
37
|
-
parts.push(`font-family: "${family}";`);
|
|
38
|
-
parts.push(`src: ${descriptors.src};`);
|
|
39
|
-
for (const [key, cssName] of Object.entries(FONT_FACE_DESCRIPTOR_MAP)) {
|
|
40
|
-
const value = descriptors[key];
|
|
41
|
-
if (value !== void 0) parts.push(`${cssName}: ${value};`);
|
|
42
|
-
}
|
|
43
|
-
return parts.join(" ");
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Format a single @font-face rule as CSS.
|
|
47
|
-
*/
|
|
48
|
-
function formatFontFaceRule(family, descriptors) {
|
|
49
|
-
return `@font-face { ${formatFontFaceDeclarations(family, descriptors)} }`;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Generate a content hash for deduplication of a single font-face rule.
|
|
53
|
-
*/
|
|
54
|
-
function fontFaceContentHash(family, descriptors) {
|
|
55
|
-
return JSON.stringify({
|
|
56
|
-
family,
|
|
57
|
-
...descriptors
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
export { extractLocalFontFace, fontFaceContentHash, formatFontFaceDeclarations, formatFontFaceRule, hasLocalFontFace };
|
|
62
|
-
|
|
63
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/font-face/index.ts"],"sourcesContent":["/**\n * Font Face Utilities\n *\n * Utilities for extracting and processing CSS @font-face definitions in styles.\n * Font-face rules are permanent once injected and do not need cleanup.\n */\n\nimport type { FontFaceDescriptors, FontFaceInput } from '../injector/types';\nimport type { Styles } from '../styles/types';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst FONT_FACE_KEY = '@fontFace';\n\n// ============================================================================\n// Extraction Functions\n// ============================================================================\n\n/**\n * Check if styles object has local @fontFace definition.\n */\nexport function hasLocalFontFace(styles: Styles): boolean {\n return FONT_FACE_KEY in styles;\n}\n\n/**\n * Extract local @fontFace from styles object.\n * Returns null if no local font faces (fast path).\n */\nexport function extractLocalFontFace(\n styles: Styles,\n): Record<string, FontFaceInput> | null {\n const fontFace = styles[FONT_FACE_KEY];\n if (!fontFace || typeof fontFace !== 'object') {\n return null;\n }\n return fontFace as Record<string, FontFaceInput>;\n}\n\n// ============================================================================\n// CSS Formatting\n// ============================================================================\n\nconst FONT_FACE_DESCRIPTOR_MAP: Record<string, string> = {\n fontWeight: 'font-weight',\n fontStyle: 'font-style',\n fontStretch: 'font-stretch',\n fontDisplay: 'font-display',\n unicodeRange: 'unicode-range',\n ascentOverride: 'ascent-override',\n descentOverride: 'descent-override',\n lineGapOverride: 'line-gap-override',\n sizeAdjust: 'size-adjust',\n fontFeatureSettings: 'font-feature-settings',\n fontVariationSettings: 'font-variation-settings',\n};\n\n/**\n * Format the inner declarations of a @font-face rule (no wrapper).\n * Used by the injector which needs selector and declarations separately.\n */\nexport function formatFontFaceDeclarations(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n const parts: string[] = [];\n\n parts.push(`font-family: \"${family}\";`);\n parts.push(`src: ${descriptors.src};`);\n\n for (const [key, cssName] of Object.entries(FONT_FACE_DESCRIPTOR_MAP)) {\n const value = descriptors[key as keyof FontFaceDescriptors];\n if (value !== undefined) {\n parts.push(`${cssName}: ${value};`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Format a single @font-face rule as CSS.\n */\nexport function formatFontFaceRule(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n return `@font-face { ${formatFontFaceDeclarations(family, descriptors)} }`;\n}\n\n/**\n * Format all @font-face rules for a family (handles single or array form).\n * Returns an array of CSS strings, one per rule.\n */\nexport function formatFontFaceRules(\n family: string,\n input: FontFaceInput,\n): string[] {\n const descriptors = Array.isArray(input) ? input : [input];\n return descriptors.map((desc) => formatFontFaceRule(family, desc));\n}\n\n/**\n * Generate a content hash for deduplication of a single font-face rule.\n */\nexport function fontFaceContentHash(\n family: string,\n descriptors: FontFaceDescriptors,\n): string {\n return JSON.stringify({ family, ...descriptors });\n}\n"],"mappings":";AAcA,MAAM,gBAAgB;;;;AAStB,SAAgB,iBAAiB,QAAyB;AACxD,QAAO,iBAAiB;;;;;;AAO1B,SAAgB,qBACd,QACsC;CACtC,MAAM,WAAW,OAAO;AACxB,KAAI,CAAC,YAAY,OAAO,aAAa,SACnC,QAAO;AAET,QAAO;;AAOT,MAAM,2BAAmD;CACvD,YAAY;CACZ,WAAW;CACX,aAAa;CACb,aAAa;CACb,cAAc;CACd,gBAAgB;CAChB,iBAAiB;CACjB,iBAAiB;CACjB,YAAY;CACZ,qBAAqB;CACrB,uBAAuB;CACxB;;;;;AAMD,SAAgB,2BACd,QACA,aACQ;CACR,MAAM,QAAkB,EAAE;AAE1B,OAAM,KAAK,iBAAiB,OAAO,IAAI;AACvC,OAAM,KAAK,QAAQ,YAAY,IAAI,GAAG;AAEtC,MAAK,MAAM,CAAC,KAAK,YAAY,OAAO,QAAQ,yBAAyB,EAAE;EACrE,MAAM,QAAQ,YAAY;AAC1B,MAAI,UAAU,KAAA,EACZ,OAAM,KAAK,GAAG,QAAQ,IAAI,MAAM,GAAG;;AAIvC,QAAO,MAAM,KAAK,IAAI;;;;;AAMxB,SAAgB,mBACd,QACA,aACQ;AACR,QAAO,gBAAgB,2BAA2B,QAAQ,YAAY,CAAC;;;;;AAkBzE,SAAgB,oBACd,QACA,aACQ;AACR,QAAO,KAAK,UAAU;EAAE;EAAQ,GAAG;EAAa,CAAC"}
|
package/dist/hooks/index.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { UseStylesOptions, UseStylesResult, useStyles } from "./useStyles.js";
|
|
2
|
-
import { useGlobalStyles } from "./useGlobalStyles.js";
|
|
3
|
-
import { useRawCSS } from "./useRawCSS.js";
|
|
4
|
-
import { useKeyframes } from "./useKeyframes.js";
|
|
5
|
-
import { UsePropertyOptions, useProperty } from "./useProperty.js";
|
|
6
|
-
import { useFontFace } from "./useFontFace.js";
|
|
7
|
-
import { useCounterStyle } from "./useCounterStyle.js";
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { CounterStyleDescriptors } from "../injector/types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/hooks/useCounterStyle.d.ts
|
|
4
|
-
interface UseCounterStyleOptions {
|
|
5
|
-
name?: string;
|
|
6
|
-
root?: Document | ShadowRoot;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Hook to inject a CSS @counter-style rule and return the generated name.
|
|
10
|
-
* Permanent — no cleanup on unmount. Deduplicates by name.
|
|
11
|
-
*
|
|
12
|
-
* @example Basic usage
|
|
13
|
-
* ```tsx
|
|
14
|
-
* function EmojiList() {
|
|
15
|
-
* const styleName = useCounterStyle({
|
|
16
|
-
* system: 'cyclic',
|
|
17
|
-
* symbols: '"👍"',
|
|
18
|
-
* suffix: '" "',
|
|
19
|
-
* }, { name: 'thumbs' });
|
|
20
|
-
*
|
|
21
|
-
* return (
|
|
22
|
-
* <ol style={{ listStyleType: styleName }}>
|
|
23
|
-
* <li>First</li>
|
|
24
|
-
* <li>Second</li>
|
|
25
|
-
* </ol>
|
|
26
|
-
* );
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @example Factory function with dependencies
|
|
31
|
-
* ```tsx
|
|
32
|
-
* function DynamicList({ marker }: { marker: string }) {
|
|
33
|
-
* const styleName = useCounterStyle(
|
|
34
|
-
* () => ({
|
|
35
|
-
* system: 'cyclic',
|
|
36
|
-
* symbols: `"${marker}"`,
|
|
37
|
-
* suffix: '" "',
|
|
38
|
-
* }),
|
|
39
|
-
* [marker],
|
|
40
|
-
* );
|
|
41
|
-
*
|
|
42
|
-
* return <ol style={{ listStyleType: styleName }}>...</ol>;
|
|
43
|
-
* }
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
declare function useCounterStyle(descriptors: CounterStyleDescriptors, options?: UseCounterStyleOptions): string;
|
|
47
|
-
declare function useCounterStyle(factory: () => CounterStyleDescriptors, deps: readonly unknown[], options?: UseCounterStyleOptions): string;
|
|
48
|
-
//#endregion
|
|
49
|
-
export { useCounterStyle };
|
|
50
|
-
//# sourceMappingURL=useCounterStyle.d.ts.map
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { formatCounterStyleRule } from "../counter-style/index.js";
|
|
2
|
-
import { getGlobalInjector } from "../config.js";
|
|
3
|
-
import { getRegisteredSSRCollector } from "../ssr/ssr-collector-ref.js";
|
|
4
|
-
import { useInsertionEffect, useMemo } from "react";
|
|
5
|
-
//#region src/hooks/useCounterStyle.ts
|
|
6
|
-
let clientCounterStyleCounter = 0;
|
|
7
|
-
function useCounterStyle(descriptorsOrFactory, depsOrOptions, options) {
|
|
8
|
-
const ssrCollector = getRegisteredSSRCollector();
|
|
9
|
-
const isFactory = typeof descriptorsOrFactory === "function";
|
|
10
|
-
const deps = isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : void 0;
|
|
11
|
-
const opts = isFactory ? options : depsOrOptions;
|
|
12
|
-
const inputKey = useMemo(() => isFactory ? null : JSON.stringify(descriptorsOrFactory), [isFactory ? null : descriptorsOrFactory]);
|
|
13
|
-
const descriptorsData = useMemo(() => {
|
|
14
|
-
const descriptors = isFactory ? descriptorsOrFactory() : descriptorsOrFactory;
|
|
15
|
-
if (!descriptors || !descriptors.system) return null;
|
|
16
|
-
return descriptors;
|
|
17
|
-
}, isFactory ? deps ?? [] : [inputKey]);
|
|
18
|
-
const name = useMemo(() => {
|
|
19
|
-
if (!descriptorsData) return "";
|
|
20
|
-
if (ssrCollector) {
|
|
21
|
-
const actualName = ssrCollector.allocateCounterStyleName(opts?.name);
|
|
22
|
-
const css = formatCounterStyleRule(actualName, descriptorsData);
|
|
23
|
-
ssrCollector.collectCounterStyle(actualName, css);
|
|
24
|
-
return actualName;
|
|
25
|
-
}
|
|
26
|
-
return opts?.name ?? `cs${clientCounterStyleCounter++}`;
|
|
27
|
-
}, [
|
|
28
|
-
descriptorsData,
|
|
29
|
-
opts?.name,
|
|
30
|
-
ssrCollector
|
|
31
|
-
]);
|
|
32
|
-
useInsertionEffect(() => {
|
|
33
|
-
if (!descriptorsData || !name) return;
|
|
34
|
-
getGlobalInjector().counterStyle(name, descriptorsData, { root: opts?.root });
|
|
35
|
-
}, [
|
|
36
|
-
descriptorsData,
|
|
37
|
-
name,
|
|
38
|
-
opts?.root
|
|
39
|
-
]);
|
|
40
|
-
return name;
|
|
41
|
-
}
|
|
42
|
-
//#endregion
|
|
43
|
-
export { useCounterStyle };
|
|
44
|
-
|
|
45
|
-
//# sourceMappingURL=useCounterStyle.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useCounterStyle.js","names":[],"sources":["../../src/hooks/useCounterStyle.ts"],"sourcesContent":["import { useInsertionEffect, useMemo } from 'react';\n\nimport { getGlobalInjector } from '../config';\nimport { formatCounterStyleRule } from '../counter-style';\nimport type { CounterStyleDescriptors } from '../injector/types';\nimport { getRegisteredSSRCollector } from '../ssr/ssr-collector-ref';\n\ninterface UseCounterStyleOptions {\n name?: string;\n root?: Document | ShadowRoot;\n}\n\nlet clientCounterStyleCounter = 0;\n\n/**\n * Hook to inject a CSS @counter-style rule and return the generated name.\n * Permanent — no cleanup on unmount. Deduplicates by name.\n *\n * @example Basic usage\n * ```tsx\n * function EmojiList() {\n * const styleName = useCounterStyle({\n * system: 'cyclic',\n * symbols: '\"👍\"',\n * suffix: '\" \"',\n * }, { name: 'thumbs' });\n *\n * return (\n * <ol style={{ listStyleType: styleName }}>\n * <li>First</li>\n * <li>Second</li>\n * </ol>\n * );\n * }\n * ```\n *\n * @example Factory function with dependencies\n * ```tsx\n * function DynamicList({ marker }: { marker: string }) {\n * const styleName = useCounterStyle(\n * () => ({\n * system: 'cyclic',\n * symbols: `\"${marker}\"`,\n * suffix: '\" \"',\n * }),\n * [marker],\n * );\n *\n * return <ol style={{ listStyleType: styleName }}>...</ol>;\n * }\n * ```\n */\n\n// Overload 1: Static descriptors\nexport function useCounterStyle(\n descriptors: CounterStyleDescriptors,\n options?: UseCounterStyleOptions,\n): string;\n\n// Overload 2: Factory function with dependencies\nexport function useCounterStyle(\n factory: () => CounterStyleDescriptors,\n deps: readonly unknown[],\n options?: UseCounterStyleOptions,\n): string;\n\n// Implementation\nexport function useCounterStyle(\n descriptorsOrFactory:\n | CounterStyleDescriptors\n | (() => CounterStyleDescriptors),\n depsOrOptions?: readonly unknown[] | UseCounterStyleOptions,\n options?: UseCounterStyleOptions,\n): string {\n const ssrCollector = getRegisteredSSRCollector();\n\n const isFactory = typeof descriptorsOrFactory === 'function';\n\n const deps =\n isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : undefined;\n const opts = isFactory\n ? options\n : (depsOrOptions as UseCounterStyleOptions | undefined);\n\n // Stable key for the static path — avoids re-triggering when caller\n // passes an inline object literal with the same content.\n const inputKey = useMemo(\n () => (isFactory ? null : JSON.stringify(descriptorsOrFactory)),\n [isFactory ? null : descriptorsOrFactory],\n );\n\n const descriptorsData = useMemo(\n () => {\n const descriptors = isFactory\n ? (descriptorsOrFactory as () => CounterStyleDescriptors)()\n : (descriptorsOrFactory as CounterStyleDescriptors);\n\n if (!descriptors || !descriptors.system) {\n return null;\n }\n\n return descriptors;\n },\n\n isFactory ? (deps ?? []) : [inputKey],\n );\n\n const name = useMemo(() => {\n if (!descriptorsData) {\n return '';\n }\n\n // SSR path: format and collect, return name without DOM injection\n if (ssrCollector) {\n const actualName = ssrCollector.allocateCounterStyleName(opts?.name);\n const css = formatCounterStyleRule(actualName, descriptorsData);\n ssrCollector.collectCounterStyle(actualName, css);\n return actualName;\n }\n\n // Client path: return the name (injection happens in useInsertionEffect)\n return opts?.name ?? `cs${clientCounterStyleCounter++}`;\n }, [descriptorsData, opts?.name, ssrCollector]);\n\n // Client path: inject via DOM\n useInsertionEffect(() => {\n if (!descriptorsData || !name) return;\n\n const injector = getGlobalInjector();\n injector.counterStyle(name, descriptorsData, { root: opts?.root });\n }, [descriptorsData, name, opts?.root]);\n\n return name;\n}\n"],"mappings":";;;;;AAYA,IAAI,4BAA4B;AAuDhC,SAAgB,gBACd,sBAGA,eACA,SACQ;CACR,MAAM,eAAe,2BAA2B;CAEhD,MAAM,YAAY,OAAO,yBAAyB;CAElD,MAAM,OACJ,aAAa,MAAM,QAAQ,cAAc,GAAG,gBAAgB,KAAA;CAC9D,MAAM,OAAO,YACT,UACC;CAIL,MAAM,WAAW,cACR,YAAY,OAAO,KAAK,UAAU,qBAAqB,EAC9D,CAAC,YAAY,OAAO,qBAAqB,CAC1C;CAED,MAAM,kBAAkB,cAChB;EACJ,MAAM,cAAc,YACf,sBAAwD,GACxD;AAEL,MAAI,CAAC,eAAe,CAAC,YAAY,OAC/B,QAAO;AAGT,SAAO;IAGT,YAAa,QAAQ,EAAE,GAAI,CAAC,SAAS,CACtC;CAED,MAAM,OAAO,cAAc;AACzB,MAAI,CAAC,gBACH,QAAO;AAIT,MAAI,cAAc;GAChB,MAAM,aAAa,aAAa,yBAAyB,MAAM,KAAK;GACpE,MAAM,MAAM,uBAAuB,YAAY,gBAAgB;AAC/D,gBAAa,oBAAoB,YAAY,IAAI;AACjD,UAAO;;AAIT,SAAO,MAAM,QAAQ,KAAK;IACzB;EAAC;EAAiB,MAAM;EAAM;EAAa,CAAC;AAG/C,0BAAyB;AACvB,MAAI,CAAC,mBAAmB,CAAC,KAAM;AAEd,qBAAmB,CAC3B,aAAa,MAAM,iBAAiB,EAAE,MAAM,MAAM,MAAM,CAAC;IACjE;EAAC;EAAiB;EAAM,MAAM;EAAK,CAAC;AAEvC,QAAO"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { FontFaceInput } from "../injector/types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/hooks/useFontFace.d.ts
|
|
4
|
-
interface UseFontFaceOptions {
|
|
5
|
-
root?: Document | ShadowRoot;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Hook to inject CSS @font-face rules.
|
|
9
|
-
* Permanent — no cleanup on unmount. Deduplicates by content hash.
|
|
10
|
-
*
|
|
11
|
-
* @param family - The font-family name
|
|
12
|
-
* @param input - Single descriptor object or array of descriptors (for multiple weights/styles)
|
|
13
|
-
* @param options - Optional settings (e.g. Shadow DOM root)
|
|
14
|
-
*
|
|
15
|
-
* @example Single weight
|
|
16
|
-
* ```tsx
|
|
17
|
-
* function App() {
|
|
18
|
-
* useFontFace('Brand Sans', {
|
|
19
|
-
* src: 'url("/fonts/brand-sans.woff2") format("woff2")',
|
|
20
|
-
* fontWeight: '400 700',
|
|
21
|
-
* fontDisplay: 'swap',
|
|
22
|
-
* });
|
|
23
|
-
*
|
|
24
|
-
* return <div style={{ fontFamily: '"Brand Sans", sans-serif' }}>Hello</div>;
|
|
25
|
-
* }
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* @example Multiple weights
|
|
29
|
-
* ```tsx
|
|
30
|
-
* function App() {
|
|
31
|
-
* useFontFace('Brand Sans', [
|
|
32
|
-
* { src: 'url("/fonts/brand-regular.woff2") format("woff2")', fontWeight: 400, fontDisplay: 'swap' },
|
|
33
|
-
* { src: 'url("/fonts/brand-bold.woff2") format("woff2")', fontWeight: 700, fontDisplay: 'swap' },
|
|
34
|
-
* ]);
|
|
35
|
-
*
|
|
36
|
-
* return <div style={{ fontFamily: '"Brand Sans", sans-serif' }}>Hello</div>;
|
|
37
|
-
* }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
declare function useFontFace(family: string, input: FontFaceInput, options?: UseFontFaceOptions): void;
|
|
41
|
-
//#endregion
|
|
42
|
-
export { useFontFace };
|
|
43
|
-
//# sourceMappingURL=useFontFace.d.ts.map
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { fontFaceContentHash, formatFontFaceRule } from "../font-face/index.js";
|
|
2
|
-
import { getGlobalInjector } from "../config.js";
|
|
3
|
-
import { getRegisteredSSRCollector } from "../ssr/ssr-collector-ref.js";
|
|
4
|
-
import { useInsertionEffect, useMemo } from "react";
|
|
5
|
-
//#region src/hooks/useFontFace.ts
|
|
6
|
-
/**
|
|
7
|
-
* Hook to inject CSS @font-face rules.
|
|
8
|
-
* Permanent — no cleanup on unmount. Deduplicates by content hash.
|
|
9
|
-
*
|
|
10
|
-
* @param family - The font-family name
|
|
11
|
-
* @param input - Single descriptor object or array of descriptors (for multiple weights/styles)
|
|
12
|
-
* @param options - Optional settings (e.g. Shadow DOM root)
|
|
13
|
-
*
|
|
14
|
-
* @example Single weight
|
|
15
|
-
* ```tsx
|
|
16
|
-
* function App() {
|
|
17
|
-
* useFontFace('Brand Sans', {
|
|
18
|
-
* src: 'url("/fonts/brand-sans.woff2") format("woff2")',
|
|
19
|
-
* fontWeight: '400 700',
|
|
20
|
-
* fontDisplay: 'swap',
|
|
21
|
-
* });
|
|
22
|
-
*
|
|
23
|
-
* return <div style={{ fontFamily: '"Brand Sans", sans-serif' }}>Hello</div>;
|
|
24
|
-
* }
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* @example Multiple weights
|
|
28
|
-
* ```tsx
|
|
29
|
-
* function App() {
|
|
30
|
-
* useFontFace('Brand Sans', [
|
|
31
|
-
* { src: 'url("/fonts/brand-regular.woff2") format("woff2")', fontWeight: 400, fontDisplay: 'swap' },
|
|
32
|
-
* { src: 'url("/fonts/brand-bold.woff2") format("woff2")', fontWeight: 700, fontDisplay: 'swap' },
|
|
33
|
-
* ]);
|
|
34
|
-
*
|
|
35
|
-
* return <div style={{ fontFamily: '"Brand Sans", sans-serif' }}>Hello</div>;
|
|
36
|
-
* }
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
function useFontFace(family, input, options) {
|
|
40
|
-
const ssrCollector = getRegisteredSSRCollector();
|
|
41
|
-
const inputKey = useMemo(() => JSON.stringify(input), [input]);
|
|
42
|
-
useMemo(() => {
|
|
43
|
-
if (!ssrCollector || !family) return;
|
|
44
|
-
const descriptors = Array.isArray(input) ? input : [input];
|
|
45
|
-
for (const desc of descriptors) {
|
|
46
|
-
const hash = fontFaceContentHash(family, desc);
|
|
47
|
-
const css = formatFontFaceRule(family, desc);
|
|
48
|
-
ssrCollector.collectFontFace(hash, css);
|
|
49
|
-
}
|
|
50
|
-
}, [
|
|
51
|
-
ssrCollector,
|
|
52
|
-
family,
|
|
53
|
-
inputKey
|
|
54
|
-
]);
|
|
55
|
-
useInsertionEffect(() => {
|
|
56
|
-
if (!family) return;
|
|
57
|
-
const injector = getGlobalInjector();
|
|
58
|
-
const descriptors = Array.isArray(input) ? input : [input];
|
|
59
|
-
for (const desc of descriptors) injector.fontFace(family, desc, { root: options?.root });
|
|
60
|
-
}, [
|
|
61
|
-
family,
|
|
62
|
-
inputKey,
|
|
63
|
-
options?.root
|
|
64
|
-
]);
|
|
65
|
-
}
|
|
66
|
-
//#endregion
|
|
67
|
-
export { useFontFace };
|
|
68
|
-
|
|
69
|
-
//# sourceMappingURL=useFontFace.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useFontFace.js","names":[],"sources":["../../src/hooks/useFontFace.ts"],"sourcesContent":["import { useInsertionEffect, useMemo } from 'react';\n\nimport { getGlobalInjector } from '../config';\nimport { fontFaceContentHash, formatFontFaceRule } from '../font-face';\nimport type { FontFaceDescriptors, FontFaceInput } from '../injector/types';\nimport { getRegisteredSSRCollector } from '../ssr/ssr-collector-ref';\n\ninterface UseFontFaceOptions {\n root?: Document | ShadowRoot;\n}\n\n/**\n * Hook to inject CSS @font-face rules.\n * Permanent — no cleanup on unmount. Deduplicates by content hash.\n *\n * @param family - The font-family name\n * @param input - Single descriptor object or array of descriptors (for multiple weights/styles)\n * @param options - Optional settings (e.g. Shadow DOM root)\n *\n * @example Single weight\n * ```tsx\n * function App() {\n * useFontFace('Brand Sans', {\n * src: 'url(\"/fonts/brand-sans.woff2\") format(\"woff2\")',\n * fontWeight: '400 700',\n * fontDisplay: 'swap',\n * });\n *\n * return <div style={{ fontFamily: '\"Brand Sans\", sans-serif' }}>Hello</div>;\n * }\n * ```\n *\n * @example Multiple weights\n * ```tsx\n * function App() {\n * useFontFace('Brand Sans', [\n * { src: 'url(\"/fonts/brand-regular.woff2\") format(\"woff2\")', fontWeight: 400, fontDisplay: 'swap' },\n * { src: 'url(\"/fonts/brand-bold.woff2\") format(\"woff2\")', fontWeight: 700, fontDisplay: 'swap' },\n * ]);\n *\n * return <div style={{ fontFamily: '\"Brand Sans\", sans-serif' }}>Hello</div>;\n * }\n * ```\n */\nexport function useFontFace(\n family: string,\n input: FontFaceInput,\n options?: UseFontFaceOptions,\n): void {\n const ssrCollector = getRegisteredSSRCollector();\n\n const inputKey = useMemo(() => JSON.stringify(input), [input]);\n\n // SSR path: collect @font-face CSS during render\n useMemo(() => {\n if (!ssrCollector || !family) return;\n\n const descriptors: FontFaceDescriptors[] = Array.isArray(input)\n ? input\n : [input];\n\n for (const desc of descriptors) {\n const hash = fontFaceContentHash(family, desc);\n const css = formatFontFaceRule(family, desc);\n ssrCollector.collectFontFace(hash, css);\n }\n }, [ssrCollector, family, inputKey]);\n\n // Client path: inject via DOM\n useInsertionEffect(() => {\n if (!family) return;\n\n const injector = getGlobalInjector();\n const descriptors: FontFaceDescriptors[] = Array.isArray(input)\n ? input\n : [input];\n\n for (const desc of descriptors) {\n injector.fontFace(family, desc, { root: options?.root });\n }\n }, [family, inputKey, options?.root]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,SAAgB,YACd,QACA,OACA,SACM;CACN,MAAM,eAAe,2BAA2B;CAEhD,MAAM,WAAW,cAAc,KAAK,UAAU,MAAM,EAAE,CAAC,MAAM,CAAC;AAG9D,eAAc;AACZ,MAAI,CAAC,gBAAgB,CAAC,OAAQ;EAE9B,MAAM,cAAqC,MAAM,QAAQ,MAAM,GAC3D,QACA,CAAC,MAAM;AAEX,OAAK,MAAM,QAAQ,aAAa;GAC9B,MAAM,OAAO,oBAAoB,QAAQ,KAAK;GAC9C,MAAM,MAAM,mBAAmB,QAAQ,KAAK;AAC5C,gBAAa,gBAAgB,MAAM,IAAI;;IAExC;EAAC;EAAc;EAAQ;EAAS,CAAC;AAGpC,0BAAyB;AACvB,MAAI,CAAC,OAAQ;EAEb,MAAM,WAAW,mBAAmB;EACpC,MAAM,cAAqC,MAAM,QAAQ,MAAM,GAC3D,QACA,CAAC,MAAM;AAEX,OAAK,MAAM,QAAQ,YACjB,UAAS,SAAS,QAAQ,MAAM,EAAE,MAAM,SAAS,MAAM,CAAC;IAEzD;EAAC;EAAQ;EAAU,SAAS;EAAK,CAAC"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { Styles } from "../styles/types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/hooks/useGlobalStyles.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Hook to inject global styles for a given selector.
|
|
6
|
-
* Useful for styling elements by selector without generating classNames.
|
|
7
|
-
*
|
|
8
|
-
* SSR-aware: when a ServerStyleCollector is available, CSS is collected
|
|
9
|
-
* during the render phase instead of being injected into the DOM.
|
|
10
|
-
*
|
|
11
|
-
* @param selector - CSS selector to apply styles to (e.g., '.my-class', ':root', 'body')
|
|
12
|
-
* @param styles - Tasty styles object
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```tsx
|
|
16
|
-
* function MyComponent() {
|
|
17
|
-
* useGlobalStyles('.card', {
|
|
18
|
-
* padding: '2x',
|
|
19
|
-
* radius: '1r',
|
|
20
|
-
* fill: '#white',
|
|
21
|
-
* });
|
|
22
|
-
*
|
|
23
|
-
* return <div className="card">Content</div>;
|
|
24
|
-
* }
|
|
25
|
-
* ```
|
|
26
|
-
*/
|
|
27
|
-
declare function useGlobalStyles(selector: string, styles?: Styles): void;
|
|
28
|
-
//#endregion
|
|
29
|
-
export { useGlobalStyles };
|
|
30
|
-
//# sourceMappingURL=useGlobalStyles.d.ts.map
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { renderStyles } from "../pipeline/index.js";
|
|
2
|
-
import { getConfig } from "../config.js";
|
|
3
|
-
import { injectGlobal } from "../injector/index.js";
|
|
4
|
-
import { collectAutoInferredProperties } from "../ssr/collect-auto-properties.js";
|
|
5
|
-
import { formatGlobalRules } from "../ssr/format-global-rules.js";
|
|
6
|
-
import { getRegisteredSSRCollector } from "../ssr/ssr-collector-ref.js";
|
|
7
|
-
import { resolveRecipes } from "../utils/resolve-recipes.js";
|
|
8
|
-
import { useInsertionEffect, useMemo, useRef } from "react";
|
|
9
|
-
//#region src/hooks/useGlobalStyles.ts
|
|
10
|
-
/**
|
|
11
|
-
* Hook to inject global styles for a given selector.
|
|
12
|
-
* Useful for styling elements by selector without generating classNames.
|
|
13
|
-
*
|
|
14
|
-
* SSR-aware: when a ServerStyleCollector is available, CSS is collected
|
|
15
|
-
* during the render phase instead of being injected into the DOM.
|
|
16
|
-
*
|
|
17
|
-
* @param selector - CSS selector to apply styles to (e.g., '.my-class', ':root', 'body')
|
|
18
|
-
* @param styles - Tasty styles object
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```tsx
|
|
22
|
-
* function MyComponent() {
|
|
23
|
-
* useGlobalStyles('.card', {
|
|
24
|
-
* padding: '2x',
|
|
25
|
-
* radius: '1r',
|
|
26
|
-
* fill: '#white',
|
|
27
|
-
* });
|
|
28
|
-
*
|
|
29
|
-
* return <div className="card">Content</div>;
|
|
30
|
-
* }
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
function useGlobalStyles(selector, styles) {
|
|
34
|
-
const ssrCollector = getRegisteredSSRCollector();
|
|
35
|
-
const disposeRef = useRef(null);
|
|
36
|
-
const resolvedStyles = useMemo(() => {
|
|
37
|
-
if (!styles) return styles;
|
|
38
|
-
return resolveRecipes(styles);
|
|
39
|
-
}, [styles]);
|
|
40
|
-
const styleResults = useMemo(() => {
|
|
41
|
-
if (!resolvedStyles) return [];
|
|
42
|
-
if (!selector) {
|
|
43
|
-
console.warn("[Tasty] useGlobalStyles: selector is required and cannot be empty. Styles will not be injected.");
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
return renderStyles(resolvedStyles, selector);
|
|
47
|
-
}, [resolvedStyles, selector]);
|
|
48
|
-
useMemo(() => {
|
|
49
|
-
if (!ssrCollector || styleResults.length === 0) return;
|
|
50
|
-
ssrCollector.collectInternals();
|
|
51
|
-
const css = formatGlobalRules(styleResults);
|
|
52
|
-
if (css) {
|
|
53
|
-
const key = `global:${selector}:${css.length}:${css.slice(0, 64)}`;
|
|
54
|
-
ssrCollector.collectGlobalStyles(key, css);
|
|
55
|
-
}
|
|
56
|
-
if (getConfig().autoPropertyTypes !== false) collectAutoInferredProperties(styleResults, ssrCollector, resolvedStyles);
|
|
57
|
-
}, [
|
|
58
|
-
ssrCollector,
|
|
59
|
-
styleResults,
|
|
60
|
-
selector
|
|
61
|
-
]);
|
|
62
|
-
useInsertionEffect(() => {
|
|
63
|
-
disposeRef.current?.();
|
|
64
|
-
if (styleResults.length > 0) {
|
|
65
|
-
const { dispose } = injectGlobal(styleResults);
|
|
66
|
-
disposeRef.current = dispose;
|
|
67
|
-
} else disposeRef.current = null;
|
|
68
|
-
return () => {
|
|
69
|
-
disposeRef.current?.();
|
|
70
|
-
disposeRef.current = null;
|
|
71
|
-
};
|
|
72
|
-
}, [styleResults]);
|
|
73
|
-
}
|
|
74
|
-
//#endregion
|
|
75
|
-
export { useGlobalStyles };
|
|
76
|
-
|
|
77
|
-
//# sourceMappingURL=useGlobalStyles.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useGlobalStyles.js","names":[],"sources":["../../src/hooks/useGlobalStyles.ts"],"sourcesContent":["import { useInsertionEffect, useMemo, useRef } from 'react';\n\nimport { getConfig } from '../config';\nimport { injectGlobal } from '../injector';\nimport type { StyleResult } from '../pipeline';\nimport { renderStyles } from '../pipeline';\nimport { collectAutoInferredProperties } from '../ssr/collect-auto-properties';\nimport { formatGlobalRules } from '../ssr/format-global-rules';\nimport { getRegisteredSSRCollector } from '../ssr/ssr-collector-ref';\nimport type { Styles } from '../styles/types';\nimport { resolveRecipes } from '../utils/resolve-recipes';\n\n/**\n * Hook to inject global styles for a given selector.\n * Useful for styling elements by selector without generating classNames.\n *\n * SSR-aware: when a ServerStyleCollector is available, CSS is collected\n * during the render phase instead of being injected into the DOM.\n *\n * @param selector - CSS selector to apply styles to (e.g., '.my-class', ':root', 'body')\n * @param styles - Tasty styles object\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * useGlobalStyles('.card', {\n * padding: '2x',\n * radius: '1r',\n * fill: '#white',\n * });\n *\n * return <div className=\"card\">Content</div>;\n * }\n * ```\n */\nexport function useGlobalStyles(selector: string, styles?: Styles): void {\n const ssrCollector = getRegisteredSSRCollector();\n\n const disposeRef = useRef<(() => void) | null>(null);\n\n // Resolve recipes before rendering (zero overhead if no recipes configured)\n const resolvedStyles = useMemo(() => {\n if (!styles) return styles;\n return resolveRecipes(styles);\n }, [styles]);\n\n // Render styles with the provided selector\n // Note: renderStyles overload with selector string returns StyleResult[] directly\n const styleResults = useMemo((): StyleResult[] => {\n if (!resolvedStyles) return [];\n\n if (!selector) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n '[Tasty] useGlobalStyles: selector is required and cannot be empty. ' +\n 'Styles will not be injected.',\n );\n }\n return [];\n }\n\n const result = renderStyles(resolvedStyles, selector);\n return result as StyleResult[];\n }, [resolvedStyles, selector]);\n\n // SSR path: collect CSS during render\n useMemo(() => {\n if (!ssrCollector || styleResults.length === 0) return;\n\n ssrCollector.collectInternals();\n\n const css = formatGlobalRules(styleResults);\n if (css) {\n const key = `global:${selector}:${css.length}:${css.slice(0, 64)}`;\n ssrCollector.collectGlobalStyles(key, css);\n }\n\n if (getConfig().autoPropertyTypes !== false) {\n collectAutoInferredProperties(styleResults, ssrCollector, resolvedStyles);\n }\n }, [ssrCollector, styleResults, selector]);\n\n // Client path: inject via DOM\n useInsertionEffect(() => {\n disposeRef.current?.();\n\n if (styleResults.length > 0) {\n const { dispose } = injectGlobal(styleResults);\n disposeRef.current = dispose;\n } else {\n disposeRef.current = null;\n }\n\n return () => {\n disposeRef.current?.();\n disposeRef.current = null;\n };\n }, [styleResults]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,gBAAgB,UAAkB,QAAuB;CACvE,MAAM,eAAe,2BAA2B;CAEhD,MAAM,aAAa,OAA4B,KAAK;CAGpD,MAAM,iBAAiB,cAAc;AACnC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,eAAe,OAAO;IAC5B,CAAC,OAAO,CAAC;CAIZ,MAAM,eAAe,cAA6B;AAChD,MAAI,CAAC,eAAgB,QAAO,EAAE;AAE9B,MAAI,CAAC,UAAU;AAEX,WAAQ,KACN,kGAED;AAEH,UAAO,EAAE;;AAIX,SADe,aAAa,gBAAgB,SAAS;IAEpD,CAAC,gBAAgB,SAAS,CAAC;AAG9B,eAAc;AACZ,MAAI,CAAC,gBAAgB,aAAa,WAAW,EAAG;AAEhD,eAAa,kBAAkB;EAE/B,MAAM,MAAM,kBAAkB,aAAa;AAC3C,MAAI,KAAK;GACP,MAAM,MAAM,UAAU,SAAS,GAAG,IAAI,OAAO,GAAG,IAAI,MAAM,GAAG,GAAG;AAChE,gBAAa,oBAAoB,KAAK,IAAI;;AAG5C,MAAI,WAAW,CAAC,sBAAsB,MACpC,+BAA8B,cAAc,cAAc,eAAe;IAE1E;EAAC;EAAc;EAAc;EAAS,CAAC;AAG1C,0BAAyB;AACvB,aAAW,WAAW;AAEtB,MAAI,aAAa,SAAS,GAAG;GAC3B,MAAM,EAAE,YAAY,aAAa,aAAa;AAC9C,cAAW,UAAU;QAErB,YAAW,UAAU;AAGvB,eAAa;AACX,cAAW,WAAW;AACtB,cAAW,UAAU;;IAEtB,CAAC,aAAa,CAAC"}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { KeyframesSteps } from "../injector/types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/hooks/useKeyframes.d.ts
|
|
4
|
-
interface UseKeyframesOptions {
|
|
5
|
-
name?: string;
|
|
6
|
-
root?: Document | ShadowRoot;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Hook to inject CSS @keyframes and return the generated animation name.
|
|
10
|
-
* Handles keyframes injection with proper cleanup on unmount or dependency changes.
|
|
11
|
-
*
|
|
12
|
-
* @example Basic usage - steps object is the dependency
|
|
13
|
-
* ```tsx
|
|
14
|
-
* function MyComponent() {
|
|
15
|
-
* const bounce = useKeyframes({
|
|
16
|
-
* '0%': { transform: 'scale(1)' },
|
|
17
|
-
* '50%': { transform: 'scale(1.1)' },
|
|
18
|
-
* '100%': { transform: 'scale(1)' },
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
* return <div style={{ animation: `${bounce} 1s infinite` }}>Bouncing</div>;
|
|
22
|
-
* }
|
|
23
|
-
* ```
|
|
24
|
-
*
|
|
25
|
-
* @example With custom name
|
|
26
|
-
* ```tsx
|
|
27
|
-
* function MyComponent() {
|
|
28
|
-
* const fadeIn = useKeyframes(
|
|
29
|
-
* { from: { opacity: 0 }, to: { opacity: 1 } },
|
|
30
|
-
* { name: 'fadeIn' }
|
|
31
|
-
* );
|
|
32
|
-
*
|
|
33
|
-
* return <div style={{ animation: `${fadeIn} 0.3s ease-out` }}>Fading in</div>;
|
|
34
|
-
* }
|
|
35
|
-
* ```
|
|
36
|
-
*
|
|
37
|
-
* @example Factory function with dependencies
|
|
38
|
-
* ```tsx
|
|
39
|
-
* function MyComponent({ scale }: { scale: number }) {
|
|
40
|
-
* const pulse = useKeyframes(
|
|
41
|
-
* () => ({
|
|
42
|
-
* '0%': { transform: 'scale(1)' },
|
|
43
|
-
* '100%': { transform: `scale(${scale})` },
|
|
44
|
-
* }),
|
|
45
|
-
* [scale]
|
|
46
|
-
* );
|
|
47
|
-
*
|
|
48
|
-
* return <div style={{ animation: `${pulse} 1s infinite` }}>Pulsing</div>;
|
|
49
|
-
* }
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
declare function useKeyframes(steps: KeyframesSteps, options?: UseKeyframesOptions): string;
|
|
53
|
-
declare function useKeyframes(factory: () => KeyframesSteps, deps: readonly unknown[], options?: UseKeyframesOptions): string;
|
|
54
|
-
//#endregion
|
|
55
|
-
export { useKeyframes };
|
|
56
|
-
//# sourceMappingURL=useKeyframes.d.ts.map
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { keyframes } from "../injector/index.js";
|
|
2
|
-
import { formatKeyframesCSS } from "../ssr/format-keyframes.js";
|
|
3
|
-
import { getRegisteredSSRCollector } from "../ssr/ssr-collector-ref.js";
|
|
4
|
-
import { useInsertionEffect, useMemo, useRef } from "react";
|
|
5
|
-
//#region src/hooks/useKeyframes.ts
|
|
6
|
-
function useKeyframes(stepsOrFactory, depsOrOptions, options) {
|
|
7
|
-
const ssrCollector = getRegisteredSSRCollector();
|
|
8
|
-
const isFactory = typeof stepsOrFactory === "function";
|
|
9
|
-
const deps = isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : void 0;
|
|
10
|
-
const opts = isFactory ? options : depsOrOptions;
|
|
11
|
-
const stepsData = useMemo(() => {
|
|
12
|
-
const steps = isFactory ? stepsOrFactory() : stepsOrFactory;
|
|
13
|
-
if (!steps || Object.keys(steps).length === 0) return null;
|
|
14
|
-
return steps;
|
|
15
|
-
}, isFactory ? deps ?? [] : [stepsOrFactory]);
|
|
16
|
-
const renderResultRef = useRef(null);
|
|
17
|
-
const effectResultRef = useRef(null);
|
|
18
|
-
const name = useMemo(() => {
|
|
19
|
-
if (!stepsData) return "";
|
|
20
|
-
if (ssrCollector) {
|
|
21
|
-
const actualName = ssrCollector.allocateKeyframeName(opts?.name);
|
|
22
|
-
const css = formatKeyframesCSS(actualName, stepsData);
|
|
23
|
-
ssrCollector.collectKeyframes(actualName, css);
|
|
24
|
-
return actualName;
|
|
25
|
-
}
|
|
26
|
-
renderResultRef.current?.dispose();
|
|
27
|
-
renderResultRef.current = null;
|
|
28
|
-
const result = keyframes(stepsData, {
|
|
29
|
-
name: opts?.name,
|
|
30
|
-
root: opts?.root
|
|
31
|
-
});
|
|
32
|
-
renderResultRef.current = result;
|
|
33
|
-
return result.toString();
|
|
34
|
-
}, [
|
|
35
|
-
stepsData,
|
|
36
|
-
opts?.name,
|
|
37
|
-
opts?.root,
|
|
38
|
-
ssrCollector
|
|
39
|
-
]);
|
|
40
|
-
useInsertionEffect(() => {
|
|
41
|
-
effectResultRef.current?.dispose();
|
|
42
|
-
effectResultRef.current = null;
|
|
43
|
-
if (stepsData) effectResultRef.current = keyframes(stepsData, {
|
|
44
|
-
name: opts?.name,
|
|
45
|
-
root: opts?.root
|
|
46
|
-
});
|
|
47
|
-
return () => {
|
|
48
|
-
effectResultRef.current?.dispose();
|
|
49
|
-
effectResultRef.current = null;
|
|
50
|
-
renderResultRef.current?.dispose();
|
|
51
|
-
renderResultRef.current = null;
|
|
52
|
-
};
|
|
53
|
-
}, [
|
|
54
|
-
stepsData,
|
|
55
|
-
opts?.name,
|
|
56
|
-
opts?.root
|
|
57
|
-
]);
|
|
58
|
-
return name;
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
export { useKeyframes };
|
|
62
|
-
|
|
63
|
-
//# sourceMappingURL=useKeyframes.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useKeyframes.js","names":[],"sources":["../../src/hooks/useKeyframes.ts"],"sourcesContent":["import { useInsertionEffect, useMemo, useRef } from 'react';\n\nimport { keyframes } from '../injector';\nimport type { KeyframesResult, KeyframesSteps } from '../injector/types';\nimport { formatKeyframesCSS } from '../ssr/format-keyframes';\nimport { getRegisteredSSRCollector } from '../ssr/ssr-collector-ref';\n\ninterface UseKeyframesOptions {\n name?: string;\n root?: Document | ShadowRoot;\n}\n\n/**\n * Hook to inject CSS @keyframes and return the generated animation name.\n * Handles keyframes injection with proper cleanup on unmount or dependency changes.\n *\n * @example Basic usage - steps object is the dependency\n * ```tsx\n * function MyComponent() {\n * const bounce = useKeyframes({\n * '0%': { transform: 'scale(1)' },\n * '50%': { transform: 'scale(1.1)' },\n * '100%': { transform: 'scale(1)' },\n * });\n *\n * return <div style={{ animation: `${bounce} 1s infinite` }}>Bouncing</div>;\n * }\n * ```\n *\n * @example With custom name\n * ```tsx\n * function MyComponent() {\n * const fadeIn = useKeyframes(\n * { from: { opacity: 0 }, to: { opacity: 1 } },\n * { name: 'fadeIn' }\n * );\n *\n * return <div style={{ animation: `${fadeIn} 0.3s ease-out` }}>Fading in</div>;\n * }\n * ```\n *\n * @example Factory function with dependencies\n * ```tsx\n * function MyComponent({ scale }: { scale: number }) {\n * const pulse = useKeyframes(\n * () => ({\n * '0%': { transform: 'scale(1)' },\n * '100%': { transform: `scale(${scale})` },\n * }),\n * [scale]\n * );\n *\n * return <div style={{ animation: `${pulse} 1s infinite` }}>Pulsing</div>;\n * }\n * ```\n */\n\n// Overload 1: Static steps object\nexport function useKeyframes(\n steps: KeyframesSteps,\n options?: UseKeyframesOptions,\n): string;\n\n// Overload 2: Factory function with dependencies\nexport function useKeyframes(\n factory: () => KeyframesSteps,\n deps: readonly unknown[],\n options?: UseKeyframesOptions,\n): string;\n\n// Implementation\nexport function useKeyframes(\n stepsOrFactory: KeyframesSteps | (() => KeyframesSteps),\n depsOrOptions?: readonly unknown[] | UseKeyframesOptions,\n options?: UseKeyframesOptions,\n): string {\n const ssrCollector = getRegisteredSSRCollector();\n\n // Detect which overload is being used\n const isFactory = typeof stepsOrFactory === 'function';\n\n // Parse arguments based on overload\n const deps =\n isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : undefined;\n const opts = isFactory\n ? options\n : (depsOrOptions as UseKeyframesOptions | undefined);\n\n // Memoize the keyframes steps to get a stable reference\n const stepsData = useMemo(\n () => {\n const steps = isFactory\n ? (stepsOrFactory as () => KeyframesSteps)()\n : (stepsOrFactory as KeyframesSteps);\n\n if (!steps || Object.keys(steps).length === 0) {\n return null;\n }\n\n return steps;\n },\n\n isFactory ? (deps ?? []) : [stepsOrFactory],\n );\n\n // Store keyframes results for cleanup (client only)\n const renderResultRef = useRef<KeyframesResult | null>(null);\n const effectResultRef = useRef<KeyframesResult | null>(null);\n\n const name = useMemo(() => {\n if (!stepsData) {\n return '';\n }\n\n // SSR path: format and collect, return name without DOM injection\n if (ssrCollector) {\n const actualName = ssrCollector.allocateKeyframeName(opts?.name);\n const css = formatKeyframesCSS(actualName, stepsData);\n ssrCollector.collectKeyframes(actualName, css);\n return actualName;\n }\n\n // Client path: inject keyframes synchronously for immediate name availability\n renderResultRef.current?.dispose();\n renderResultRef.current = null;\n\n const result = keyframes(stepsData, {\n name: opts?.name,\n root: opts?.root,\n });\n\n renderResultRef.current = result;\n\n return result.toString();\n }, [stepsData, opts?.name, opts?.root, ssrCollector]);\n\n // Client path: handle Strict Mode double-invocation and cleanup\n useInsertionEffect(() => {\n effectResultRef.current?.dispose();\n effectResultRef.current = null;\n\n if (stepsData) {\n const result = keyframes(stepsData, {\n name: opts?.name,\n root: opts?.root,\n });\n effectResultRef.current = result;\n }\n\n return () => {\n effectResultRef.current?.dispose();\n effectResultRef.current = null;\n renderResultRef.current?.dispose();\n renderResultRef.current = null;\n };\n }, [stepsData, opts?.name, opts?.root]);\n\n return name;\n}\n"],"mappings":";;;;;AAuEA,SAAgB,aACd,gBACA,eACA,SACQ;CACR,MAAM,eAAe,2BAA2B;CAGhD,MAAM,YAAY,OAAO,mBAAmB;CAG5C,MAAM,OACJ,aAAa,MAAM,QAAQ,cAAc,GAAG,gBAAgB,KAAA;CAC9D,MAAM,OAAO,YACT,UACC;CAGL,MAAM,YAAY,cACV;EACJ,MAAM,QAAQ,YACT,gBAAyC,GACzC;AAEL,MAAI,CAAC,SAAS,OAAO,KAAK,MAAM,CAAC,WAAW,EAC1C,QAAO;AAGT,SAAO;IAGT,YAAa,QAAQ,EAAE,GAAI,CAAC,eAAe,CAC5C;CAGD,MAAM,kBAAkB,OAA+B,KAAK;CAC5D,MAAM,kBAAkB,OAA+B,KAAK;CAE5D,MAAM,OAAO,cAAc;AACzB,MAAI,CAAC,UACH,QAAO;AAIT,MAAI,cAAc;GAChB,MAAM,aAAa,aAAa,qBAAqB,MAAM,KAAK;GAChE,MAAM,MAAM,mBAAmB,YAAY,UAAU;AACrD,gBAAa,iBAAiB,YAAY,IAAI;AAC9C,UAAO;;AAIT,kBAAgB,SAAS,SAAS;AAClC,kBAAgB,UAAU;EAE1B,MAAM,SAAS,UAAU,WAAW;GAClC,MAAM,MAAM;GACZ,MAAM,MAAM;GACb,CAAC;AAEF,kBAAgB,UAAU;AAE1B,SAAO,OAAO,UAAU;IACvB;EAAC;EAAW,MAAM;EAAM,MAAM;EAAM;EAAa,CAAC;AAGrD,0BAAyB;AACvB,kBAAgB,SAAS,SAAS;AAClC,kBAAgB,UAAU;AAE1B,MAAI,UAKF,iBAAgB,UAJD,UAAU,WAAW;GAClC,MAAM,MAAM;GACZ,MAAM,MAAM;GACb,CAAC;AAIJ,eAAa;AACX,mBAAgB,SAAS,SAAS;AAClC,mBAAgB,UAAU;AAC1B,mBAAgB,SAAS,SAAS;AAClC,mBAAgB,UAAU;;IAE3B;EAAC;EAAW,MAAM;EAAM,MAAM;EAAK,CAAC;AAEvC,QAAO"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
//#region src/hooks/useProperty.d.ts
|
|
2
|
-
interface UsePropertyOptions {
|
|
3
|
-
/**
|
|
4
|
-
* CSS syntax string for the property (e.g., '<color>', '<length>', '<angle>').
|
|
5
|
-
* For color tokens (#name), this is auto-set to '<color>' and cannot be overridden.
|
|
6
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/@property/syntax
|
|
7
|
-
*/
|
|
8
|
-
syntax?: string;
|
|
9
|
-
/**
|
|
10
|
-
* Whether the property inherits from parent elements
|
|
11
|
-
* @default true
|
|
12
|
-
*/
|
|
13
|
-
inherits?: boolean;
|
|
14
|
-
/**
|
|
15
|
-
* Initial value for the property.
|
|
16
|
-
* For color tokens (#name), this defaults to 'transparent' if not specified.
|
|
17
|
-
*/
|
|
18
|
-
initialValue?: string | number;
|
|
19
|
-
/**
|
|
20
|
-
* Shadow root or document to inject into
|
|
21
|
-
*/
|
|
22
|
-
root?: Document | ShadowRoot;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Hook to register a CSS @property custom property.
|
|
26
|
-
* This enables advanced features like animating custom properties.
|
|
27
|
-
*
|
|
28
|
-
* Note: @property rules are global and persistent once defined.
|
|
29
|
-
* The hook ensures the property is only registered once per root.
|
|
30
|
-
*
|
|
31
|
-
* Accepts tasty token syntax for the property name:
|
|
32
|
-
* - `$name` → defines `--name`
|
|
33
|
-
* - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')
|
|
34
|
-
* - `--name` → defines `--name` (legacy format)
|
|
35
|
-
*
|
|
36
|
-
* @param name - The property token ($name, #name) or CSS property name (--name)
|
|
37
|
-
* @param options - Property configuration
|
|
38
|
-
*
|
|
39
|
-
* @example Basic property with token syntax
|
|
40
|
-
* ```tsx
|
|
41
|
-
* function Spinner() {
|
|
42
|
-
* useProperty('$rotation', {
|
|
43
|
-
* syntax: '<angle>',
|
|
44
|
-
* inherits: false,
|
|
45
|
-
* initialValue: '0deg',
|
|
46
|
-
* });
|
|
47
|
-
*
|
|
48
|
-
* return <div className="spinner" />;
|
|
49
|
-
* }
|
|
50
|
-
* ```
|
|
51
|
-
*
|
|
52
|
-
* @example Color property with token syntax (auto-sets syntax)
|
|
53
|
-
* ```tsx
|
|
54
|
-
* function MyComponent() {
|
|
55
|
-
* useProperty('#theme', {
|
|
56
|
-
* initialValue: 'red', // syntax: '<color>' is auto-set
|
|
57
|
-
* });
|
|
58
|
-
*
|
|
59
|
-
* // Now --theme-color can be animated with CSS transitions
|
|
60
|
-
* return <div style={{ '--theme-color': 'blue' } as React.CSSProperties}>Colored</div>;
|
|
61
|
-
* }
|
|
62
|
-
* ```
|
|
63
|
-
*
|
|
64
|
-
* @example Legacy format (still supported)
|
|
65
|
-
* ```tsx
|
|
66
|
-
* function ResizableBox() {
|
|
67
|
-
* useProperty('--box-size', {
|
|
68
|
-
* syntax: '<length>',
|
|
69
|
-
* initialValue: '100px',
|
|
70
|
-
* });
|
|
71
|
-
*
|
|
72
|
-
* return <div style={{ width: 'var(--box-size)' }} />;
|
|
73
|
-
* }
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
declare function useProperty(name: string, options?: UsePropertyOptions): void;
|
|
77
|
-
//#endregion
|
|
78
|
-
export { UsePropertyOptions, useProperty };
|
|
79
|
-
//# sourceMappingURL=useProperty.d.ts.map
|