@tenphi/tasty 2.11.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -7
- package/dist/astro-B53trJyX.js +156 -0
- package/dist/astro-B53trJyX.js.map +1 -0
- package/dist/babel-HlEpSZrj.d.ts +83 -0
- package/dist/{collector-DYA5AOwr.d.ts → collector-BPzZezAG.d.ts} +44 -7
- package/dist/{collector-AHZaBSv8.js → collector-D14DcZx9.js} +75 -14
- package/dist/collector-D14DcZx9.js.map +1 -0
- package/dist/{config-YDAcLaVf.js → config-CCcE_tqx.js} +2312 -1131
- package/dist/config-CCcE_tqx.js.map +1 -0
- package/dist/{config-BtK9fUaz.d.ts → config-D2INrjr_.d.ts} +252 -25
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +6 -6
- package/dist/{core-CS4bzqGu.js → core-B5d0IPi2.js} +85 -133
- package/dist/core-B5d0IPi2.js.map +1 -0
- package/dist/{css-writer-BXSANVrq.js → css-writer-B5DBoxhf.js} +54 -15
- package/dist/css-writer-B5DBoxhf.js.map +1 -0
- package/dist/{format-rules-CYriCDwq.js → format-rules-BbKDjsfO.js} +2 -2
- package/dist/{format-rules-CYriCDwq.js.map → format-rules-BbKDjsfO.js.map} +1 -1
- package/dist/{hydrate-GVTorHpU.js → hydrate-CwALW3J9.js} +3 -11
- package/dist/{hydrate-GVTorHpU.js.map → hydrate-CwALW3J9.js.map} +1 -1
- package/dist/{index-BYtnj_gA.d.ts → index-BAAbdfRs.d.ts} +228 -153
- package/dist/{index-B9ih23uv.d.ts → index-l_NdJSUS.d.ts} +172 -61
- package/dist/index.d.ts +5 -5
- package/dist/index.js +191 -56
- package/dist/index.js.map +1 -1
- package/dist/{keyframes-CtcSlw4k.js → keyframes-B8M1FmtE.js} +10 -181
- package/dist/keyframes-B8M1FmtE.js.map +1 -0
- package/dist/{merge-styles-D4ITH4bc.js → merge-styles--1zOSFlS.js} +2 -2
- package/dist/{merge-styles-D4ITH4bc.js.map → merge-styles--1zOSFlS.js.map} +1 -1
- package/dist/{merge-styles-BZV-XAwX.d.ts → merge-styles-NEvqayL_.d.ts} +2 -2
- package/dist/{resolve-recipes-llr0COs8.js → resolve-recipes-Caix5NnH.js} +3 -3
- package/dist/{resolve-recipes-llr0COs8.js.map → resolve-recipes-Caix5NnH.js.map} +1 -1
- package/dist/ssr/astro-client.js +1 -1
- package/dist/ssr/astro-middleware.js +1 -1
- package/dist/ssr/astro-middleware.js.map +1 -1
- package/dist/ssr/astro.d.ts +1 -5
- package/dist/ssr/astro.js +2 -147
- package/dist/ssr/index.d.ts +2 -9
- package/dist/ssr/index.js +4 -4
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next.d.ts +1 -1
- package/dist/ssr/next.js +5 -6
- package/dist/ssr/next.js.map +1 -1
- package/dist/static/index.d.ts +2 -2
- package/dist/static/index.js +1 -1
- package/dist/zero/babel.d.ts +2 -80
- package/dist/zero/babel.js +27 -23
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +16 -2
- package/dist/zero/index.js +2 -2
- package/dist/zero/next.d.ts +1 -1
- package/dist/zero/next.js +1 -1
- package/dist/zero/next.js.map +1 -1
- package/docs/README.md +3 -1
- package/docs/ai-agents.md +21 -7
- package/docs/configuration.md +220 -30
- package/docs/debug.md +7 -7
- package/docs/design-system.md +2 -2
- package/docs/dsl.md +68 -8
- package/docs/injector.md +46 -4
- package/docs/methodology.md +1 -1
- package/docs/migration-v3.md +285 -0
- package/docs/pipeline.md +3 -3
- package/docs/plugins.md +349 -0
- package/docs/react-api.md +82 -3
- package/docs/ssr.md +40 -33
- package/docs/styles.md +27 -9
- package/docs/tasty-static.md +8 -6
- package/package.json +7 -7
- package/tasty.config.ts +4 -0
- package/dist/collector-AHZaBSv8.js.map +0 -1
- package/dist/config-YDAcLaVf.js.map +0 -1
- package/dist/core-CS4bzqGu.js.map +0 -1
- package/dist/css-writer-BXSANVrq.js.map +0 -1
- package/dist/keyframes-CtcSlw4k.js.map +0 -1
- package/dist/ssr/astro.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import {
|
|
3
|
-
import { A as property,
|
|
4
|
-
import { n as formatPropertyCSS } from "./format-rules-
|
|
5
|
-
import { t as mergeStyles } from "./merge-styles
|
|
6
|
-
import { t as resolveRecipes } from "./resolve-recipes-
|
|
1
|
+
import { $ as SheetManager, $t as getNamedColorHex, A as FLOW_STYLES, At as registerFunctionPolyfill, B as createStateParserContext, Bt as stringifyStyles, C as BASE_STYLES, Ct as LAYOUT_CHUNK_STYLES, D as COLOR_STYLES, Dt as formatFunctionRule, E as BLOCK_STYLES, Ft as getGlobalParser, G as StyleInjector, Gt as createColorFunc, Ht as okhstPlugin, I as isSelector, It as getGlobalPredefinedTokens, L as renderStyles, Lt as normalizeColorTokenValue, M as OUTER_STYLES, Mt as CUSTOM_UNITS, N as POSITION_STYLES, Nt as DIRECTIONS, O as CONTAINER_STYLES, P as TEXT_STYLES, Pt as filterMods, R as parseStateKey, Rt as parseColor, S as baseStylePropsRegistry, St as FONT_CHUNK_STYLES, T as BLOCK_OUTER_STYLES, Tt as STYLE_TO_CHUNK, U as getGlobalPredefinedStates, Ut as okhslFunction, Vt as okhstFunction, W as setGlobalPredefinedStates, Wt as okhslPlugin, X as fontFaceContentHash, Z as formatFontFaceRule, _ as isFunctionsPolyfillEnabled, _t as propHandlerRegistry, a as getGlobalCounterStyles, at as DEFAULT_NAME_PREFIX, b as resetConfig, bt as DIMENSION_CHUNK_STYLES, c as getGlobalInjector, ct as makeCounterStyleName, en as getRgbValuesFromRgbaString, f as getNamePrefix, ft as hashString, g as isConfigLocked, h as hasStylesGenerated, in as resolveFunctionColor, j as INNER_STYLES, k as DIMENSION_STYLES, kt as parseFunctionName, l as getGlobalKeyframes, lt as makeKeyframeName, m as hasGlobalRecipes, n as getConfig, nn as hslToRgbValues, nt as styleHandlers, o as getGlobalFontFaces, ot as DEFAULT_ZERO_NAME_PREFIX, p as hasGlobalKeyframes, q as formatCounterStyleRule, qt as StyleParser, rn as strToRgb, s as getGlobalFunctions, t as configure, tn as hexToRgb, tt as defineHandler, u as getGlobalRecipes, v as isTestEnvironment, vt as APPEARANCE_CHUNK_STYLES, w as BLOCK_INNER_STYLES, wt as POSITION_CHUNK_STYLES, x as generateTypographyTokens, xt as DISPLAY_CHUNK_STYLES, yt as CHUNK_NAMES, zt as parseStyle } from "./config-CCcE_tqx.js";
|
|
2
|
+
import { l as categorizeStyleKeys } from "./keyframes-B8M1FmtE.js";
|
|
3
|
+
import { A as property, C as getRawCSSText, D as injector, E as injectRawCSS, M as ChunkSheetRegistry, N as chunkSheetRegistry, O as isPropertyDefined, S as getCSSTextForNode, T as injectGlobal, _ as destroy, a as color, b as gc, c as hasKeys, d as collectAutoInferredPropertiesRSC, f as getStyleTarget, g as createInjector, h as counterStyle, i as _modAttrs, j as touch, k as keyframes, l as formatKeyframesCSS, m as cleanup, n as processTokens, o as filterBaseProps, p as pushRSCCSS, r as dotize, s as computeStyles, t as tastyDebug, u as collectAutoInferredProperties, v as fontFace, w as inject, x as getCSSText, y as func } from "./core-B5d0IPi2.js";
|
|
4
|
+
import { n as formatPropertyCSS } from "./format-rules-BbKDjsfO.js";
|
|
5
|
+
import { t as mergeStyles } from "./merge-styles--1zOSFlS.js";
|
|
6
|
+
import { t as resolveRecipes } from "./resolve-recipes-Caix5NnH.js";
|
|
7
7
|
import { t as getTastySSRContext } from "./context-CA8YKeMn.js";
|
|
8
8
|
import { t as formatGlobalRules } from "./format-global-rules-DklyaXv-.js";
|
|
9
9
|
import { Fragment, createElement, forwardRef, useContext } from "react";
|
|
@@ -106,7 +106,7 @@ function tasty(Component, options) {
|
|
|
106
106
|
return tastyElement(Component);
|
|
107
107
|
}
|
|
108
108
|
function tastyWrap(Component, options) {
|
|
109
|
-
const { as: extendTag, element: extendElement, ...defaultProps } = options ?? {};
|
|
109
|
+
const { as: extendTag, element: extendElement, styleProps: _styleProps, modProps: _modProps, tokenProps: _tokenProps, variants: _variants, elements: _elements, ...defaultProps } = options ?? {};
|
|
110
110
|
const propsWithStyles = ["styles"].concat(Object.keys(defaultProps).filter((prop) => prop.endsWith("Styles")));
|
|
111
111
|
const _WrappedComponent = forwardRef((props, ref) => {
|
|
112
112
|
const { as, element, ...restProps } = props;
|
|
@@ -154,14 +154,22 @@ function tastyElement(tastyOptions) {
|
|
|
154
154
|
if (!variantStylesMap["default"]) variantStylesMap["default"] = defaultStyles;
|
|
155
155
|
}
|
|
156
156
|
const { qa: defaultQa, qaVal: defaultQaVal, ...otherDefaultProps } = defaultProps ?? {};
|
|
157
|
-
const
|
|
157
|
+
const ownPropsToCheck = styleProps ? styleProps.concat(BASE_STYLES) : BASE_STYLES;
|
|
158
|
+
let propsToCheck = ownPropsToCheck;
|
|
159
|
+
let propsToCheckVersion = -1;
|
|
158
160
|
const modPropsKeys = modPropsDef ? Array.isArray(modPropsDef) ? modPropsDef : Object.keys(modPropsDef) : void 0;
|
|
159
161
|
const tokenPropsMapping = tokenPropsDef ? buildTokenPropsMapping(tokenPropsDef) : void 0;
|
|
160
162
|
const classNameCache = /* @__PURE__ */ new Map();
|
|
161
|
-
const _TastyComponent = forwardRef((
|
|
162
|
-
const
|
|
163
|
+
const _TastyComponent = forwardRef((incomingProps, ref) => {
|
|
164
|
+
const applyPropHandlers = propHandlerRegistry.apply;
|
|
165
|
+
const { as, styles: rawStyles, variant, mods, element, qa, qaVal, className: userClassName, tokens, style, theme, ...otherProps } = applyPropHandlers ? applyPropHandlers(incomingProps) : incomingProps;
|
|
163
166
|
let styles = rawStyles;
|
|
164
167
|
let propStyles = null;
|
|
168
|
+
if (propsToCheckVersion !== baseStylePropsRegistry.version) {
|
|
169
|
+
const promoted = baseStylePropsRegistry.list;
|
|
170
|
+
propsToCheck = promoted.length === 0 ? ownPropsToCheck : ownPropsToCheck.concat(promoted);
|
|
171
|
+
propsToCheckVersion = baseStylePropsRegistry.version;
|
|
172
|
+
}
|
|
165
173
|
for (const prop of propsToCheck) {
|
|
166
174
|
const key = prop;
|
|
167
175
|
if (key in otherProps) {
|
|
@@ -228,6 +236,7 @@ function tastyElement(tastyOptions) {
|
|
|
228
236
|
"data-element": element || defaultElement,
|
|
229
237
|
"data-qa": qa || defaultQa,
|
|
230
238
|
"data-qaval": qaVal || defaultQaVal,
|
|
239
|
+
"data-theme": theme,
|
|
231
240
|
...otherDefaultProps,
|
|
232
241
|
...modDataAttrs || {},
|
|
233
242
|
...otherProps,
|
|
@@ -236,6 +245,7 @@ function tastyElement(tastyOptions) {
|
|
|
236
245
|
ref
|
|
237
246
|
};
|
|
238
247
|
handleIsProperties(elementProps);
|
|
248
|
+
if (elementProps["data-theme"] === void 0) delete elementProps["data-theme"];
|
|
239
249
|
const el = createElement(as ?? originalAs, elementProps);
|
|
240
250
|
if (stylesResult.css) {
|
|
241
251
|
const nonce = getConfig().nonce;
|
|
@@ -287,8 +297,41 @@ function useStyles(styles, options) {
|
|
|
287
297
|
});
|
|
288
298
|
}
|
|
289
299
|
//#endregion
|
|
300
|
+
//#region src/utils/client-state.ts
|
|
301
|
+
/**
|
|
302
|
+
* Build a per-(injector, root) client state cache for the standalone style
|
|
303
|
+
* functions (`useGlobalStyles`, `useRawCSS`, `useKeyframes`, `useCounterStyle`).
|
|
304
|
+
*
|
|
305
|
+
* Two levels, both weak:
|
|
306
|
+
*
|
|
307
|
+
* - **injector** — `configure()` replaces the global injector, and every dispose
|
|
308
|
+
* handle and generated name we cache belongs to the one that produced it.
|
|
309
|
+
* Keying by injector makes stale state fall away with it, instead of letting
|
|
310
|
+
* change-detection keys suppress re-injection into the new sheets.
|
|
311
|
+
* - **root** — the same selector or slot name can be used in several shadow
|
|
312
|
+
* roots, and each holds its own injection.
|
|
313
|
+
*/
|
|
314
|
+
function createClientState(create) {
|
|
315
|
+
const byInjector = /* @__PURE__ */ new WeakMap();
|
|
316
|
+
return (root) => {
|
|
317
|
+
const injector = getGlobalInjector();
|
|
318
|
+
let byRoot = byInjector.get(injector);
|
|
319
|
+
if (!byRoot) {
|
|
320
|
+
byRoot = /* @__PURE__ */ new WeakMap();
|
|
321
|
+
byInjector.set(injector, byRoot);
|
|
322
|
+
}
|
|
323
|
+
let state = byRoot.get(root);
|
|
324
|
+
if (!state) {
|
|
325
|
+
state = create();
|
|
326
|
+
byRoot.set(root, state);
|
|
327
|
+
}
|
|
328
|
+
return state;
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
//#endregion
|
|
290
332
|
//#region src/hooks/useGlobalStyles.ts
|
|
291
|
-
const
|
|
333
|
+
const getClientGlobalSlots = createClientState(() => /* @__PURE__ */ new Map());
|
|
334
|
+
const noop = () => {};
|
|
292
335
|
/**
|
|
293
336
|
* Inject global styles for a given selector.
|
|
294
337
|
* Useful for styling elements by selector without generating classNames.
|
|
@@ -302,6 +345,10 @@ const clientGlobalEntries = /* @__PURE__ */ new Map();
|
|
|
302
345
|
* Use the `id` option for update tracking when styles change over the
|
|
303
346
|
* component lifecycle.
|
|
304
347
|
*
|
|
348
|
+
* Update tracking is per-slot and per-root: a slot (`id`, or the selector when
|
|
349
|
+
* no `id` is given) holds exactly one injection per `root`. Changing the styles
|
|
350
|
+
* replaces it; rendering styles that produce no CSS clears it.
|
|
351
|
+
*
|
|
305
352
|
* @param selector - CSS selector to apply styles to (e.g., '.my-class', ':root', 'body')
|
|
306
353
|
* @param styles - Tasty styles object
|
|
307
354
|
* @param options - Optional settings including `id` for update tracking
|
|
@@ -326,21 +373,29 @@ function useGlobalStyles(selector, styles, options) {
|
|
|
326
373
|
return;
|
|
327
374
|
}
|
|
328
375
|
const target = getStyleTarget();
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
376
|
+
const slots = target.mode === "client" ? getClientGlobalSlots(options?.root ?? document) : null;
|
|
377
|
+
const slotKey = options?.id ?? selector;
|
|
378
|
+
const stylesKey = slots ? JSON.stringify(styles) : "";
|
|
379
|
+
const existing = slots?.get(slotKey);
|
|
380
|
+
if (existing && existing.stylesKey === stylesKey) return;
|
|
335
381
|
const resolvedStyles = resolveRecipes(styles);
|
|
336
382
|
const styleResults = renderStyles(resolvedStyles, selector);
|
|
337
|
-
if (styleResults.length === 0)
|
|
383
|
+
if (styleResults.length === 0) {
|
|
384
|
+
if (slots) {
|
|
385
|
+
existing?.dispose();
|
|
386
|
+
slots.set(slotKey, {
|
|
387
|
+
stylesKey,
|
|
388
|
+
dispose: noop
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
338
393
|
if (target.mode === "ssr") {
|
|
339
394
|
target.collector.collectInternals();
|
|
340
395
|
const css = formatGlobalRules(styleResults);
|
|
341
396
|
if (css) {
|
|
342
397
|
const key = options?.id ? `global:${options.id}` : `global:${selector}:${hashString(css)}`;
|
|
343
|
-
target.collector.collectGlobalStyles(key, css);
|
|
398
|
+
target.collector.collectGlobalStyles(key, css, options?.id != null);
|
|
344
399
|
}
|
|
345
400
|
if (getConfig().autoPropertyTypes !== false) collectAutoInferredProperties(styleResults, target.collector, resolvedStyles);
|
|
346
401
|
return;
|
|
@@ -349,19 +404,19 @@ function useGlobalStyles(selector, styles, options) {
|
|
|
349
404
|
const css = formatGlobalRules(styleResults);
|
|
350
405
|
if (css) {
|
|
351
406
|
const key = options?.id ? `__global:${options.id}` : `__global:${selector}:${hashString(css)}`;
|
|
352
|
-
pushRSCCSS(target.cache, key, css);
|
|
407
|
+
pushRSCCSS(target.cache, key, css, options?.id != null);
|
|
353
408
|
}
|
|
354
409
|
if (getConfig().autoPropertyTypes !== false) collectAutoInferredPropertiesRSC(styleResults, target.cache, resolvedStyles);
|
|
355
410
|
return;
|
|
356
411
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
412
|
+
if (slots) {
|
|
413
|
+
existing?.dispose();
|
|
414
|
+
const { dispose } = injectGlobal(styleResults, { root: options?.root });
|
|
415
|
+
slots.set(slotKey, {
|
|
416
|
+
stylesKey,
|
|
417
|
+
dispose
|
|
418
|
+
});
|
|
419
|
+
}
|
|
365
420
|
}
|
|
366
421
|
//#endregion
|
|
367
422
|
//#region src/utils/deps-equal.ts
|
|
@@ -377,9 +432,11 @@ function depsEqual(a, b) {
|
|
|
377
432
|
}
|
|
378
433
|
//#endregion
|
|
379
434
|
//#region src/hooks/useRawCSS.ts
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
|
|
435
|
+
const getClientState$1 = createClientState(() => ({
|
|
436
|
+
entries: /* @__PURE__ */ new Map(),
|
|
437
|
+
contentDedup: /* @__PURE__ */ new Set(),
|
|
438
|
+
factoryDeps: /* @__PURE__ */ new Map()
|
|
439
|
+
}));
|
|
383
440
|
/**
|
|
384
441
|
* Inject raw CSS text directly without parsing.
|
|
385
442
|
* This is a low-overhead alternative for injecting global CSS that doesn't need tasty processing.
|
|
@@ -435,53 +492,59 @@ function useRawCSS(cssOrFactory, depsOrOptions, options) {
|
|
|
435
492
|
const deps = isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : void 0;
|
|
436
493
|
const opts = isFactory ? options : depsOrOptions;
|
|
437
494
|
const target = getStyleTarget();
|
|
438
|
-
|
|
439
|
-
|
|
495
|
+
const state = target.mode === "client" ? getClientState$1(opts?.root ?? document) : null;
|
|
496
|
+
if (isFactory && deps && opts?.id && state) {
|
|
497
|
+
const cachedDeps = state.factoryDeps.get(opts.id);
|
|
440
498
|
if (cachedDeps && depsEqual(cachedDeps, deps)) return;
|
|
441
499
|
}
|
|
442
500
|
const css = isFactory ? cssOrFactory() : cssOrFactory;
|
|
443
501
|
if (!css.trim()) return;
|
|
444
502
|
if (target.mode === "ssr") {
|
|
445
503
|
const key = opts?.id ? `raw:${opts.id}` : `raw:${hashString(css)}`;
|
|
446
|
-
target.collector.collectRawCSS(key, css);
|
|
504
|
+
target.collector.collectRawCSS(key, css, opts?.id != null);
|
|
447
505
|
return;
|
|
448
506
|
}
|
|
449
507
|
if (target.mode === "rsc") {
|
|
450
508
|
const key = opts?.id ? `__raw:${opts.id}` : `__raw:${hashString(css)}`;
|
|
451
|
-
pushRSCCSS(target.cache, key, css);
|
|
509
|
+
pushRSCCSS(target.cache, key, css, opts?.id != null);
|
|
452
510
|
return;
|
|
453
511
|
}
|
|
512
|
+
if (!state) return;
|
|
454
513
|
const id = opts?.id;
|
|
455
514
|
if (id) {
|
|
456
|
-
const existing =
|
|
515
|
+
const existing = state.entries.get(id);
|
|
457
516
|
if (existing) {
|
|
458
517
|
if (existing.contentKey === css) return;
|
|
459
518
|
existing.dispose();
|
|
460
519
|
}
|
|
461
520
|
const { dispose } = injectRawCSS(css, opts);
|
|
462
|
-
|
|
521
|
+
state.entries.set(id, {
|
|
463
522
|
contentKey: css,
|
|
464
523
|
dispose
|
|
465
524
|
});
|
|
466
|
-
if (deps)
|
|
525
|
+
if (deps) state.factoryDeps.set(id, deps);
|
|
467
526
|
} else {
|
|
468
527
|
const contentKey = hashString(css);
|
|
469
|
-
if (
|
|
470
|
-
|
|
528
|
+
if (state.contentDedup.has(contentKey)) return;
|
|
529
|
+
state.contentDedup.add(contentKey);
|
|
471
530
|
injectRawCSS(css, opts);
|
|
472
531
|
}
|
|
473
532
|
}
|
|
474
533
|
//#endregion
|
|
475
534
|
//#region src/hooks/useKeyframes.ts
|
|
476
|
-
const
|
|
477
|
-
|
|
535
|
+
const getClientState = createClientState(() => ({
|
|
536
|
+
contentToName: /* @__PURE__ */ new Map(),
|
|
537
|
+
namedSlots: /* @__PURE__ */ new Map(),
|
|
538
|
+
factoryDeps: /* @__PURE__ */ new Map()
|
|
539
|
+
}));
|
|
478
540
|
function useKeyframes(stepsOrFactory, depsOrOptions, options) {
|
|
479
541
|
const isFactory = typeof stepsOrFactory === "function";
|
|
480
542
|
const deps = isFactory && Array.isArray(depsOrOptions) ? depsOrOptions : void 0;
|
|
481
543
|
const opts = isFactory ? options : depsOrOptions;
|
|
482
544
|
const target = getStyleTarget();
|
|
483
|
-
|
|
484
|
-
|
|
545
|
+
const clientState = target.mode === "client" ? getClientState(opts?.root ?? document) : null;
|
|
546
|
+
if (isFactory && deps && opts?.name && clientState) {
|
|
547
|
+
const cached = clientState.factoryDeps.get(opts.name);
|
|
485
548
|
if (cached && depsEqual(cached.deps, deps)) return cached.name;
|
|
486
549
|
}
|
|
487
550
|
const steps = isFactory ? stepsOrFactory() : stepsOrFactory;
|
|
@@ -503,19 +566,36 @@ function useKeyframes(stepsOrFactory, depsOrOptions, options) {
|
|
|
503
566
|
target.cache.generatedNames.set(key, actualName);
|
|
504
567
|
return actualName;
|
|
505
568
|
}
|
|
569
|
+
const state = clientState ?? getClientState(opts?.root ?? document);
|
|
506
570
|
const serializedContent = JSON.stringify(steps);
|
|
507
571
|
const cacheKey = `${opts?.name ?? ""}:${serializedContent}`;
|
|
508
|
-
const cachedName =
|
|
572
|
+
const cachedName = state.contentToName.get(cacheKey);
|
|
509
573
|
if (cachedName) return cachedName;
|
|
510
|
-
const
|
|
511
|
-
|
|
574
|
+
const providedName = opts?.name;
|
|
575
|
+
if (providedName) {
|
|
576
|
+
const slot = state.namedSlots.get(providedName);
|
|
577
|
+
if (slot && slot.cacheKey !== cacheKey) {
|
|
578
|
+
slot.dispose();
|
|
579
|
+
state.contentToName.delete(slot.cacheKey);
|
|
580
|
+
state.namedSlots.delete(providedName);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
const result = keyframes(steps, {
|
|
584
|
+
name: providedName,
|
|
512
585
|
root: opts?.root
|
|
513
|
-
}).toString();
|
|
514
|
-
clientContentToName$1.set(cacheKey, name);
|
|
515
|
-
if (deps && opts?.name) factoryDepsCache.set(opts.name, {
|
|
516
|
-
deps,
|
|
517
|
-
name
|
|
518
586
|
});
|
|
587
|
+
const name = result.toString();
|
|
588
|
+
state.contentToName.set(cacheKey, name);
|
|
589
|
+
if (providedName) {
|
|
590
|
+
state.namedSlots.set(providedName, {
|
|
591
|
+
cacheKey,
|
|
592
|
+
dispose: result.dispose
|
|
593
|
+
});
|
|
594
|
+
if (deps) state.factoryDeps.set(providedName, {
|
|
595
|
+
deps,
|
|
596
|
+
name
|
|
597
|
+
});
|
|
598
|
+
}
|
|
519
599
|
return name;
|
|
520
600
|
}
|
|
521
601
|
//#endregion
|
|
@@ -671,7 +751,7 @@ function useFontFace(family, input, options) {
|
|
|
671
751
|
//#endregion
|
|
672
752
|
//#region src/hooks/useCounterStyle.ts
|
|
673
753
|
let clientCounterStyleCounter = 0;
|
|
674
|
-
const
|
|
754
|
+
const getClientContentToName = createClientState(() => /* @__PURE__ */ new Map());
|
|
675
755
|
/**
|
|
676
756
|
* Inject a CSS @counter-style rule and return the generated name.
|
|
677
757
|
* Permanent — no cleanup on unmount. Deduplicates by name.
|
|
@@ -717,16 +797,71 @@ function useCounterStyle(descriptors, options) {
|
|
|
717
797
|
target.cache.generatedNames.set(key, actualName);
|
|
718
798
|
return actualName;
|
|
719
799
|
}
|
|
800
|
+
const contentToName = getClientContentToName(options?.root ?? document);
|
|
720
801
|
const serializedContent = JSON.stringify(descriptors);
|
|
721
802
|
const cacheKey = `${options?.name ?? ""}:${serializedContent}`;
|
|
722
|
-
const existingName =
|
|
803
|
+
const existingName = contentToName.get(cacheKey);
|
|
723
804
|
if (existingName) return existingName;
|
|
724
805
|
const name = options?.name ?? makeCounterStyleName(getNamePrefix(), String(clientCounterStyleCounter++));
|
|
725
|
-
|
|
806
|
+
contentToName.set(cacheKey, name);
|
|
726
807
|
getGlobalInjector().counterStyle(name, descriptors, { root: options?.root });
|
|
727
808
|
return name;
|
|
728
809
|
}
|
|
729
810
|
//#endregion
|
|
730
|
-
|
|
811
|
+
//#region src/hooks/useFunction.ts
|
|
812
|
+
/**
|
|
813
|
+
* Register a CSS @function (custom function).
|
|
814
|
+
*
|
|
815
|
+
* @function rules are global and persistent once defined. The hook ensures the
|
|
816
|
+
* function is only registered once per root (deduplicated by function name).
|
|
817
|
+
*
|
|
818
|
+
* Accepts tasty token syntax for the function name:
|
|
819
|
+
* - `$$name` → defines `--name` (matches the call site `$$name(...)`)
|
|
820
|
+
* - `$name` / `--name` → also accepted
|
|
821
|
+
*
|
|
822
|
+
* Works in all environments: client, SSR with collector, and React Server Components.
|
|
823
|
+
*
|
|
824
|
+
* @param name - The function name token (`$$name`, `$name`, or `--name`)
|
|
825
|
+
* @param definition - Function definition (args, returns, result, local vars)
|
|
826
|
+
*
|
|
827
|
+
* Call the function through the Tasty DSL, not a raw `style` prop: an inline
|
|
828
|
+
* `style` value reaches the browser unparsed, so the `$$name(...)` sugar is never
|
|
829
|
+
* expanded and `polyfills.functions` cannot rewrite it either.
|
|
830
|
+
*
|
|
831
|
+
* @example
|
|
832
|
+
* ```tsx
|
|
833
|
+
* const Box = tasty({ styles: { marginTop: '$$negative(10px)' } });
|
|
834
|
+
*
|
|
835
|
+
* function Layout() {
|
|
836
|
+
* useFunction('$$negative', { args: ['$value'], result: '(-1 * $value)' });
|
|
837
|
+
* return <Box />;
|
|
838
|
+
* }
|
|
839
|
+
* ```
|
|
840
|
+
*/
|
|
841
|
+
function useFunction(name, definition, options) {
|
|
842
|
+
if (!name) {
|
|
843
|
+
console.warn(`[Tasty] useFunction: function name is required`);
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
if (isFunctionsPolyfillEnabled()) {
|
|
847
|
+
registerFunctionPolyfill(name, definition);
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
const target = getStyleTarget();
|
|
851
|
+
if (target.mode === "ssr") {
|
|
852
|
+
target.collector.collectInternals();
|
|
853
|
+
const css = formatFunctionRule(name, definition);
|
|
854
|
+
if (css) target.collector.collectFunction(parseFunctionName(name), css);
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
if (target.mode === "rsc") {
|
|
858
|
+
const css = formatFunctionRule(name, definition);
|
|
859
|
+
if (css) pushRSCCSS(target.cache, `__func:${parseFunctionName(name)}`, css);
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
getGlobalInjector().func(name, definition, { root: options?.root });
|
|
863
|
+
}
|
|
864
|
+
//#endregion
|
|
865
|
+
export { APPEARANCE_CHUNK_STYLES, BASE_STYLES, BLOCK_INNER_STYLES, BLOCK_OUTER_STYLES, BLOCK_STYLES, CHUNK_NAMES, COLOR_STYLES, CONTAINER_STYLES, CUSTOM_UNITS, ChunkSheetRegistry, DEFAULT_NAME_PREFIX, DEFAULT_ZERO_NAME_PREFIX, DIMENSION_CHUNK_STYLES, DIMENSION_STYLES, DIRECTIONS, DISPLAY_CHUNK_STYLES, Element, FLOW_STYLES, FONT_CHUNK_STYLES, INNER_STYLES, LAYOUT_CHUNK_STYLES, OUTER_STYLES, POSITION_CHUNK_STYLES, POSITION_STYLES, STYLE_TO_CHUNK, SheetManager, StyleInjector, StyleParser, TEXT_STYLES, categorizeStyleKeys, chunkSheetRegistry, cleanup, color, computeStyles, configure, counterStyle, createColorFunc, createInjector, createStateParserContext, defineHandler, destroy, dotize, filterBaseProps, filterMods, fontFace, func, gc, generateTypographyTokens, getCSSText, getCSSTextForNode, getConfig, getDisplayName, getGlobalCounterStyles, getGlobalFontFaces, getGlobalFunctions, getGlobalKeyframes, getGlobalParser, getGlobalPredefinedStates, getGlobalPredefinedTokens, getGlobalRecipes, getNamePrefix, getNamedColorHex, getRawCSSText, getRgbValuesFromRgbaString, hasGlobalKeyframes, hasGlobalRecipes, hasStylesGenerated, hexToRgb, hslToRgbValues, inject, injectGlobal, injectRawCSS, injector, isConfigLocked, isPropertyDefined, isSelector, isTestEnvironment, keyframes, mergeStyles, _modAttrs as modAttrs, normalizeColorTokenValue, okhslFunction, okhslPlugin, okhstFunction, okhstPlugin, parseColor, parseStateKey, parseStyle, processTokens, property, renderStyles, resetConfig, resolveFunctionColor, resolveRecipes, setGlobalPredefinedStates, strToRgb, stringifyStyles, styleHandlers, tasty, tastyDebug, touch, useCounterStyle, useFontFace, useFunction, useGlobalStyles, useKeyframes, useProperty, useRawCSS, useStyles };
|
|
731
866
|
|
|
732
867
|
//# sourceMappingURL=index.js.map
|