@tenphi/tasty 0.0.0-snapshot.d2dcdeb → 0.0.0-snapshot.d4ccea8
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 +181 -131
- package/dist/{ssr/async-storage.js → async-storage-DKK-wTD4.js} +2 -2
- package/dist/async-storage-DKK-wTD4.js.map +1 -0
- package/dist/babel-eMs_zZjM.d.ts +83 -0
- package/dist/{ssr/collector.js → collector-BjkQEtbh.js} +111 -38
- package/dist/collector-BjkQEtbh.js.map +1 -0
- package/dist/{ssr/collector.d.ts → collector-DzeNxHOq.d.ts} +58 -7
- package/dist/config-DMslHK_e.d.ts +1298 -0
- package/dist/config-DX126v_w.js +12318 -0
- package/dist/config-DX126v_w.js.map +1 -0
- package/dist/{ssr/context.js → context-CA8YKeMn.js} +11 -3
- 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-CMn-Tj2X.js +1573 -0
- package/dist/core-CMn-Tj2X.js.map +1 -0
- package/dist/{zero/extractor.js → css-writer-C8ShXK5R.js} +148 -24
- package/dist/css-writer-C8ShXK5R.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-BkstDvlN.js} +59 -2
- package/dist/format-rules-BkstDvlN.js.map +1 -0
- package/dist/{ssr/hydrate.js → hydrate-DXXWZgm0.js} +4 -12
- package/dist/hydrate-DXXWZgm0.js.map +1 -0
- package/dist/index-BcsaHo8x.d.ts +1568 -0
- package/dist/index-CC0wykKn.d.ts +1909 -0
- package/dist/index.d.ts +5 -51
- package/dist/index.js +922 -36
- package/dist/index.js.map +1 -0
- package/dist/keyframes-Z0YLVOWq.js +493 -0
- package/dist/keyframes-Z0YLVOWq.js.map +1 -0
- package/dist/{utils/merge-styles.d.ts → merge-styles-BTFAkYSD.d.ts} +3 -3
- package/dist/{utils/merge-styles.js → merge-styles-Dpueyn82.js} +3 -4
- package/dist/merge-styles-Dpueyn82.js.map +1 -0
- package/dist/{utils/resolve-recipes.js → resolve-recipes-B2Vjr7ET.js} +4 -6
- package/dist/resolve-recipes-B2Vjr7ET.js.map +1 -0
- package/dist/ssr/astro-client.js +1 -1
- package/dist/ssr/astro-client.js.map +1 -1
- package/dist/ssr/astro-middleware-static.d.ts +16 -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 +8 -6
- package/dist/ssr/astro-middleware.js +10 -10
- package/dist/ssr/astro-middleware.js.map +1 -1
- package/dist/ssr/astro.d.ts +2 -17
- package/dist/ssr/astro.js +29 -21
- package/dist/ssr/astro.js.map +1 -1
- package/dist/ssr/index.d.ts +37 -4
- package/dist/ssr/index.js +5 -5
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next.d.ts +2 -3
- package/dist/ssr/next.js +7 -8
- package/dist/ssr/next.js.map +1 -1
- 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 -81
- package/dist/zero/babel.js +45 -29
- 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 +18 -10
- package/docs/adoption.md +56 -31
- package/docs/ai-agents.md +224 -0
- package/docs/comparison.md +69 -40
- package/docs/configuration.md +501 -72
- package/docs/debug.md +22 -18
- package/docs/design-system.md +43 -24
- package/docs/dsl.md +512 -179
- package/docs/getting-started.md +60 -39
- package/docs/injector.md +110 -32
- package/docs/methodology.md +68 -36
- package/docs/migration-v3.md +285 -0
- package/docs/pipeline.md +741 -0
- package/docs/plugins.md +353 -0
- package/docs/react-api.md +164 -40
- package/docs/runtime-benchmarks.md +216 -0
- package/docs/ssr.md +92 -81
- package/docs/styles.md +65 -16
- package/docs/tasty-static.md +149 -99
- package/package.json +49 -21
- package/tasty.config.ts +6 -0
- package/dist/_virtual/_rolldown/runtime.js +0 -7
- package/dist/chunks/cacheKey.d.ts +0 -1
- 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 -335
- package/dist/compute-styles.js.map +0 -1
- package/dist/config.d.ts +0 -407
- package/dist/config.js +0 -587
- 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 -36
- package/dist/hooks/useCounterStyle.js +0 -65
- package/dist/hooks/useCounterStyle.js.map +0 -1
- package/dist/hooks/useFontFace.d.ts +0 -45
- package/dist/hooks/useFontFace.js +0 -66
- package/dist/hooks/useFontFace.js.map +0 -1
- package/dist/hooks/useGlobalStyles.d.ts +0 -46
- package/dist/hooks/useGlobalStyles.js +0 -88
- package/dist/hooks/useGlobalStyles.js.map +0 -1
- package/dist/hooks/useKeyframes.d.ts +0 -58
- package/dist/hooks/useKeyframes.js +0 -55
- package/dist/hooks/useKeyframes.js.map +0 -1
- package/dist/hooks/useProperty.d.ts +0 -81
- package/dist/hooks/useProperty.js +0 -96
- package/dist/hooks/useProperty.js.map +0 -1
- package/dist/hooks/useRawCSS.d.ts +0 -22
- package/dist/hooks/useRawCSS.js +0 -103
- package/dist/hooks/useRawCSS.js.map +0 -1
- package/dist/hooks/useStyles.d.ts +0 -40
- package/dist/hooks/useStyles.js +0 -31
- package/dist/hooks/useStyles.js.map +0 -1
- package/dist/injector/index.d.ts +0 -182
- package/dist/injector/index.js +0 -185
- package/dist/injector/index.js.map +0 -1
- package/dist/injector/injector.d.ts +0 -198
- package/dist/injector/injector.js +0 -651
- package/dist/injector/injector.js.map +0 -1
- package/dist/injector/sheet-manager.d.ts +0 -132
- package/dist/injector/sheet-manager.js +0 -699
- package/dist/injector/sheet-manager.js.map +0 -1
- package/dist/injector/types.d.ts +0 -235
- 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 -87
- 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/rsc-cache.js +0 -79
- package/dist/rsc-cache.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 -58
- package/dist/ssr/collect-auto-properties.js.map +0 -1
- package/dist/ssr/collector.js.map +0 -1
- package/dist/ssr/context.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 -29
- package/dist/ssr/hydrate.js.map +0 -1
- package/dist/ssr/ssr-collector-ref.js +0 -29
- 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 -248
- 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/deps-equal.js +0 -15
- package/dist/utils/deps-equal.js.map +0 -1
- 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/hash.js +0 -14
- package/dist/utils/hash.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 -58
- 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
|
@@ -0,0 +1,1298 @@
|
|
|
1
|
+
import { At as StyleRule, Ct as PropertyDefinition, Dt as RuleInfo, Et as RootRegistry, Ot as SheetInfo, P as StyleHandlerDefinition, St as KeyframesSteps, Tt as RawCSSResult, _t as InjectResult, b as Styles, bt as KeyframesInfo, dt as FunctionDefinition, gt as InjectOptions, h as ConfigTokens, ht as GlobalInjectResult, it as UnitHandler, kt as StyleInjectorConfig, lt as FontFaceDescriptors, mt as GCOptions, n as StyleResult, nt as StyleDetails, ot as CacheMetrics, pt as GCConfig, st as CounterStyleDescriptors, ut as FontFaceInput, v as RecipeStyles, xt as KeyframesResult } from "./index-BcsaHo8x.js";
|
|
2
|
+
|
|
3
|
+
//#region src/prop-handlers.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Props middleware for tasty components.
|
|
6
|
+
*
|
|
7
|
+
* A prop handler receives a component's props and returns them, changed or not.
|
|
8
|
+
* That makes it the extension point for props that are *not* style properties:
|
|
9
|
+
* it can read a custom prop, strip it so it never reaches the DOM, and fold its
|
|
10
|
+
* meaning into `styles`, `mods`, `tokens`, `variant`, or `as`.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* configure({
|
|
14
|
+
* propHandlers: {
|
|
15
|
+
* glaze: (props) => {
|
|
16
|
+
* const { glaze, ...rest } = props;
|
|
17
|
+
* if (!glaze) return rest;
|
|
18
|
+
* return { ...rest, styles: mergeStyles(glazeStyles(glaze), rest.styles) };
|
|
19
|
+
* },
|
|
20
|
+
* },
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Handlers run on every render of every tasty component, so the registry is a
|
|
25
|
+
* pre-composed chain that is `null` while nothing is registered — the cost when
|
|
26
|
+
* unused is one property load and one branch.
|
|
27
|
+
*/
|
|
28
|
+
/** Props object handed to a prop handler. Deliberately untyped: handlers see everything. */
|
|
29
|
+
type PropHandlerProps = Record<string, unknown>;
|
|
30
|
+
/**
|
|
31
|
+
* Props middleware: props in, props out. Returning nothing means "unchanged".
|
|
32
|
+
*
|
|
33
|
+
* Must be a **pure function** and must not mutate its input. Style values are
|
|
34
|
+
* cached by object identity, so mutating a value object in place produces a stale
|
|
35
|
+
* class name and stale CSS. Return fresh (ideally frozen, ideally memoized)
|
|
36
|
+
* objects instead.
|
|
37
|
+
*/
|
|
38
|
+
type PropHandler = (props: PropHandlerProps) => PropHandlerProps | void | null;
|
|
39
|
+
/**
|
|
40
|
+
* How a prop handler is declared. The map key is both its name and, by default,
|
|
41
|
+
* the prop that triggers it.
|
|
42
|
+
*
|
|
43
|
+
* - `fn` — triggered when a prop matching the key is present
|
|
44
|
+
* - `['glaze', fn]` — triggered by the named prop
|
|
45
|
+
* - `[['glaze', 'tone'], fn]` — triggered by any of them
|
|
46
|
+
* - `['*', fn]` — unconditional; runs on every render of every component
|
|
47
|
+
*/
|
|
48
|
+
type PropHandlerDefinition = PropHandler | [string, PropHandler] | [string[], PropHandler];
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/injector/sheet-manager.d.ts
|
|
51
|
+
declare class SheetManager {
|
|
52
|
+
private rootRegistries;
|
|
53
|
+
/** Strong set of active roots so background GC can iterate them all */
|
|
54
|
+
private activeRoots;
|
|
55
|
+
private config;
|
|
56
|
+
/** Dedicated style elements for raw CSS per root */
|
|
57
|
+
private rawStyleElements;
|
|
58
|
+
/** Constructable sheets for raw CSS in adopted mode */
|
|
59
|
+
private rawConstructableSheets;
|
|
60
|
+
/** Tracking for raw CSS blocks per root */
|
|
61
|
+
private rawCSSBlocks;
|
|
62
|
+
/** Counter for generating unique raw CSS IDs */
|
|
63
|
+
private rawCSSCounter;
|
|
64
|
+
constructor(config: StyleInjectorConfig);
|
|
65
|
+
/**
|
|
66
|
+
* Resolve the underlying CSSStyleSheet from a SheetInfo,
|
|
67
|
+
* abstracting away adopted vs style-element modes.
|
|
68
|
+
*/
|
|
69
|
+
getCSSSheet(sheetInfo: SheetInfo): CSSStyleSheet | null;
|
|
70
|
+
/**
|
|
71
|
+
* Record an inserted rule text at its rule index (text mode only).
|
|
72
|
+
*
|
|
73
|
+
* `textRules` mirrors the sheet's rule order. `textContent` cannot be edited
|
|
74
|
+
* rule-by-rule the way CSSOM can, so keeping the texts is what makes
|
|
75
|
+
* deletion possible at all in this mode.
|
|
76
|
+
*/
|
|
77
|
+
private trackTextRule;
|
|
78
|
+
/**
|
|
79
|
+
* Remove rule indices from a text-mode sheet and rewrite the element's text.
|
|
80
|
+
* Returns the indices that were actually removed.
|
|
81
|
+
*/
|
|
82
|
+
private deleteTextRules;
|
|
83
|
+
/**
|
|
84
|
+
* Determine the injection mode for a root.
|
|
85
|
+
* ShadowRoot uses adopted stylesheets when supported; Document uses <style> elements.
|
|
86
|
+
*/
|
|
87
|
+
private detectInjectionMode;
|
|
88
|
+
/**
|
|
89
|
+
* Get or create registry for a root (Document or ShadowRoot)
|
|
90
|
+
*/
|
|
91
|
+
getRegistry(root: Document | ShadowRoot): RootRegistry;
|
|
92
|
+
/** Return all roots with active registries (for background GC sweep). */
|
|
93
|
+
getActiveRoots(): Iterable<Document | ShadowRoot>;
|
|
94
|
+
/** Check whether any roots have active registries. */
|
|
95
|
+
hasActiveRoots(): boolean;
|
|
96
|
+
/** Remove registries for ShadowRoots whose host has been detached from the DOM. */
|
|
97
|
+
pruneDisconnectedRoots(): void;
|
|
98
|
+
/**
|
|
99
|
+
* Create a new stylesheet for the registry.
|
|
100
|
+
* In adopted mode (ShadowRoot), creates a constructable CSSStyleSheet and
|
|
101
|
+
* pushes it to adoptedStyleSheets. Otherwise creates a <style> element.
|
|
102
|
+
*/
|
|
103
|
+
createSheet(registry: RootRegistry, root: Document | ShadowRoot): SheetInfo;
|
|
104
|
+
/**
|
|
105
|
+
* Create a style element and append to document
|
|
106
|
+
*/
|
|
107
|
+
private createStyleElement;
|
|
108
|
+
/**
|
|
109
|
+
* Insert CSS rules as a single block
|
|
110
|
+
*/
|
|
111
|
+
insertRule(registry: RootRegistry, flattenedRules: StyleRule[], className: string, root: Document | ShadowRoot): RuleInfo | null;
|
|
112
|
+
/**
|
|
113
|
+
* Insert global CSS rules
|
|
114
|
+
*/
|
|
115
|
+
insertGlobalRule(registry: RootRegistry, flattenedRules: StyleRule[], globalKey: string, root: Document | ShadowRoot): RuleInfo | null;
|
|
116
|
+
/**
|
|
117
|
+
* Delete a global CSS rule by key
|
|
118
|
+
*/
|
|
119
|
+
deleteGlobalRule(registry: RootRegistry, globalKey: string): void;
|
|
120
|
+
/**
|
|
121
|
+
* Adjust rule indices after deletion to account for shifting
|
|
122
|
+
*/
|
|
123
|
+
private adjustIndicesAfterDeletion;
|
|
124
|
+
/**
|
|
125
|
+
* Delete a CSS rule from the sheet
|
|
126
|
+
*/
|
|
127
|
+
deleteRule(registry: RootRegistry, ruleInfo: RuleInfo): void;
|
|
128
|
+
/**
|
|
129
|
+
* Find a sheet with available space or return null
|
|
130
|
+
*/
|
|
131
|
+
private findAvailableSheet;
|
|
132
|
+
/**
|
|
133
|
+
* Find an available rule index in the sheet
|
|
134
|
+
*/
|
|
135
|
+
findAvailableRuleIndex(sheet: SheetInfo): number;
|
|
136
|
+
/**
|
|
137
|
+
* Probe whether the underlying CSS engine supports `@property` at-rules.
|
|
138
|
+
* Result is cached per registry on `registry.atPropertySupported`.
|
|
139
|
+
*
|
|
140
|
+
* The probe inserts and immediately deletes a minimal known-valid rule
|
|
141
|
+
* (`@property --__tasty_probe__ { syntax: "*"; inherits: true; }`).
|
|
142
|
+
* Engines that lack `@property` support (jsdom, happy-dom) reject any
|
|
143
|
+
* `@property` rule including this one, so a probe failure is a reliable
|
|
144
|
+
* signal that further `@property` rejections are environmental noise and
|
|
145
|
+
* not user-authored bugs.
|
|
146
|
+
*
|
|
147
|
+
* The probe is intentionally a separate operation from the user's failing
|
|
148
|
+
* insertion: we don't want to leak `--__tasty_probe__` into the sheet, so
|
|
149
|
+
* on success we delete the probe rule immediately, leaving `ruleCount`
|
|
150
|
+
* and `cssRules.length` unchanged.
|
|
151
|
+
*/
|
|
152
|
+
private engineSupportsAtProperty;
|
|
153
|
+
/**
|
|
154
|
+
* Delete the given classes: their rules leave the sheets and every registry
|
|
155
|
+
* entry pointing at them is dropped.
|
|
156
|
+
*
|
|
157
|
+
* Deciding *what* is unused belongs to `StyleInjector.gc()`, which owns the
|
|
158
|
+
* DOM scan and the capacity policy. This only re-checks that each class is
|
|
159
|
+
* still safe to delete, and reports how many were.
|
|
160
|
+
*
|
|
161
|
+
* @returns Number of classes actually deleted.
|
|
162
|
+
*/
|
|
163
|
+
deleteClasses(registry: RootRegistry, classNames: Iterable<string>): number;
|
|
164
|
+
/**
|
|
165
|
+
* Get total number of rules across all sheets
|
|
166
|
+
*/
|
|
167
|
+
getTotalRuleCount(registry: RootRegistry): number;
|
|
168
|
+
/**
|
|
169
|
+
* Get CSS text from all sheets (for SSR)
|
|
170
|
+
*/
|
|
171
|
+
getCSSText(registry: RootRegistry): string;
|
|
172
|
+
/**
|
|
173
|
+
* Get cache performance metrics
|
|
174
|
+
*/
|
|
175
|
+
getMetrics(registry: RootRegistry): CacheMetrics | null;
|
|
176
|
+
/**
|
|
177
|
+
* Reset cache performance metrics
|
|
178
|
+
*/
|
|
179
|
+
resetMetrics(registry: RootRegistry): void;
|
|
180
|
+
/**
|
|
181
|
+
* Convert keyframes steps to CSS string.
|
|
182
|
+
* Public so the SSR collector can format keyframes without DOM access.
|
|
183
|
+
* Returns both the CSS text and a combined declarations string for property type scanning.
|
|
184
|
+
*/
|
|
185
|
+
stepsToCSS(steps: KeyframesSteps): {
|
|
186
|
+
css: string;
|
|
187
|
+
declarations: string;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Insert keyframes rule.
|
|
191
|
+
* Returns the KeyframesInfo and the raw declarations string for property type scanning.
|
|
192
|
+
*/
|
|
193
|
+
insertKeyframes(registry: RootRegistry, steps: KeyframesSteps, name: string, root: Document | ShadowRoot): {
|
|
194
|
+
info: KeyframesInfo;
|
|
195
|
+
declarations: string;
|
|
196
|
+
} | null;
|
|
197
|
+
/**
|
|
198
|
+
* Delete keyframes rule
|
|
199
|
+
*/
|
|
200
|
+
deleteKeyframes(registry: RootRegistry, info: KeyframesInfo): void;
|
|
201
|
+
/**
|
|
202
|
+
* Clean up resources for a root
|
|
203
|
+
*/
|
|
204
|
+
cleanup(root: Document | ShadowRoot): void;
|
|
205
|
+
/**
|
|
206
|
+
* Check if a root uses adopted injection mode.
|
|
207
|
+
*/
|
|
208
|
+
private isAdoptedMode;
|
|
209
|
+
/**
|
|
210
|
+
* Get or create a constructable CSSStyleSheet for raw CSS in adopted mode.
|
|
211
|
+
* The raw sheet is prepended to adoptedStyleSheets so it precedes tasty rules.
|
|
212
|
+
*/
|
|
213
|
+
private getOrCreateRawAdoptedSheet;
|
|
214
|
+
/**
|
|
215
|
+
* Get or create a dedicated style element for raw CSS
|
|
216
|
+
* Raw CSS is kept separate from tasty-managed sheets to avoid index conflicts
|
|
217
|
+
*/
|
|
218
|
+
private getOrCreateRawStyleElement;
|
|
219
|
+
/**
|
|
220
|
+
* Inject raw CSS text directly without parsing
|
|
221
|
+
* Returns a dispose function to remove the injected CSS
|
|
222
|
+
*/
|
|
223
|
+
injectRawCSS(css: string, root: Document | ShadowRoot): RawCSSResult;
|
|
224
|
+
/**
|
|
225
|
+
* Rebuild the raw CSS constructable sheet from all tracked blocks.
|
|
226
|
+
*/
|
|
227
|
+
private rebuildRawAdoptedSheet;
|
|
228
|
+
/**
|
|
229
|
+
* Remove a raw CSS block by ID
|
|
230
|
+
*/
|
|
231
|
+
private disposeRawCSS;
|
|
232
|
+
/**
|
|
233
|
+
* Get the raw CSS content
|
|
234
|
+
*/
|
|
235
|
+
getRawCSSText(root: Document | ShadowRoot): string;
|
|
236
|
+
}
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/injector/injector.d.ts
|
|
239
|
+
declare class StyleInjector {
|
|
240
|
+
private sheetManager;
|
|
241
|
+
private config;
|
|
242
|
+
private globalRuleCounter;
|
|
243
|
+
/** Cancels the scheduled sweep, whichever timer scheduled it. */
|
|
244
|
+
private cancelPendingGC;
|
|
245
|
+
private namePrefix;
|
|
246
|
+
private classRegex;
|
|
247
|
+
private rscClassRegex;
|
|
248
|
+
/** @internal — exposed for debug utilities only */
|
|
249
|
+
get _sheetManager(): SheetManager;
|
|
250
|
+
/**
|
|
251
|
+
* Whether sheet writes should be queued instead of applied immediately.
|
|
252
|
+
*
|
|
253
|
+
* Only ever true on the client: SSR collects CSS as text and the RSC path
|
|
254
|
+
* returns it as strings, so neither has a live sheet to batch writes against.
|
|
255
|
+
*
|
|
256
|
+
* In the default `true` mode a write is only queued inside an open batch
|
|
257
|
+
* window — a commit in which `<TastyBatchProvider>` rendered and will
|
|
258
|
+
* therefore flush in its insertion effect, before any layout effect can
|
|
259
|
+
* measure. Everything else falls through to a synchronous write, so enabling
|
|
260
|
+
* the flag cannot make a `useLayoutEffect` read an unstyled element.
|
|
261
|
+
* `'always'` drops the gate and accepts that trade for wider coverage.
|
|
262
|
+
*/
|
|
263
|
+
private get batching();
|
|
264
|
+
/**
|
|
265
|
+
* Apply a sheet write now, or queue it when batching is on.
|
|
266
|
+
* Returns the queue handle when deferred, so the caller can cancel it if it
|
|
267
|
+
* disposes before the flush.
|
|
268
|
+
*/
|
|
269
|
+
private writeSheet;
|
|
270
|
+
/**
|
|
271
|
+
* Insert a global (non-class) rule, honouring batching.
|
|
272
|
+
*
|
|
273
|
+
* `onApplied` records the caller's dedupe bookkeeping. When the write is
|
|
274
|
+
* queued it runs eagerly, so a repeat call before the flush bails out instead
|
|
275
|
+
* of queueing the same rule twice — the same reasoning as
|
|
276
|
+
* `insertPropertyRule`'s eager marking. When written synchronously it runs
|
|
277
|
+
* only on success, preserving the existing retry-on-failure behaviour.
|
|
278
|
+
*/
|
|
279
|
+
private writeGlobalRule;
|
|
280
|
+
constructor(config?: StyleInjectorConfig);
|
|
281
|
+
/**
|
|
282
|
+
* Generate a deterministic class name from a cache key using content hash.
|
|
283
|
+
* The same cache key always produces the same class name across environments
|
|
284
|
+
* with the same `namePrefix`.
|
|
285
|
+
*/
|
|
286
|
+
private generateClassName;
|
|
287
|
+
/**
|
|
288
|
+
* Check if `className` was hydrated from server-rendered styles and,
|
|
289
|
+
* if so, wire the cacheKey mapping. Returns true on hit.
|
|
290
|
+
*/
|
|
291
|
+
private tryHydratedHit;
|
|
292
|
+
/**
|
|
293
|
+
* Allocate a className for a cacheKey without injecting styles yet.
|
|
294
|
+
* This allows separating className allocation (render phase) from style injection (insertion phase).
|
|
295
|
+
*/
|
|
296
|
+
allocateClassName(cacheKey: string, options?: {
|
|
297
|
+
root?: Document | ShadowRoot;
|
|
298
|
+
}): {
|
|
299
|
+
className: string;
|
|
300
|
+
isNewAllocation: boolean;
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Inject styles from StyleResult objects
|
|
304
|
+
*/
|
|
305
|
+
inject(rules: StyleResult[], options?: InjectOptions): InjectResult;
|
|
306
|
+
/**
|
|
307
|
+
* Inject global styles (rules without a generated tasty class selector)
|
|
308
|
+
* This ensures we don't reserve a tasty class name (t{number}) for global rules,
|
|
309
|
+
* which could otherwise collide with element-level styles and break lookups.
|
|
310
|
+
*/
|
|
311
|
+
injectGlobal(rules: StyleResult[], options?: {
|
|
312
|
+
root?: Document | ShadowRoot;
|
|
313
|
+
}): GlobalInjectResult;
|
|
314
|
+
/**
|
|
315
|
+
* Inject raw CSS text directly without parsing
|
|
316
|
+
* This is a low-overhead alternative to createGlobalStyle for raw CSS
|
|
317
|
+
* The CSS is inserted into a separate style element to avoid conflicts with tasty's chunking
|
|
318
|
+
*/
|
|
319
|
+
injectRawCSS(css: string, options?: {
|
|
320
|
+
root?: Document | ShadowRoot;
|
|
321
|
+
}): RawCSSResult;
|
|
322
|
+
/**
|
|
323
|
+
* Get raw CSS text for SSR
|
|
324
|
+
*/
|
|
325
|
+
getRawCSSText(options?: {
|
|
326
|
+
root?: Document | ShadowRoot;
|
|
327
|
+
}): string;
|
|
328
|
+
/**
|
|
329
|
+
* Pin an already-injected cacheKey and return the handle that releases it.
|
|
330
|
+
* For callers that skipped the pipeline on a cache hit but still need the
|
|
331
|
+
* class held. Returns null if the cacheKey is not found.
|
|
332
|
+
*/
|
|
333
|
+
trackRef(cacheKey: string, options?: {
|
|
334
|
+
root?: Document | ShadowRoot;
|
|
335
|
+
}): InjectResult | null;
|
|
336
|
+
/**
|
|
337
|
+
* Seed the LRU stamp for a newly injected class, so it sorts as the newest
|
|
338
|
+
* rather than the oldest eviction candidate.
|
|
339
|
+
*/
|
|
340
|
+
private markUsage;
|
|
341
|
+
/**
|
|
342
|
+
* Release one pin on a className. At zero pins the class is not deleted — it
|
|
343
|
+
* stays cached and collectible, and `gc()` decides when it actually goes.
|
|
344
|
+
*/
|
|
345
|
+
private unpin;
|
|
346
|
+
/**
|
|
347
|
+
* Remove every style that is neither in the DOM nor referenced by an
|
|
348
|
+
* outstanding `inject()` handle, ignoring the GC capacity threshold.
|
|
349
|
+
*/
|
|
350
|
+
cleanup(root?: Document | ShadowRoot): void;
|
|
351
|
+
/**
|
|
352
|
+
* Get CSS text from all sheets (for SSR)
|
|
353
|
+
*/
|
|
354
|
+
getCSSText(options?: {
|
|
355
|
+
root?: Document | ShadowRoot;
|
|
356
|
+
}): string;
|
|
357
|
+
/**
|
|
358
|
+
* Get CSS only for the provided tasty classNames (e.g., ["t0","t3"])
|
|
359
|
+
*/
|
|
360
|
+
getCSSTextForClasses(classNames: Iterable<string>, options?: {
|
|
361
|
+
root?: Document | ShadowRoot;
|
|
362
|
+
}): string;
|
|
363
|
+
/**
|
|
364
|
+
* Get cache performance metrics
|
|
365
|
+
*/
|
|
366
|
+
getMetrics(options?: {
|
|
367
|
+
root?: Document | ShadowRoot;
|
|
368
|
+
}): CacheMetrics | null;
|
|
369
|
+
/**
|
|
370
|
+
* Reset cache performance metrics
|
|
371
|
+
*/
|
|
372
|
+
resetMetrics(options?: {
|
|
373
|
+
root?: Document | ShadowRoot;
|
|
374
|
+
}): void;
|
|
375
|
+
/**
|
|
376
|
+
* Define a CSS @property custom property.
|
|
377
|
+
*
|
|
378
|
+
* Accepts tasty token syntax for the property name:
|
|
379
|
+
* - `$name` → defines `--name`
|
|
380
|
+
* - `#name` → defines `--name-color` (auto-sets syntax: '<color>', defaults initialValue: 'transparent')
|
|
381
|
+
* - `--name` → defines `--name` (legacy format)
|
|
382
|
+
*
|
|
383
|
+
* Example:
|
|
384
|
+
* @property --rotation { syntax: "<angle>"; inherits: false; initial-value: 45deg; }
|
|
385
|
+
*
|
|
386
|
+
* Note: No caching or dispose — this defines a global property.
|
|
387
|
+
*
|
|
388
|
+
* If the same property is registered with different options, a warning is emitted
|
|
389
|
+
* but the original definition is preserved (CSS @property cannot be redefined).
|
|
390
|
+
*/
|
|
391
|
+
property(name: string, options?: PropertyDefinition & {
|
|
392
|
+
root?: Document | ShadowRoot;
|
|
393
|
+
}): void;
|
|
394
|
+
/**
|
|
395
|
+
* Build and insert a single `@property` rule into the given registry.
|
|
396
|
+
* No-op if the property was already injected.
|
|
397
|
+
*/
|
|
398
|
+
private insertPropertyRule;
|
|
399
|
+
/**
|
|
400
|
+
* Check whether a given @property name was already injected by this injector.
|
|
401
|
+
*
|
|
402
|
+
* Accepts tasty token syntax:
|
|
403
|
+
* - `$name` → checks `--name`
|
|
404
|
+
* - `#name` → checks `--name-color`
|
|
405
|
+
* - `--name` → checks `--name` (legacy format)
|
|
406
|
+
*/
|
|
407
|
+
isPropertyDefined(name: string, options?: {
|
|
408
|
+
root?: Document | ShadowRoot;
|
|
409
|
+
}): boolean;
|
|
410
|
+
/**
|
|
411
|
+
* Inject a CSS @font-face rule.
|
|
412
|
+
*
|
|
413
|
+
* Permanent and global — no dispose or ref-counting.
|
|
414
|
+
* Deduplicates by content hash (family + descriptors).
|
|
415
|
+
*/
|
|
416
|
+
fontFace(family: string, descriptors: FontFaceDescriptors, options?: {
|
|
417
|
+
root?: Document | ShadowRoot;
|
|
418
|
+
}): void;
|
|
419
|
+
/**
|
|
420
|
+
* Inject a CSS @counter-style rule.
|
|
421
|
+
*
|
|
422
|
+
* Permanent and global — no dispose or ref-counting. Deduplicates by name.
|
|
423
|
+
* By default a definition overrides a previously injected one of the same
|
|
424
|
+
* name. Pass `weak: true` for global `configure()` definitions, which must
|
|
425
|
+
* never clobber an existing rule (so component-local definitions win
|
|
426
|
+
* regardless of injection order).
|
|
427
|
+
*/
|
|
428
|
+
counterStyle(name: string, descriptors: CounterStyleDescriptors, options?: {
|
|
429
|
+
root?: Document | ShadowRoot;
|
|
430
|
+
weak?: boolean;
|
|
431
|
+
}): void;
|
|
432
|
+
/**
|
|
433
|
+
* Inject a CSS @function rule (custom function).
|
|
434
|
+
*
|
|
435
|
+
* Permanent and global — no dispose or ref-counting. Deduplicates by function
|
|
436
|
+
* name. By default a definition overrides a previously injected one of the
|
|
437
|
+
* same name. Pass `weak: true` for global `configure()` definitions, which
|
|
438
|
+
* must never clobber an existing rule (so component-local definitions win
|
|
439
|
+
* regardless of injection order).
|
|
440
|
+
*/
|
|
441
|
+
func(name: string, definition: FunctionDefinition, options?: {
|
|
442
|
+
root?: Document | ShadowRoot;
|
|
443
|
+
weak?: boolean;
|
|
444
|
+
}): void;
|
|
445
|
+
/**
|
|
446
|
+
* Inject keyframes and return object with toString() and dispose()
|
|
447
|
+
*
|
|
448
|
+
* Keyframes are cached by content (steps). If the same content is injected
|
|
449
|
+
* multiple times with different provided names, the first injected name is reused.
|
|
450
|
+
*
|
|
451
|
+
* If the same name is provided with different content (collision), a unique
|
|
452
|
+
* name is generated to avoid overwriting the existing keyframes.
|
|
453
|
+
*/
|
|
454
|
+
keyframes(steps: KeyframesSteps, nameOrOptions?: string | {
|
|
455
|
+
root?: Document | ShadowRoot;
|
|
456
|
+
name?: string;
|
|
457
|
+
}): KeyframesResult;
|
|
458
|
+
/**
|
|
459
|
+
* Dispose keyframes
|
|
460
|
+
*/
|
|
461
|
+
private disposeKeyframes;
|
|
462
|
+
/**
|
|
463
|
+
* Record a render-time usage hit for one or more classNames.
|
|
464
|
+
* Handles space-separated multi-chunk classNames.
|
|
465
|
+
* When the global touch counter reaches `touchInterval`, schedules a GC
|
|
466
|
+
* via `requestIdleCallback`.
|
|
467
|
+
* No-op on the server.
|
|
468
|
+
*/
|
|
469
|
+
touch(className: string, options?: {
|
|
470
|
+
root?: Document | ShadowRoot;
|
|
471
|
+
}): void;
|
|
472
|
+
/**
|
|
473
|
+
* Schedule a GC in idle time. Runs GC on all active roots, and avoids
|
|
474
|
+
* double-scheduling.
|
|
475
|
+
*
|
|
476
|
+
* Requires `gc.unsafeAutoCollect`. A sweep judges a class finished by not
|
|
477
|
+
* finding it in the DOM, which a render that has injected but not yet
|
|
478
|
+
* committed cannot be told apart from — so sweeping on a schedule nobody
|
|
479
|
+
* asked for can delete rules an in-flight render is about to attach.
|
|
480
|
+
*
|
|
481
|
+
* Without `requestIdleCallback` there is no automatic collection either
|
|
482
|
+
* unless `gc.timeoutFallback` opts into a timeout: running the sweep inline
|
|
483
|
+
* here would put it inside the render that touched the class.
|
|
484
|
+
*/
|
|
485
|
+
private scheduleGC;
|
|
486
|
+
/**
|
|
487
|
+
* The one definition of "unused": this injector owns the class's rules, no
|
|
488
|
+
* element in `root` carries it, and nobody pinned it.
|
|
489
|
+
*
|
|
490
|
+
* `gc()` evicts from this set, `getMetrics()` counts it, and `tastyDebug`
|
|
491
|
+
* reports it — all through here, so the three can never disagree about what
|
|
492
|
+
* "unused" means. Entries carry their last `touch()` so callers can drop the
|
|
493
|
+
* oldest first; a class that was never touched sorts as oldest.
|
|
494
|
+
*/
|
|
495
|
+
private collectUnused;
|
|
496
|
+
/**
|
|
497
|
+
* Class names this injector holds CSS for that nothing renders and nobody
|
|
498
|
+
* pinned — exactly what `gc({ force: true })` would delete. Unordered.
|
|
499
|
+
*/
|
|
500
|
+
getUnusedClasses(options?: {
|
|
501
|
+
root?: Document | ShadowRoot;
|
|
502
|
+
}): string[];
|
|
503
|
+
/**
|
|
504
|
+
* Synchronous garbage collection.
|
|
505
|
+
*
|
|
506
|
+
* 1. Quick upper-bound check: skip if the registry is smaller than capacity.
|
|
507
|
+
* 2. Scans the DOM for live tasty classNames — the DOM, not a ref count, is
|
|
508
|
+
* what says a class rendered by a component is still in use.
|
|
509
|
+
* 3. With `force: true`: deletes every unused class.
|
|
510
|
+
* Without `force`: keeps the `capacity` most recently touched and deletes
|
|
511
|
+
* the rest, oldest first.
|
|
512
|
+
*
|
|
513
|
+
* @returns Number of styles evicted.
|
|
514
|
+
*/
|
|
515
|
+
gc(options?: GCOptions): number;
|
|
516
|
+
/**
|
|
517
|
+
* Destroy all resources for a root
|
|
518
|
+
*/
|
|
519
|
+
destroy(root?: Document | ShadowRoot): void;
|
|
520
|
+
}
|
|
521
|
+
//#endregion
|
|
522
|
+
//#region src/functions/index.d.ts
|
|
523
|
+
/**
|
|
524
|
+
* A parse-time function: receives the parsed (comma-separated) argument groups
|
|
525
|
+
* and returns a CSS value string. This is the JS flavor of the unified
|
|
526
|
+
* `functions` config (bare-name keys), distinct from declarative `@function`
|
|
527
|
+
* definitions (`$$`-prefixed keys).
|
|
528
|
+
*/
|
|
529
|
+
type ParseFunction = (groups: StyleDetails[]) => string;
|
|
530
|
+
/**
|
|
531
|
+
* The unified `functions` map: keys are either bare names (parse functions,
|
|
532
|
+
* value is a function) or `$$name`/`$name`/`--name` (declarative CSS functions,
|
|
533
|
+
* value is a {@link FunctionDefinition} object).
|
|
534
|
+
*/
|
|
535
|
+
type FunctionsConfig = Record<string, FunctionDefinition | ParseFunction>;
|
|
536
|
+
//#endregion
|
|
537
|
+
//#region src/utils/color-space.d.ts
|
|
538
|
+
/**
|
|
539
|
+
* Color handling that survives into the emitted CSS.
|
|
540
|
+
*
|
|
541
|
+
* Tasty does not rewrite a color into a particular color space: opacity is
|
|
542
|
+
* applied with CSS relative color syntax, which reads the channels off whatever
|
|
543
|
+
* the browser resolves a value to, so a color is emitted exactly as authored.
|
|
544
|
+
* What is left here is how an alpha gets applied, and the one distinction that
|
|
545
|
+
* matters — replacing a token's alpha versus composing onto an inherited one.
|
|
546
|
+
*/
|
|
547
|
+
/**
|
|
548
|
+
* The color space a `#name` token's value used to be rewritten into.
|
|
549
|
+
*
|
|
550
|
+
* @deprecated Kept for the `colorSpace` config option, which no longer has any
|
|
551
|
+
* effect. Colors are emitted as authored and opacity is always applied in
|
|
552
|
+
* `oklch` through relative color syntax.
|
|
553
|
+
*/
|
|
554
|
+
type ColorSpace = 'rgb' | 'hsl' | 'oklch';
|
|
555
|
+
//#endregion
|
|
556
|
+
//#region src/utils/typography.d.ts
|
|
557
|
+
/**
|
|
558
|
+
* A typography token value: plain value or a state map for responsive/theme-aware presets.
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* // Plain value
|
|
562
|
+
* fontWeight: '400'
|
|
563
|
+
* // State map
|
|
564
|
+
* fontWeight: { '': '400', '@dark': '300' }
|
|
565
|
+
*/
|
|
566
|
+
type TypographyTokenValue = string | number | Record<string, string | number | undefined | null | '@inherit'>;
|
|
567
|
+
/**
|
|
568
|
+
* Typography preset configuration.
|
|
569
|
+
* Each preset defines font properties that get expanded into CSS custom properties.
|
|
570
|
+
* All fields accept plain values or state maps for responsive/theme-aware tokens.
|
|
571
|
+
*
|
|
572
|
+
* Use with `generateTypographyTokens()` to create typography tokens for your design system.
|
|
573
|
+
*/
|
|
574
|
+
interface TypographyPreset {
|
|
575
|
+
fontSize: TypographyTokenValue;
|
|
576
|
+
lineHeight: TypographyTokenValue;
|
|
577
|
+
letterSpacing?: TypographyTokenValue;
|
|
578
|
+
fontWeight: TypographyTokenValue;
|
|
579
|
+
boldFontWeight?: TypographyTokenValue;
|
|
580
|
+
iconSize?: TypographyTokenValue;
|
|
581
|
+
textTransform?: TypographyTokenValue;
|
|
582
|
+
fontFamily?: TypographyTokenValue;
|
|
583
|
+
fontStyle?: TypographyTokenValue;
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Generate typography tokens with $ prefix for CSS custom properties.
|
|
587
|
+
*
|
|
588
|
+
* Each preset generates the following CSS custom properties:
|
|
589
|
+
* - `${name}-font-size`
|
|
590
|
+
* - `${name}-line-height`
|
|
591
|
+
* - `${name}-letter-spacing`
|
|
592
|
+
* - `${name}-font-weight`
|
|
593
|
+
* - `${name}-bold-font-weight` (if defined)
|
|
594
|
+
* - `${name}-icon-size` (if defined)
|
|
595
|
+
* - `${name}-text-transform` (if defined)
|
|
596
|
+
* - `${name}-font-family` (if defined)
|
|
597
|
+
* - `${name}-font-style` (if defined)
|
|
598
|
+
*
|
|
599
|
+
* @param presets - Typography presets object
|
|
600
|
+
* @returns ConfigTokens object with $ prefixed keys
|
|
601
|
+
*
|
|
602
|
+
* @example
|
|
603
|
+
* const customTokens = generateTypographyTokens({
|
|
604
|
+
* myHeading: { fontSize: '24px', lineHeight: '32px', fontWeight: '700' },
|
|
605
|
+
* body: { fontSize: '16px', lineHeight: '24px', fontWeight: '400' },
|
|
606
|
+
* });
|
|
607
|
+
*/
|
|
608
|
+
declare function generateTypographyTokens(presets: Record<string, TypographyPreset>): ConfigTokens;
|
|
609
|
+
//#endregion
|
|
610
|
+
//#region src/plugins/types.d.ts
|
|
611
|
+
/**
|
|
612
|
+
* A tasty plugin that extends the style system with custom functions, units, states, or handlers.
|
|
613
|
+
*/
|
|
614
|
+
interface TastyPlugin {
|
|
615
|
+
/** Unique name for the plugin (used for debugging and conflict detection) */
|
|
616
|
+
name: string;
|
|
617
|
+
/**
|
|
618
|
+
* Custom functions (unified map). Bare keys map to parse functions
|
|
619
|
+
* `(groups) => string`; `$$name` keys map to declarative CSS `@function`
|
|
620
|
+
* definitions. See {@link FunctionsConfig}.
|
|
621
|
+
*/
|
|
622
|
+
functions?: FunctionsConfig;
|
|
623
|
+
/** Custom units that transform numeric values (e.g., `2x` → `calc(2 * var(--gap))`) */
|
|
624
|
+
units?: Record<string, string | UnitHandler>;
|
|
625
|
+
/** Custom state aliases (e.g., `'@mobile': '@media(w < 768px)'`) */
|
|
626
|
+
states?: Record<string, string>;
|
|
627
|
+
/**
|
|
628
|
+
* Custom style handlers that transform style properties into CSS declarations.
|
|
629
|
+
* Handlers replace built-in handlers for the same style name.
|
|
630
|
+
* @example
|
|
631
|
+
* ```ts
|
|
632
|
+
* handlers: {
|
|
633
|
+
* // Simple handler - lookup style inferred from key
|
|
634
|
+
* fill: ({ fill }) => fill ? { 'background-color': fill } : undefined,
|
|
635
|
+
* // Multi-property handler
|
|
636
|
+
* spacing: [['gap', 'padding'], ({ gap, padding }) => ({ ... })],
|
|
637
|
+
* }
|
|
638
|
+
* ```
|
|
639
|
+
*/
|
|
640
|
+
handlers?: Record<string, StyleHandlerDefinition>;
|
|
641
|
+
/**
|
|
642
|
+
* Props middleware for every tasty component — props in, props out. The
|
|
643
|
+
* extension point for props that are not style properties: read a custom prop,
|
|
644
|
+
* strip it so it never reaches the DOM, and fold its meaning into `styles`,
|
|
645
|
+
* `mods`, `tokens`, `variant`, or `as`.
|
|
646
|
+
*
|
|
647
|
+
* Must be pure and must not mutate its input.
|
|
648
|
+
* See {@link TastyConfig.propHandlers}.
|
|
649
|
+
* @example
|
|
650
|
+
* ```ts
|
|
651
|
+
* propHandlers: {
|
|
652
|
+
* glaze: (props) => {
|
|
653
|
+
* const { glaze, ...rest } = props;
|
|
654
|
+
* if (!glaze) return rest;
|
|
655
|
+
* return { ...rest, styles: mergeStyles(glazeStyles(glaze), rest.styles) };
|
|
656
|
+
* },
|
|
657
|
+
* }
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
propHandlers?: Record<string, PropHandlerDefinition>;
|
|
661
|
+
/**
|
|
662
|
+
* Style properties exposed as top-level props on every tasty component, in
|
|
663
|
+
* addition to the built-in base styles.
|
|
664
|
+
* See {@link TastyConfig.baseStyleProps}.
|
|
665
|
+
*/
|
|
666
|
+
baseStyleProps?: readonly string[];
|
|
667
|
+
/**
|
|
668
|
+
* Design tokens injected as CSS custom properties on `:root`.
|
|
669
|
+
* Values are parsed through the Tasty DSL. Supports state maps.
|
|
670
|
+
* - `$name` → `--name` CSS custom property
|
|
671
|
+
* - `#name` → `--name-color`
|
|
672
|
+
*/
|
|
673
|
+
tokens?: ConfigTokens;
|
|
674
|
+
/** Predefined tokens replaced during style parsing (`$name` or `#name`) */
|
|
675
|
+
replaceTokens?: Record<`$${string}` | `#${string}`, string | number>;
|
|
676
|
+
/**
|
|
677
|
+
* Predefined style recipes -- named style bundles that can be applied via `recipe` style property.
|
|
678
|
+
* Recipe values are flat tasty styles (no sub-element keys).
|
|
679
|
+
* @example
|
|
680
|
+
* ```ts
|
|
681
|
+
* recipes: {
|
|
682
|
+
* card: { padding: '4x', fill: '#surface', radius: '1r', border: true },
|
|
683
|
+
* elevated: { shadow: '2x 2x 4x #shadow' },
|
|
684
|
+
* }
|
|
685
|
+
* ```
|
|
686
|
+
*/
|
|
687
|
+
recipes?: Record<string, RecipeStyles>;
|
|
688
|
+
/**
|
|
689
|
+
* Typography presets — shorthand for `generateTypographyTokens()`.
|
|
690
|
+
* Generated tokens are merged under explicit `tokens` (tokens win on conflict).
|
|
691
|
+
*/
|
|
692
|
+
presets?: Record<string, TypographyPreset>;
|
|
693
|
+
/**
|
|
694
|
+
* Global Tasty styles keyed by CSS selector.
|
|
695
|
+
* Supports the full Tasty style syntax.
|
|
696
|
+
*/
|
|
697
|
+
globalStyles?: Record<string, Styles>;
|
|
698
|
+
/**
|
|
699
|
+
* Global CSS `@property` definitions. A plugin whose handler or prop handler
|
|
700
|
+
* emits a custom property usually wants one, so the property animates and
|
|
701
|
+
* inherits correctly instead of being treated as an untyped string.
|
|
702
|
+
* See {@link TastyConfig.properties}.
|
|
703
|
+
*/
|
|
704
|
+
properties?: Record<string, PropertyDefinition>;
|
|
705
|
+
/** Global keyframes, injected only when referenced. See {@link TastyConfig.keyframes}. */
|
|
706
|
+
keyframes?: Record<string, KeyframesSteps>;
|
|
707
|
+
/** Global `@font-face` definitions. See {@link TastyConfig.fontFaces}. */
|
|
708
|
+
fontFaces?: Record<string, FontFaceInput>;
|
|
709
|
+
/** Global `@counter-style` definitions. See {@link TastyConfig.counterStyles}. */
|
|
710
|
+
counterStyles?: Record<string, CounterStyleDescriptors>;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* A factory function that creates a TastyPlugin.
|
|
714
|
+
* Can optionally accept configuration options.
|
|
715
|
+
*
|
|
716
|
+
* @example
|
|
717
|
+
* ```ts
|
|
718
|
+
* // Plugin without options
|
|
719
|
+
* const okhslPlugin: TastyPluginFactory = () => ({
|
|
720
|
+
* name: 'okhsl',
|
|
721
|
+
* functions: { okhsl: okhslFunction },
|
|
722
|
+
* });
|
|
723
|
+
*
|
|
724
|
+
* // Plugin with options
|
|
725
|
+
* const debugPlugin: TastyPluginFactory<{ verbose: boolean }> = (options) => ({
|
|
726
|
+
* name: 'debug',
|
|
727
|
+
* functions: { debug: createDebugFunc(options.verbose) },
|
|
728
|
+
* });
|
|
729
|
+
* ```
|
|
730
|
+
*/
|
|
731
|
+
type TastyPluginFactory<TOptions = void> = TOptions extends void ? () => TastyPlugin : (options: TOptions) => TastyPlugin;
|
|
732
|
+
//#endregion
|
|
733
|
+
//#region src/config.d.ts
|
|
734
|
+
/**
|
|
735
|
+
* Configuration options for the Tasty style system
|
|
736
|
+
*/
|
|
737
|
+
interface TastyConfig {
|
|
738
|
+
/** CSP nonce for style elements */
|
|
739
|
+
nonce?: string;
|
|
740
|
+
/** Maximum rules per stylesheet (default: 8192) */
|
|
741
|
+
maxRulesPerSheet?: number;
|
|
742
|
+
/** Force text injection mode, auto-detected in test environments (default: auto) */
|
|
743
|
+
forceTextInjection?: boolean;
|
|
744
|
+
/** Enable development mode features: performance metrics and debug info (default: auto) */
|
|
745
|
+
devMode?: boolean;
|
|
746
|
+
/**
|
|
747
|
+
* Global predefined states for advanced state mapping.
|
|
748
|
+
* These are state aliases that can be used in any component.
|
|
749
|
+
* Example: { '@mobile': '@media(w < 920px)', '@dark': '@root(theme=dark)' }
|
|
750
|
+
*/
|
|
751
|
+
states?: Record<string, string>;
|
|
752
|
+
/**
|
|
753
|
+
* Parser LRU cache size (default: 1000).
|
|
754
|
+
* Larger values improve performance for apps with many unique style values.
|
|
755
|
+
*/
|
|
756
|
+
parserCacheSize?: number;
|
|
757
|
+
/**
|
|
758
|
+
* Custom units for the style parser (merged with built-in units).
|
|
759
|
+
* Units transform numeric values like `2x` → `calc(2 * var(--gap))`.
|
|
760
|
+
* @example { em: 'em', vw: 'vw', custom: (n) => `${n * 10}px` }
|
|
761
|
+
*/
|
|
762
|
+
units?: Record<string, string | UnitHandler>;
|
|
763
|
+
/**
|
|
764
|
+
* Custom functions (merged with existing). A single map holds both flavors,
|
|
765
|
+
* discriminated by value type:
|
|
766
|
+
*
|
|
767
|
+
* - **Bare key + function value** — a parse-time function that processes the
|
|
768
|
+
* parsed argument groups and returns a CSS value. Called as `name(...)`.
|
|
769
|
+
* - **`$$name` key + object value** — a declarative CSS `@function`
|
|
770
|
+
* definition. Called as `$$name(...)` (→ native `--name(...)`).
|
|
771
|
+
*
|
|
772
|
+
* A key whose prefix does not match its value type (object under a bare key,
|
|
773
|
+
* or function under a `$$` key) is ignored with a dev warning.
|
|
774
|
+
*
|
|
775
|
+
* @example
|
|
776
|
+
* ```ts
|
|
777
|
+
* configure({
|
|
778
|
+
* functions: {
|
|
779
|
+
* double: (groups) => `calc(2 * ${groups[0].output})`, // parse function
|
|
780
|
+
* $$negative: { args: ['$value'], result: '(-1 * $value)' }, // CSS function
|
|
781
|
+
* },
|
|
782
|
+
* });
|
|
783
|
+
* ```
|
|
784
|
+
*/
|
|
785
|
+
functions?: FunctionsConfig;
|
|
786
|
+
/**
|
|
787
|
+
* @deprecated No longer has any effect; will be removed in the next major.
|
|
788
|
+
* Setting it warns in development.
|
|
789
|
+
*
|
|
790
|
+
* A `#name` token's value used to be rewritten into this color space so an
|
|
791
|
+
* opacity suffix had numeric channels to write an alpha into. Opacity now uses
|
|
792
|
+
* relative color syntax — `oklch(from var(--name-color) l c h / .5)` — which
|
|
793
|
+
* has the browser read the channels, so a color is emitted exactly as
|
|
794
|
+
* authored and there is nothing left for the setting to decide.
|
|
795
|
+
*
|
|
796
|
+
* To address a token's channels yourself, write relative color syntax against
|
|
797
|
+
* the token: `oklch(from var(--brand-color) calc(l * 1.2) c h)`. It works on
|
|
798
|
+
* every `<color>`, including the ones no conversion could evaluate.
|
|
799
|
+
*/
|
|
800
|
+
colorSpace?: ColorSpace;
|
|
801
|
+
/**
|
|
802
|
+
* Automatically infer and register CSS @property declarations
|
|
803
|
+
* from custom property values found in styles, keyframes, and global config.
|
|
804
|
+
* Covers all types: \<color\>, \<number\>, \<length\>, \<angle\>, \<percentage\>, \<time\>.
|
|
805
|
+
* When false, only explicitly declared @property are registered.
|
|
806
|
+
* @default true
|
|
807
|
+
*/
|
|
808
|
+
autoPropertyTypes?: boolean;
|
|
809
|
+
/**
|
|
810
|
+
* Defer stylesheet writes and apply them in one batch instead of performing
|
|
811
|
+
* one `insertRule()` per component during render.
|
|
812
|
+
*
|
|
813
|
+
* Each `insertRule()` on a live sheet invalidates style for that sheet's
|
|
814
|
+
* scope. When components inject during React's render phase while other
|
|
815
|
+
* components read layout in the same pass, the two interleave and the browser
|
|
816
|
+
* is forced to recalculate style between every injection. Batching collapses
|
|
817
|
+
* that into one invalidation per flush.
|
|
818
|
+
*
|
|
819
|
+
* - `false` (default) — inject synchronously, one write per component.
|
|
820
|
+
* - `true` — batch, but only inside a *batch window*: a commit in which
|
|
821
|
+
* `<TastyBatchProvider>` rendered and will therefore flush in its
|
|
822
|
+
* `useInsertionEffect`, before any `useLayoutEffect` runs. Any injection
|
|
823
|
+
* outside a window — a deep update the provider did not re-render for, an
|
|
824
|
+
* injection from a layout effect, an event handler, an async callback — is
|
|
825
|
+
* written straight through. Enabling this can never make a layout effect
|
|
826
|
+
* measure an unstyled element. Requires `<TastyBatchProvider>`; without it
|
|
827
|
+
* nothing is batched (and dev mode says so once).
|
|
828
|
+
* - `'always'` — batch every injection, flushing on a microtask when no
|
|
829
|
+
* window is open. Wins on more commits, but a `useLayoutEffect` that
|
|
830
|
+
* measures a freshly mounted element can read its unstyled box, because
|
|
831
|
+
* microtasks run after the layout phase. Paint is unaffected: microtasks
|
|
832
|
+
* always drain before the browser paints.
|
|
833
|
+
*
|
|
834
|
+
* No effect during SSR or RSC: styles are collected as text there, the
|
|
835
|
+
* runtime injector never runs, and the provider is inert without a
|
|
836
|
+
* `document`. No effect on zero-runtime `tastyStatic` styles either — those
|
|
837
|
+
* are extracted at build time and never reach the injector.
|
|
838
|
+
*
|
|
839
|
+
* @default false
|
|
840
|
+
* @example
|
|
841
|
+
* ```tsx
|
|
842
|
+
* configure({ batchInjection: true });
|
|
843
|
+
*
|
|
844
|
+
* <TastyBatchProvider>
|
|
845
|
+
* <App />
|
|
846
|
+
* </TastyBatchProvider>
|
|
847
|
+
* ```
|
|
848
|
+
*/
|
|
849
|
+
batchInjection?: boolean | 'always';
|
|
850
|
+
/**
|
|
851
|
+
* Garbage collection configuration for unused styles.
|
|
852
|
+
* GC is triggered by touch count: every `touchInterval` touches, the
|
|
853
|
+
* oldest unused styles are evicted when their count exceeds `capacity`.
|
|
854
|
+
* @example
|
|
855
|
+
* ```ts
|
|
856
|
+
* configure({
|
|
857
|
+
* gc: { touchInterval: 1000, capacity: 1000 },
|
|
858
|
+
* });
|
|
859
|
+
* ```
|
|
860
|
+
*/
|
|
861
|
+
gc?: GCConfig;
|
|
862
|
+
/**
|
|
863
|
+
* Prefix prepended to every generated identifier (class names,
|
|
864
|
+
* keyframe names, counter-style names). The hash is appended verbatim,
|
|
865
|
+
* so include any separator inside the prefix itself (e.g. `'myapp-'`).
|
|
866
|
+
*
|
|
867
|
+
* Discriminator letters are inserted between the prefix and the hash
|
|
868
|
+
* for non-class names so the three kinds stay visually distinct:
|
|
869
|
+
* - class: `${namePrefix}${hash}` — e.g. `t1a2b3`
|
|
870
|
+
* - keyframe: `${namePrefix}k${hash}` — e.g. `tk1a2b3`
|
|
871
|
+
* - counter-style: `${namePrefix}c${hash}` — e.g. `tc1a2b3`
|
|
872
|
+
*
|
|
873
|
+
* The runtime, SSR, and RSC paths must agree on this value or
|
|
874
|
+
* hydration will mismatch. The zero-runtime build path defaults to
|
|
875
|
+
* `'ts'` (overridable via the same option) so its classes can't
|
|
876
|
+
* collide with runtime classes when both are loaded on the same page.
|
|
877
|
+
*
|
|
878
|
+
* Must match `^[a-zA-Z_][a-zA-Z0-9_-]{0,31}$`. Locked once styles
|
|
879
|
+
* have been generated.
|
|
880
|
+
*
|
|
881
|
+
* @default 't'
|
|
882
|
+
*/
|
|
883
|
+
namePrefix?: string;
|
|
884
|
+
/**
|
|
885
|
+
* Plugins that extend tasty with custom functions, units, or states.
|
|
886
|
+
* Plugins are processed in order, with later plugins overriding earlier ones.
|
|
887
|
+
* @example
|
|
888
|
+
* ```ts
|
|
889
|
+
* import { okhslPlugin } from '@tenphi/tasty';
|
|
890
|
+
*
|
|
891
|
+
* configure({
|
|
892
|
+
* plugins: [okhslPlugin()],
|
|
893
|
+
* });
|
|
894
|
+
* ```
|
|
895
|
+
*/
|
|
896
|
+
plugins?: TastyPlugin[];
|
|
897
|
+
/**
|
|
898
|
+
* Global keyframes definitions that can be referenced by animation names in styles.
|
|
899
|
+
* Keys are animation names, values are keyframes step definitions.
|
|
900
|
+
* Keyframes are only injected when actually used in styles.
|
|
901
|
+
* @example
|
|
902
|
+
* ```ts
|
|
903
|
+
* configure({
|
|
904
|
+
* keyframes: {
|
|
905
|
+
* fadeIn: { from: { opacity: 0 }, to: { opacity: 1 } },
|
|
906
|
+
* pulse: { '0%, 100%': { transform: 'scale(1)' }, '50%': { transform: 'scale(1.05)' } },
|
|
907
|
+
* },
|
|
908
|
+
* });
|
|
909
|
+
* ```
|
|
910
|
+
*/
|
|
911
|
+
keyframes?: Record<string, KeyframesSteps>;
|
|
912
|
+
/**
|
|
913
|
+
* Global CSS @property definitions for custom properties.
|
|
914
|
+
* Keys use tasty token syntax ($name for properties, #name for colors).
|
|
915
|
+
*
|
|
916
|
+
* Tasty ships with `DEFAULT_PROPERTIES` (e.g. `$gap`, `$radius`, `#white`,
|
|
917
|
+
* `#black`, `#clear`, `#border`, etc.) that are always included.
|
|
918
|
+
* Properties you specify here are merged on top, so you can override any
|
|
919
|
+
* default by using the same key.
|
|
920
|
+
*
|
|
921
|
+
* For color tokens (#name), `syntax: '<color>'` is auto-set and
|
|
922
|
+
* `initialValue` defaults to `'transparent'` if not specified.
|
|
923
|
+
*
|
|
924
|
+
* @example
|
|
925
|
+
* ```ts
|
|
926
|
+
* configure({
|
|
927
|
+
* properties: {
|
|
928
|
+
* '$rotation': { syntax: '<angle>', initialValue: '0deg' },
|
|
929
|
+
* '$scale': { syntax: '<number>', inherits: false, initialValue: 1 },
|
|
930
|
+
* '#accent': { initialValue: 'purple' }, // syntax: '<color>' auto-set
|
|
931
|
+
* // Override a default property:
|
|
932
|
+
* '$gap': { syntax: '<length>', inherits: true, initialValue: '8px' },
|
|
933
|
+
* },
|
|
934
|
+
* });
|
|
935
|
+
*
|
|
936
|
+
* // Now use in styles - properties are registered when component renders:
|
|
937
|
+
* const Spinner = tasty({
|
|
938
|
+
* styles: {
|
|
939
|
+
* transform: 'rotate($rotation)',
|
|
940
|
+
* transition: '$$rotation 0.3s', // outputs: --rotation 0.3s
|
|
941
|
+
* },
|
|
942
|
+
* });
|
|
943
|
+
* ```
|
|
944
|
+
*/
|
|
945
|
+
properties?: Record<string, PropertyDefinition>;
|
|
946
|
+
/**
|
|
947
|
+
* Global @font-face definitions.
|
|
948
|
+
* Keys are font-family names, values are descriptors or arrays of descriptors
|
|
949
|
+
* (for multiple weights/styles of the same family).
|
|
950
|
+
* Injected eagerly when styles are first generated.
|
|
951
|
+
* @example
|
|
952
|
+
* ```ts
|
|
953
|
+
* configure({
|
|
954
|
+
* fontFaces: {
|
|
955
|
+
* 'Brand Sans': [
|
|
956
|
+
* { src: 'url("/fonts/brand-regular.woff2") format("woff2")', fontWeight: 400, fontDisplay: 'swap' },
|
|
957
|
+
* { src: 'url("/fonts/brand-bold.woff2") format("woff2")', fontWeight: 700, fontDisplay: 'swap' },
|
|
958
|
+
* ],
|
|
959
|
+
* Icons: { src: 'url("/fonts/icons.woff2") format("woff2")', fontDisplay: 'block' },
|
|
960
|
+
* },
|
|
961
|
+
* });
|
|
962
|
+
* ```
|
|
963
|
+
*/
|
|
964
|
+
fontFaces?: Record<string, FontFaceInput>;
|
|
965
|
+
/**
|
|
966
|
+
* Global @counter-style definitions.
|
|
967
|
+
* Keys are counter-style names, values are descriptor objects.
|
|
968
|
+
* Injected eagerly when styles are first generated.
|
|
969
|
+
* @example
|
|
970
|
+
* ```ts
|
|
971
|
+
* configure({
|
|
972
|
+
* counterStyles: {
|
|
973
|
+
* thumbs: { system: 'cyclic', symbols: '"👍"', suffix: '" "' },
|
|
974
|
+
* },
|
|
975
|
+
* });
|
|
976
|
+
* ```
|
|
977
|
+
*/
|
|
978
|
+
counterStyles?: Record<string, CounterStyleDescriptors>;
|
|
979
|
+
/**
|
|
980
|
+
* Opt-in polyfills for not-yet-baseline CSS features. Each key toggles a
|
|
981
|
+
* feature polyfill; all default to `false`.
|
|
982
|
+
*
|
|
983
|
+
* - `functions` — polyfill CSS `@function` by inlining every `$$name(...)`
|
|
984
|
+
* call into plain CSS (calc/var/color-mix) at parse time instead of
|
|
985
|
+
* emitting the native `@function` at-rule. Enables `@function` usage in
|
|
986
|
+
* browsers that don't support it yet (Firefox/Safari). Note this is the
|
|
987
|
+
* `functions` *feature toggle*, distinct from the top-level `functions`
|
|
988
|
+
* definitions map.
|
|
989
|
+
*
|
|
990
|
+
* @example
|
|
991
|
+
* ```ts
|
|
992
|
+
* configure({ polyfills: { functions: true } });
|
|
993
|
+
* ```
|
|
994
|
+
*/
|
|
995
|
+
polyfills?: {
|
|
996
|
+
functions?: boolean;
|
|
997
|
+
};
|
|
998
|
+
/**
|
|
999
|
+
* Custom style handlers that transform style properties into CSS declarations.
|
|
1000
|
+
* Handlers replace built-in handlers for the same style name.
|
|
1001
|
+
* @example
|
|
1002
|
+
* ```ts
|
|
1003
|
+
* import { styleHandlers } from '@tenphi/tasty';
|
|
1004
|
+
*
|
|
1005
|
+
* configure({
|
|
1006
|
+
* handlers: {
|
|
1007
|
+
* // Override fill with custom behavior
|
|
1008
|
+
* fill: ({ fill }) => {
|
|
1009
|
+
* if (fill?.startsWith('gradient:')) {
|
|
1010
|
+
* return { background: fill.slice(9) };
|
|
1011
|
+
* }
|
|
1012
|
+
* return styleHandlers.fill({ fill });
|
|
1013
|
+
* },
|
|
1014
|
+
* // Add new custom style
|
|
1015
|
+
* elevation: ({ elevation }) => {
|
|
1016
|
+
* const level = parseInt(elevation) || 1;
|
|
1017
|
+
* return {
|
|
1018
|
+
* 'box-shadow': `0 ${level * 2}px ${level * 4}px rgba(0,0,0,0.1)`,
|
|
1019
|
+
* 'z-index': String(level * 100),
|
|
1020
|
+
* };
|
|
1021
|
+
* },
|
|
1022
|
+
* },
|
|
1023
|
+
* });
|
|
1024
|
+
* ```
|
|
1025
|
+
*/
|
|
1026
|
+
handlers?: Record<string, StyleHandlerDefinition>;
|
|
1027
|
+
/**
|
|
1028
|
+
* Props middleware for every tasty component. A prop handler receives the
|
|
1029
|
+
* component's props and returns them, changed or not — the extension point for
|
|
1030
|
+
* props that are not style properties.
|
|
1031
|
+
*
|
|
1032
|
+
* The map key is the handler's name and, by default, the prop that triggers it.
|
|
1033
|
+
* Use `['*', fn]` for an unconditional handler, or `[['a', 'b'], fn]` to trigger
|
|
1034
|
+
* on any of several props.
|
|
1035
|
+
*
|
|
1036
|
+
* Handlers must be pure and must not mutate their input: style values are cached
|
|
1037
|
+
* by object identity, so mutating one in place yields stale CSS. Memoize the
|
|
1038
|
+
* styles you build per input value.
|
|
1039
|
+
*
|
|
1040
|
+
* Not applicable to zero-runtime mode — `tastyStatic()` takes styles objects, not
|
|
1041
|
+
* props, so there is nothing for middleware to run on. Components rendered
|
|
1042
|
+
* through `tasty()` are unaffected and keep the runtime injector.
|
|
1043
|
+
*
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```ts
|
|
1046
|
+
* configure({
|
|
1047
|
+
* propHandlers: {
|
|
1048
|
+
* glaze: (props) => {
|
|
1049
|
+
* const { glaze, ...rest } = props;
|
|
1050
|
+
* if (!glaze) return rest;
|
|
1051
|
+
* return { ...rest, styles: mergeStyles(glazeStyles(glaze), rest.styles) };
|
|
1052
|
+
* },
|
|
1053
|
+
* },
|
|
1054
|
+
* });
|
|
1055
|
+
*
|
|
1056
|
+
* <Element glaze="purple" />
|
|
1057
|
+
* ```
|
|
1058
|
+
*/
|
|
1059
|
+
propHandlers?: Record<string, PropHandlerDefinition>;
|
|
1060
|
+
/**
|
|
1061
|
+
* Style properties exposed as top-level props on **every** tasty component, in
|
|
1062
|
+
* addition to the built-in base styles, without each component listing them in
|
|
1063
|
+
* `styleProps`.
|
|
1064
|
+
*
|
|
1065
|
+
* Augment `TastyBaseStylePropNames` to type them. Each name costs one property
|
|
1066
|
+
* check per render of every component, so keep the list short; the effect is
|
|
1067
|
+
* app-global and cannot be scoped to a subtree.
|
|
1068
|
+
*
|
|
1069
|
+
* @example
|
|
1070
|
+
* ```ts
|
|
1071
|
+
* configure({ baseStyleProps: ['radius', 'shadow'] });
|
|
1072
|
+
*
|
|
1073
|
+
* <Card radius="1r" shadow />
|
|
1074
|
+
* ```
|
|
1075
|
+
*/
|
|
1076
|
+
baseStyleProps?: readonly string[];
|
|
1077
|
+
/**
|
|
1078
|
+
* Design tokens injected as CSS custom properties on `:root`.
|
|
1079
|
+
* Values are parsed through the Tasty DSL. Supports state maps
|
|
1080
|
+
* for responsive/theme-aware tokens.
|
|
1081
|
+
*
|
|
1082
|
+
* - `$name` keys become `--name` CSS custom properties
|
|
1083
|
+
* - `#name` keys become `--name-color` properties
|
|
1084
|
+
*
|
|
1085
|
+
* Tokens are injected once when the first style is rendered.
|
|
1086
|
+
*
|
|
1087
|
+
* @example
|
|
1088
|
+
* ```ts
|
|
1089
|
+
* configure({
|
|
1090
|
+
* tokens: {
|
|
1091
|
+
* '$gap': '4px',
|
|
1092
|
+
* '#primary': {
|
|
1093
|
+
* '': '#purple',
|
|
1094
|
+
* '@dark': '#light-purple',
|
|
1095
|
+
* },
|
|
1096
|
+
* },
|
|
1097
|
+
* });
|
|
1098
|
+
* ```
|
|
1099
|
+
*/
|
|
1100
|
+
tokens?: ConfigTokens;
|
|
1101
|
+
/**
|
|
1102
|
+
* Predefined tokens that are replaced during style parsing (parse-time substitution).
|
|
1103
|
+
* Use `$name` for custom properties and `#name` for color tokens.
|
|
1104
|
+
* Values are substituted inline before CSS generation, unlike `tokens` which
|
|
1105
|
+
* inject CSS custom properties on `:root`.
|
|
1106
|
+
*
|
|
1107
|
+
* For color tokens (#name), boolean `true` is converted to `transparent`.
|
|
1108
|
+
*
|
|
1109
|
+
* @example
|
|
1110
|
+
* ```ts
|
|
1111
|
+
* configure({
|
|
1112
|
+
* replaceTokens: {
|
|
1113
|
+
* $spacing: '2x',
|
|
1114
|
+
* '#accent': '#purple',
|
|
1115
|
+
* '#overlay': true, // → transparent
|
|
1116
|
+
* },
|
|
1117
|
+
* });
|
|
1118
|
+
*
|
|
1119
|
+
* // Now use in styles - tokens are replaced at parse time:
|
|
1120
|
+
* const Card = tasty({
|
|
1121
|
+
* styles: {
|
|
1122
|
+
* padding: '$spacing', // → calc(2 * var(--gap))
|
|
1123
|
+
* fill: '#accent', // → var(--purple-color)
|
|
1124
|
+
* },
|
|
1125
|
+
* });
|
|
1126
|
+
* ```
|
|
1127
|
+
*/
|
|
1128
|
+
replaceTokens?: Record<`$${string}`, string | number | boolean> & Record<`#${string}`, string | number | boolean>;
|
|
1129
|
+
/**
|
|
1130
|
+
* Predefined style recipes -- named style bundles that can be applied via `recipe` style property.
|
|
1131
|
+
* Recipe values are flat tasty styles (no sub-element keys). They may contain base styles,
|
|
1132
|
+
* tokens (`$name`/`#name` definitions), local states, `@keyframes`, and `@property`.
|
|
1133
|
+
*
|
|
1134
|
+
* Components reference recipes via: `recipe: 'name1 name2'` in their styles.
|
|
1135
|
+
* Use `/` to separate base recipes from post recipes: `recipe: 'base1 base2 / post1'`.
|
|
1136
|
+
* Use `none` to skip base recipes: `recipe: 'none / post1'`.
|
|
1137
|
+
* Resolution order: `base_recipes → component styles → post_recipes`.
|
|
1138
|
+
*
|
|
1139
|
+
* Recipes cannot reference other recipes.
|
|
1140
|
+
*
|
|
1141
|
+
* @example
|
|
1142
|
+
* ```ts
|
|
1143
|
+
* configure({
|
|
1144
|
+
* recipes: {
|
|
1145
|
+
* card: { padding: '4x', fill: '#surface', radius: '1r', border: true },
|
|
1146
|
+
* elevated: { shadow: '2x 2x 4x #shadow' },
|
|
1147
|
+
* },
|
|
1148
|
+
* });
|
|
1149
|
+
*
|
|
1150
|
+
* // Usage in styles:
|
|
1151
|
+
* const Card = tasty({
|
|
1152
|
+
* styles: {
|
|
1153
|
+
* recipe: 'card elevated',
|
|
1154
|
+
* color: '#text', // Overrides recipe values
|
|
1155
|
+
* },
|
|
1156
|
+
* });
|
|
1157
|
+
* ```
|
|
1158
|
+
*/
|
|
1159
|
+
recipes?: Record<string, RecipeStyles>;
|
|
1160
|
+
/**
|
|
1161
|
+
* Typography presets — shorthand for `generateTypographyTokens()`.
|
|
1162
|
+
* Accepts the same input and internally generates typography tokens
|
|
1163
|
+
* that are merged into `tokens`. Explicit `tokens` override preset-generated ones.
|
|
1164
|
+
*
|
|
1165
|
+
* @example
|
|
1166
|
+
* ```ts
|
|
1167
|
+
* configure({
|
|
1168
|
+
* presets: {
|
|
1169
|
+
* h1: { fontSize: '32px', lineHeight: '1.2', fontWeight: '700' },
|
|
1170
|
+
* t2: { fontSize: '16px', lineHeight: '1.5', fontWeight: '400' },
|
|
1171
|
+
* },
|
|
1172
|
+
* tokens: {
|
|
1173
|
+
* // Overrides the preset-generated $t2-font-weight
|
|
1174
|
+
* '$t2-font-weight': { '': '400', '@dark': '300' },
|
|
1175
|
+
* },
|
|
1176
|
+
* });
|
|
1177
|
+
* ```
|
|
1178
|
+
*/
|
|
1179
|
+
presets?: Record<string, TypographyPreset>;
|
|
1180
|
+
/**
|
|
1181
|
+
* Global Tasty styles keyed by CSS selector.
|
|
1182
|
+
* Each entry applies the full Tasty style syntax (style properties,
|
|
1183
|
+
* tokens, state maps, selector-based sub-styling) to the given selector.
|
|
1184
|
+
* Injected alongside `:root` tokens when the first style is rendered.
|
|
1185
|
+
*
|
|
1186
|
+
* @example
|
|
1187
|
+
* ```ts
|
|
1188
|
+
* configure({
|
|
1189
|
+
* globalStyles: {
|
|
1190
|
+
* body: { fill: '#surface', color: '#text', preset: 't2', margin: 0 },
|
|
1191
|
+
* html: { overflow: 'hidden' },
|
|
1192
|
+
* },
|
|
1193
|
+
* });
|
|
1194
|
+
* ```
|
|
1195
|
+
*/
|
|
1196
|
+
globalStyles?: Record<string, Styles>;
|
|
1197
|
+
}
|
|
1198
|
+
declare const GLOBAL_INJECTOR_KEY = "__TASTY_GLOBAL_INJECTOR__";
|
|
1199
|
+
declare global {
|
|
1200
|
+
interface Window {
|
|
1201
|
+
[GLOBAL_INJECTOR_KEY]?: StyleInjector;
|
|
1202
|
+
}
|
|
1203
|
+
var __TASTY_GLOBAL_INJECTOR__: StyleInjector | undefined;
|
|
1204
|
+
}
|
|
1205
|
+
/**
|
|
1206
|
+
* Detect if we're running in a test environment
|
|
1207
|
+
*/
|
|
1208
|
+
declare function isTestEnvironment(): boolean;
|
|
1209
|
+
/**
|
|
1210
|
+
* Check if styles have been generated (configuration is locked)
|
|
1211
|
+
*/
|
|
1212
|
+
declare function hasStylesGenerated(): boolean;
|
|
1213
|
+
/**
|
|
1214
|
+
* Check if any global keyframes are configured.
|
|
1215
|
+
* Uses a pre-computed flag to avoid Object.keys() allocation on every call.
|
|
1216
|
+
*/
|
|
1217
|
+
declare function hasGlobalKeyframes(): boolean;
|
|
1218
|
+
/**
|
|
1219
|
+
* Get global keyframes configuration.
|
|
1220
|
+
* Returns null if no keyframes configured (fast path for zero-overhead).
|
|
1221
|
+
*/
|
|
1222
|
+
declare function getGlobalKeyframes(): Record<string, KeyframesSteps> | null;
|
|
1223
|
+
/**
|
|
1224
|
+
* Get global font-face configuration.
|
|
1225
|
+
* Returns null if no font faces configured.
|
|
1226
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
1227
|
+
*/
|
|
1228
|
+
declare function getGlobalFontFaces(): Record<string, FontFaceInput> | null;
|
|
1229
|
+
/**
|
|
1230
|
+
* Get global counter-style configuration.
|
|
1231
|
+
* Returns null if no counter styles configured.
|
|
1232
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
1233
|
+
*/
|
|
1234
|
+
declare function getGlobalCounterStyles(): Record<string, CounterStyleDescriptors> | null;
|
|
1235
|
+
/**
|
|
1236
|
+
* Get global @function configuration.
|
|
1237
|
+
* Returns null if no functions configured.
|
|
1238
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
1239
|
+
*/
|
|
1240
|
+
declare function getGlobalFunctions(): Record<string, FunctionDefinition> | null;
|
|
1241
|
+
/**
|
|
1242
|
+
* Check if any global recipes are configured.
|
|
1243
|
+
* Fast path: returns false if no recipes were ever set.
|
|
1244
|
+
*/
|
|
1245
|
+
declare function hasGlobalRecipes(): boolean;
|
|
1246
|
+
/**
|
|
1247
|
+
* Get global recipes configuration.
|
|
1248
|
+
* Returns null if no recipes configured (fast path for zero-overhead).
|
|
1249
|
+
*/
|
|
1250
|
+
declare function getGlobalRecipes(): Record<string, RecipeStyles> | null;
|
|
1251
|
+
/**
|
|
1252
|
+
* Check if configuration is locked (styles have been generated)
|
|
1253
|
+
*/
|
|
1254
|
+
declare function isConfigLocked(): boolean;
|
|
1255
|
+
/**
|
|
1256
|
+
* Configure the Tasty style system.
|
|
1257
|
+
*
|
|
1258
|
+
* Must be called BEFORE any styles are generated (before first render that uses tasty).
|
|
1259
|
+
* After styles are generated, configuration is locked and calls to configure() will
|
|
1260
|
+
* emit a warning and be ignored.
|
|
1261
|
+
*
|
|
1262
|
+
* @example
|
|
1263
|
+
* ```ts
|
|
1264
|
+
* import { configure } from '@tenphi/tasty';
|
|
1265
|
+
*
|
|
1266
|
+
* // Configure before app renders
|
|
1267
|
+
* configure({
|
|
1268
|
+
* nonce: 'abc123',
|
|
1269
|
+
* states: {
|
|
1270
|
+
* '@mobile': '@media(w < 768px)',
|
|
1271
|
+
* '@dark': '@root(theme=dark)',
|
|
1272
|
+
* },
|
|
1273
|
+
* });
|
|
1274
|
+
* ```
|
|
1275
|
+
*/
|
|
1276
|
+
declare function configure(config?: Partial<TastyConfig>): void;
|
|
1277
|
+
/**
|
|
1278
|
+
* Get the current configuration.
|
|
1279
|
+
* If not configured, returns default configuration.
|
|
1280
|
+
*/
|
|
1281
|
+
declare function getConfig(): TastyConfig;
|
|
1282
|
+
/**
|
|
1283
|
+
* Get the configured prefix used for every generated identifier
|
|
1284
|
+
* (class names, keyframe names, counter-style names).
|
|
1285
|
+
*
|
|
1286
|
+
* Falls back to the default prefix (`'t'`) when `configure()` has not
|
|
1287
|
+
* been called yet — this matches the auto-configuration behavior used
|
|
1288
|
+
* by the rest of the system.
|
|
1289
|
+
*/
|
|
1290
|
+
declare function getNamePrefix(): string;
|
|
1291
|
+
/**
|
|
1292
|
+
* Reset configuration (for testing only).
|
|
1293
|
+
* Clears the global injector and allows reconfiguration.
|
|
1294
|
+
*/
|
|
1295
|
+
declare function resetConfig(): void;
|
|
1296
|
+
//#endregion
|
|
1297
|
+
export { ParseFunction as C, PropHandlerDefinition as D, PropHandler as E, PropHandlerProps as O, FunctionsConfig as S, SheetManager as T, TastyPluginFactory as _, getGlobalFontFaces as a, generateTypographyTokens as b, getGlobalRecipes as c, hasGlobalRecipes as d, hasStylesGenerated as f, TastyPlugin as g, resetConfig as h, getGlobalCounterStyles as i, getNamePrefix as l, isTestEnvironment as m, configure as n, getGlobalFunctions as o, isConfigLocked as p, getConfig as r, getGlobalKeyframes as s, TastyConfig as t, hasGlobalKeyframes as u, TypographyPreset as v, StyleInjector as w, ColorSpace as x, TypographyTokenValue as y };
|
|
1298
|
+
//# sourceMappingURL=config-DMslHK_e.d.ts.map
|