@tenphi/tasty 1.5.2 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +2 -0
- package/dist/config.js +32 -5
- package/dist/config.js.map +1 -1
- package/dist/hooks/useStyles.d.ts +4 -4
- package/dist/hooks/useStyles.js +7 -5
- package/dist/hooks/useStyles.js.map +1 -1
- package/dist/ssr/astro.js +32 -17
- package/dist/ssr/astro.js.map +1 -1
- package/dist/ssr/context.js +16 -0
- package/dist/ssr/context.js.map +1 -0
- package/dist/ssr/index.js +2 -2
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next.d.ts +3 -1
- package/dist/ssr/next.js +2 -1
- package/dist/ssr/next.js.map +1 -1
- package/dist/ssr/ssr-collector-ref.js +17 -1
- package/dist/ssr/ssr-collector-ref.js.map +1 -1
- package/dist/tasty.d.ts +1 -1
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -309,11 +309,13 @@ declare function getGlobalKeyframes(): Record<string, KeyframesSteps> | null;
|
|
|
309
309
|
/**
|
|
310
310
|
* Get global font-face configuration.
|
|
311
311
|
* Returns null if no font faces configured.
|
|
312
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
312
313
|
*/
|
|
313
314
|
declare function getGlobalFontFace(): Record<string, FontFaceInput> | null;
|
|
314
315
|
/**
|
|
315
316
|
* Get global counter-style configuration.
|
|
316
317
|
* Returns null if no counter styles configured.
|
|
318
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
317
319
|
*/
|
|
318
320
|
declare function getGlobalCounterStyle(): Record<string, CounterStyleDescriptors> | null;
|
|
319
321
|
/**
|
package/dist/config.js
CHANGED
|
@@ -37,6 +37,23 @@ let globalCounterStyle = null;
|
|
|
37
37
|
let globalProperties = null;
|
|
38
38
|
let globalRecipes = null;
|
|
39
39
|
let globalConfigTokens = null;
|
|
40
|
+
const GTKEY_TOKENS = "__tasty_cfg_tokens__";
|
|
41
|
+
const GTKEY_FONT_FACE = "__tasty_cfg_font_face__";
|
|
42
|
+
const GTKEY_COUNTER_STYLE = "__tasty_cfg_counter_style__";
|
|
43
|
+
const GTKEY_PROPERTIES = "__tasty_cfg_properties__";
|
|
44
|
+
function setOnGlobalThis(key, value) {
|
|
45
|
+
globalThis[key] = value;
|
|
46
|
+
}
|
|
47
|
+
function getFromGlobalThis(key) {
|
|
48
|
+
return globalThis[key];
|
|
49
|
+
}
|
|
50
|
+
function clearGlobalThisConfig() {
|
|
51
|
+
const g = globalThis;
|
|
52
|
+
delete g[GTKEY_TOKENS];
|
|
53
|
+
delete g[GTKEY_FONT_FACE];
|
|
54
|
+
delete g[GTKEY_COUNTER_STYLE];
|
|
55
|
+
delete g[GTKEY_PROPERTIES];
|
|
56
|
+
}
|
|
40
57
|
/**
|
|
41
58
|
* Default properties shipped with tasty.
|
|
42
59
|
* These are always included unless explicitly overridden via `configure({ properties })`.
|
|
@@ -205,24 +222,28 @@ function setGlobalProperties(properties) {
|
|
|
205
222
|
return;
|
|
206
223
|
}
|
|
207
224
|
globalProperties = properties;
|
|
225
|
+
setOnGlobalThis(GTKEY_PROPERTIES, globalProperties);
|
|
208
226
|
}
|
|
209
227
|
/**
|
|
210
228
|
* Get the effective properties: DEFAULT_PROPERTIES merged with user-configured
|
|
211
229
|
* properties. User properties override defaults with matching keys.
|
|
230
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
212
231
|
*/
|
|
213
232
|
function getEffectiveProperties() {
|
|
214
|
-
|
|
233
|
+
const props = globalProperties ?? getFromGlobalThis(GTKEY_PROPERTIES);
|
|
234
|
+
if (!props) return DEFAULT_PROPERTIES;
|
|
215
235
|
return {
|
|
216
236
|
...DEFAULT_PROPERTIES,
|
|
217
|
-
...
|
|
237
|
+
...props
|
|
218
238
|
};
|
|
219
239
|
}
|
|
220
240
|
/**
|
|
221
241
|
* Get global font-face configuration.
|
|
222
242
|
* Returns null if no font faces configured.
|
|
243
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
223
244
|
*/
|
|
224
245
|
function getGlobalFontFace() {
|
|
225
|
-
return globalFontFace;
|
|
246
|
+
return globalFontFace ?? getFromGlobalThis(GTKEY_FONT_FACE) ?? null;
|
|
226
247
|
}
|
|
227
248
|
/**
|
|
228
249
|
* Set global font faces (called from configure).
|
|
@@ -234,13 +255,15 @@ function setGlobalFontFace(fontFace) {
|
|
|
234
255
|
return;
|
|
235
256
|
}
|
|
236
257
|
globalFontFace = fontFace;
|
|
258
|
+
setOnGlobalThis(GTKEY_FONT_FACE, globalFontFace);
|
|
237
259
|
}
|
|
238
260
|
/**
|
|
239
261
|
* Get global counter-style configuration.
|
|
240
262
|
* Returns null if no counter styles configured.
|
|
263
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
241
264
|
*/
|
|
242
265
|
function getGlobalCounterStyle() {
|
|
243
|
-
return globalCounterStyle;
|
|
266
|
+
return globalCounterStyle ?? getFromGlobalThis(GTKEY_COUNTER_STYLE) ?? null;
|
|
244
267
|
}
|
|
245
268
|
/**
|
|
246
269
|
* Set global counter styles (called from configure).
|
|
@@ -252,6 +275,7 @@ function setGlobalCounterStyle(counterStyle) {
|
|
|
252
275
|
return;
|
|
253
276
|
}
|
|
254
277
|
globalCounterStyle = counterStyle;
|
|
278
|
+
setOnGlobalThis(GTKEY_COUNTER_STYLE, globalCounterStyle);
|
|
255
279
|
}
|
|
256
280
|
/**
|
|
257
281
|
* Check if any global recipes are configured.
|
|
@@ -288,9 +312,10 @@ function setGlobalRecipes(recipes) {
|
|
|
288
312
|
/**
|
|
289
313
|
* Get global token styles for :root injection.
|
|
290
314
|
* Returns null if no tokens configured.
|
|
315
|
+
* Reads from globalThis first for cross-module SSR support.
|
|
291
316
|
*/
|
|
292
317
|
function getGlobalConfigTokens() {
|
|
293
|
-
return globalConfigTokens;
|
|
318
|
+
return globalConfigTokens ?? getFromGlobalThis(GTKEY_TOKENS) ?? null;
|
|
294
319
|
}
|
|
295
320
|
/**
|
|
296
321
|
* Set global token styles (called from configure).
|
|
@@ -305,6 +330,7 @@ function setGlobalConfigTokens(styles) {
|
|
|
305
330
|
...globalConfigTokens,
|
|
306
331
|
...styles
|
|
307
332
|
} : styles;
|
|
333
|
+
setOnGlobalThis(GTKEY_TOKENS, globalConfigTokens);
|
|
308
334
|
}
|
|
309
335
|
/**
|
|
310
336
|
* Check if configuration is locked (styles have been generated)
|
|
@@ -488,6 +514,7 @@ function resetConfig() {
|
|
|
488
514
|
globalCounterStyle = null;
|
|
489
515
|
globalRecipes = null;
|
|
490
516
|
globalConfigTokens = null;
|
|
517
|
+
clearGlobalThisConfig();
|
|
491
518
|
resetGlobalPredefinedTokens();
|
|
492
519
|
resetHandlers();
|
|
493
520
|
resetColorSpace();
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["/**\n * Tasty Configuration Module\n *\n * Centralizes all tasty configuration, including:\n * - Style injector settings (nonce, cleanup thresholds, etc.)\n * - Global predefined states for advanced state mapping\n * - stylesGenerated flag that locks configuration after first style generation\n *\n * Configuration must be done BEFORE any styles are generated.\n * After the first `inject()` call, configuration is locked and attempts to\n * reconfigure will emit a warning and be ignored.\n */\n\nimport { StyleInjector } from './injector/injector';\nimport { clearPipelineCache, isSelector, renderStyles } from './pipeline';\nimport { setGlobalPredefinedStates } from './states';\nimport {\n normalizeHandlerDefinition,\n registerHandler,\n resetHandlers,\n} from './styles/predefined';\nimport { resetColorSpace, setColorSpace } from './utils/color-space';\nimport { isDevEnv } from './utils/is-dev-env';\nimport {\n CUSTOM_UNITS,\n getGlobalFuncs,\n getGlobalParser,\n normalizeColorTokenValue,\n resetGlobalPredefinedTokens,\n setGlobalPredefinedTokens,\n} from './utils/styles';\n\nimport type { ColorSpace } from './utils/color-space';\n\nimport type {\n CounterStyleDescriptors,\n FontFaceInput,\n GCConfig,\n KeyframesSteps,\n PropertyDefinition,\n} from './injector/types';\nimport type { StyleDetails, UnitHandler } from './parser/types';\nimport type { StyleResult } from './pipeline';\nimport type { TastyPlugin } from './plugins/types';\nimport type { RecipeStyles, ConfigTokens } from './styles/types';\nimport type { StyleHandlerDefinition } from './utils/styles';\n\n/**\n * Configuration options for the Tasty style system\n */\nexport interface TastyConfig {\n /** CSP nonce for style elements */\n nonce?: string;\n /** Maximum rules per stylesheet (default: 8192) */\n maxRulesPerSheet?: number;\n /** Force text injection mode, auto-detected in test environments (default: auto) */\n forceTextInjection?: boolean;\n /** Enable development mode features: performance metrics and debug info (default: auto) */\n devMode?: boolean;\n /**\n * Global predefined states for advanced state mapping.\n * These are state aliases that can be used in any component.\n * Example: { '@mobile': '@media(w < 920px)', '@dark': '@root(theme=dark)' }\n */\n states?: Record<string, string>;\n /**\n * Parser LRU cache size (default: 1000).\n * Larger values improve performance for apps with many unique style values.\n */\n parserCacheSize?: number;\n /**\n * Custom units for the style parser (merged with built-in units).\n * Units transform numeric values like `2x` → `calc(2 * var(--gap))`.\n * @example { em: 'em', vw: 'vw', custom: (n) => `${n * 10}px` }\n */\n units?: Record<string, string | UnitHandler>;\n /**\n * Custom functions for the style parser (merged with existing).\n * Functions process parsed style groups and return CSS values.\n * @example { myFunc: (groups) => groups.map(g => g.output).join(' ') }\n */\n funcs?: Record<string, (groups: StyleDetails[]) => string>;\n /**\n * Color space used for decomposed color token companion variables.\n * Controls the CSS function and suffix for alpha composition.\n *\n * - `'rgb'` — suffix `-rgb`, e.g. `rgb(var(--name-color-rgb) / .5)`\n * - `'hsl'` — suffix `-hsl`, e.g. `hsl(var(--name-color-hsl) / .5)`\n * - `'oklch'` — suffix `-oklch`, e.g. `oklch(var(--name-color-oklch) / .5)`\n *\n * @default 'oklch'\n */\n colorSpace?: ColorSpace;\n /**\n * Automatically infer and register CSS @property declarations\n * from custom property values found in styles, keyframes, and global config.\n * Covers all types: \\<color\\>, \\<number\\>, \\<length\\>, \\<angle\\>, \\<percentage\\>, \\<time\\>.\n * When false, only explicitly declared @properties are registered.\n * @default true\n */\n autoPropertyTypes?: boolean;\n /**\n * Garbage collection configuration for unused styles.\n * GC is triggered by touch count: every `touchInterval` touches, the\n * oldest unused styles are evicted when their count exceeds `capacity`.\n * @example\n * ```ts\n * configure({\n * gc: { touchInterval: 1000, capacity: 1000 },\n * });\n * ```\n */\n gc?: GCConfig;\n /**\n * Plugins that extend tasty with custom functions, units, or states.\n * Plugins are processed in order, with later plugins overriding earlier ones.\n * @example\n * ```ts\n * import { okhslPlugin } from '@tenphi/tasty';\n *\n * configure({\n * plugins: [okhslPlugin()],\n * });\n * ```\n */\n plugins?: TastyPlugin[];\n /**\n * Global keyframes definitions that can be referenced by animation names in styles.\n * Keys are animation names, values are keyframes step definitions.\n * Keyframes are only injected when actually used in styles.\n * @example\n * ```ts\n * configure({\n * keyframes: {\n * fadeIn: { from: { opacity: 0 }, to: { opacity: 1 } },\n * pulse: { '0%, 100%': { transform: 'scale(1)' }, '50%': { transform: 'scale(1.05)' } },\n * },\n * });\n * ```\n */\n keyframes?: Record<string, KeyframesSteps>;\n /**\n * Global CSS @property definitions for custom properties.\n * Keys use tasty token syntax ($name for properties, #name for colors).\n *\n * Tasty ships with `DEFAULT_PROPERTIES` (e.g. `$gap`, `$radius`, `#white`,\n * `#black`, `#clear`, `#border`, etc.) that are always included.\n * Properties you specify here are merged on top, so you can override any\n * default by using the same key.\n *\n * For color tokens (#name), `syntax: '<color>'` is auto-set and\n * `initialValue` defaults to `'transparent'` if not specified.\n *\n * @example\n * ```ts\n * configure({\n * properties: {\n * '$rotation': { syntax: '<angle>', initialValue: '0deg' },\n * '$scale': { syntax: '<number>', inherits: false, initialValue: 1 },\n * '#accent': { initialValue: 'purple' }, // syntax: '<color>' auto-set\n * // Override a default property:\n * '$gap': { syntax: '<length>', inherits: true, initialValue: '8px' },\n * },\n * });\n *\n * // Now use in styles - properties are registered when component renders:\n * const Spinner = tasty({\n * styles: {\n * transform: 'rotate($rotation)',\n * transition: '$$rotation 0.3s', // outputs: --rotation 0.3s\n * },\n * });\n * ```\n */\n properties?: Record<string, PropertyDefinition>;\n /**\n * Global @font-face definitions.\n * Keys are font-family names, values are descriptors or arrays of descriptors\n * (for multiple weights/styles of the same family).\n * Injected eagerly when styles are first generated.\n * @example\n * ```ts\n * configure({\n * fontFace: {\n * '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 * Icons: { src: 'url(\"/fonts/icons.woff2\") format(\"woff2\")', fontDisplay: 'block' },\n * },\n * });\n * ```\n */\n fontFace?: Record<string, FontFaceInput>;\n /**\n * Global @counter-style definitions.\n * Keys are counter-style names, values are descriptor objects.\n * Injected eagerly when styles are first generated.\n * @example\n * ```ts\n * configure({\n * counterStyle: {\n * thumbs: { system: 'cyclic', symbols: '\"👍\"', suffix: '\" \"' },\n * },\n * });\n * ```\n */\n counterStyle?: Record<string, CounterStyleDescriptors>;\n /**\n * Custom style handlers that transform style properties into CSS declarations.\n * Handlers replace built-in handlers for the same style name.\n * @example\n * ```ts\n * import { styleHandlers } from '@tenphi/tasty';\n *\n * configure({\n * handlers: {\n * // Override fill with custom behavior\n * fill: ({ fill }) => {\n * if (fill?.startsWith('gradient:')) {\n * return { background: fill.slice(9) };\n * }\n * return styleHandlers.fill({ fill });\n * },\n * // Add new custom style\n * elevation: ({ elevation }) => {\n * const level = parseInt(elevation) || 1;\n * return {\n * 'box-shadow': `0 ${level * 2}px ${level * 4}px rgba(0,0,0,0.1)`,\n * 'z-index': String(level * 100),\n * };\n * },\n * },\n * });\n * ```\n */\n handlers?: Record<string, StyleHandlerDefinition>;\n /**\n * Design tokens injected as CSS custom properties on `:root`.\n * Values are parsed through the Tasty DSL. Supports state maps\n * for responsive/theme-aware tokens.\n *\n * - `$name` keys become `--name` CSS custom properties\n * - `#name` keys become `--name-color` and `--name-color-{colorSpace}` properties\n *\n * Tokens are injected once when the first style is rendered.\n *\n * @example\n * ```ts\n * configure({\n * tokens: {\n * '$gap': '4px',\n * '#primary': {\n * '': '#purple',\n * '@dark': '#light-purple',\n * },\n * },\n * });\n * ```\n */\n tokens?: ConfigTokens;\n /**\n * Predefined tokens that are replaced during style parsing (parse-time substitution).\n * Use `$name` for custom properties and `#name` for color tokens.\n * Values are substituted inline before CSS generation, unlike `tokens` which\n * inject CSS custom properties on `:root`.\n *\n * For color tokens (#name), boolean `true` is converted to `transparent`.\n *\n * @example\n * ```ts\n * configure({\n * replaceTokens: {\n * $spacing: '2x',\n * '#accent': '#purple',\n * '#overlay': true, // → transparent\n * },\n * });\n *\n * // Now use in styles - tokens are replaced at parse time:\n * const Card = tasty({\n * styles: {\n * padding: '$spacing', // → calc(2 * var(--gap))\n * fill: '#accent', // → var(--purple-color)\n * },\n * });\n * ```\n */\n replaceTokens?: Record<`$${string}`, string | number | boolean> &\n Record<`#${string}`, string | number | boolean>;\n /**\n * Predefined style recipes -- named style bundles that can be applied via `recipe` style property.\n * Recipe values are flat tasty styles (no sub-element keys). They may contain base styles,\n * tokens (`$name`/`#name` definitions), local states, `@keyframes`, and `@properties`.\n *\n * Components reference recipes via: `recipe: 'name1 name2'` in their styles.\n * Use `/` to separate base recipes from post recipes: `recipe: 'base1 base2 / post1'`.\n * Use `none` to skip base recipes: `recipe: 'none / post1'`.\n * Resolution order: `base_recipes → component styles → post_recipes`.\n *\n * Recipes cannot reference other recipes.\n *\n * @example\n * ```ts\n * configure({\n * recipes: {\n * card: { padding: '4x', fill: '#surface', radius: '1r', border: true },\n * elevated: { shadow: '2x 2x 4x #shadow' },\n * },\n * });\n *\n * // Usage in styles:\n * const Card = tasty({\n * styles: {\n * recipe: 'card elevated',\n * color: '#text', // Overrides recipe values\n * },\n * });\n * ```\n */\n recipes?: Record<string, RecipeStyles>;\n}\n\n// Warnings tracking to avoid duplicates\nconst emittedWarnings = new Set<string>();\n\nconst devMode = isDevEnv();\n\n/**\n * Emit a warning only once\n */\nfunction warnOnce(key: string, message: string): void {\n if (devMode && !emittedWarnings.has(key)) {\n emittedWarnings.add(key);\n console.warn(message);\n }\n}\n\n// ============================================================================\n// Configuration State\n// ============================================================================\n\n// Track whether styles have been generated (locks configuration)\nlet stylesGenerated = false;\n\n// Current configuration (null until first configure() or auto-configured on first use)\nlet currentConfig: TastyConfig | null = null;\n\n// Global keyframes storage (null = no keyframes configured, empty object checked via hasGlobalKeyframes)\nlet globalKeyframes: Record<string, KeyframesSteps> | null = null;\n\n// Global font-face storage (null = no font faces configured)\nlet globalFontFace: Record<string, FontFaceInput> | null = null;\n\n// Global counter-style storage (null = no counter styles configured)\nlet globalCounterStyle: Record<string, CounterStyleDescriptors> | null = null;\n\n// Global properties storage (null = no properties configured)\nlet globalProperties: Record<string, PropertyDefinition> | null = null;\n\n// Global recipes storage (null = no recipes configured)\nlet globalRecipes: Record<string, RecipeStyles> | null = null;\n\n// Global token styles storage (injected as :root CSS custom properties)\nlet globalConfigTokens: ConfigTokens | null = null;\n\n/**\n * Default properties shipped with tasty.\n * These are always included unless explicitly overridden via `configure({ properties })`.\n * Keys use tasty token syntax (#name for colors, $name for other properties).\n *\n * For properties with CSS @property-compatible types (length, time, number, color),\n * an `initialValue` is provided so the property works even without a project-level token.\n */\nexport const DEFAULT_PROPERTIES: Record<string, PropertyDefinition> = {\n // Used by dual-fill feature to enable CSS transitions on the second fill color\n '#tasty-second-fill': {\n inherits: false,\n initialValue: 'transparent',\n },\n // Current color context variable (set by the color style handler).\n '#current': {\n inherits: true,\n initialValue: 'transparent',\n },\n // White and black are fundamental colors that need explicit initial values.\n '#white': {\n inherits: true,\n initialValue: 'rgb(255 255 255)',\n },\n '#black': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n // Shorthand for transparent\n '#clear': {\n inherits: true,\n initialValue: 'transparent',\n },\n // Default border color\n '#border': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n\n // ---- Core design tokens used by style handlers ----\n // These provide sensible defaults so tasty works standalone without a design system.\n // Consuming projects (e.g. uikit) override these by defining tokens on :root.\n\n $gap: {\n syntax: '<length>',\n inherits: true,\n initialValue: '4px',\n },\n $radius: {\n syntax: '<length>',\n inherits: true,\n initialValue: '6px',\n },\n '$border-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '1px',\n },\n '$outline-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '3px',\n },\n $transition: {\n syntax: '<time>',\n inherits: true,\n initialValue: '80ms',\n },\n // Used by radius.ts for `radius=\"leaf\"` modifier\n '$sharp-radius': {\n syntax: '<length>',\n inherits: true,\n initialValue: '0px',\n },\n // Used by preset.ts for `preset=\"name / strong\"`\n '$bold-font-weight': {\n syntax: '<number>',\n inherits: true,\n initialValue: '700',\n },\n // Used by preset.ts as fallback font stacks\n '$font-sans-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", sans-serif',\n },\n '$font-mono-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n },\n};\n\n// Global injector instance key\nconst GLOBAL_INJECTOR_KEY = '__TASTY_GLOBAL_INJECTOR__';\n\ninterface TastyGlobalStorage {\n [GLOBAL_INJECTOR_KEY]?: StyleInjector;\n}\n\ndeclare global {\n interface Window {\n [GLOBAL_INJECTOR_KEY]?: StyleInjector;\n }\n\n var __TASTY_GLOBAL_INJECTOR__: StyleInjector | undefined;\n}\n\n/**\n * Detect if we're running in a test environment\n */\nexport function isTestEnvironment(): boolean {\n // Check Node.js environment\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') {\n return true;\n }\n\n // Check for test runner globals (safely)\n if (typeof global !== 'undefined') {\n const g = global as unknown as Record<string, unknown>;\n if (g.vi || g.jest || g.expect || g.describe || g.it) {\n return true;\n }\n }\n\n // Check for jsdom environment (common in tests)\n if (\n typeof window !== 'undefined' &&\n window.navigator?.userAgent?.includes('jsdom')\n ) {\n return true;\n }\n\n // Check for other test runners\n if (typeof globalThis !== 'undefined') {\n const gt = globalThis as unknown as Record<string, unknown>;\n if (gt.vitest || gt.mocha) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Create default configuration with optional test environment detection\n */\nfunction createDefaultConfig(isTest?: boolean): TastyConfig {\n return {\n maxRulesPerSheet: 8192,\n forceTextInjection: isTest ?? false,\n devMode: isDevEnv(),\n };\n}\n\n// ============================================================================\n// stylesGenerated Flag Management\n// ============================================================================\n\n/**\n * Mark that styles have been generated (called by injector on first inject)\n * This locks the configuration - no further changes allowed.\n * Also injects internal and global properties.\n */\nexport function markStylesGenerated(): void {\n if (stylesGenerated) return; // Already marked, skip\n\n stylesGenerated = true;\n\n const injector = getGlobalInjector();\n\n // Inject all properties (defaults merged with user-configured overrides)\n for (const [token, definition] of Object.entries(getEffectiveProperties())) {\n injector.property(token, definition);\n }\n\n // Inject global @font-face rules (eagerly — fonts should be available before render)\n if (globalFontFace && Object.keys(globalFontFace).length > 0) {\n for (const [family, input] of Object.entries(globalFontFace)) {\n const descriptors = Array.isArray(input) ? input : [input];\n for (const desc of descriptors) {\n injector.fontFace(family, desc);\n }\n }\n }\n\n // Inject global @counter-style rules (eagerly)\n if (globalCounterStyle && Object.keys(globalCounterStyle).length > 0) {\n for (const [name, descriptors] of Object.entries(globalCounterStyle)) {\n injector.counterStyle(name, descriptors);\n }\n }\n\n // Inject configured tokens as :root CSS custom properties\n if (globalConfigTokens && Object.keys(globalConfigTokens).length > 0) {\n const tokenRules = renderStyles(\n globalConfigTokens,\n ':root',\n ) as StyleResult[];\n if (tokenRules.length > 0) {\n injector.injectGlobal(tokenRules);\n }\n }\n}\n\n/**\n * Check if styles have been generated (configuration is locked)\n */\nexport function hasStylesGenerated(): boolean {\n return stylesGenerated;\n}\n\n/**\n * Reset styles generated flag (for testing only)\n */\nexport function resetStylesGenerated(): void {\n stylesGenerated = false;\n emittedWarnings.clear();\n}\n\n// ============================================================================\n// Global Keyframes Management\n// ============================================================================\n\nlet _hasGlobalKeyframes = false;\n\n/**\n * Check if any global keyframes are configured.\n * Uses a pre-computed flag to avoid Object.keys() allocation on every call.\n */\nexport function hasGlobalKeyframes(): boolean {\n return _hasGlobalKeyframes;\n}\n\n/**\n * Get global keyframes configuration.\n * Returns null if no keyframes configured (fast path for zero-overhead).\n */\nexport function getGlobalKeyframes(): Record<string, KeyframesSteps> | null {\n return globalKeyframes;\n}\n\n/**\n * Set global keyframes (called from configure).\n * Internal use only.\n */\nfunction setGlobalKeyframes(keyframes: Record<string, KeyframesSteps>): void {\n if (stylesGenerated) {\n warnOnce(\n 'keyframes-after-styles',\n `[Tasty] Cannot update keyframes after styles have been generated.\\n` +\n `The new keyframes will be ignored.`,\n );\n return;\n }\n globalKeyframes = keyframes;\n _hasGlobalKeyframes = Object.keys(keyframes).length > 0;\n}\n\n// ============================================================================\n// Global Properties Management\n// ============================================================================\n\n/**\n * Check if any global properties are configured.\n * Fast path: returns false if no properties were ever set.\n */\nexport function hasGlobalProperties(): boolean {\n return globalProperties !== null && Object.keys(globalProperties).length > 0;\n}\n\n/**\n * Get global properties configuration.\n * Returns null if no properties configured (fast path for zero-overhead).\n */\nexport function getGlobalProperties(): Record<\n string,\n PropertyDefinition\n> | null {\n return globalProperties;\n}\n\n/**\n * Set global properties (called from configure).\n * Internal use only.\n */\nfunction setGlobalProperties(\n properties: Record<string, PropertyDefinition>,\n): void {\n if (stylesGenerated) {\n warnOnce(\n 'properties-after-styles',\n `[Tasty] Cannot update properties after styles have been generated.\\n` +\n `The new properties will be ignored.`,\n );\n return;\n }\n globalProperties = properties;\n}\n\n/**\n * Get the effective properties: DEFAULT_PROPERTIES merged with user-configured\n * properties. User properties override defaults with matching keys.\n */\nexport function getEffectiveProperties(): Record<string, PropertyDefinition> {\n if (!globalProperties) return DEFAULT_PROPERTIES;\n return { ...DEFAULT_PROPERTIES, ...globalProperties };\n}\n\n// ============================================================================\n// Global Font Face Management\n// ============================================================================\n\n/**\n * Get global font-face configuration.\n * Returns null if no font faces configured.\n */\nexport function getGlobalFontFace(): Record<string, FontFaceInput> | null {\n return globalFontFace;\n}\n\n/**\n * Set global font faces (called from configure).\n * Internal use only.\n */\nfunction setGlobalFontFace(fontFace: Record<string, FontFaceInput>): void {\n if (stylesGenerated) {\n warnOnce(\n 'fontface-after-styles',\n `[Tasty] Cannot update fontFace after styles have been generated.\\n` +\n `The new font faces will be ignored.`,\n );\n return;\n }\n globalFontFace = fontFace;\n}\n\n// ============================================================================\n// Global Counter Style Management\n// ============================================================================\n\n/**\n * Get global counter-style configuration.\n * Returns null if no counter styles configured.\n */\nexport function getGlobalCounterStyle(): Record<\n string,\n CounterStyleDescriptors\n> | null {\n return globalCounterStyle;\n}\n\n/**\n * Set global counter styles (called from configure).\n * Internal use only.\n */\nfunction setGlobalCounterStyle(\n counterStyle: Record<string, CounterStyleDescriptors>,\n): void {\n if (stylesGenerated) {\n warnOnce(\n 'counterstyle-after-styles',\n `[Tasty] Cannot update counterStyle after styles have been generated.\\n` +\n `The new counter styles will be ignored.`,\n );\n return;\n }\n globalCounterStyle = counterStyle;\n}\n\n// ============================================================================\n// Global Recipes Management\n// ============================================================================\n\n/**\n * Check if any global recipes are configured.\n * Fast path: returns false if no recipes were ever set.\n */\nexport function hasGlobalRecipes(): boolean {\n return globalRecipes !== null && Object.keys(globalRecipes).length > 0;\n}\n\n/**\n * Get global recipes configuration.\n * Returns null if no recipes configured (fast path for zero-overhead).\n */\nexport function getGlobalRecipes(): Record<string, RecipeStyles> | null {\n return globalRecipes;\n}\n\n/**\n * Set global recipes (called from configure).\n * Internal use only.\n */\nfunction setGlobalRecipes(recipes: Record<string, RecipeStyles>): void {\n if (stylesGenerated) {\n warnOnce(\n 'recipes-after-styles',\n `[Tasty] Cannot update recipes after styles have been generated.\\n` +\n `The new recipes will be ignored.`,\n );\n return;\n }\n\n // Dev-mode validation\n if (devMode) {\n for (const [name, recipeStyles] of Object.entries(recipes)) {\n if (name === 'none') {\n warnOnce(\n 'recipe-reserved-none',\n `[Tasty] Recipe name \"none\" is reserved. ` +\n `It is used as a keyword meaning \"no base recipes\" ` +\n `(e.g. recipe: 'none / post-recipe'). ` +\n `Choose a different name for your recipe.`,\n );\n }\n\n for (const key of Object.keys(recipeStyles)) {\n if (isSelector(key)) {\n warnOnce(\n `recipe-selector-${name}-${key}`,\n `[Tasty] Recipe \"${name}\" contains sub-element key \"${key}\". ` +\n `Recipes must be flat styles without sub-element keys. ` +\n `Remove the sub-element key from the recipe definition.`,\n );\n }\n if (key === 'recipe') {\n warnOnce(\n `recipe-recursive-${name}`,\n `[Tasty] Recipe \"${name}\" contains a \"recipe\" key. ` +\n `Recipes cannot reference other recipes. ` +\n `Use space-separated names for composition: recipe: 'base elevated'.`,\n );\n }\n }\n }\n }\n\n globalRecipes = recipes;\n}\n\n// ============================================================================\n// Global Token Styles Management\n// ============================================================================\n\n/**\n * Get global token styles for :root injection.\n * Returns null if no tokens configured.\n */\nexport function getGlobalConfigTokens(): ConfigTokens | null {\n return globalConfigTokens;\n}\n\n/**\n * Set global token styles (called from configure).\n * Internal use only.\n */\nfunction setGlobalConfigTokens(styles: ConfigTokens): void {\n if (stylesGenerated) {\n warnOnce(\n 'tokens-after-styles',\n `[Tasty] Cannot update tokens after styles have been generated.\\n` +\n `The new tokens will be ignored.`,\n );\n return;\n }\n globalConfigTokens = globalConfigTokens\n ? { ...globalConfigTokens, ...styles }\n : styles;\n}\n\n/**\n * Check if configuration is locked (styles have been generated)\n */\nexport function isConfigLocked(): boolean {\n return stylesGenerated;\n}\n\n// ============================================================================\n// Configuration API\n// ============================================================================\n\n/**\n * Configure the Tasty style system.\n *\n * Must be called BEFORE any styles are generated (before first render that uses tasty).\n * After styles are generated, configuration is locked and calls to configure() will\n * emit a warning and be ignored.\n *\n * @example\n * ```ts\n * import { configure } from '@tenphi/tasty';\n *\n * // Configure before app renders\n * configure({\n * nonce: 'abc123',\n * states: {\n * '@mobile': '@media(w < 768px)',\n * '@dark': '@root(theme=dark)',\n * },\n * });\n * ```\n */\nexport function configure(config: Partial<TastyConfig> = {}): void {\n if (stylesGenerated) {\n warnOnce(\n 'configure-after-styles',\n `[Tasty] Cannot call configure() after styles have been generated.\\n` +\n `Configuration must be done before the first render. The configuration will be ignored.`,\n );\n return;\n }\n\n // Collect merged values from plugins first, then override with direct config\n let mergedStates: Record<string, string> = {};\n let mergedUnits: Record<string, string | UnitHandler> = {};\n let mergedFuncs: Record<string, (groups: StyleDetails[]) => string> = {};\n let mergedHandlers: Record<string, StyleHandlerDefinition> = {};\n let mergedReplaceTokens: Record<string, string | number | boolean> = {};\n let mergedConfigTokens: ConfigTokens = {} as ConfigTokens;\n let mergedRecipes: Record<string, RecipeStyles> = {};\n\n // Process plugins in order\n if (config.plugins) {\n for (const plugin of config.plugins) {\n if (plugin.states) {\n mergedStates = { ...mergedStates, ...plugin.states };\n }\n if (plugin.units) {\n mergedUnits = { ...mergedUnits, ...plugin.units };\n }\n if (plugin.funcs) {\n mergedFuncs = { ...mergedFuncs, ...plugin.funcs };\n }\n if (plugin.handlers) {\n mergedHandlers = { ...mergedHandlers, ...plugin.handlers };\n }\n if (plugin.replaceTokens) {\n mergedReplaceTokens = {\n ...mergedReplaceTokens,\n ...plugin.replaceTokens,\n };\n }\n if (plugin.tokens) {\n mergedConfigTokens = { ...mergedConfigTokens, ...plugin.tokens };\n }\n if (plugin.recipes) {\n mergedRecipes = { ...mergedRecipes, ...plugin.recipes };\n }\n }\n }\n\n // Direct config overrides plugins\n if (config.states) {\n mergedStates = { ...mergedStates, ...config.states };\n }\n if (config.units) {\n mergedUnits = { ...mergedUnits, ...config.units };\n }\n if (config.funcs) {\n mergedFuncs = { ...mergedFuncs, ...config.funcs };\n }\n if (config.handlers) {\n mergedHandlers = { ...mergedHandlers, ...config.handlers };\n }\n if (config.replaceTokens) {\n mergedReplaceTokens = { ...mergedReplaceTokens, ...config.replaceTokens };\n }\n if (config.tokens) {\n mergedConfigTokens = { ...mergedConfigTokens, ...config.tokens };\n }\n if (config.recipes) {\n mergedRecipes = { ...mergedRecipes, ...config.recipes };\n }\n\n // Warn on tokens/replaceTokens key conflicts\n if (devMode) {\n const tokenKeys = new Set(Object.keys(mergedConfigTokens));\n for (const key of Object.keys(mergedReplaceTokens)) {\n if (tokenKeys.has(key)) {\n warnOnce(\n `token-conflict-${key}`,\n `[Tasty] Token \"${key}\" is defined in both \\`tokens\\` and \\`replaceTokens\\`. ` +\n `\\`replaceTokens\\` performs parse-time substitution, so the \\`tokens\\` ` +\n `CSS custom property will be injected but never used by Tasty styles. ` +\n `Remove it from one of the two.`,\n );\n }\n }\n }\n\n // Handle color space (must be set before any token processing)\n if (config.colorSpace) {\n setColorSpace(config.colorSpace);\n // Color space affects parser output (e.g. #name.5 → oklch(...) vs rgb(...))\n getGlobalParser().clearCache();\n }\n\n // Handle predefined states\n if (Object.keys(mergedStates).length > 0) {\n setGlobalPredefinedStates(mergedStates);\n }\n\n // Handle parser configuration (merge semantics - extend, not replace)\n const parser = getGlobalParser();\n\n if (config.parserCacheSize !== undefined) {\n parser.updateOptions({ cacheSize: config.parserCacheSize });\n }\n\n if (Object.keys(mergedUnits).length > 0) {\n // Merge with existing units\n const currentUnits = parser.getUnits() ?? CUSTOM_UNITS;\n parser.setUnits({ ...currentUnits, ...mergedUnits });\n }\n\n if (Object.keys(mergedFuncs).length > 0) {\n // Merge with existing funcs\n const currentFuncs = getGlobalFuncs();\n const finalFuncs = { ...currentFuncs, ...mergedFuncs };\n parser.setFuncs(finalFuncs);\n // Also update the global registry so customFunc() continues to work\n Object.assign(currentFuncs, mergedFuncs);\n }\n\n // Handle keyframes\n if (config.keyframes) {\n setGlobalKeyframes(config.keyframes);\n }\n\n // Handle properties\n if (config.properties) {\n setGlobalProperties(config.properties);\n }\n\n // Handle font faces\n if (config.fontFace) {\n setGlobalFontFace(config.fontFace);\n }\n\n // Handle counter styles\n if (config.counterStyle) {\n setGlobalCounterStyle(config.counterStyle);\n }\n\n // Handle custom handlers\n if (Object.keys(mergedHandlers).length > 0) {\n for (const [name, definition] of Object.entries(mergedHandlers)) {\n const handler = normalizeHandlerDefinition(name, definition);\n registerHandler(handler);\n }\n }\n\n // Handle replaceTokens (parse-time substitution)\n if (Object.keys(mergedReplaceTokens).length > 0) {\n const processedTokens: Record<string, string> = {};\n for (const [key, value] of Object.entries(mergedReplaceTokens)) {\n if (key.startsWith('#')) {\n const normalized = normalizeColorTokenValue(value);\n if (normalized === null) continue;\n processedTokens[key] = String(normalized);\n } else if (value === false) {\n continue;\n } else {\n processedTokens[key] = String(value);\n }\n }\n setGlobalPredefinedTokens(processedTokens);\n }\n\n // Handle tokens (CSS custom properties on :root)\n if (Object.keys(mergedConfigTokens).length > 0) {\n setGlobalConfigTokens(mergedConfigTokens);\n }\n\n // Handle recipes\n if (Object.keys(mergedRecipes).length > 0) {\n setGlobalRecipes(mergedRecipes);\n }\n\n const {\n states: _states,\n parserCacheSize: _parserCacheSize,\n units: _units,\n funcs: _funcs,\n plugins: _plugins,\n keyframes: _keyframes,\n properties: _properties,\n fontFace: _fontFace,\n counterStyle: _counterStyle,\n handlers: _handlers,\n tokens: _tokens,\n replaceTokens: _replaceTokens,\n recipes: _recipes,\n colorSpace: _colorSpace,\n ...injectorConfig\n } = config;\n\n const fullConfig: TastyConfig = {\n ...createDefaultConfig(),\n ...currentConfig,\n ...injectorConfig,\n };\n\n // Store the config\n currentConfig = fullConfig;\n\n // Create/replace the global injector\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n storage[GLOBAL_INJECTOR_KEY] = new StyleInjector(fullConfig);\n}\n\n/**\n * Get the current configuration.\n * If not configured, returns default configuration.\n */\nexport function getConfig(): TastyConfig {\n if (!currentConfig) {\n currentConfig = createDefaultConfig(isTestEnvironment());\n }\n return currentConfig;\n}\n\n/**\n * Get the global injector instance.\n * Auto-configures with defaults if not already configured.\n */\nexport function getGlobalInjector(): StyleInjector {\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n\n if (!storage[GLOBAL_INJECTOR_KEY]) {\n configure();\n }\n\n return storage[GLOBAL_INJECTOR_KEY]!;\n}\n\n/**\n * Reset configuration (for testing only).\n * Clears the global injector and allows reconfiguration.\n */\nexport function resetConfig(): void {\n stylesGenerated = false;\n currentConfig = null;\n globalKeyframes = null;\n _hasGlobalKeyframes = false;\n globalProperties = null;\n globalFontFace = null;\n globalCounterStyle = null;\n globalRecipes = null;\n globalConfigTokens = null;\n resetGlobalPredefinedTokens();\n resetHandlers();\n resetColorSpace();\n clearPipelineCache();\n emittedWarnings.clear();\n\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n delete storage[GLOBAL_INJECTOR_KEY];\n}\n\n// Re-export TastyConfig as StyleInjectorConfig for backward compatibility\nexport type { TastyConfig as StyleInjectorConfig };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["/**\n * Tasty Configuration Module\n *\n * Centralizes all tasty configuration, including:\n * - Style injector settings (nonce, cleanup thresholds, etc.)\n * - Global predefined states for advanced state mapping\n * - stylesGenerated flag that locks configuration after first style generation\n *\n * Configuration must be done BEFORE any styles are generated.\n * After the first `inject()` call, configuration is locked and attempts to\n * reconfigure will emit a warning and be ignored.\n */\n\nimport { StyleInjector } from './injector/injector';\nimport { clearPipelineCache, isSelector, renderStyles } from './pipeline';\nimport { setGlobalPredefinedStates } from './states';\nimport {\n normalizeHandlerDefinition,\n registerHandler,\n resetHandlers,\n} from './styles/predefined';\nimport { resetColorSpace, setColorSpace } from './utils/color-space';\nimport { isDevEnv } from './utils/is-dev-env';\nimport {\n CUSTOM_UNITS,\n getGlobalFuncs,\n getGlobalParser,\n normalizeColorTokenValue,\n resetGlobalPredefinedTokens,\n setGlobalPredefinedTokens,\n} from './utils/styles';\n\nimport type { ColorSpace } from './utils/color-space';\n\nimport type {\n CounterStyleDescriptors,\n FontFaceInput,\n GCConfig,\n KeyframesSteps,\n PropertyDefinition,\n} from './injector/types';\nimport type { StyleDetails, UnitHandler } from './parser/types';\nimport type { StyleResult } from './pipeline';\nimport type { TastyPlugin } from './plugins/types';\nimport type { RecipeStyles, ConfigTokens } from './styles/types';\nimport type { StyleHandlerDefinition } from './utils/styles';\n\n/**\n * Configuration options for the Tasty style system\n */\nexport interface TastyConfig {\n /** CSP nonce for style elements */\n nonce?: string;\n /** Maximum rules per stylesheet (default: 8192) */\n maxRulesPerSheet?: number;\n /** Force text injection mode, auto-detected in test environments (default: auto) */\n forceTextInjection?: boolean;\n /** Enable development mode features: performance metrics and debug info (default: auto) */\n devMode?: boolean;\n /**\n * Global predefined states for advanced state mapping.\n * These are state aliases that can be used in any component.\n * Example: { '@mobile': '@media(w < 920px)', '@dark': '@root(theme=dark)' }\n */\n states?: Record<string, string>;\n /**\n * Parser LRU cache size (default: 1000).\n * Larger values improve performance for apps with many unique style values.\n */\n parserCacheSize?: number;\n /**\n * Custom units for the style parser (merged with built-in units).\n * Units transform numeric values like `2x` → `calc(2 * var(--gap))`.\n * @example { em: 'em', vw: 'vw', custom: (n) => `${n * 10}px` }\n */\n units?: Record<string, string | UnitHandler>;\n /**\n * Custom functions for the style parser (merged with existing).\n * Functions process parsed style groups and return CSS values.\n * @example { myFunc: (groups) => groups.map(g => g.output).join(' ') }\n */\n funcs?: Record<string, (groups: StyleDetails[]) => string>;\n /**\n * Color space used for decomposed color token companion variables.\n * Controls the CSS function and suffix for alpha composition.\n *\n * - `'rgb'` — suffix `-rgb`, e.g. `rgb(var(--name-color-rgb) / .5)`\n * - `'hsl'` — suffix `-hsl`, e.g. `hsl(var(--name-color-hsl) / .5)`\n * - `'oklch'` — suffix `-oklch`, e.g. `oklch(var(--name-color-oklch) / .5)`\n *\n * @default 'oklch'\n */\n colorSpace?: ColorSpace;\n /**\n * Automatically infer and register CSS @property declarations\n * from custom property values found in styles, keyframes, and global config.\n * Covers all types: \\<color\\>, \\<number\\>, \\<length\\>, \\<angle\\>, \\<percentage\\>, \\<time\\>.\n * When false, only explicitly declared @properties are registered.\n * @default true\n */\n autoPropertyTypes?: boolean;\n /**\n * Garbage collection configuration for unused styles.\n * GC is triggered by touch count: every `touchInterval` touches, the\n * oldest unused styles are evicted when their count exceeds `capacity`.\n * @example\n * ```ts\n * configure({\n * gc: { touchInterval: 1000, capacity: 1000 },\n * });\n * ```\n */\n gc?: GCConfig;\n /**\n * Plugins that extend tasty with custom functions, units, or states.\n * Plugins are processed in order, with later plugins overriding earlier ones.\n * @example\n * ```ts\n * import { okhslPlugin } from '@tenphi/tasty';\n *\n * configure({\n * plugins: [okhslPlugin()],\n * });\n * ```\n */\n plugins?: TastyPlugin[];\n /**\n * Global keyframes definitions that can be referenced by animation names in styles.\n * Keys are animation names, values are keyframes step definitions.\n * Keyframes are only injected when actually used in styles.\n * @example\n * ```ts\n * configure({\n * keyframes: {\n * fadeIn: { from: { opacity: 0 }, to: { opacity: 1 } },\n * pulse: { '0%, 100%': { transform: 'scale(1)' }, '50%': { transform: 'scale(1.05)' } },\n * },\n * });\n * ```\n */\n keyframes?: Record<string, KeyframesSteps>;\n /**\n * Global CSS @property definitions for custom properties.\n * Keys use tasty token syntax ($name for properties, #name for colors).\n *\n * Tasty ships with `DEFAULT_PROPERTIES` (e.g. `$gap`, `$radius`, `#white`,\n * `#black`, `#clear`, `#border`, etc.) that are always included.\n * Properties you specify here are merged on top, so you can override any\n * default by using the same key.\n *\n * For color tokens (#name), `syntax: '<color>'` is auto-set and\n * `initialValue` defaults to `'transparent'` if not specified.\n *\n * @example\n * ```ts\n * configure({\n * properties: {\n * '$rotation': { syntax: '<angle>', initialValue: '0deg' },\n * '$scale': { syntax: '<number>', inherits: false, initialValue: 1 },\n * '#accent': { initialValue: 'purple' }, // syntax: '<color>' auto-set\n * // Override a default property:\n * '$gap': { syntax: '<length>', inherits: true, initialValue: '8px' },\n * },\n * });\n *\n * // Now use in styles - properties are registered when component renders:\n * const Spinner = tasty({\n * styles: {\n * transform: 'rotate($rotation)',\n * transition: '$$rotation 0.3s', // outputs: --rotation 0.3s\n * },\n * });\n * ```\n */\n properties?: Record<string, PropertyDefinition>;\n /**\n * Global @font-face definitions.\n * Keys are font-family names, values are descriptors or arrays of descriptors\n * (for multiple weights/styles of the same family).\n * Injected eagerly when styles are first generated.\n * @example\n * ```ts\n * configure({\n * fontFace: {\n * '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 * Icons: { src: 'url(\"/fonts/icons.woff2\") format(\"woff2\")', fontDisplay: 'block' },\n * },\n * });\n * ```\n */\n fontFace?: Record<string, FontFaceInput>;\n /**\n * Global @counter-style definitions.\n * Keys are counter-style names, values are descriptor objects.\n * Injected eagerly when styles are first generated.\n * @example\n * ```ts\n * configure({\n * counterStyle: {\n * thumbs: { system: 'cyclic', symbols: '\"👍\"', suffix: '\" \"' },\n * },\n * });\n * ```\n */\n counterStyle?: Record<string, CounterStyleDescriptors>;\n /**\n * Custom style handlers that transform style properties into CSS declarations.\n * Handlers replace built-in handlers for the same style name.\n * @example\n * ```ts\n * import { styleHandlers } from '@tenphi/tasty';\n *\n * configure({\n * handlers: {\n * // Override fill with custom behavior\n * fill: ({ fill }) => {\n * if (fill?.startsWith('gradient:')) {\n * return { background: fill.slice(9) };\n * }\n * return styleHandlers.fill({ fill });\n * },\n * // Add new custom style\n * elevation: ({ elevation }) => {\n * const level = parseInt(elevation) || 1;\n * return {\n * 'box-shadow': `0 ${level * 2}px ${level * 4}px rgba(0,0,0,0.1)`,\n * 'z-index': String(level * 100),\n * };\n * },\n * },\n * });\n * ```\n */\n handlers?: Record<string, StyleHandlerDefinition>;\n /**\n * Design tokens injected as CSS custom properties on `:root`.\n * Values are parsed through the Tasty DSL. Supports state maps\n * for responsive/theme-aware tokens.\n *\n * - `$name` keys become `--name` CSS custom properties\n * - `#name` keys become `--name-color` and `--name-color-{colorSpace}` properties\n *\n * Tokens are injected once when the first style is rendered.\n *\n * @example\n * ```ts\n * configure({\n * tokens: {\n * '$gap': '4px',\n * '#primary': {\n * '': '#purple',\n * '@dark': '#light-purple',\n * },\n * },\n * });\n * ```\n */\n tokens?: ConfigTokens;\n /**\n * Predefined tokens that are replaced during style parsing (parse-time substitution).\n * Use `$name` for custom properties and `#name` for color tokens.\n * Values are substituted inline before CSS generation, unlike `tokens` which\n * inject CSS custom properties on `:root`.\n *\n * For color tokens (#name), boolean `true` is converted to `transparent`.\n *\n * @example\n * ```ts\n * configure({\n * replaceTokens: {\n * $spacing: '2x',\n * '#accent': '#purple',\n * '#overlay': true, // → transparent\n * },\n * });\n *\n * // Now use in styles - tokens are replaced at parse time:\n * const Card = tasty({\n * styles: {\n * padding: '$spacing', // → calc(2 * var(--gap))\n * fill: '#accent', // → var(--purple-color)\n * },\n * });\n * ```\n */\n replaceTokens?: Record<`$${string}`, string | number | boolean> &\n Record<`#${string}`, string | number | boolean>;\n /**\n * Predefined style recipes -- named style bundles that can be applied via `recipe` style property.\n * Recipe values are flat tasty styles (no sub-element keys). They may contain base styles,\n * tokens (`$name`/`#name` definitions), local states, `@keyframes`, and `@properties`.\n *\n * Components reference recipes via: `recipe: 'name1 name2'` in their styles.\n * Use `/` to separate base recipes from post recipes: `recipe: 'base1 base2 / post1'`.\n * Use `none` to skip base recipes: `recipe: 'none / post1'`.\n * Resolution order: `base_recipes → component styles → post_recipes`.\n *\n * Recipes cannot reference other recipes.\n *\n * @example\n * ```ts\n * configure({\n * recipes: {\n * card: { padding: '4x', fill: '#surface', radius: '1r', border: true },\n * elevated: { shadow: '2x 2x 4x #shadow' },\n * },\n * });\n *\n * // Usage in styles:\n * const Card = tasty({\n * styles: {\n * recipe: 'card elevated',\n * color: '#text', // Overrides recipe values\n * },\n * });\n * ```\n */\n recipes?: Record<string, RecipeStyles>;\n}\n\n// Warnings tracking to avoid duplicates\nconst emittedWarnings = new Set<string>();\n\nconst devMode = isDevEnv();\n\n/**\n * Emit a warning only once\n */\nfunction warnOnce(key: string, message: string): void {\n if (devMode && !emittedWarnings.has(key)) {\n emittedWarnings.add(key);\n console.warn(message);\n }\n}\n\n// ============================================================================\n// Configuration State\n// ============================================================================\n\n// Track whether styles have been generated (locks configuration)\nlet stylesGenerated = false;\n\n// Current configuration (null until first configure() or auto-configured on first use)\nlet currentConfig: TastyConfig | null = null;\n\n// Global keyframes storage (null = no keyframes configured, empty object checked via hasGlobalKeyframes)\nlet globalKeyframes: Record<string, KeyframesSteps> | null = null;\n\n// Global font-face storage (null = no font faces configured)\nlet globalFontFace: Record<string, FontFaceInput> | null = null;\n\n// Global counter-style storage (null = no counter styles configured)\nlet globalCounterStyle: Record<string, CounterStyleDescriptors> | null = null;\n\n// Global properties storage (null = no properties configured)\nlet globalProperties: Record<string, PropertyDefinition> | null = null;\n\n// Global recipes storage (null = no recipes configured)\nlet globalRecipes: Record<string, RecipeStyles> | null = null;\n\n// Global token styles storage (injected as :root CSS custom properties)\nlet globalConfigTokens: ConfigTokens | null = null;\n\n// ============================================================================\n// Cross-module config sharing via globalThis\n//\n// Frameworks like Astro may load middleware and page components from\n// separate module graphs, creating duplicate module-level state.\n// Config values read by SSR collector's collectInternals() are mirrored\n// to globalThis so they're accessible regardless of which module instance\n// the collector was loaded from.\n// ============================================================================\n\nconst GTKEY_TOKENS = '__tasty_cfg_tokens__';\nconst GTKEY_FONT_FACE = '__tasty_cfg_font_face__';\nconst GTKEY_COUNTER_STYLE = '__tasty_cfg_counter_style__';\nconst GTKEY_PROPERTIES = '__tasty_cfg_properties__';\n\nfunction setOnGlobalThis(key: string, value: unknown): void {\n (globalThis as Record<string, unknown>)[key] = value;\n}\n\nfunction getFromGlobalThis<T>(key: string): T | undefined {\n return (globalThis as Record<string, unknown>)[key] as T | undefined;\n}\n\nfunction clearGlobalThisConfig(): void {\n const g = globalThis as Record<string, unknown>;\n delete g[GTKEY_TOKENS];\n delete g[GTKEY_FONT_FACE];\n delete g[GTKEY_COUNTER_STYLE];\n delete g[GTKEY_PROPERTIES];\n}\n\n/**\n * Default properties shipped with tasty.\n * These are always included unless explicitly overridden via `configure({ properties })`.\n * Keys use tasty token syntax (#name for colors, $name for other properties).\n *\n * For properties with CSS @property-compatible types (length, time, number, color),\n * an `initialValue` is provided so the property works even without a project-level token.\n */\nexport const DEFAULT_PROPERTIES: Record<string, PropertyDefinition> = {\n // Used by dual-fill feature to enable CSS transitions on the second fill color\n '#tasty-second-fill': {\n inherits: false,\n initialValue: 'transparent',\n },\n // Current color context variable (set by the color style handler).\n '#current': {\n inherits: true,\n initialValue: 'transparent',\n },\n // White and black are fundamental colors that need explicit initial values.\n '#white': {\n inherits: true,\n initialValue: 'rgb(255 255 255)',\n },\n '#black': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n // Shorthand for transparent\n '#clear': {\n inherits: true,\n initialValue: 'transparent',\n },\n // Default border color\n '#border': {\n inherits: true,\n initialValue: 'rgb(0 0 0)',\n },\n\n // ---- Core design tokens used by style handlers ----\n // These provide sensible defaults so tasty works standalone without a design system.\n // Consuming projects (e.g. uikit) override these by defining tokens on :root.\n\n $gap: {\n syntax: '<length>',\n inherits: true,\n initialValue: '4px',\n },\n $radius: {\n syntax: '<length>',\n inherits: true,\n initialValue: '6px',\n },\n '$border-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '1px',\n },\n '$outline-width': {\n syntax: '<length>',\n inherits: true,\n initialValue: '3px',\n },\n $transition: {\n syntax: '<time>',\n inherits: true,\n initialValue: '80ms',\n },\n // Used by radius.ts for `radius=\"leaf\"` modifier\n '$sharp-radius': {\n syntax: '<length>',\n inherits: true,\n initialValue: '0px',\n },\n // Used by preset.ts for `preset=\"name / strong\"`\n '$bold-font-weight': {\n syntax: '<number>',\n inherits: true,\n initialValue: '700',\n },\n // Used by preset.ts as fallback font stacks\n '$font-sans-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'system-ui, -apple-system, \"Segoe UI\", Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\", sans-serif',\n },\n '$font-mono-fallback': {\n syntax: '*',\n inherits: true,\n initialValue:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n },\n};\n\n// Global injector instance key\nconst GLOBAL_INJECTOR_KEY = '__TASTY_GLOBAL_INJECTOR__';\n\ninterface TastyGlobalStorage {\n [GLOBAL_INJECTOR_KEY]?: StyleInjector;\n}\n\ndeclare global {\n interface Window {\n [GLOBAL_INJECTOR_KEY]?: StyleInjector;\n }\n\n var __TASTY_GLOBAL_INJECTOR__: StyleInjector | undefined;\n}\n\n/**\n * Detect if we're running in a test environment\n */\nexport function isTestEnvironment(): boolean {\n // Check Node.js environment\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') {\n return true;\n }\n\n // Check for test runner globals (safely)\n if (typeof global !== 'undefined') {\n const g = global as unknown as Record<string, unknown>;\n if (g.vi || g.jest || g.expect || g.describe || g.it) {\n return true;\n }\n }\n\n // Check for jsdom environment (common in tests)\n if (\n typeof window !== 'undefined' &&\n window.navigator?.userAgent?.includes('jsdom')\n ) {\n return true;\n }\n\n // Check for other test runners\n if (typeof globalThis !== 'undefined') {\n const gt = globalThis as unknown as Record<string, unknown>;\n if (gt.vitest || gt.mocha) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Create default configuration with optional test environment detection\n */\nfunction createDefaultConfig(isTest?: boolean): TastyConfig {\n return {\n maxRulesPerSheet: 8192,\n forceTextInjection: isTest ?? false,\n devMode: isDevEnv(),\n };\n}\n\n// ============================================================================\n// stylesGenerated Flag Management\n// ============================================================================\n\n/**\n * Mark that styles have been generated (called by injector on first inject)\n * This locks the configuration - no further changes allowed.\n * Also injects internal and global properties.\n */\nexport function markStylesGenerated(): void {\n if (stylesGenerated) return; // Already marked, skip\n\n stylesGenerated = true;\n\n const injector = getGlobalInjector();\n\n // Inject all properties (defaults merged with user-configured overrides)\n for (const [token, definition] of Object.entries(getEffectiveProperties())) {\n injector.property(token, definition);\n }\n\n // Inject global @font-face rules (eagerly — fonts should be available before render)\n if (globalFontFace && Object.keys(globalFontFace).length > 0) {\n for (const [family, input] of Object.entries(globalFontFace)) {\n const descriptors = Array.isArray(input) ? input : [input];\n for (const desc of descriptors) {\n injector.fontFace(family, desc);\n }\n }\n }\n\n // Inject global @counter-style rules (eagerly)\n if (globalCounterStyle && Object.keys(globalCounterStyle).length > 0) {\n for (const [name, descriptors] of Object.entries(globalCounterStyle)) {\n injector.counterStyle(name, descriptors);\n }\n }\n\n // Inject configured tokens as :root CSS custom properties\n if (globalConfigTokens && Object.keys(globalConfigTokens).length > 0) {\n const tokenRules = renderStyles(\n globalConfigTokens,\n ':root',\n ) as StyleResult[];\n if (tokenRules.length > 0) {\n injector.injectGlobal(tokenRules);\n }\n }\n}\n\n/**\n * Check if styles have been generated (configuration is locked)\n */\nexport function hasStylesGenerated(): boolean {\n return stylesGenerated;\n}\n\n/**\n * Reset styles generated flag (for testing only)\n */\nexport function resetStylesGenerated(): void {\n stylesGenerated = false;\n emittedWarnings.clear();\n}\n\n// ============================================================================\n// Global Keyframes Management\n// ============================================================================\n\nlet _hasGlobalKeyframes = false;\n\n/**\n * Check if any global keyframes are configured.\n * Uses a pre-computed flag to avoid Object.keys() allocation on every call.\n */\nexport function hasGlobalKeyframes(): boolean {\n return _hasGlobalKeyframes;\n}\n\n/**\n * Get global keyframes configuration.\n * Returns null if no keyframes configured (fast path for zero-overhead).\n */\nexport function getGlobalKeyframes(): Record<string, KeyframesSteps> | null {\n return globalKeyframes;\n}\n\n/**\n * Set global keyframes (called from configure).\n * Internal use only.\n */\nfunction setGlobalKeyframes(keyframes: Record<string, KeyframesSteps>): void {\n if (stylesGenerated) {\n warnOnce(\n 'keyframes-after-styles',\n `[Tasty] Cannot update keyframes after styles have been generated.\\n` +\n `The new keyframes will be ignored.`,\n );\n return;\n }\n globalKeyframes = keyframes;\n _hasGlobalKeyframes = Object.keys(keyframes).length > 0;\n}\n\n// ============================================================================\n// Global Properties Management\n// ============================================================================\n\n/**\n * Check if any global properties are configured.\n * Fast path: returns false if no properties were ever set.\n */\nexport function hasGlobalProperties(): boolean {\n return globalProperties !== null && Object.keys(globalProperties).length > 0;\n}\n\n/**\n * Get global properties configuration.\n * Returns null if no properties configured (fast path for zero-overhead).\n */\nexport function getGlobalProperties(): Record<\n string,\n PropertyDefinition\n> | null {\n return globalProperties;\n}\n\n/**\n * Set global properties (called from configure).\n * Internal use only.\n */\nfunction setGlobalProperties(\n properties: Record<string, PropertyDefinition>,\n): void {\n if (stylesGenerated) {\n warnOnce(\n 'properties-after-styles',\n `[Tasty] Cannot update properties after styles have been generated.\\n` +\n `The new properties will be ignored.`,\n );\n return;\n }\n globalProperties = properties;\n setOnGlobalThis(GTKEY_PROPERTIES, globalProperties);\n}\n\n/**\n * Get the effective properties: DEFAULT_PROPERTIES merged with user-configured\n * properties. User properties override defaults with matching keys.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getEffectiveProperties(): Record<string, PropertyDefinition> {\n const props =\n globalProperties ??\n getFromGlobalThis<Record<string, PropertyDefinition>>(GTKEY_PROPERTIES);\n if (!props) return DEFAULT_PROPERTIES;\n return { ...DEFAULT_PROPERTIES, ...props };\n}\n\n// ============================================================================\n// Global Font Face Management\n// ============================================================================\n\n/**\n * Get global font-face configuration.\n * Returns null if no font faces configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalFontFace(): Record<string, FontFaceInput> | null {\n return (\n globalFontFace ??\n getFromGlobalThis<Record<string, FontFaceInput>>(GTKEY_FONT_FACE) ??\n null\n );\n}\n\n/**\n * Set global font faces (called from configure).\n * Internal use only.\n */\nfunction setGlobalFontFace(fontFace: Record<string, FontFaceInput>): void {\n if (stylesGenerated) {\n warnOnce(\n 'fontface-after-styles',\n `[Tasty] Cannot update fontFace after styles have been generated.\\n` +\n `The new font faces will be ignored.`,\n );\n return;\n }\n globalFontFace = fontFace;\n setOnGlobalThis(GTKEY_FONT_FACE, globalFontFace);\n}\n\n// ============================================================================\n// Global Counter Style Management\n// ============================================================================\n\n/**\n * Get global counter-style configuration.\n * Returns null if no counter styles configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalCounterStyle(): Record<\n string,\n CounterStyleDescriptors\n> | null {\n return (\n globalCounterStyle ??\n getFromGlobalThis<Record<string, CounterStyleDescriptors>>(\n GTKEY_COUNTER_STYLE,\n ) ??\n null\n );\n}\n\n/**\n * Set global counter styles (called from configure).\n * Internal use only.\n */\nfunction setGlobalCounterStyle(\n counterStyle: Record<string, CounterStyleDescriptors>,\n): void {\n if (stylesGenerated) {\n warnOnce(\n 'counterstyle-after-styles',\n `[Tasty] Cannot update counterStyle after styles have been generated.\\n` +\n `The new counter styles will be ignored.`,\n );\n return;\n }\n globalCounterStyle = counterStyle;\n setOnGlobalThis(GTKEY_COUNTER_STYLE, globalCounterStyle);\n}\n\n// ============================================================================\n// Global Recipes Management\n// ============================================================================\n\n/**\n * Check if any global recipes are configured.\n * Fast path: returns false if no recipes were ever set.\n */\nexport function hasGlobalRecipes(): boolean {\n return globalRecipes !== null && Object.keys(globalRecipes).length > 0;\n}\n\n/**\n * Get global recipes configuration.\n * Returns null if no recipes configured (fast path for zero-overhead).\n */\nexport function getGlobalRecipes(): Record<string, RecipeStyles> | null {\n return globalRecipes;\n}\n\n/**\n * Set global recipes (called from configure).\n * Internal use only.\n */\nfunction setGlobalRecipes(recipes: Record<string, RecipeStyles>): void {\n if (stylesGenerated) {\n warnOnce(\n 'recipes-after-styles',\n `[Tasty] Cannot update recipes after styles have been generated.\\n` +\n `The new recipes will be ignored.`,\n );\n return;\n }\n\n // Dev-mode validation\n if (devMode) {\n for (const [name, recipeStyles] of Object.entries(recipes)) {\n if (name === 'none') {\n warnOnce(\n 'recipe-reserved-none',\n `[Tasty] Recipe name \"none\" is reserved. ` +\n `It is used as a keyword meaning \"no base recipes\" ` +\n `(e.g. recipe: 'none / post-recipe'). ` +\n `Choose a different name for your recipe.`,\n );\n }\n\n for (const key of Object.keys(recipeStyles)) {\n if (isSelector(key)) {\n warnOnce(\n `recipe-selector-${name}-${key}`,\n `[Tasty] Recipe \"${name}\" contains sub-element key \"${key}\". ` +\n `Recipes must be flat styles without sub-element keys. ` +\n `Remove the sub-element key from the recipe definition.`,\n );\n }\n if (key === 'recipe') {\n warnOnce(\n `recipe-recursive-${name}`,\n `[Tasty] Recipe \"${name}\" contains a \"recipe\" key. ` +\n `Recipes cannot reference other recipes. ` +\n `Use space-separated names for composition: recipe: 'base elevated'.`,\n );\n }\n }\n }\n }\n\n globalRecipes = recipes;\n}\n\n// ============================================================================\n// Global Token Styles Management\n// ============================================================================\n\n/**\n * Get global token styles for :root injection.\n * Returns null if no tokens configured.\n * Reads from globalThis first for cross-module SSR support.\n */\nexport function getGlobalConfigTokens(): ConfigTokens | null {\n return (\n globalConfigTokens ?? getFromGlobalThis<ConfigTokens>(GTKEY_TOKENS) ?? null\n );\n}\n\n/**\n * Set global token styles (called from configure).\n * Internal use only.\n */\nfunction setGlobalConfigTokens(styles: ConfigTokens): void {\n if (stylesGenerated) {\n warnOnce(\n 'tokens-after-styles',\n `[Tasty] Cannot update tokens after styles have been generated.\\n` +\n `The new tokens will be ignored.`,\n );\n return;\n }\n globalConfigTokens = globalConfigTokens\n ? { ...globalConfigTokens, ...styles }\n : styles;\n setOnGlobalThis(GTKEY_TOKENS, globalConfigTokens);\n}\n\n/**\n * Check if configuration is locked (styles have been generated)\n */\nexport function isConfigLocked(): boolean {\n return stylesGenerated;\n}\n\n// ============================================================================\n// Configuration API\n// ============================================================================\n\n/**\n * Configure the Tasty style system.\n *\n * Must be called BEFORE any styles are generated (before first render that uses tasty).\n * After styles are generated, configuration is locked and calls to configure() will\n * emit a warning and be ignored.\n *\n * @example\n * ```ts\n * import { configure } from '@tenphi/tasty';\n *\n * // Configure before app renders\n * configure({\n * nonce: 'abc123',\n * states: {\n * '@mobile': '@media(w < 768px)',\n * '@dark': '@root(theme=dark)',\n * },\n * });\n * ```\n */\nexport function configure(config: Partial<TastyConfig> = {}): void {\n if (stylesGenerated) {\n warnOnce(\n 'configure-after-styles',\n `[Tasty] Cannot call configure() after styles have been generated.\\n` +\n `Configuration must be done before the first render. The configuration will be ignored.`,\n );\n return;\n }\n\n // Collect merged values from plugins first, then override with direct config\n let mergedStates: Record<string, string> = {};\n let mergedUnits: Record<string, string | UnitHandler> = {};\n let mergedFuncs: Record<string, (groups: StyleDetails[]) => string> = {};\n let mergedHandlers: Record<string, StyleHandlerDefinition> = {};\n let mergedReplaceTokens: Record<string, string | number | boolean> = {};\n let mergedConfigTokens: ConfigTokens = {} as ConfigTokens;\n let mergedRecipes: Record<string, RecipeStyles> = {};\n\n // Process plugins in order\n if (config.plugins) {\n for (const plugin of config.plugins) {\n if (plugin.states) {\n mergedStates = { ...mergedStates, ...plugin.states };\n }\n if (plugin.units) {\n mergedUnits = { ...mergedUnits, ...plugin.units };\n }\n if (plugin.funcs) {\n mergedFuncs = { ...mergedFuncs, ...plugin.funcs };\n }\n if (plugin.handlers) {\n mergedHandlers = { ...mergedHandlers, ...plugin.handlers };\n }\n if (plugin.replaceTokens) {\n mergedReplaceTokens = {\n ...mergedReplaceTokens,\n ...plugin.replaceTokens,\n };\n }\n if (plugin.tokens) {\n mergedConfigTokens = { ...mergedConfigTokens, ...plugin.tokens };\n }\n if (plugin.recipes) {\n mergedRecipes = { ...mergedRecipes, ...plugin.recipes };\n }\n }\n }\n\n // Direct config overrides plugins\n if (config.states) {\n mergedStates = { ...mergedStates, ...config.states };\n }\n if (config.units) {\n mergedUnits = { ...mergedUnits, ...config.units };\n }\n if (config.funcs) {\n mergedFuncs = { ...mergedFuncs, ...config.funcs };\n }\n if (config.handlers) {\n mergedHandlers = { ...mergedHandlers, ...config.handlers };\n }\n if (config.replaceTokens) {\n mergedReplaceTokens = { ...mergedReplaceTokens, ...config.replaceTokens };\n }\n if (config.tokens) {\n mergedConfigTokens = { ...mergedConfigTokens, ...config.tokens };\n }\n if (config.recipes) {\n mergedRecipes = { ...mergedRecipes, ...config.recipes };\n }\n\n // Warn on tokens/replaceTokens key conflicts\n if (devMode) {\n const tokenKeys = new Set(Object.keys(mergedConfigTokens));\n for (const key of Object.keys(mergedReplaceTokens)) {\n if (tokenKeys.has(key)) {\n warnOnce(\n `token-conflict-${key}`,\n `[Tasty] Token \"${key}\" is defined in both \\`tokens\\` and \\`replaceTokens\\`. ` +\n `\\`replaceTokens\\` performs parse-time substitution, so the \\`tokens\\` ` +\n `CSS custom property will be injected but never used by Tasty styles. ` +\n `Remove it from one of the two.`,\n );\n }\n }\n }\n\n // Handle color space (must be set before any token processing)\n if (config.colorSpace) {\n setColorSpace(config.colorSpace);\n // Color space affects parser output (e.g. #name.5 → oklch(...) vs rgb(...))\n getGlobalParser().clearCache();\n }\n\n // Handle predefined states\n if (Object.keys(mergedStates).length > 0) {\n setGlobalPredefinedStates(mergedStates);\n }\n\n // Handle parser configuration (merge semantics - extend, not replace)\n const parser = getGlobalParser();\n\n if (config.parserCacheSize !== undefined) {\n parser.updateOptions({ cacheSize: config.parserCacheSize });\n }\n\n if (Object.keys(mergedUnits).length > 0) {\n // Merge with existing units\n const currentUnits = parser.getUnits() ?? CUSTOM_UNITS;\n parser.setUnits({ ...currentUnits, ...mergedUnits });\n }\n\n if (Object.keys(mergedFuncs).length > 0) {\n // Merge with existing funcs\n const currentFuncs = getGlobalFuncs();\n const finalFuncs = { ...currentFuncs, ...mergedFuncs };\n parser.setFuncs(finalFuncs);\n // Also update the global registry so customFunc() continues to work\n Object.assign(currentFuncs, mergedFuncs);\n }\n\n // Handle keyframes\n if (config.keyframes) {\n setGlobalKeyframes(config.keyframes);\n }\n\n // Handle properties\n if (config.properties) {\n setGlobalProperties(config.properties);\n }\n\n // Handle font faces\n if (config.fontFace) {\n setGlobalFontFace(config.fontFace);\n }\n\n // Handle counter styles\n if (config.counterStyle) {\n setGlobalCounterStyle(config.counterStyle);\n }\n\n // Handle custom handlers\n if (Object.keys(mergedHandlers).length > 0) {\n for (const [name, definition] of Object.entries(mergedHandlers)) {\n const handler = normalizeHandlerDefinition(name, definition);\n registerHandler(handler);\n }\n }\n\n // Handle replaceTokens (parse-time substitution)\n if (Object.keys(mergedReplaceTokens).length > 0) {\n const processedTokens: Record<string, string> = {};\n for (const [key, value] of Object.entries(mergedReplaceTokens)) {\n if (key.startsWith('#')) {\n const normalized = normalizeColorTokenValue(value);\n if (normalized === null) continue;\n processedTokens[key] = String(normalized);\n } else if (value === false) {\n continue;\n } else {\n processedTokens[key] = String(value);\n }\n }\n setGlobalPredefinedTokens(processedTokens);\n }\n\n // Handle tokens (CSS custom properties on :root)\n if (Object.keys(mergedConfigTokens).length > 0) {\n setGlobalConfigTokens(mergedConfigTokens);\n }\n\n // Handle recipes\n if (Object.keys(mergedRecipes).length > 0) {\n setGlobalRecipes(mergedRecipes);\n }\n\n const {\n states: _states,\n parserCacheSize: _parserCacheSize,\n units: _units,\n funcs: _funcs,\n plugins: _plugins,\n keyframes: _keyframes,\n properties: _properties,\n fontFace: _fontFace,\n counterStyle: _counterStyle,\n handlers: _handlers,\n tokens: _tokens,\n replaceTokens: _replaceTokens,\n recipes: _recipes,\n colorSpace: _colorSpace,\n ...injectorConfig\n } = config;\n\n const fullConfig: TastyConfig = {\n ...createDefaultConfig(),\n ...currentConfig,\n ...injectorConfig,\n };\n\n // Store the config\n currentConfig = fullConfig;\n\n // Create/replace the global injector\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n storage[GLOBAL_INJECTOR_KEY] = new StyleInjector(fullConfig);\n}\n\n/**\n * Get the current configuration.\n * If not configured, returns default configuration.\n */\nexport function getConfig(): TastyConfig {\n if (!currentConfig) {\n currentConfig = createDefaultConfig(isTestEnvironment());\n }\n return currentConfig;\n}\n\n/**\n * Get the global injector instance.\n * Auto-configures with defaults if not already configured.\n */\nexport function getGlobalInjector(): StyleInjector {\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n\n if (!storage[GLOBAL_INJECTOR_KEY]) {\n configure();\n }\n\n return storage[GLOBAL_INJECTOR_KEY]!;\n}\n\n/**\n * Reset configuration (for testing only).\n * Clears the global injector and allows reconfiguration.\n */\nexport function resetConfig(): void {\n stylesGenerated = false;\n currentConfig = null;\n globalKeyframes = null;\n _hasGlobalKeyframes = false;\n globalProperties = null;\n globalFontFace = null;\n globalCounterStyle = null;\n globalRecipes = null;\n globalConfigTokens = null;\n clearGlobalThisConfig();\n resetGlobalPredefinedTokens();\n resetHandlers();\n resetColorSpace();\n clearPipelineCache();\n emittedWarnings.clear();\n\n const storage: TastyGlobalStorage =\n typeof window !== 'undefined' ? window : globalThis;\n delete storage[GLOBAL_INJECTOR_KEY];\n}\n\n// Re-export TastyConfig as StyleInjectorConfig for backward compatibility\nexport type { TastyConfig as StyleInjectorConfig };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoUA,MAAM,kCAAkB,IAAI,KAAa;AAEzC,MAAM,UAAU,UAAU;;;;AAK1B,SAAS,SAAS,KAAa,SAAuB;AACpD,KAAI,WAAW,CAAC,gBAAgB,IAAI,IAAI,EAAE;AACxC,kBAAgB,IAAI,IAAI;AACxB,UAAQ,KAAK,QAAQ;;;AASzB,IAAI,kBAAkB;AAGtB,IAAI,gBAAoC;AAGxC,IAAI,kBAAyD;AAG7D,IAAI,iBAAuD;AAG3D,IAAI,qBAAqE;AAGzE,IAAI,mBAA8D;AAGlE,IAAI,gBAAqD;AAGzD,IAAI,qBAA0C;AAY9C,MAAM,eAAe;AACrB,MAAM,kBAAkB;AACxB,MAAM,sBAAsB;AAC5B,MAAM,mBAAmB;AAEzB,SAAS,gBAAgB,KAAa,OAAsB;AACzD,YAAuC,OAAO;;AAGjD,SAAS,kBAAqB,KAA4B;AACxD,QAAQ,WAAuC;;AAGjD,SAAS,wBAA8B;CACrC,MAAM,IAAI;AACV,QAAO,EAAE;AACT,QAAO,EAAE;AACT,QAAO,EAAE;AACT,QAAO,EAAE;;;;;;;;;;AAWX,MAAa,qBAAyD;CAEpE,sBAAsB;EACpB,UAAU;EACV,cAAc;EACf;CAED,YAAY;EACV,UAAU;EACV,cAAc;EACf;CAED,UAAU;EACR,UAAU;EACV,cAAc;EACf;CACD,UAAU;EACR,UAAU;EACV,cAAc;EACf;CAED,UAAU;EACR,UAAU;EACV,cAAc;EACf;CAED,WAAW;EACT,UAAU;EACV,cAAc;EACf;CAMD,MAAM;EACJ,QAAQ;EACR,UAAU;EACV,cAAc;EACf;CACD,SAAS;EACP,QAAQ;EACR,UAAU;EACV,cAAc;EACf;CACD,iBAAiB;EACf,QAAQ;EACR,UAAU;EACV,cAAc;EACf;CACD,kBAAkB;EAChB,QAAQ;EACR,UAAU;EACV,cAAc;EACf;CACD,aAAa;EACX,QAAQ;EACR,UAAU;EACV,cAAc;EACf;CAED,iBAAiB;EACf,QAAQ;EACR,UAAU;EACV,cAAc;EACf;CAED,qBAAqB;EACnB,QAAQ;EACR,UAAU;EACV,cAAc;EACf;CAED,uBAAuB;EACrB,QAAQ;EACR,UAAU;EACV,cACE;EACH;CACD,uBAAuB;EACrB,QAAQ;EACR,UAAU;EACV,cACE;EACH;CACF;AAGD,MAAM,sBAAsB;;;;AAiB5B,SAAgB,oBAA6B;AAO3C,KAAI,OAAO,WAAW,aAAa;EACjC,MAAM,IAAI;AACV,MAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,GAChD,QAAO;;AAKX,KACE,OAAO,WAAW,eAClB,OAAO,WAAW,WAAW,SAAS,QAAQ,CAE9C,QAAO;AAIT,KAAI,OAAO,eAAe,aAAa;EACrC,MAAM,KAAK;AACX,MAAI,GAAG,UAAU,GAAG,MAClB,QAAO;;AAIX,QAAO;;;;;AAMT,SAAS,oBAAoB,QAA+B;AAC1D,QAAO;EACL,kBAAkB;EAClB,oBAAoB,UAAU;EAC9B,SAAS,UAAU;EACpB;;;;;;;AAYH,SAAgB,sBAA4B;AAC1C,KAAI,gBAAiB;AAErB,mBAAkB;CAElB,MAAM,WAAW,mBAAmB;AAGpC,MAAK,MAAM,CAAC,OAAO,eAAe,OAAO,QAAQ,wBAAwB,CAAC,CACxE,UAAS,SAAS,OAAO,WAAW;AAItC,KAAI,kBAAkB,OAAO,KAAK,eAAe,CAAC,SAAS,EACzD,MAAK,MAAM,CAAC,QAAQ,UAAU,OAAO,QAAQ,eAAe,EAAE;EAC5D,MAAM,cAAc,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,MAAM;AAC1D,OAAK,MAAM,QAAQ,YACjB,UAAS,SAAS,QAAQ,KAAK;;AAMrC,KAAI,sBAAsB,OAAO,KAAK,mBAAmB,CAAC,SAAS,EACjE,MAAK,MAAM,CAAC,MAAM,gBAAgB,OAAO,QAAQ,mBAAmB,CAClE,UAAS,aAAa,MAAM,YAAY;AAK5C,KAAI,sBAAsB,OAAO,KAAK,mBAAmB,CAAC,SAAS,GAAG;EACpE,MAAM,aAAa,aACjB,oBACA,QACD;AACD,MAAI,WAAW,SAAS,EACtB,UAAS,aAAa,WAAW;;;;;;AAQvC,SAAgB,qBAA8B;AAC5C,QAAO;;AAeT,IAAI,sBAAsB;;;;;AAM1B,SAAgB,qBAA8B;AAC5C,QAAO;;;;;;AAOT,SAAgB,qBAA4D;AAC1E,QAAO;;;;;;AAOT,SAAS,mBAAmB,WAAiD;AAC3E,KAAI,iBAAiB;AACnB,WACE,0BACA,wGAED;AACD;;AAEF,mBAAkB;AAClB,uBAAsB,OAAO,KAAK,UAAU,CAAC,SAAS;;;;;;AA8BxD,SAAS,oBACP,YACM;AACN,KAAI,iBAAiB;AACnB,WACE,2BACA,0GAED;AACD;;AAEF,oBAAmB;AACnB,iBAAgB,kBAAkB,iBAAiB;;;;;;;AAQrD,SAAgB,yBAA6D;CAC3E,MAAM,QACJ,oBACA,kBAAsD,iBAAiB;AACzE,KAAI,CAAC,MAAO,QAAO;AACnB,QAAO;EAAE,GAAG;EAAoB,GAAG;EAAO;;;;;;;AAY5C,SAAgB,oBAA0D;AACxE,QACE,kBACA,kBAAiD,gBAAgB,IACjE;;;;;;AAQJ,SAAS,kBAAkB,UAA+C;AACxE,KAAI,iBAAiB;AACnB,WACE,yBACA,wGAED;AACD;;AAEF,kBAAiB;AACjB,iBAAgB,iBAAiB,eAAe;;;;;;;AAYlD,SAAgB,wBAGP;AACP,QACE,sBACA,kBACE,oBACD,IACD;;;;;;AAQJ,SAAS,sBACP,cACM;AACN,KAAI,iBAAiB;AACnB,WACE,6BACA,gHAED;AACD;;AAEF,sBAAqB;AACrB,iBAAgB,qBAAqB,mBAAmB;;;;;;AAW1D,SAAgB,mBAA4B;AAC1C,QAAO,kBAAkB,QAAQ,OAAO,KAAK,cAAc,CAAC,SAAS;;;;;;AAOvE,SAAgB,mBAAwD;AACtE,QAAO;;;;;;AAOT,SAAS,iBAAiB,SAA6C;AACrE,KAAI,iBAAiB;AACnB,WACE,wBACA,oGAED;AACD;;AAIF,KAAI,QACF,MAAK,MAAM,CAAC,MAAM,iBAAiB,OAAO,QAAQ,QAAQ,EAAE;AAC1D,MAAI,SAAS,OACX,UACE,wBACA,8KAID;AAGH,OAAK,MAAM,OAAO,OAAO,KAAK,aAAa,EAAE;AAC3C,OAAI,WAAW,IAAI,CACjB,UACE,mBAAmB,KAAK,GAAG,OAC3B,mBAAmB,KAAK,8BAA8B,IAAI,iHAG3D;AAEH,OAAI,QAAQ,SACV,UACE,oBAAoB,QACpB,mBAAmB,KAAK,wIAGzB;;;AAMT,iBAAgB;;;;;;;AAYlB,SAAgB,wBAA6C;AAC3D,QACE,sBAAsB,kBAAgC,aAAa,IAAI;;;;;;AAQ3E,SAAS,sBAAsB,QAA4B;AACzD,KAAI,iBAAiB;AACnB,WACE,uBACA,kGAED;AACD;;AAEF,sBAAqB,qBACjB;EAAE,GAAG;EAAoB,GAAG;EAAQ,GACpC;AACJ,iBAAgB,cAAc,mBAAmB;;;;;AAMnD,SAAgB,iBAA0B;AACxC,QAAO;;;;;;;;;;;;;;;;;;;;;;;AA4BT,SAAgB,UAAU,SAA+B,EAAE,EAAQ;AACjE,KAAI,iBAAiB;AACnB,WACE,0BACA,4JAED;AACD;;CAIF,IAAI,eAAuC,EAAE;CAC7C,IAAI,cAAoD,EAAE;CAC1D,IAAI,cAAkE,EAAE;CACxE,IAAI,iBAAyD,EAAE;CAC/D,IAAI,sBAAiE,EAAE;CACvE,IAAI,qBAAmC,EAAE;CACzC,IAAI,gBAA8C,EAAE;AAGpD,KAAI,OAAO,QACT,MAAK,MAAM,UAAU,OAAO,SAAS;AACnC,MAAI,OAAO,OACT,gBAAe;GAAE,GAAG;GAAc,GAAG,OAAO;GAAQ;AAEtD,MAAI,OAAO,MACT,eAAc;GAAE,GAAG;GAAa,GAAG,OAAO;GAAO;AAEnD,MAAI,OAAO,MACT,eAAc;GAAE,GAAG;GAAa,GAAG,OAAO;GAAO;AAEnD,MAAI,OAAO,SACT,kBAAiB;GAAE,GAAG;GAAgB,GAAG,OAAO;GAAU;AAE5D,MAAI,OAAO,cACT,uBAAsB;GACpB,GAAG;GACH,GAAG,OAAO;GACX;AAEH,MAAI,OAAO,OACT,sBAAqB;GAAE,GAAG;GAAoB,GAAG,OAAO;GAAQ;AAElE,MAAI,OAAO,QACT,iBAAgB;GAAE,GAAG;GAAe,GAAG,OAAO;GAAS;;AAM7D,KAAI,OAAO,OACT,gBAAe;EAAE,GAAG;EAAc,GAAG,OAAO;EAAQ;AAEtD,KAAI,OAAO,MACT,eAAc;EAAE,GAAG;EAAa,GAAG,OAAO;EAAO;AAEnD,KAAI,OAAO,MACT,eAAc;EAAE,GAAG;EAAa,GAAG,OAAO;EAAO;AAEnD,KAAI,OAAO,SACT,kBAAiB;EAAE,GAAG;EAAgB,GAAG,OAAO;EAAU;AAE5D,KAAI,OAAO,cACT,uBAAsB;EAAE,GAAG;EAAqB,GAAG,OAAO;EAAe;AAE3E,KAAI,OAAO,OACT,sBAAqB;EAAE,GAAG;EAAoB,GAAG,OAAO;EAAQ;AAElE,KAAI,OAAO,QACT,iBAAgB;EAAE,GAAG;EAAe,GAAG,OAAO;EAAS;AAIzD,KAAI,SAAS;EACX,MAAM,YAAY,IAAI,IAAI,OAAO,KAAK,mBAAmB,CAAC;AAC1D,OAAK,MAAM,OAAO,OAAO,KAAK,oBAAoB,CAChD,KAAI,UAAU,IAAI,IAAI,CACpB,UACE,kBAAkB,OAClB,kBAAkB,IAAI,kOAIvB;;AAMP,KAAI,OAAO,YAAY;AACrB,gBAAc,OAAO,WAAW;AAEhC,mBAAiB,CAAC,YAAY;;AAIhC,KAAI,OAAO,KAAK,aAAa,CAAC,SAAS,EACrC,2BAA0B,aAAa;CAIzC,MAAM,SAAS,iBAAiB;AAEhC,KAAI,OAAO,oBAAoB,KAAA,EAC7B,QAAO,cAAc,EAAE,WAAW,OAAO,iBAAiB,CAAC;AAG7D,KAAI,OAAO,KAAK,YAAY,CAAC,SAAS,GAAG;EAEvC,MAAM,eAAe,OAAO,UAAU,IAAI;AAC1C,SAAO,SAAS;GAAE,GAAG;GAAc,GAAG;GAAa,CAAC;;AAGtD,KAAI,OAAO,KAAK,YAAY,CAAC,SAAS,GAAG;EAEvC,MAAM,eAAe,gBAAgB;EACrC,MAAM,aAAa;GAAE,GAAG;GAAc,GAAG;GAAa;AACtD,SAAO,SAAS,WAAW;AAE3B,SAAO,OAAO,cAAc,YAAY;;AAI1C,KAAI,OAAO,UACT,oBAAmB,OAAO,UAAU;AAItC,KAAI,OAAO,WACT,qBAAoB,OAAO,WAAW;AAIxC,KAAI,OAAO,SACT,mBAAkB,OAAO,SAAS;AAIpC,KAAI,OAAO,aACT,uBAAsB,OAAO,aAAa;AAI5C,KAAI,OAAO,KAAK,eAAe,CAAC,SAAS,EACvC,MAAK,MAAM,CAAC,MAAM,eAAe,OAAO,QAAQ,eAAe,CAE7D,iBADgB,2BAA2B,MAAM,WAAW,CACpC;AAK5B,KAAI,OAAO,KAAK,oBAAoB,CAAC,SAAS,GAAG;EAC/C,MAAM,kBAA0C,EAAE;AAClD,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,oBAAoB,CAC5D,KAAI,IAAI,WAAW,IAAI,EAAE;GACvB,MAAM,aAAa,yBAAyB,MAAM;AAClD,OAAI,eAAe,KAAM;AACzB,mBAAgB,OAAO,OAAO,WAAW;aAChC,UAAU,MACnB;MAEA,iBAAgB,OAAO,OAAO,MAAM;AAGxC,4BAA0B,gBAAgB;;AAI5C,KAAI,OAAO,KAAK,mBAAmB,CAAC,SAAS,EAC3C,uBAAsB,mBAAmB;AAI3C,KAAI,OAAO,KAAK,cAAc,CAAC,SAAS,EACtC,kBAAiB,cAAc;CAGjC,MAAM,EACJ,QAAQ,SACR,iBAAiB,kBACjB,OAAO,QACP,OAAO,QACP,SAAS,UACT,WAAW,YACX,YAAY,aACZ,UAAU,WACV,cAAc,eACd,UAAU,WACV,QAAQ,SACR,eAAe,gBACf,SAAS,UACT,YAAY,aACZ,GAAG,mBACD;CAEJ,MAAM,aAA0B;EAC9B,GAAG,qBAAqB;EACxB,GAAG;EACH,GAAG;EACJ;AAGD,iBAAgB;CAGhB,MAAM,UACJ,OAAO,WAAW,cAAc,SAAS;AAC3C,SAAQ,uBAAuB,IAAI,cAAc,WAAW;;;;;;AAO9D,SAAgB,YAAyB;AACvC,KAAI,CAAC,cACH,iBAAgB,oBAAoB,mBAAmB,CAAC;AAE1D,QAAO;;;;;;AAOT,SAAgB,oBAAmC;CACjD,MAAM,UACJ,OAAO,WAAW,cAAc,SAAS;AAE3C,KAAI,CAAC,QAAQ,qBACX,YAAW;AAGb,QAAO,QAAQ;;;;;;AAOjB,SAAgB,cAAoB;AAClC,mBAAkB;AAClB,iBAAgB;AAChB,mBAAkB;AAClB,uBAAsB;AACtB,oBAAmB;AACnB,kBAAiB;AACjB,sBAAqB;AACrB,iBAAgB;AAChB,sBAAqB;AACrB,wBAAuB;AACvB,8BAA6B;AAC7B,gBAAe;AACf,kBAAiB;AACjB,qBAAoB;AACpB,iBAAgB,OAAO;CAEvB,MAAM,UACJ,OAAO,WAAW,cAAc,SAAS;AAC3C,QAAO,QAAQ"}
|
|
@@ -15,11 +15,11 @@ interface UseStylesResult {
|
|
|
15
15
|
className: string;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
* Thin
|
|
18
|
+
* Hook to generate CSS classes from Tasty styles.
|
|
19
|
+
* Thin wrapper around `computeStyles()` that adds React context-based
|
|
20
|
+
* SSR collector discovery for backward compatibility with TastyRegistry.
|
|
20
21
|
*
|
|
21
|
-
*
|
|
22
|
-
* from both client components and React Server Components.
|
|
22
|
+
* For hook-free usage (e.g. in server components), use `computeStyles()` directly.
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
25
25
|
* ```tsx
|
package/dist/hooks/useStyles.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { computeStyles } from "../compute-styles.js";
|
|
2
|
+
import { TastySSRContext } from "../ssr/context.js";
|
|
3
|
+
import { useContext } from "react";
|
|
2
4
|
//#region src/hooks/useStyles.ts
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Thin
|
|
6
|
+
* Hook to generate CSS classes from Tasty styles.
|
|
7
|
+
* Thin wrapper around `computeStyles()` that adds React context-based
|
|
8
|
+
* SSR collector discovery for backward compatibility with TastyRegistry.
|
|
6
9
|
*
|
|
7
|
-
*
|
|
8
|
-
* from both client components and React Server Components.
|
|
10
|
+
* For hook-free usage (e.g. in server components), use `computeStyles()` directly.
|
|
9
11
|
*
|
|
10
12
|
* @example
|
|
11
13
|
* ```tsx
|
|
@@ -21,7 +23,7 @@ import { computeStyles } from "../compute-styles.js";
|
|
|
21
23
|
* ```
|
|
22
24
|
*/
|
|
23
25
|
function useStyles(styles) {
|
|
24
|
-
return computeStyles(styles);
|
|
26
|
+
return computeStyles(styles, { ssrCollector: useContext(TastySSRContext) });
|
|
25
27
|
}
|
|
26
28
|
//#endregion
|
|
27
29
|
export { useStyles };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useStyles.js","names":[],"sources":["../../src/hooks/useStyles.ts"],"sourcesContent":["import { computeStyles } from '../compute-styles';\nimport type { Styles } from '../styles/types';\n\n/**\n * Tasty styles object to generate CSS classes for.\n * Can be undefined or empty object for no styles.\n */\nexport type UseStylesOptions = Styles | undefined;\n\nexport interface UseStylesResult {\n /**\n * Generated className(s) to apply to the element.\n * Can be empty string if no styles are provided.\n * With chunking enabled, may contain multiple space-separated class names.\n */\n className: string;\n}\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"useStyles.js","names":[],"sources":["../../src/hooks/useStyles.ts"],"sourcesContent":["import { useContext } from 'react';\n\nimport { computeStyles } from '../compute-styles';\nimport { TastySSRContext } from '../ssr/context';\nimport type { Styles } from '../styles/types';\n\n/**\n * Tasty styles object to generate CSS classes for.\n * Can be undefined or empty object for no styles.\n */\nexport type UseStylesOptions = Styles | undefined;\n\nexport interface UseStylesResult {\n /**\n * Generated className(s) to apply to the element.\n * Can be empty string if no styles are provided.\n * With chunking enabled, may contain multiple space-separated class names.\n */\n className: string;\n}\n\n/**\n * Hook to generate CSS classes from Tasty styles.\n * Thin wrapper around `computeStyles()` that adds React context-based\n * SSR collector discovery for backward compatibility with TastyRegistry.\n *\n * For hook-free usage (e.g. in server components), use `computeStyles()` directly.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { className } = useStyles({\n * padding: '2x',\n * fill: '#purple',\n * radius: '1r',\n * });\n *\n * return <div className={className}>Styled content</div>;\n * }\n * ```\n */\nexport function useStyles(styles: UseStylesOptions): UseStylesResult {\n return computeStyles(styles, { ssrCollector: useContext(TastySSRContext) });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,UAAU,QAA2C;AACnE,QAAO,cAAc,QAAQ,EAAE,cAAc,WAAW,gBAAgB,EAAE,CAAC"}
|
package/dist/ssr/astro.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getConfig } from "../config.js";
|
|
2
|
-
import {
|
|
2
|
+
import { registerSSRCollectorGetterGlobal } from "./ssr-collector-ref.js";
|
|
3
3
|
import { ServerStyleCollector } from "./collector.js";
|
|
4
4
|
import { getSSRCollector, runWithCollector } from "./async-storage.js";
|
|
5
5
|
//#region src/ssr/astro.ts
|
|
@@ -12,7 +12,7 @@ import { getSSRCollector, runWithCollector } from "./async-storage.js";
|
|
|
12
12
|
*
|
|
13
13
|
* Import from '@tenphi/tasty/ssr/astro'.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
registerSSRCollectorGetterGlobal(getSSRCollector);
|
|
16
16
|
/**
|
|
17
17
|
* Create an Astro middleware that collects Tasty styles during SSR.
|
|
18
18
|
*
|
|
@@ -43,21 +43,36 @@ function tastyMiddleware(options) {
|
|
|
43
43
|
return async (_context, next) => {
|
|
44
44
|
const transferCache = options?.transferCache ?? true;
|
|
45
45
|
const collector = new ServerStyleCollector();
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
46
|
+
const rendered = await runWithCollector(collector, async () => {
|
|
47
|
+
const response = await next();
|
|
48
|
+
const body = response.body;
|
|
49
|
+
if (!body) return {
|
|
50
|
+
html: null,
|
|
51
|
+
status: response.status,
|
|
52
|
+
headers: response.headers
|
|
53
|
+
};
|
|
54
|
+
const reader = body.pipeThrough(new TextDecoderStream()).getReader();
|
|
55
|
+
const parts = [];
|
|
56
|
+
for (;;) {
|
|
57
|
+
const { done, value } = await reader.read();
|
|
58
|
+
if (done) break;
|
|
59
|
+
parts.push(value);
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
html: parts.join(""),
|
|
63
|
+
status: response.status,
|
|
64
|
+
headers: response.headers
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
if (!rendered.html) return new Response(null, {
|
|
68
|
+
status: rendered.status,
|
|
69
|
+
headers: rendered.headers
|
|
70
|
+
});
|
|
71
|
+
let { html } = rendered;
|
|
57
72
|
const css = collector.getCSS();
|
|
58
73
|
if (!css) return new Response(html, {
|
|
59
|
-
status:
|
|
60
|
-
headers:
|
|
74
|
+
status: rendered.status,
|
|
75
|
+
headers: rendered.headers
|
|
61
76
|
});
|
|
62
77
|
const nonce = getConfig().nonce;
|
|
63
78
|
const nonceAttr = nonce ? ` nonce="${nonce}"` : "";
|
|
@@ -71,10 +86,10 @@ function tastyMiddleware(options) {
|
|
|
71
86
|
const idx = html.indexOf("</head>");
|
|
72
87
|
if (idx !== -1) html = html.slice(0, idx) + injection + html.slice(idx);
|
|
73
88
|
else html = injection + html;
|
|
74
|
-
const headers = new Headers(
|
|
89
|
+
const headers = new Headers(rendered.headers);
|
|
75
90
|
headers.delete("content-length");
|
|
76
91
|
return new Response(html, {
|
|
77
|
-
status:
|
|
92
|
+
status: rendered.status,
|
|
78
93
|
headers
|
|
79
94
|
});
|
|
80
95
|
};
|
package/dist/ssr/astro.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"astro.js","names":[],"sources":["../../src/ssr/astro.ts"],"sourcesContent":["/**\n * Astro integration for Tasty SSR.\n *\n * Provides:\n * - tastyIntegration() — Astro Integration API (recommended)\n * - tastyMiddleware() — manual middleware for advanced composition\n *\n * Import from '@tenphi/tasty/ssr/astro'.\n */\n\nimport { getConfig } from '../config';\nimport { getSSRCollector, runWithCollector } from './async-storage';\nimport { ServerStyleCollector } from './collector';\nimport {
|
|
1
|
+
{"version":3,"file":"astro.js","names":[],"sources":["../../src/ssr/astro.ts"],"sourcesContent":["/**\n * Astro integration for Tasty SSR.\n *\n * Provides:\n * - tastyIntegration() — Astro Integration API (recommended)\n * - tastyMiddleware() — manual middleware for advanced composition\n *\n * Import from '@tenphi/tasty/ssr/astro'.\n */\n\nimport { getConfig } from '../config';\nimport { getSSRCollector, runWithCollector } from './async-storage';\nimport { ServerStyleCollector } from './collector';\nimport { registerSSRCollectorGetterGlobal } from './ssr-collector-ref';\n\n// Wire up ALS-based collector discovery so computeStyles() can find\n// the collector set by tastyMiddleware's runWithCollector().\n// Uses globalThis so the getter is visible across Astro's separate\n// module graphs (middleware vs page components).\nregisterSSRCollectorGetterGlobal(getSSRCollector);\n\nexport interface TastyMiddlewareOptions {\n /**\n * Whether to embed the cache state script for client hydration.\n * Set to false to skip cache transfer. Default: true.\n */\n transferCache?: boolean;\n}\n\n/**\n * Create an Astro middleware that collects Tasty styles during SSR.\n *\n * All React components rendered during the request will have their\n * computeStyles() calls captured by the collector via AsyncLocalStorage.\n * After rendering, the middleware injects the collected CSS into </head>.\n *\n * @example Manual middleware setup\n * ```ts\n * // src/middleware.ts\n * import { tastyMiddleware } from '@tenphi/tasty/ssr/astro';\n * export const onRequest = tastyMiddleware();\n * ```\n *\n * @example Composing with other middleware\n * ```ts\n * // src/middleware.ts\n * import { sequence } from 'astro:middleware';\n * import { tastyMiddleware } from '@tenphi/tasty/ssr/astro';\n *\n * export const onRequest = sequence(\n * tastyMiddleware(),\n * myOtherMiddleware,\n * );\n * ```\n */\nexport function tastyMiddleware(options?: TastyMiddlewareOptions) {\n return async (\n _context: unknown,\n next: () => Promise<Response>,\n ): Promise<Response> => {\n const transferCache = options?.transferCache ?? true;\n const collector = new ServerStyleCollector();\n\n // Run the entire request — including body stream consumption — inside\n // the ALS context so that components rendering lazily during stream\n // reads can still find the collector via getSSRCollector().\n const rendered = await runWithCollector(collector, async () => {\n const response = await next();\n const body = response.body;\n if (!body) {\n return {\n html: null as string | null,\n status: response.status,\n headers: response.headers,\n };\n }\n\n const reader = body.pipeThrough(new TextDecoderStream()).getReader();\n const parts: string[] = [];\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n parts.push(value);\n }\n return {\n html: parts.join(''),\n status: response.status,\n headers: response.headers,\n };\n });\n\n if (!rendered.html) {\n return new Response(null, {\n status: rendered.status,\n headers: rendered.headers,\n });\n }\n\n let { html } = rendered;\n\n const css = collector.getCSS();\n if (!css) {\n return new Response(html, {\n status: rendered.status,\n headers: rendered.headers,\n });\n }\n\n const nonce = getConfig().nonce;\n const nonceAttr = nonce ? ` nonce=\"${nonce}\"` : '';\n const styleTag = `<style data-tasty-ssr${nonceAttr}>${css}</style>`;\n\n let cacheTag = '';\n if (transferCache) {\n const cacheState = collector.getCacheState();\n const hasHydratableStyles = Object.keys(cacheState.entries).length > 0;\n if (hasHydratableStyles) {\n cacheTag = `<script data-tasty-cache type=\"application/json\"${nonceAttr}>${JSON.stringify(cacheState)}</script>`;\n }\n }\n\n const injection = styleTag + cacheTag;\n const idx = html.indexOf('</head>');\n if (idx !== -1) {\n html = html.slice(0, idx) + injection + html.slice(idx);\n } else {\n html = injection + html;\n }\n\n const headers = new Headers(rendered.headers);\n headers.delete('content-length');\n\n return new Response(html, {\n status: rendered.status,\n headers,\n });\n };\n}\n\n// ============================================================================\n// Module-level middleware config (set by tastyIntegration, read by\n// astro-middleware.ts via getter property)\n// ============================================================================\n\nlet _middlewareTransferCache = true;\n\n/** @internal */\nexport function setMiddlewareTransferCache(value: boolean): void {\n _middlewareTransferCache = value;\n}\n\n/** @internal */\nexport function getMiddlewareTransferCache(): boolean {\n return _middlewareTransferCache;\n}\n\n// ============================================================================\n// Astro Integration API\n// ============================================================================\n\nexport interface TastyIntegrationOptions {\n /**\n * Enable island hydration support.\n *\n * When `true` (default): injects a client hydration script via\n * `injectScript('before-hydration')` and sets `transferCache: true`\n * on the middleware. Islands skip the style pipeline during hydration.\n *\n * When `false`: no client JS is shipped and `transferCache` is set\n * to `false`. Use this for fully static sites without `client:*`\n * directives.\n */\n islands?: boolean;\n}\n\n/**\n * Astro integration that automatically sets up Tasty SSR.\n *\n * Registers middleware for cross-component CSS deduplication and\n * optionally injects a client hydration script for island support.\n *\n * @example Basic setup (with islands)\n * ```ts\n * // astro.config.mjs\n * import { tastyIntegration } from '@tenphi/tasty/ssr/astro';\n *\n * export default defineConfig({\n * integrations: [tastyIntegration()],\n * });\n * ```\n *\n * @example Static-only (no client JS)\n * ```ts\n * // astro.config.mjs\n * import { tastyIntegration } from '@tenphi/tasty/ssr/astro';\n *\n * export default defineConfig({\n * integrations: [tastyIntegration({ islands: false })],\n * });\n * ```\n */\nexport function tastyIntegration(options?: TastyIntegrationOptions) {\n const { islands = true } = options ?? {};\n\n setMiddlewareTransferCache(islands);\n\n return {\n name: '@tenphi/tasty',\n hooks: {\n 'astro:config:setup': ({\n addMiddleware,\n injectScript,\n }: {\n addMiddleware: (middleware: {\n entrypoint: string | URL;\n order: 'pre' | 'post';\n }) => void;\n injectScript: (stage: string, content: string) => void;\n }) => {\n addMiddleware({\n entrypoint: new URL('./astro-middleware.js', import.meta.url),\n order: 'pre',\n });\n\n if (islands) {\n injectScript(\n 'before-hydration',\n `import \"@tenphi/tasty/ssr/astro-client\";`,\n );\n }\n },\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,iCAAiC,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCjD,SAAgB,gBAAgB,SAAkC;AAChE,QAAO,OACL,UACA,SACsB;EACtB,MAAM,gBAAgB,SAAS,iBAAiB;EAChD,MAAM,YAAY,IAAI,sBAAsB;EAK5C,MAAM,WAAW,MAAM,iBAAiB,WAAW,YAAY;GAC7D,MAAM,WAAW,MAAM,MAAM;GAC7B,MAAM,OAAO,SAAS;AACtB,OAAI,CAAC,KACH,QAAO;IACL,MAAM;IACN,QAAQ,SAAS;IACjB,SAAS,SAAS;IACnB;GAGH,MAAM,SAAS,KAAK,YAAY,IAAI,mBAAmB,CAAC,CAAC,WAAW;GACpE,MAAM,QAAkB,EAAE;AAC1B,YAAS;IACP,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,QAAI,KAAM;AACV,UAAM,KAAK,MAAM;;AAEnB,UAAO;IACL,MAAM,MAAM,KAAK,GAAG;IACpB,QAAQ,SAAS;IACjB,SAAS,SAAS;IACnB;IACD;AAEF,MAAI,CAAC,SAAS,KACZ,QAAO,IAAI,SAAS,MAAM;GACxB,QAAQ,SAAS;GACjB,SAAS,SAAS;GACnB,CAAC;EAGJ,IAAI,EAAE,SAAS;EAEf,MAAM,MAAM,UAAU,QAAQ;AAC9B,MAAI,CAAC,IACH,QAAO,IAAI,SAAS,MAAM;GACxB,QAAQ,SAAS;GACjB,SAAS,SAAS;GACnB,CAAC;EAGJ,MAAM,QAAQ,WAAW,CAAC;EAC1B,MAAM,YAAY,QAAQ,WAAW,MAAM,KAAK;EAChD,MAAM,WAAW,wBAAwB,UAAU,GAAG,IAAI;EAE1D,IAAI,WAAW;AACf,MAAI,eAAe;GACjB,MAAM,aAAa,UAAU,eAAe;AAE5C,OAD4B,OAAO,KAAK,WAAW,QAAQ,CAAC,SAAS,EAEnE,YAAW,mDAAmD,UAAU,GAAG,KAAK,UAAU,WAAW,CAAC;;EAI1G,MAAM,YAAY,WAAW;EAC7B,MAAM,MAAM,KAAK,QAAQ,UAAU;AACnC,MAAI,QAAQ,GACV,QAAO,KAAK,MAAM,GAAG,IAAI,GAAG,YAAY,KAAK,MAAM,IAAI;MAEvD,QAAO,YAAY;EAGrB,MAAM,UAAU,IAAI,QAAQ,SAAS,QAAQ;AAC7C,UAAQ,OAAO,iBAAiB;AAEhC,SAAO,IAAI,SAAS,MAAM;GACxB,QAAQ,SAAS;GACjB;GACD,CAAC;;;AASN,IAAI,2BAA2B;;AAG/B,SAAgB,2BAA2B,OAAsB;AAC/D,4BAA2B;;;AAI7B,SAAgB,6BAAsC;AACpD,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDT,SAAgB,iBAAiB,SAAmC;CAClE,MAAM,EAAE,UAAU,SAAS,WAAW,EAAE;AAExC,4BAA2B,QAAQ;AAEnC,QAAO;EACL,MAAM;EACN,OAAO,EACL,uBAAuB,EACrB,eACA,mBAOI;AACJ,iBAAc;IACZ,YAAY,IAAI,IAAI,yBAAyB,OAAO,KAAK,IAAI;IAC7D,OAAO;IACR,CAAC;AAEF,OAAI,QACF,cACE,oBACA,2CACD;KAGN;EACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
//#region src/ssr/context.ts
|
|
3
|
+
/**
|
|
4
|
+
* React context for SSR collector discovery.
|
|
5
|
+
*
|
|
6
|
+
* Used by Next.js TastyRegistry to provide the ServerStyleCollector
|
|
7
|
+
* to useStyles() via React context (the streaming-compatible path).
|
|
8
|
+
*
|
|
9
|
+
* This avoids relying on globalThis for cross-layer communication,
|
|
10
|
+
* which leaks between RSC and SSR module graphs in Next.js App Router.
|
|
11
|
+
*/
|
|
12
|
+
const TastySSRContext = createContext(null);
|
|
13
|
+
//#endregion
|
|
14
|
+
export { TastySSRContext };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../../src/ssr/context.ts"],"sourcesContent":["/**\n * React context for SSR collector discovery.\n *\n * Used by Next.js TastyRegistry to provide the ServerStyleCollector\n * to useStyles() via React context (the streaming-compatible path).\n *\n * This avoids relying on globalThis for cross-layer communication,\n * which leaks between RSC and SSR module graphs in Next.js App Router.\n */\n\nimport { createContext } from 'react';\n\nimport type { ServerStyleCollector } from './collector';\n\nexport const TastySSRContext = createContext<ServerStyleCollector | null>(null);\n"],"mappings":";;;;;;;;;;;AAcA,MAAa,kBAAkB,cAA2C,KAAK"}
|
package/dist/ssr/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { registerSSRCollectorGetterGlobal } from "./ssr-collector-ref.js";
|
|
2
2
|
import { ServerStyleCollector } from "./collector.js";
|
|
3
3
|
import { getSSRCollector, runWithCollector } from "./async-storage.js";
|
|
4
4
|
import { hydrateTastyCache } from "./hydrate.js";
|
|
5
5
|
//#region src/ssr/index.ts
|
|
6
|
-
|
|
6
|
+
registerSSRCollectorGetterGlobal(getSSRCollector);
|
|
7
7
|
//#endregion
|
|
8
8
|
export { ServerStyleCollector, getSSRCollector, hydrateTastyCache, runWithCollector };
|
|
9
9
|
|
package/dist/ssr/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/ssr/index.ts"],"sourcesContent":["/**\n * SSR entry point for @tenphi/tasty.\n *\n * Provides the core SSR infrastructure: ServerStyleCollector,\n * AsyncLocalStorage integration, and cache hydration.\n *\n * Import from '@tenphi/tasty/ssr'.\n */\n\n// Core collector\nexport { ServerStyleCollector } from './collector';\nexport type { SSRCacheState } from './collector';\n\n// AsyncLocalStorage integration for Astro / generic frameworks\nexport { runWithCollector, getSSRCollector } from './async-storage';\n\n// Client-side cache hydration\nexport { hydrateTastyCache } from './hydrate';\n\n// Register the ALS getter so hooks can find the collector\n// without importing 'node:async_hooks' in the browser bundle.\nimport { getSSRCollector } from './async-storage';\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/ssr/index.ts"],"sourcesContent":["/**\n * SSR entry point for @tenphi/tasty.\n *\n * Provides the core SSR infrastructure: ServerStyleCollector,\n * AsyncLocalStorage integration, and cache hydration.\n *\n * Import from '@tenphi/tasty/ssr'.\n */\n\n// Core collector\nexport { ServerStyleCollector } from './collector';\nexport type { SSRCacheState } from './collector';\n\n// AsyncLocalStorage integration for Astro / generic frameworks\nexport { runWithCollector, getSSRCollector } from './async-storage';\n\n// Client-side cache hydration\nexport { hydrateTastyCache } from './hydrate';\n\n// Register the ALS getter so hooks can find the collector\n// without importing 'node:async_hooks' in the browser bundle.\n// Uses globalThis so the getter is visible across separate module graphs.\nimport { getSSRCollector } from './async-storage';\nimport { registerSSRCollectorGetterGlobal } from './ssr-collector-ref';\n\nregisterSSRCollectorGetterGlobal(getSSRCollector);\n"],"mappings":";;;;;AAyBA,iCAAiC,gBAAgB"}
|
package/dist/ssr/next.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ServerStyleCollector } from "./collector.js";
|
|
2
|
+
import * as _$react from "react";
|
|
1
3
|
import { ReactNode } from "react";
|
|
2
4
|
|
|
3
5
|
//#region src/ssr/next.d.ts
|
|
@@ -37,7 +39,7 @@ interface TastyRegistryProps {
|
|
|
37
39
|
declare function TastyRegistry({
|
|
38
40
|
children,
|
|
39
41
|
transferCache
|
|
40
|
-
}: TastyRegistryProps):
|
|
42
|
+
}: TastyRegistryProps): _$react.FunctionComponentElement<_$react.ProviderProps<ServerStyleCollector | null>>;
|
|
41
43
|
//#endregion
|
|
42
44
|
export { TastyRegistry, TastyRegistryProps };
|
|
43
45
|
//# sourceMappingURL=next.d.ts.map
|
package/dist/ssr/next.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { getConfig } from "../config.js";
|
|
3
3
|
import { registerSSRCollectorGetter } from "./ssr-collector-ref.js";
|
|
4
|
+
import { TastySSRContext } from "./context.js";
|
|
4
5
|
import { ServerStyleCollector } from "./collector.js";
|
|
5
6
|
import { hydrateTastyCache } from "./hydrate.js";
|
|
6
7
|
import { Fragment, createElement, useState } from "react";
|
|
@@ -66,7 +67,7 @@ function TastyRegistry({ children, transferCache = true }) {
|
|
|
66
67
|
dangerouslySetInnerHTML: { __html: `(window.__TASTY_SSR_CACHE__=window.__TASTY_SSR_CACHE__||{entries:{},classCounter:0});Object.assign(window.__TASTY_SSR_CACHE__.entries,${JSON.stringify(cacheState.entries)});window.__TASTY_SSR_CACHE__.classCounter=${cacheState.classCounter};` }
|
|
67
68
|
}));
|
|
68
69
|
});
|
|
69
|
-
return children;
|
|
70
|
+
return createElement(TastySSRContext.Provider, { value: collector }, children);
|
|
70
71
|
}
|
|
71
72
|
//#endregion
|
|
72
73
|
export { TastyRegistry };
|
package/dist/ssr/next.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next.js","names":[],"sources":["../../src/ssr/next.ts"],"sourcesContent":["/**\n * Next.js integration for Tasty SSR.\n *\n * Provides TastyRegistry for App Router (streaming via useServerInsertedHTML)\n * and createTastySSRDocument for Pages Router (non-streaming).\n *\n * Import from '@tenphi/tasty/ssr/next'.\n */\n\n'use client';\n\n/// <reference path=\"./next-navigation.d.ts\" />\n\nimport { createElement, Fragment, useState, type ReactNode } from 'react';\nimport { useServerInsertedHTML } from 'next/navigation';\n\nimport { getConfig } from '../config';\nimport { ServerStyleCollector } from './collector';\nimport { hydrateTastyCache } from './hydrate';\nimport { registerSSRCollectorGetter } from './ssr-collector-ref';\n\n// Auto-hydrate on module load (client only).\n// When this module is imported by the TastyRegistry client component,\n// the streaming cache scripts have already populated __TASTY_SSR_CACHE__.\nif (typeof window !== 'undefined' && window.__TASTY_SSR_CACHE__) {\n hydrateTastyCache(window.__TASTY_SSR_CACHE__);\n}\n\nexport interface TastyRegistryProps {\n children: ReactNode;\n /**\n * Whether to embed the cache state script for client hydration.\n * Set to false to skip cache transfer (useful when cache size\n * exceeds the hydration benefit). Default: true.\n */\n transferCache?: boolean;\n}\n\n/**\n * Next.js App Router registry for Tasty SSR.\n *\n * Wraps the component tree with a ServerStyleCollector and flushes\n * collected CSS into the HTML stream via useServerInsertedHTML.\n *\n * @example\n * ```tsx\n * // app/tasty-registry.tsx\n * 'use client';\n * import { TastyRegistry } from '@tenphi/tasty/ssr/next';\n * export default function TastyStyleRegistry({ children }) {\n * return <TastyRegistry>{children}</TastyRegistry>;\n * }\n *\n * // app/layout.tsx\n * import TastyStyleRegistry from './tasty-registry';\n * export default function RootLayout({ children }) {\n * return <html><body>\n * <TastyStyleRegistry>{children}</TastyStyleRegistry>\n * </body></html>;\n * }\n * ```\n */\nexport function TastyRegistry({\n children,\n transferCache = true,\n}: TastyRegistryProps) {\n const isClient = typeof window !== 'undefined';\n\n const [collector] = useState(() => {\n if (isClient) return null;\n\n const instance = new ServerStyleCollector();\n\n registerSSRCollectorGetter(() => instance);\n\n return instance;\n });\n const nonce = getConfig().nonce;\n\n useServerInsertedHTML(() => {\n if (!collector) return null;\n\n const css = collector.flushCSS();\n const cacheState = collector.getCacheState();\n\n if (!css) return null;\n\n const styleEl = createElement('style', {\n key: 'tasty-ssr-styles',\n 'data-tasty-ssr': '',\n nonce,\n dangerouslySetInnerHTML: { __html: css },\n });\n\n if (!transferCache) return styleEl;\n\n const scriptEl = createElement('script', {\n key: 'tasty-ssr-cache',\n nonce,\n dangerouslySetInnerHTML: {\n __html:\n `(window.__TASTY_SSR_CACHE__=window.__TASTY_SSR_CACHE__||{entries:{},classCounter:0});` +\n `Object.assign(window.__TASTY_SSR_CACHE__.entries,${JSON.stringify(cacheState.entries)});` +\n `window.__TASTY_SSR_CACHE__.classCounter=${cacheState.classCounter};`,\n },\n });\n\n return createElement(Fragment, null, styleEl, scriptEl);\n });\n\n return children;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"next.js","names":[],"sources":["../../src/ssr/next.ts"],"sourcesContent":["/**\n * Next.js integration for Tasty SSR.\n *\n * Provides TastyRegistry for App Router (streaming via useServerInsertedHTML)\n * and createTastySSRDocument for Pages Router (non-streaming).\n *\n * Import from '@tenphi/tasty/ssr/next'.\n */\n\n'use client';\n\n/// <reference path=\"./next-navigation.d.ts\" />\n\nimport { createElement, Fragment, useState, type ReactNode } from 'react';\nimport { useServerInsertedHTML } from 'next/navigation';\n\nimport { getConfig } from '../config';\nimport { ServerStyleCollector } from './collector';\nimport { TastySSRContext } from './context';\nimport { hydrateTastyCache } from './hydrate';\nimport { registerSSRCollectorGetter } from './ssr-collector-ref';\n\n// Auto-hydrate on module load (client only).\n// When this module is imported by the TastyRegistry client component,\n// the streaming cache scripts have already populated __TASTY_SSR_CACHE__.\nif (typeof window !== 'undefined' && window.__TASTY_SSR_CACHE__) {\n hydrateTastyCache(window.__TASTY_SSR_CACHE__);\n}\n\nexport interface TastyRegistryProps {\n children: ReactNode;\n /**\n * Whether to embed the cache state script for client hydration.\n * Set to false to skip cache transfer (useful when cache size\n * exceeds the hydration benefit). Default: true.\n */\n transferCache?: boolean;\n}\n\n/**\n * Next.js App Router registry for Tasty SSR.\n *\n * Wraps the component tree with a ServerStyleCollector and flushes\n * collected CSS into the HTML stream via useServerInsertedHTML.\n *\n * @example\n * ```tsx\n * // app/tasty-registry.tsx\n * 'use client';\n * import { TastyRegistry } from '@tenphi/tasty/ssr/next';\n * export default function TastyStyleRegistry({ children }) {\n * return <TastyRegistry>{children}</TastyRegistry>;\n * }\n *\n * // app/layout.tsx\n * import TastyStyleRegistry from './tasty-registry';\n * export default function RootLayout({ children }) {\n * return <html><body>\n * <TastyStyleRegistry>{children}</TastyStyleRegistry>\n * </body></html>;\n * }\n * ```\n */\nexport function TastyRegistry({\n children,\n transferCache = true,\n}: TastyRegistryProps) {\n const isClient = typeof window !== 'undefined';\n\n const [collector] = useState(() => {\n if (isClient) return null;\n\n const instance = new ServerStyleCollector();\n\n registerSSRCollectorGetter(() => instance);\n\n return instance;\n });\n const nonce = getConfig().nonce;\n\n useServerInsertedHTML(() => {\n if (!collector) return null;\n\n const css = collector.flushCSS();\n const cacheState = collector.getCacheState();\n\n if (!css) return null;\n\n const styleEl = createElement('style', {\n key: 'tasty-ssr-styles',\n 'data-tasty-ssr': '',\n nonce,\n dangerouslySetInnerHTML: { __html: css },\n });\n\n if (!transferCache) return styleEl;\n\n const scriptEl = createElement('script', {\n key: 'tasty-ssr-cache',\n nonce,\n dangerouslySetInnerHTML: {\n __html:\n `(window.__TASTY_SSR_CACHE__=window.__TASTY_SSR_CACHE__||{entries:{},classCounter:0});` +\n `Object.assign(window.__TASTY_SSR_CACHE__.entries,${JSON.stringify(cacheState.entries)});` +\n `window.__TASTY_SSR_CACHE__.classCounter=${cacheState.classCounter};`,\n },\n });\n\n return createElement(Fragment, null, styleEl, scriptEl);\n });\n\n return createElement(\n TastySSRContext.Provider,\n { value: collector },\n children,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAyBA,IAAI,OAAO,WAAW,eAAe,OAAO,oBAC1C,mBAAkB,OAAO,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;AAqC/C,SAAgB,cAAc,EAC5B,UACA,gBAAgB,QACK;CACrB,MAAM,WAAW,OAAO,WAAW;CAEnC,MAAM,CAAC,aAAa,eAAe;AACjC,MAAI,SAAU,QAAO;EAErB,MAAM,WAAW,IAAI,sBAAsB;AAE3C,mCAAiC,SAAS;AAE1C,SAAO;GACP;CACF,MAAM,QAAQ,WAAW,CAAC;AAE1B,6BAA4B;AAC1B,MAAI,CAAC,UAAW,QAAO;EAEvB,MAAM,MAAM,UAAU,UAAU;EAChC,MAAM,aAAa,UAAU,eAAe;AAE5C,MAAI,CAAC,IAAK,QAAO;EAEjB,MAAM,UAAU,cAAc,SAAS;GACrC,KAAK;GACL,kBAAkB;GAClB;GACA,yBAAyB,EAAE,QAAQ,KAAK;GACzC,CAAC;AAEF,MAAI,CAAC,cAAe,QAAO;AAa3B,SAAO,cAAc,UAAU,MAAM,SAXpB,cAAc,UAAU;GACvC,KAAK;GACL;GACA,yBAAyB,EACvB,QACE,yIACoD,KAAK,UAAU,WAAW,QAAQ,CAAC,4CAC5C,WAAW,aAAa,IACtE;GACF,CAAC,CAEqD;GACvD;AAEF,QAAO,cACL,gBAAgB,UAChB,EAAE,OAAO,WAAW,EACpB,SACD"}
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
//#region src/ssr/ssr-collector-ref.ts
|
|
2
2
|
const GETTER_KEY = "__tasty_ssr_collector_getter__";
|
|
3
|
+
let _getSSRCollector = null;
|
|
4
|
+
/**
|
|
5
|
+
* Register the collector getter in the current module graph only.
|
|
6
|
+
* Used by Next.js TastyRegistry.
|
|
7
|
+
*/
|
|
3
8
|
function registerSSRCollectorGetter(fn) {
|
|
9
|
+
_getSSRCollector = fn;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register the collector getter on globalThis so it is visible across
|
|
13
|
+
* separate module graphs (e.g. Astro middleware ↔ page components).
|
|
14
|
+
*/
|
|
15
|
+
function registerSSRCollectorGetterGlobal(fn) {
|
|
4
16
|
globalThis[GETTER_KEY] = fn;
|
|
5
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Retrieve the SSR collector: module-level first, globalThis fallback.
|
|
20
|
+
*/
|
|
6
21
|
function getRegisteredSSRCollector() {
|
|
22
|
+
if (_getSSRCollector) return _getSSRCollector();
|
|
7
23
|
const getter = globalThis[GETTER_KEY];
|
|
8
24
|
return getter ? getter() : null;
|
|
9
25
|
}
|
|
10
26
|
//#endregion
|
|
11
|
-
export { getRegisteredSSRCollector, registerSSRCollectorGetter };
|
|
27
|
+
export { getRegisteredSSRCollector, registerSSRCollectorGetter, registerSSRCollectorGetterGlobal };
|
|
12
28
|
|
|
13
29
|
//# sourceMappingURL=ssr-collector-ref.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-collector-ref.js","names":[],"sources":["../../src/ssr/ssr-collector-ref.ts"],"sourcesContent":["/**\n * Global reference to the SSR collector getter function.\n *\n * This indirection avoids importing 'node:async_hooks' in the browser bundle.\n * The SSR entry point sets this ref when loaded on the server. The useStyles\n * hook calls it if set; on the client it stays null and is never called.\n *\n * Uses
|
|
1
|
+
{"version":3,"file":"ssr-collector-ref.js","names":[],"sources":["../../src/ssr/ssr-collector-ref.ts"],"sourcesContent":["/**\n * Global reference to the SSR collector getter function.\n *\n * This indirection avoids importing 'node:async_hooks' in the browser bundle.\n * The SSR entry point sets this ref when loaded on the server. The useStyles\n * hook calls it if set; on the client it stays null and is never called.\n *\n * Uses a module-level variable as the primary mechanism. In Next.js App\n * Router the RSC and SSR module graphs load separate copies of this module,\n * so the getter registered by TastyRegistry (SSR layer) is invisible to\n * server components (RSC layer) — which correctly fall through to inline\n * RSC styles.\n *\n * A globalThis fallback (`registerSSRCollectorGetterGlobal`) is provided\n * for frameworks like Astro where middleware and page components live in\n * different module graphs and must share the getter across them.\n */\n\nimport type { ServerStyleCollector } from './collector';\n\ntype SSRCollectorGetter = () => ServerStyleCollector | null;\n\nconst GETTER_KEY = '__tasty_ssr_collector_getter__';\n\nlet _getSSRCollector: SSRCollectorGetter | null = null;\n\n/**\n * Register the collector getter in the current module graph only.\n * Used by Next.js TastyRegistry.\n */\nexport function registerSSRCollectorGetter(fn: SSRCollectorGetter): void {\n _getSSRCollector = fn;\n}\n\n/**\n * Register the collector getter on globalThis so it is visible across\n * separate module graphs (e.g. Astro middleware ↔ page components).\n */\nexport function registerSSRCollectorGetterGlobal(fn: SSRCollectorGetter): void {\n (globalThis as Record<string, unknown>)[GETTER_KEY] = fn;\n}\n\n/**\n * Retrieve the SSR collector: module-level first, globalThis fallback.\n */\nexport function getRegisteredSSRCollector(): ServerStyleCollector | null {\n if (_getSSRCollector) return _getSSRCollector();\n const getter = (globalThis as Record<string, unknown>)[GETTER_KEY] as\n | SSRCollectorGetter\n | undefined;\n return getter ? getter() : null;\n}\n"],"mappings":";AAsBA,MAAM,aAAa;AAEnB,IAAI,mBAA8C;;;;;AAMlD,SAAgB,2BAA2B,IAA8B;AACvE,oBAAmB;;;;;;AAOrB,SAAgB,iCAAiC,IAA8B;AAC5E,YAAuC,cAAc;;;;;AAMxD,SAAgB,4BAAyD;AACvE,KAAI,iBAAkB,QAAO,kBAAkB;CAC/C,MAAM,SAAU,WAAuC;AAGvD,QAAO,SAAS,QAAQ,GAAG"}
|
package/dist/tasty.d.ts
CHANGED
|
@@ -128,7 +128,7 @@ type TastyElementProps<K extends StyleList, V extends VariantMap, Tag extends ke
|
|
|
128
128
|
type TastyComponentPropsWithDefaults<Props extends PropsWithStyles, DefaultProps extends Partial<Props>> = keyof DefaultProps extends never ? Props : { [key in Extract<keyof Props, keyof DefaultProps>]?: Props[key] } & { [key in keyof Omit<Props, keyof DefaultProps>]: Props[key] };
|
|
129
129
|
declare function tasty<K extends StyleList, V extends VariantMap, E extends ElementsDefinition = Record<string, never>, Tag extends keyof JSX.IntrinsicElements = 'div', M extends ModPropsInput = readonly never[], TP extends TokenPropsInput = readonly never[]>(options: TastyElementOptions<K, V, E, Tag, M, TP>, secondArg?: never): ForwardRefExoticComponent<PropsWithoutRef<TastyElementProps<K, V, Tag, M, TP>> & RefAttributes<unknown>> & SubElementComponents<E>;
|
|
130
130
|
declare function tasty<Props extends PropsWithStyles, DefaultProps extends Partial<Props> = Partial<Props>>(Component: ComponentType<Props>, options?: TastyProps<never, never, Record<string, never>, Props>): ComponentType<TastyComponentPropsWithDefaults<Props, DefaultProps>>;
|
|
131
|
-
declare const Element: ForwardRefExoticComponent<Omit<AllBasePropsWithMods<StyleList, readonly never[], readonly never[]>, "children" | "slot" | "title" | "className" | "role" | "id" | "hidden" | "prefix" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "radioGroup" | "about" | "datatype" | "inlist" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "popover" | "popoverTargetAction" | "popoverTarget" | "inert" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onScrollEnd" | "onScrollEndCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onToggle" | "onBeforeToggle" | "onTransitionCancel" | "onTransitionCancelCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "onTransitionRun" | "onTransitionRunCapture" | "onTransitionStart" | "onTransitionStartCapture" | "key"> & WithVariant<VariantMap> & Omit<Omit<AllHTMLAttributes<HTMLElement>, keyof _$react.ClassAttributes<HTMLDivElement> | keyof _$react.HTMLAttributes<HTMLDivElement>> & _$react.ClassAttributes<HTMLDivElement> & _$react.HTMLAttributes<HTMLDivElement>, "top" | "right" | "bottom" | "left" | "display" | "font" | "preset" | "hide" | "whiteSpace" | "opacity" | "transition" | "gridArea" | "order" | "gridColumn" | "gridRow" | "placeSelf" | "alignSelf" | "justifySelf" | "zIndex" | "margin" | "inset" | "position" | "scrollMargin" | "padding" | "paddingInline" | "paddingBlock" | "overflow" | "scrollbar" | "textAlign" | "border" | "radius" | "shadow" | "outline" | "color" | "fill" | "fade" | "image" | "textTransform" | "fontWeight" | "fontStyle" | "width" | "height" | "flexBasis" | "flexGrow" | "flexShrink" | "flex" | "flow" | "place" | "placeItems" | "placeContent" | "alignItems" | "alignContent" | "justifyItems" | "justifyContent" | "align" | "justify" | "gap" | "columnGap" | "rowGap" | "gridColumns" | "gridRows" | "gridTemplate" | "gridAreas" | "style" | "mods" | "css" | "content" | "translate" | "as" | "background" | "all" | "page" | "qa" | "qaVal" | "scrollMarginTop" | "scrollMarginRight" | "scrollMarginBottom" | "scrollMarginLeft" | "scrollMarginBlock" | "scrollMarginInline" | "accentColor" | "alignTracks" | "alignmentBaseline" | "anchorName" | "anchorScope" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationRangeEnd" | "animationRangeStart" | "animationTimeline" | "animationTimingFunction" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "baselineShift" | "blockSize" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipPath" | "clipRule" | "colorAdjust" | "colorInterpolationFilters" | "colorScheme" | "columnCount" | "columnFill" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "containerName" | "containerType" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "cx" | "cy" | "d" | "direction" | "dominantBaseline" | "emptyCells" | "fieldSizing" | "fillOpacity" | "fillRule" | "filter" | "flexDirection" | "flexWrap" | "float" | "floodColor" | "floodOpacity" | "fontFamily" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontPalette" | "fontSize" | "fontSizeAdjust" | "fontSmooth" | "fontSynthesis" | "fontSynthesisPosition" | "fontSynthesisSmallCaps" | "fontSynthesisStyle" | "fontSynthesisWeight" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantEmoji" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontVariationSettings" | "fontWidth" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "hyphenateCharacter" | "hyphenateLimitChars" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "interpolateSize" | "isolation" | "justifyTracks" | "letterSpacing" | "lightingColor" | "lineBreak" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "marker" | "markerEnd" | "markerMid" | "markerStart" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "motionDistance" | "motionPath" | "motionRotation" | "objectFit" | "objectPosition" | "objectViewBox" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "offsetRotation" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflowAnchor" | "overflowBlock" | "overflowClipBox" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overlay" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "positionAnchor" | "positionArea" | "positionTryFallbacks" | "positionTryOrder" | "positionVisibility" | "printColorAdjust" | "quotes" | "r" | "resize" | "rotate" | "rubyAlign" | "rubyMerge" | "rubyOverhang" | "rubyPosition" | "rx" | "ry" | "scale" | "scrollBehavior" | "scrollInitialTarget" | "scrollMarginBlockEnd" | "scrollMarginBlockStart" | "scrollMarginInlineEnd" | "scrollMarginInlineStart" | "scrollPaddingBlockEnd" | "scrollPaddingBlockStart" | "scrollPaddingBottom" | "scrollPaddingInlineEnd" | "scrollPaddingInlineStart" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapMarginBottom" | "scrollSnapMarginLeft" | "scrollSnapMarginRight" | "scrollSnapMarginTop" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "shapeRendering" | "speakAs" | "stopColor" | "stopOpacity" | "stroke" | "strokeColor" | "strokeDasharray" | "strokeDashoffset" | "strokeLinecap" | "strokeLinejoin" | "strokeMiterlimit" | "strokeOpacity" | "strokeWidth" | "tabSize" | "tableLayout" | "textAlignLast" | "textAnchor" | "textAutospace" | "textBox" | "textBoxEdge" | "textBoxTrim" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textSpacingTrim" | "textUnderlineOffset" | "textUnderlinePosition" | "textWrapMode" | "textWrapStyle" | "timelineScope" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionBehavior" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "unicodeBidi" | "userSelect" | "vectorEffect" | "verticalAlign" | "viewTimelineAxis" | "viewTimelineInset" | "viewTimelineName" | "viewTransitionClass" | "viewTransitionName" | "visibility" | "whiteSpaceCollapse" | "widows" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "x" | "y" | "zoom" | "animation" | "animationRange" | "backgroundPosition" | "borderBlock" | "borderBlockColor" | "borderBlockEnd" | "borderBlockStart" | "borderBlockStyle" | "borderBlockWidth" | "borderBottom" | "borderColor" | "borderImage" | "borderInline" | "borderInlineColor" | "borderInlineEnd" | "borderInlineStart" | "borderInlineStyle" | "borderInlineWidth" | "borderLeft" | "borderRadius" | "borderRight" | "borderStyle" | "borderTop" | "borderWidth" | "caret" | "columnRule" | "columns" | "containIntrinsicSize" | "container" | "flexFlow" | "grid" | "insetBlock" | "insetInline" | "lineClamp" | "listStyle" | "marginBlock" | "marginInline" | "mask" | "maskBorder" | "motion" | "offset" | "overscrollBehavior" | "positionTry" | "scrollPadding" | "scrollPaddingBlock" | "scrollPaddingInline" | "scrollSnapMargin" | "scrollTimeline" | "textDecoration" | "textEmphasis" | "textWrap" | "viewTimeline" | "MozAnimationDelay" | "MozAnimationDirection" | "MozAnimationDuration" | "MozAnimationFillMode" | "MozAnimationIterationCount" | "MozAnimationName" | "MozAnimationPlayState" | "MozAnimationTimingFunction" | "MozAppearance" | "MozBackfaceVisibility" | "MozBinding" | "MozBorderBottomColors" | "MozBorderEndColor" | "MozBorderEndStyle" | "MozBorderEndWidth" | "MozBorderLeftColors" | "MozBorderRightColors" | "MozBorderStartColor" | "MozBorderStartStyle" | "MozBorderTopColors" | "MozBoxSizing" | "MozColumnRuleColor" | "MozColumnRuleStyle" | "MozColumnRuleWidth" | "MozColumnWidth" | "MozContextProperties" | "MozFontFeatureSettings" | "MozFontLanguageOverride" | "MozHyphens" | "MozMarginEnd" | "MozMarginStart" | "MozOrient" | "MozOsxFontSmoothing" | "MozOutlineRadiusBottomleft" | "MozOutlineRadiusBottomright" | "MozOutlineRadiusTopleft" | "MozOutlineRadiusTopright" | "MozPaddingEnd" | "MozPaddingStart" | "MozPerspective" | "MozPerspectiveOrigin" | "MozStackSizing" | "MozTabSize" | "MozTextBlink" | "MozTextSizeAdjust" | "MozTransform" | "MozTransformOrigin" | "MozTransformStyle" | "MozUserModify" | "MozUserSelect" | "MozWindowDragging" | "MozWindowShadow" | "msAccelerator" | "msBlockProgression" | "msContentZoomChaining" | "msContentZoomLimitMax" | "msContentZoomLimitMin" | "msContentZoomSnapPoints" | "msContentZoomSnapType" | "msContentZooming" | "msFilter" | "msFlexDirection" | "msFlexPositive" | "msFlowFrom" | "msFlowInto" | "msGridColumns" | "msGridRows" | "msHighContrastAdjust" | "msHyphenateLimitChars" | "msHyphenateLimitLines" | "msHyphenateLimitZone" | "msHyphens" | "msImeAlign" | "msLineBreak" | "msOrder" | "msOverflowStyle" | "msOverflowX" | "msOverflowY" | "msScrollChaining" | "msScrollLimitXMax" | "msScrollLimitXMin" | "msScrollLimitYMax" | "msScrollLimitYMin" | "msScrollRails" | "msScrollSnapPointsX" | "msScrollSnapPointsY" | "msScrollSnapType" | "msScrollTranslation" | "msScrollbar3dlightColor" | "msScrollbarArrowColor" | "msScrollbarBaseColor" | "msScrollbarDarkshadowColor" | "msScrollbarFaceColor" | "msScrollbarHighlightColor" | "msScrollbarShadowColor" | "msScrollbarTrackColor" | "msTextAutospace" | "msTextCombineHorizontal" | "msTextOverflow" | "msTouchAction" | "msTouchSelect" | "msTransform" | "msTransformOrigin" | "msTransitionDelay" | "msTransitionDuration" | "msTransitionProperty" | "msTransitionTimingFunction" | "msUserSelect" | "msWordBreak" | "msWrapFlow" | "msWrapMargin" | "msWrapThrough" | "msWritingMode" | "WebkitAlignContent" | "WebkitAlignItems" | "WebkitAlignSelf" | "WebkitAnimationDelay" | "WebkitAnimationDirection" | "WebkitAnimationDuration" | "WebkitAnimationFillMode" | "WebkitAnimationIterationCount" | "WebkitAnimationName" | "WebkitAnimationPlayState" | "WebkitAnimationTimingFunction" | "WebkitAppearance" | "WebkitBackdropFilter" | "WebkitBackfaceVisibility" | "WebkitBackgroundClip" | "WebkitBackgroundOrigin" | "WebkitBackgroundSize" | "WebkitBorderBeforeColor" | "WebkitBorderBeforeStyle" | "WebkitBorderBeforeWidth" | "WebkitBorderBottomLeftRadius" | "WebkitBorderBottomRightRadius" | "WebkitBorderImageSlice" | "WebkitBorderTopLeftRadius" | "WebkitBorderTopRightRadius" | "WebkitBoxDecorationBreak" | "WebkitBoxReflect" | "WebkitBoxShadow" | "WebkitBoxSizing" | "WebkitClipPath" | "WebkitColumnCount" | "WebkitColumnFill" | "WebkitColumnRuleColor" | "WebkitColumnRuleStyle" | "WebkitColumnRuleWidth" | "WebkitColumnSpan" | "WebkitColumnWidth" | "WebkitFilter" | "WebkitFlexBasis" | "WebkitFlexDirection" | "WebkitFlexGrow" | "WebkitFlexShrink" | "WebkitFlexWrap" | "WebkitFontFeatureSettings" | "WebkitFontKerning" | "WebkitFontSmoothing" | "WebkitFontVariantLigatures" | "WebkitHyphenateCharacter" | "WebkitHyphens" | "WebkitInitialLetter" | "WebkitJustifyContent" | "WebkitLineBreak" | "WebkitLineClamp" | "WebkitLogicalHeight" | "WebkitLogicalWidth" | "WebkitMarginEnd" | "WebkitMarginStart" | "WebkitMaskAttachment" | "WebkitMaskBoxImageOutset" | "WebkitMaskBoxImageRepeat" | "WebkitMaskBoxImageSlice" | "WebkitMaskBoxImageSource" | "WebkitMaskBoxImageWidth" | "WebkitMaskClip" | "WebkitMaskComposite" | "WebkitMaskImage" | "WebkitMaskOrigin" | "WebkitMaskPosition" | "WebkitMaskPositionX" | "WebkitMaskPositionY" | "WebkitMaskRepeat" | "WebkitMaskRepeatX" | "WebkitMaskRepeatY" | "WebkitMaskSize" | "WebkitMaxInlineSize" | "WebkitOrder" | "WebkitOverflowScrolling" | "WebkitPaddingEnd" | "WebkitPaddingStart" | "WebkitPerspective" | "WebkitPerspectiveOrigin" | "WebkitPrintColorAdjust" | "WebkitRubyPosition" | "WebkitScrollSnapType" | "WebkitShapeMargin" | "WebkitTapHighlightColor" | "WebkitTextCombine" | "WebkitTextDecorationColor" | "WebkitTextDecorationLine" | "WebkitTextDecorationSkip" | "WebkitTextDecorationStyle" | "WebkitTextEmphasisColor" | "WebkitTextEmphasisPosition" | "WebkitTextEmphasisStyle" | "WebkitTextFillColor" | "WebkitTextOrientation" | "WebkitTextSizeAdjust" | "WebkitTextStrokeColor" | "WebkitTextStrokeWidth" | "WebkitTextUnderlinePosition" | "WebkitTouchCallout" | "WebkitTransform" | "WebkitTransformOrigin" | "WebkitTransformStyle" | "WebkitTransitionDelay" | "WebkitTransitionDuration" | "WebkitTransitionProperty" | "WebkitTransitionTimingFunction" | "WebkitUserModify" | "WebkitUserSelect" | "WebkitWritingMode" | "MozAnimation" | "MozBorderImage" | "MozColumnRule" | "MozColumns" | "MozOutlineRadius" | "MozTransition" | "msContentZoomLimit" | "msContentZoomSnap" | "msFlex" | "msScrollLimit" | "msScrollSnapX" | "msScrollSnapY" | "msTransition" | "WebkitAnimation" | "WebkitBorderBefore" | "WebkitBorderImage" | "WebkitBorderRadius" | "WebkitColumnRule" | "WebkitColumns" | "WebkitFlex" | "WebkitFlexFlow" | "WebkitMask" | "WebkitMaskBoxImage" | "WebkitTextEmphasis" | "WebkitTextStroke" | "WebkitTransition" | "boxAlign" | "boxDirection" | "boxFlex" | "boxFlexGroup" | "boxLines" | "boxOrdinalGroup" | "boxOrient" | "boxPack" | "clip" | "fontStretch" | "gridColumnGap" | "gridGap" | "gridRowGap" | "imeMode" | "insetArea" | "offsetBlock" | "offsetBlockEnd" | "offsetBlockStart" | "offsetInline" | "offsetInlineEnd" | "offsetInlineStart" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "positionTryOptions" | "scrollSnapCoordinate" | "scrollSnapDestination" | "scrollSnapPointsX" | "scrollSnapPointsY" | "scrollSnapTypeX" | "scrollSnapTypeY" | "KhtmlBoxAlign" | "KhtmlBoxDirection" | "KhtmlBoxFlex" | "KhtmlBoxFlexGroup" | "KhtmlBoxLines" | "KhtmlBoxOrdinalGroup" | "KhtmlBoxOrient" | "KhtmlBoxPack" | "KhtmlLineBreak" | "KhtmlOpacity" | "KhtmlUserSelect" | "MozBackgroundClip" | "MozBackgroundOrigin" | "MozBackgroundSize" | "MozBorderRadius" | "MozBorderRadiusBottomleft" | "MozBorderRadiusBottomright" | "MozBorderRadiusTopleft" | "MozBorderRadiusTopright" | "MozBoxAlign" | "MozBoxDirection" | "MozBoxFlex" | "MozBoxOrdinalGroup" | "MozBoxOrient" | "MozBoxPack" | "MozBoxShadow" | "MozColumnCount" | "MozColumnFill" | "MozFloatEdge" | "MozForceBrokenImageIcon" | "MozOpacity" | "MozOutline" | "MozOutlineColor" | "MozOutlineStyle" | "MozOutlineWidth" | "MozTextAlignLast" | "MozTextDecorationColor" | "MozTextDecorationLine" | "MozTextDecorationStyle" | "MozTransitionDelay" | "MozTransitionDuration" | "MozTransitionProperty" | "MozTransitionTimingFunction" | "MozUserFocus" | "MozUserInput" | "msImeMode" | "OAnimation" | "OAnimationDelay" | "OAnimationDirection" | "OAnimationDuration" | "OAnimationFillMode" | "OAnimationIterationCount" | "OAnimationName" | "OAnimationPlayState" | "OAnimationTimingFunction" | "OBackgroundSize" | "OBorderImage" | "OObjectFit" | "OObjectPosition" | "OTabSize" | "OTextOverflow" | "OTransform" | "OTransformOrigin" | "OTransition" | "OTransitionDelay" | "OTransitionDuration" | "OTransitionProperty" | "OTransitionTimingFunction" | "WebkitBoxAlign" | "WebkitBoxDirection" | "WebkitBoxFlex" | "WebkitBoxFlexGroup" | "WebkitBoxLines" | "WebkitBoxOrdinalGroup" | "WebkitBoxOrient" | "WebkitBoxPack" | "colorInterpolation" | "colorRendering" | "glyphOrientationVertical" | "svgFill" | "boldFontWeight" | "@keyframes" | "@properties" | "@fontFace" | "@counterStyle" | "recipe" | "element" | "styles" | "breakpoints" | "block" | "inline" | "isHidden" | "isDisabled" | "theme" | "tokens" | "ref"> & RefAttributes<unknown>> & SubElementComponents<Record<string, never>>;
|
|
131
|
+
declare const Element: ForwardRefExoticComponent<Omit<AllBasePropsWithMods<StyleList, readonly never[], readonly never[]>, "slot" | "title" | "children" | "className" | "role" | "id" | "hidden" | "prefix" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "radioGroup" | "about" | "datatype" | "inlist" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "popover" | "popoverTargetAction" | "popoverTarget" | "inert" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onScrollEnd" | "onScrollEndCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onToggle" | "onBeforeToggle" | "onTransitionCancel" | "onTransitionCancelCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "onTransitionRun" | "onTransitionRunCapture" | "onTransitionStart" | "onTransitionStartCapture" | "key"> & WithVariant<VariantMap> & Omit<Omit<AllHTMLAttributes<HTMLElement>, keyof _$react.ClassAttributes<HTMLDivElement> | keyof _$react.HTMLAttributes<HTMLDivElement>> & _$react.ClassAttributes<HTMLDivElement> & _$react.HTMLAttributes<HTMLDivElement>, "style" | "clipPath" | "filter" | "image" | "marker" | "mask" | "fill" | "top" | "right" | "bottom" | "left" | "display" | "font" | "preset" | "hide" | "whiteSpace" | "opacity" | "transition" | "gridArea" | "order" | "gridColumn" | "gridRow" | "placeSelf" | "alignSelf" | "justifySelf" | "zIndex" | "margin" | "inset" | "position" | "scrollMargin" | "padding" | "paddingInline" | "paddingBlock" | "overflow" | "scrollbar" | "textAlign" | "border" | "radius" | "shadow" | "outline" | "color" | "fade" | "textTransform" | "fontWeight" | "fontStyle" | "width" | "height" | "flexBasis" | "flexGrow" | "flexShrink" | "flex" | "flow" | "place" | "placeItems" | "placeContent" | "alignItems" | "alignContent" | "justifyItems" | "justifyContent" | "align" | "justify" | "gap" | "columnGap" | "rowGap" | "gridColumns" | "gridRows" | "gridTemplate" | "gridAreas" | "mods" | "css" | "content" | "translate" | "as" | "background" | "all" | "page" | "qa" | "qaVal" | "scrollMarginTop" | "scrollMarginRight" | "scrollMarginBottom" | "scrollMarginLeft" | "scrollMarginBlock" | "scrollMarginInline" | "accentColor" | "alignTracks" | "alignmentBaseline" | "anchorName" | "anchorScope" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationRangeEnd" | "animationRangeStart" | "animationTimeline" | "animationTimingFunction" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "baselineShift" | "blockSize" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipRule" | "colorAdjust" | "colorInterpolationFilters" | "colorScheme" | "columnCount" | "columnFill" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "containerName" | "containerType" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "cx" | "cy" | "d" | "direction" | "dominantBaseline" | "emptyCells" | "fieldSizing" | "fillOpacity" | "fillRule" | "flexDirection" | "flexWrap" | "float" | "floodColor" | "floodOpacity" | "fontFamily" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontPalette" | "fontSize" | "fontSizeAdjust" | "fontSmooth" | "fontSynthesis" | "fontSynthesisPosition" | "fontSynthesisSmallCaps" | "fontSynthesisStyle" | "fontSynthesisWeight" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantEmoji" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontVariationSettings" | "fontWidth" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "hyphenateCharacter" | "hyphenateLimitChars" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "interpolateSize" | "isolation" | "justifyTracks" | "letterSpacing" | "lightingColor" | "lineBreak" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "markerEnd" | "markerMid" | "markerStart" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "motionDistance" | "motionPath" | "motionRotation" | "objectFit" | "objectPosition" | "objectViewBox" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "offsetRotation" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflowAnchor" | "overflowBlock" | "overflowClipBox" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overlay" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "positionAnchor" | "positionArea" | "positionTryFallbacks" | "positionTryOrder" | "positionVisibility" | "printColorAdjust" | "quotes" | "r" | "resize" | "rotate" | "rubyAlign" | "rubyMerge" | "rubyOverhang" | "rubyPosition" | "rx" | "ry" | "scale" | "scrollBehavior" | "scrollInitialTarget" | "scrollMarginBlockEnd" | "scrollMarginBlockStart" | "scrollMarginInlineEnd" | "scrollMarginInlineStart" | "scrollPaddingBlockEnd" | "scrollPaddingBlockStart" | "scrollPaddingBottom" | "scrollPaddingInlineEnd" | "scrollPaddingInlineStart" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapMarginBottom" | "scrollSnapMarginLeft" | "scrollSnapMarginRight" | "scrollSnapMarginTop" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "shapeRendering" | "speakAs" | "stopColor" | "stopOpacity" | "stroke" | "strokeColor" | "strokeDasharray" | "strokeDashoffset" | "strokeLinecap" | "strokeLinejoin" | "strokeMiterlimit" | "strokeOpacity" | "strokeWidth" | "tabSize" | "tableLayout" | "textAlignLast" | "textAnchor" | "textAutospace" | "textBox" | "textBoxEdge" | "textBoxTrim" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textSpacingTrim" | "textUnderlineOffset" | "textUnderlinePosition" | "textWrapMode" | "textWrapStyle" | "timelineScope" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionBehavior" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "unicodeBidi" | "userSelect" | "vectorEffect" | "verticalAlign" | "viewTimelineAxis" | "viewTimelineInset" | "viewTimelineName" | "viewTransitionClass" | "viewTransitionName" | "visibility" | "whiteSpaceCollapse" | "widows" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "x" | "y" | "zoom" | "animation" | "animationRange" | "backgroundPosition" | "borderBlock" | "borderBlockColor" | "borderBlockEnd" | "borderBlockStart" | "borderBlockStyle" | "borderBlockWidth" | "borderBottom" | "borderColor" | "borderImage" | "borderInline" | "borderInlineColor" | "borderInlineEnd" | "borderInlineStart" | "borderInlineStyle" | "borderInlineWidth" | "borderLeft" | "borderRadius" | "borderRight" | "borderStyle" | "borderTop" | "borderWidth" | "caret" | "columnRule" | "columns" | "containIntrinsicSize" | "container" | "flexFlow" | "grid" | "insetBlock" | "insetInline" | "lineClamp" | "listStyle" | "marginBlock" | "marginInline" | "maskBorder" | "motion" | "offset" | "overscrollBehavior" | "positionTry" | "scrollPadding" | "scrollPaddingBlock" | "scrollPaddingInline" | "scrollSnapMargin" | "scrollTimeline" | "textDecoration" | "textEmphasis" | "textWrap" | "viewTimeline" | "MozAnimationDelay" | "MozAnimationDirection" | "MozAnimationDuration" | "MozAnimationFillMode" | "MozAnimationIterationCount" | "MozAnimationName" | "MozAnimationPlayState" | "MozAnimationTimingFunction" | "MozAppearance" | "MozBackfaceVisibility" | "MozBinding" | "MozBorderBottomColors" | "MozBorderEndColor" | "MozBorderEndStyle" | "MozBorderEndWidth" | "MozBorderLeftColors" | "MozBorderRightColors" | "MozBorderStartColor" | "MozBorderStartStyle" | "MozBorderTopColors" | "MozBoxSizing" | "MozColumnRuleColor" | "MozColumnRuleStyle" | "MozColumnRuleWidth" | "MozColumnWidth" | "MozContextProperties" | "MozFontFeatureSettings" | "MozFontLanguageOverride" | "MozHyphens" | "MozMarginEnd" | "MozMarginStart" | "MozOrient" | "MozOsxFontSmoothing" | "MozOutlineRadiusBottomleft" | "MozOutlineRadiusBottomright" | "MozOutlineRadiusTopleft" | "MozOutlineRadiusTopright" | "MozPaddingEnd" | "MozPaddingStart" | "MozPerspective" | "MozPerspectiveOrigin" | "MozStackSizing" | "MozTabSize" | "MozTextBlink" | "MozTextSizeAdjust" | "MozTransform" | "MozTransformOrigin" | "MozTransformStyle" | "MozUserModify" | "MozUserSelect" | "MozWindowDragging" | "MozWindowShadow" | "msAccelerator" | "msBlockProgression" | "msContentZoomChaining" | "msContentZoomLimitMax" | "msContentZoomLimitMin" | "msContentZoomSnapPoints" | "msContentZoomSnapType" | "msContentZooming" | "msFilter" | "msFlexDirection" | "msFlexPositive" | "msFlowFrom" | "msFlowInto" | "msGridColumns" | "msGridRows" | "msHighContrastAdjust" | "msHyphenateLimitChars" | "msHyphenateLimitLines" | "msHyphenateLimitZone" | "msHyphens" | "msImeAlign" | "msLineBreak" | "msOrder" | "msOverflowStyle" | "msOverflowX" | "msOverflowY" | "msScrollChaining" | "msScrollLimitXMax" | "msScrollLimitXMin" | "msScrollLimitYMax" | "msScrollLimitYMin" | "msScrollRails" | "msScrollSnapPointsX" | "msScrollSnapPointsY" | "msScrollSnapType" | "msScrollTranslation" | "msScrollbar3dlightColor" | "msScrollbarArrowColor" | "msScrollbarBaseColor" | "msScrollbarDarkshadowColor" | "msScrollbarFaceColor" | "msScrollbarHighlightColor" | "msScrollbarShadowColor" | "msScrollbarTrackColor" | "msTextAutospace" | "msTextCombineHorizontal" | "msTextOverflow" | "msTouchAction" | "msTouchSelect" | "msTransform" | "msTransformOrigin" | "msTransitionDelay" | "msTransitionDuration" | "msTransitionProperty" | "msTransitionTimingFunction" | "msUserSelect" | "msWordBreak" | "msWrapFlow" | "msWrapMargin" | "msWrapThrough" | "msWritingMode" | "WebkitAlignContent" | "WebkitAlignItems" | "WebkitAlignSelf" | "WebkitAnimationDelay" | "WebkitAnimationDirection" | "WebkitAnimationDuration" | "WebkitAnimationFillMode" | "WebkitAnimationIterationCount" | "WebkitAnimationName" | "WebkitAnimationPlayState" | "WebkitAnimationTimingFunction" | "WebkitAppearance" | "WebkitBackdropFilter" | "WebkitBackfaceVisibility" | "WebkitBackgroundClip" | "WebkitBackgroundOrigin" | "WebkitBackgroundSize" | "WebkitBorderBeforeColor" | "WebkitBorderBeforeStyle" | "WebkitBorderBeforeWidth" | "WebkitBorderBottomLeftRadius" | "WebkitBorderBottomRightRadius" | "WebkitBorderImageSlice" | "WebkitBorderTopLeftRadius" | "WebkitBorderTopRightRadius" | "WebkitBoxDecorationBreak" | "WebkitBoxReflect" | "WebkitBoxShadow" | "WebkitBoxSizing" | "WebkitClipPath" | "WebkitColumnCount" | "WebkitColumnFill" | "WebkitColumnRuleColor" | "WebkitColumnRuleStyle" | "WebkitColumnRuleWidth" | "WebkitColumnSpan" | "WebkitColumnWidth" | "WebkitFilter" | "WebkitFlexBasis" | "WebkitFlexDirection" | "WebkitFlexGrow" | "WebkitFlexShrink" | "WebkitFlexWrap" | "WebkitFontFeatureSettings" | "WebkitFontKerning" | "WebkitFontSmoothing" | "WebkitFontVariantLigatures" | "WebkitHyphenateCharacter" | "WebkitHyphens" | "WebkitInitialLetter" | "WebkitJustifyContent" | "WebkitLineBreak" | "WebkitLineClamp" | "WebkitLogicalHeight" | "WebkitLogicalWidth" | "WebkitMarginEnd" | "WebkitMarginStart" | "WebkitMaskAttachment" | "WebkitMaskBoxImageOutset" | "WebkitMaskBoxImageRepeat" | "WebkitMaskBoxImageSlice" | "WebkitMaskBoxImageSource" | "WebkitMaskBoxImageWidth" | "WebkitMaskClip" | "WebkitMaskComposite" | "WebkitMaskImage" | "WebkitMaskOrigin" | "WebkitMaskPosition" | "WebkitMaskPositionX" | "WebkitMaskPositionY" | "WebkitMaskRepeat" | "WebkitMaskRepeatX" | "WebkitMaskRepeatY" | "WebkitMaskSize" | "WebkitMaxInlineSize" | "WebkitOrder" | "WebkitOverflowScrolling" | "WebkitPaddingEnd" | "WebkitPaddingStart" | "WebkitPerspective" | "WebkitPerspectiveOrigin" | "WebkitPrintColorAdjust" | "WebkitRubyPosition" | "WebkitScrollSnapType" | "WebkitShapeMargin" | "WebkitTapHighlightColor" | "WebkitTextCombine" | "WebkitTextDecorationColor" | "WebkitTextDecorationLine" | "WebkitTextDecorationSkip" | "WebkitTextDecorationStyle" | "WebkitTextEmphasisColor" | "WebkitTextEmphasisPosition" | "WebkitTextEmphasisStyle" | "WebkitTextFillColor" | "WebkitTextOrientation" | "WebkitTextSizeAdjust" | "WebkitTextStrokeColor" | "WebkitTextStrokeWidth" | "WebkitTextUnderlinePosition" | "WebkitTouchCallout" | "WebkitTransform" | "WebkitTransformOrigin" | "WebkitTransformStyle" | "WebkitTransitionDelay" | "WebkitTransitionDuration" | "WebkitTransitionProperty" | "WebkitTransitionTimingFunction" | "WebkitUserModify" | "WebkitUserSelect" | "WebkitWritingMode" | "MozAnimation" | "MozBorderImage" | "MozColumnRule" | "MozColumns" | "MozOutlineRadius" | "MozTransition" | "msContentZoomLimit" | "msContentZoomSnap" | "msFlex" | "msScrollLimit" | "msScrollSnapX" | "msScrollSnapY" | "msTransition" | "WebkitAnimation" | "WebkitBorderBefore" | "WebkitBorderImage" | "WebkitBorderRadius" | "WebkitColumnRule" | "WebkitColumns" | "WebkitFlex" | "WebkitFlexFlow" | "WebkitMask" | "WebkitMaskBoxImage" | "WebkitTextEmphasis" | "WebkitTextStroke" | "WebkitTransition" | "boxAlign" | "boxDirection" | "boxFlex" | "boxFlexGroup" | "boxLines" | "boxOrdinalGroup" | "boxOrient" | "boxPack" | "clip" | "fontStretch" | "gridColumnGap" | "gridGap" | "gridRowGap" | "imeMode" | "insetArea" | "offsetBlock" | "offsetBlockEnd" | "offsetBlockStart" | "offsetInline" | "offsetInlineEnd" | "offsetInlineStart" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "positionTryOptions" | "scrollSnapCoordinate" | "scrollSnapDestination" | "scrollSnapPointsX" | "scrollSnapPointsY" | "scrollSnapTypeX" | "scrollSnapTypeY" | "KhtmlBoxAlign" | "KhtmlBoxDirection" | "KhtmlBoxFlex" | "KhtmlBoxFlexGroup" | "KhtmlBoxLines" | "KhtmlBoxOrdinalGroup" | "KhtmlBoxOrient" | "KhtmlBoxPack" | "KhtmlLineBreak" | "KhtmlOpacity" | "KhtmlUserSelect" | "MozBackgroundClip" | "MozBackgroundOrigin" | "MozBackgroundSize" | "MozBorderRadius" | "MozBorderRadiusBottomleft" | "MozBorderRadiusBottomright" | "MozBorderRadiusTopleft" | "MozBorderRadiusTopright" | "MozBoxAlign" | "MozBoxDirection" | "MozBoxFlex" | "MozBoxOrdinalGroup" | "MozBoxOrient" | "MozBoxPack" | "MozBoxShadow" | "MozColumnCount" | "MozColumnFill" | "MozFloatEdge" | "MozForceBrokenImageIcon" | "MozOpacity" | "MozOutline" | "MozOutlineColor" | "MozOutlineStyle" | "MozOutlineWidth" | "MozTextAlignLast" | "MozTextDecorationColor" | "MozTextDecorationLine" | "MozTextDecorationStyle" | "MozTransitionDelay" | "MozTransitionDuration" | "MozTransitionProperty" | "MozTransitionTimingFunction" | "MozUserFocus" | "MozUserInput" | "msImeMode" | "OAnimation" | "OAnimationDelay" | "OAnimationDirection" | "OAnimationDuration" | "OAnimationFillMode" | "OAnimationIterationCount" | "OAnimationName" | "OAnimationPlayState" | "OAnimationTimingFunction" | "OBackgroundSize" | "OBorderImage" | "OObjectFit" | "OObjectPosition" | "OTabSize" | "OTextOverflow" | "OTransform" | "OTransformOrigin" | "OTransition" | "OTransitionDelay" | "OTransitionDuration" | "OTransitionProperty" | "OTransitionTimingFunction" | "WebkitBoxAlign" | "WebkitBoxDirection" | "WebkitBoxFlex" | "WebkitBoxFlexGroup" | "WebkitBoxLines" | "WebkitBoxOrdinalGroup" | "WebkitBoxOrient" | "WebkitBoxPack" | "colorInterpolation" | "colorRendering" | "glyphOrientationVertical" | "svgFill" | "boldFontWeight" | "@keyframes" | "@properties" | "@fontFace" | "@counterStyle" | "recipe" | "element" | "styles" | "breakpoints" | "block" | "inline" | "isHidden" | "isDisabled" | "theme" | "tokens" | "ref"> & RefAttributes<unknown>> & SubElementComponents<Record<string, never>>;
|
|
132
132
|
//#endregion
|
|
133
133
|
export { AllBasePropsWithMods, Element, ElementsDefinition, ModPropDef, ModPropsInput, ResolveModPropDef, ResolveModProps, ResolveTokenProps, SubElementDefinition, SubElementProps, TastyElementOptions, TastyElementProps, TastyProps, TokenPropsInput, VariantMap, WithVariant, tasty };
|
|
134
134
|
//# sourceMappingURL=tasty.d.ts.map
|