@tenphi/tasty 0.0.0-snapshot.e9718c0 → 0.0.0-snapshot.ea42c0b
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 +97 -230
- package/dist/{ssr/async-storage.js → async-storage-B7_o6FKt.js} +17 -8
- package/dist/async-storage-B7_o6FKt.js.map +1 -0
- package/dist/{ssr/collector.js → collector-C4sagPeG.js} +84 -37
- package/dist/collector-C4sagPeG.js.map +1 -0
- package/dist/{ssr/collector.d.ts → collector-LuU1vZ68.d.ts} +28 -15
- package/dist/config-BovFXQil.js +10234 -0
- package/dist/config-BovFXQil.js.map +1 -0
- package/dist/config-vuCRkBWX.d.ts +884 -0
- package/dist/context-CkSg-kDT.js +24 -0
- package/dist/context-CkSg-kDT.js.map +1 -0
- package/dist/core/index.d.ts +5 -34
- package/dist/core/index.js +6 -27
- package/dist/core-CpKZ2RrZ.js +1592 -0
- package/dist/core-CpKZ2RrZ.js.map +1 -0
- package/dist/{zero/extractor.js → css-writer-BYgviy4G.js} +125 -11
- package/dist/css-writer-BYgviy4G.js.map +1 -0
- package/dist/{ssr/format-global-rules.js → format-global-rules-Dbc_1tc3.js} +3 -3
- package/dist/format-global-rules-Dbc_1tc3.js.map +1 -0
- package/dist/format-rules-BBK7s2il.js +143 -0
- package/dist/format-rules-BBK7s2il.js.map +1 -0
- package/dist/hydrate-DN98QICD.js +45 -0
- package/dist/hydrate-DN98QICD.js.map +1 -0
- package/dist/index-ZRxZWzlj.d.ts +1602 -0
- package/dist/index-dUtwpOux.d.ts +1266 -0
- package/dist/index.d.ts +5 -49
- package/dist/index.js +731 -33
- package/dist/index.js.map +1 -0
- package/dist/keyframes-Bzl_6mN0.js +587 -0
- package/dist/keyframes-Bzl_6mN0.js.map +1 -0
- package/dist/{utils/merge-styles.js → merge-styles-BjdI0NVL.js} +4 -6
- package/dist/merge-styles-BjdI0NVL.js.map +1 -0
- package/dist/{utils/merge-styles.d.ts → merge-styles-CtDJMhpJ.d.ts} +3 -3
- package/dist/{utils/resolve-recipes.js → resolve-recipes-9zJQojHT.js} +5 -8
- package/dist/resolve-recipes-9zJQojHT.js.map +1 -0
- package/dist/ssr/astro-client.d.ts +1 -0
- package/dist/ssr/astro-client.js +19 -0
- package/dist/ssr/astro-client.js.map +1 -0
- package/dist/ssr/astro-middleware.d.ts +15 -0
- package/dist/ssr/astro-middleware.js +19 -0
- package/dist/ssr/astro-middleware.js.map +1 -0
- package/dist/ssr/astro.d.ts +78 -10
- package/dist/ssr/astro.js +116 -32
- package/dist/ssr/astro.js.map +1 -1
- package/dist/ssr/index.d.ts +44 -5
- package/dist/ssr/index.js +7 -9
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next.d.ts +7 -6
- package/dist/ssr/next.js +18 -14
- package/dist/ssr/next.js.map +1 -1
- package/dist/static/index.d.ts +91 -5
- package/dist/static/index.js +49 -4
- package/dist/static/index.js.map +1 -0
- package/dist/static/inject.d.ts +5 -0
- package/dist/static/inject.js +17 -0
- package/dist/static/inject.js.map +1 -0
- package/dist/zero/babel.d.ts +27 -101
- package/dist/zero/babel.js +172 -52
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +67 -3
- package/dist/zero/index.js +2 -4
- package/dist/zero/next.d.ts +12 -0
- package/dist/zero/next.js +5 -4
- package/dist/zero/next.js.map +1 -1
- package/docs/README.md +5 -5
- package/docs/adoption.md +6 -4
- package/docs/comparison.md +25 -26
- package/docs/configuration.md +130 -1
- package/docs/debug.md +11 -9
- package/docs/design-system.md +47 -12
- package/docs/dsl.md +156 -9
- package/docs/getting-started.md +10 -10
- package/docs/injector.md +43 -27
- package/docs/methodology.md +119 -6
- package/docs/{PIPELINE.md → pipeline.md} +204 -50
- package/docs/react-api.md +557 -0
- package/docs/ssr.md +141 -81
- package/docs/styles.md +45 -23
- package/docs/tasty-static.md +103 -2
- package/package.json +23 -11
- package/dist/_virtual/_rolldown/runtime.js +0 -8
- package/dist/chunks/cacheKey.js +0 -78
- package/dist/chunks/cacheKey.js.map +0 -1
- package/dist/chunks/definitions.d.ts +0 -37
- package/dist/chunks/definitions.js +0 -259
- package/dist/chunks/definitions.js.map +0 -1
- package/dist/chunks/renderChunk.js +0 -60
- package/dist/chunks/renderChunk.js.map +0 -1
- package/dist/config.d.ts +0 -323
- package/dist/config.js +0 -465
- package/dist/config.js.map +0 -1
- package/dist/debug.d.ts +0 -89
- package/dist/debug.js +0 -454
- package/dist/debug.js.map +0 -1
- package/dist/hooks/useGlobalStyles.d.ts +0 -30
- package/dist/hooks/useGlobalStyles.js +0 -83
- package/dist/hooks/useGlobalStyles.js.map +0 -1
- package/dist/hooks/useKeyframes.d.ts +0 -56
- package/dist/hooks/useKeyframes.js +0 -69
- package/dist/hooks/useKeyframes.js.map +0 -1
- package/dist/hooks/useProperty.d.ts +0 -79
- package/dist/hooks/useProperty.js +0 -114
- package/dist/hooks/useProperty.js.map +0 -1
- package/dist/hooks/useRawCSS.d.ts +0 -53
- package/dist/hooks/useRawCSS.js +0 -40
- package/dist/hooks/useRawCSS.js.map +0 -1
- package/dist/hooks/useStyles.d.ts +0 -45
- package/dist/hooks/useStyles.js +0 -249
- package/dist/hooks/useStyles.js.map +0 -1
- package/dist/injector/index.d.ts +0 -165
- package/dist/injector/index.js +0 -162
- package/dist/injector/index.js.map +0 -1
- package/dist/injector/injector.d.ts +0 -148
- package/dist/injector/injector.js +0 -430
- package/dist/injector/injector.js.map +0 -1
- package/dist/injector/sheet-manager.d.ts +0 -136
- package/dist/injector/sheet-manager.js +0 -729
- package/dist/injector/sheet-manager.js.map +0 -1
- package/dist/injector/types.d.ts +0 -144
- package/dist/keyframes/index.js +0 -206
- package/dist/keyframes/index.js.map +0 -1
- package/dist/parser/classify.js +0 -320
- package/dist/parser/classify.js.map +0 -1
- package/dist/parser/const.js +0 -33
- package/dist/parser/const.js.map +0 -1
- package/dist/parser/lru.js +0 -109
- package/dist/parser/lru.js.map +0 -1
- package/dist/parser/parser.d.ts +0 -25
- package/dist/parser/parser.js +0 -116
- package/dist/parser/parser.js.map +0 -1
- package/dist/parser/tokenizer.js +0 -69
- package/dist/parser/tokenizer.js.map +0 -1
- package/dist/parser/types.d.ts +0 -51
- package/dist/parser/types.js +0 -46
- package/dist/parser/types.js.map +0 -1
- package/dist/pipeline/conditions.d.ts +0 -134
- package/dist/pipeline/conditions.js +0 -406
- package/dist/pipeline/conditions.js.map +0 -1
- package/dist/pipeline/exclusive.js +0 -231
- package/dist/pipeline/exclusive.js.map +0 -1
- package/dist/pipeline/index.d.ts +0 -53
- package/dist/pipeline/index.js +0 -670
- package/dist/pipeline/index.js.map +0 -1
- package/dist/pipeline/materialize.js +0 -1105
- package/dist/pipeline/materialize.js.map +0 -1
- package/dist/pipeline/parseStateKey.d.ts +0 -15
- package/dist/pipeline/parseStateKey.js +0 -447
- package/dist/pipeline/parseStateKey.js.map +0 -1
- package/dist/pipeline/simplify.js +0 -516
- package/dist/pipeline/simplify.js.map +0 -1
- package/dist/pipeline/warnings.js +0 -18
- package/dist/pipeline/warnings.js.map +0 -1
- package/dist/plugins/okhsl-plugin.d.ts +0 -35
- package/dist/plugins/okhsl-plugin.js +0 -98
- package/dist/plugins/okhsl-plugin.js.map +0 -1
- package/dist/plugins/types.d.ts +0 -76
- package/dist/properties/index.js +0 -223
- package/dist/properties/index.js.map +0 -1
- package/dist/properties/property-type-resolver.d.ts +0 -24
- package/dist/properties/property-type-resolver.js +0 -91
- package/dist/properties/property-type-resolver.js.map +0 -1
- package/dist/ssr/async-storage.d.ts +0 -17
- package/dist/ssr/async-storage.js.map +0 -1
- package/dist/ssr/collect-auto-properties.js +0 -40
- package/dist/ssr/collect-auto-properties.js.map +0 -1
- package/dist/ssr/collector.js.map +0 -1
- package/dist/ssr/context.d.ts +0 -8
- package/dist/ssr/context.js +0 -14
- package/dist/ssr/context.js.map +0 -1
- package/dist/ssr/format-global-rules.js.map +0 -1
- package/dist/ssr/format-keyframes.js +0 -70
- package/dist/ssr/format-keyframes.js.map +0 -1
- package/dist/ssr/format-property.js +0 -50
- package/dist/ssr/format-property.js.map +0 -1
- package/dist/ssr/format-rules.js +0 -70
- package/dist/ssr/format-rules.js.map +0 -1
- package/dist/ssr/hydrate.d.ts +0 -22
- package/dist/ssr/hydrate.js +0 -50
- package/dist/ssr/hydrate.js.map +0 -1
- package/dist/ssr/ssr-collector-ref.js +0 -12
- package/dist/ssr/ssr-collector-ref.js.map +0 -1
- package/dist/states/index.d.ts +0 -49
- package/dist/states/index.js +0 -169
- package/dist/states/index.js.map +0 -1
- package/dist/static/tastyStatic.d.ts +0 -46
- package/dist/static/tastyStatic.js +0 -31
- package/dist/static/tastyStatic.js.map +0 -1
- package/dist/static/types.d.ts +0 -49
- package/dist/static/types.js +0 -24
- package/dist/static/types.js.map +0 -1
- package/dist/styles/align.d.ts +0 -15
- package/dist/styles/align.js +0 -14
- package/dist/styles/align.js.map +0 -1
- package/dist/styles/border.d.ts +0 -25
- package/dist/styles/border.js +0 -114
- package/dist/styles/border.js.map +0 -1
- package/dist/styles/color.d.ts +0 -14
- package/dist/styles/color.js +0 -27
- package/dist/styles/color.js.map +0 -1
- package/dist/styles/createStyle.js +0 -80
- package/dist/styles/createStyle.js.map +0 -1
- package/dist/styles/dimension.js +0 -97
- package/dist/styles/dimension.js.map +0 -1
- package/dist/styles/display.d.ts +0 -37
- package/dist/styles/display.js +0 -67
- package/dist/styles/display.js.map +0 -1
- package/dist/styles/fade.d.ts +0 -15
- package/dist/styles/fade.js +0 -58
- package/dist/styles/fade.js.map +0 -1
- package/dist/styles/fill.d.ts +0 -42
- package/dist/styles/fill.js +0 -52
- package/dist/styles/fill.js.map +0 -1
- package/dist/styles/flow.d.ts +0 -16
- package/dist/styles/flow.js +0 -12
- package/dist/styles/flow.js.map +0 -1
- package/dist/styles/gap.d.ts +0 -31
- package/dist/styles/gap.js +0 -37
- package/dist/styles/gap.js.map +0 -1
- package/dist/styles/height.d.ts +0 -17
- package/dist/styles/height.js +0 -20
- package/dist/styles/height.js.map +0 -1
- package/dist/styles/index.d.ts +0 -2
- package/dist/styles/index.js +0 -9
- package/dist/styles/index.js.map +0 -1
- package/dist/styles/inset.d.ts +0 -52
- package/dist/styles/inset.js +0 -150
- package/dist/styles/inset.js.map +0 -1
- package/dist/styles/justify.d.ts +0 -15
- package/dist/styles/justify.js +0 -14
- package/dist/styles/justify.js.map +0 -1
- package/dist/styles/list.d.ts +0 -16
- package/dist/styles/list.js +0 -98
- package/dist/styles/list.js.map +0 -1
- package/dist/styles/margin.d.ts +0 -24
- package/dist/styles/margin.js +0 -104
- package/dist/styles/margin.js.map +0 -1
- package/dist/styles/outline.d.ts +0 -29
- package/dist/styles/outline.js +0 -65
- package/dist/styles/outline.js.map +0 -1
- package/dist/styles/padding.d.ts +0 -24
- package/dist/styles/padding.js +0 -104
- package/dist/styles/padding.js.map +0 -1
- package/dist/styles/predefined.d.ts +0 -71
- package/dist/styles/predefined.js +0 -238
- package/dist/styles/predefined.js.map +0 -1
- package/dist/styles/preset.d.ts +0 -47
- package/dist/styles/preset.js +0 -126
- package/dist/styles/preset.js.map +0 -1
- package/dist/styles/radius.d.ts +0 -14
- package/dist/styles/radius.js +0 -51
- package/dist/styles/radius.js.map +0 -1
- package/dist/styles/scrollbar.d.ts +0 -25
- package/dist/styles/scrollbar.js +0 -48
- package/dist/styles/scrollbar.js.map +0 -1
- package/dist/styles/shadow.d.ts +0 -14
- package/dist/styles/shadow.js +0 -24
- package/dist/styles/shadow.js.map +0 -1
- package/dist/styles/transition.d.ts +0 -14
- package/dist/styles/transition.js +0 -158
- package/dist/styles/transition.js.map +0 -1
- package/dist/styles/types.d.ts +0 -523
- package/dist/styles/width.d.ts +0 -17
- package/dist/styles/width.js +0 -20
- package/dist/styles/width.js.map +0 -1
- package/dist/tasty.d.ts +0 -981
- package/dist/tasty.js +0 -219
- package/dist/tasty.js.map +0 -1
- package/dist/types.d.ts +0 -184
- package/dist/utils/cache-wrapper.js +0 -22
- package/dist/utils/cache-wrapper.js.map +0 -1
- package/dist/utils/case-converter.js +0 -8
- package/dist/utils/case-converter.js.map +0 -1
- package/dist/utils/color-math.d.ts +0 -46
- package/dist/utils/color-math.js +0 -749
- package/dist/utils/color-math.js.map +0 -1
- package/dist/utils/color-space.d.ts +0 -5
- package/dist/utils/color-space.js +0 -229
- package/dist/utils/color-space.js.map +0 -1
- package/dist/utils/colors.d.ts +0 -5
- package/dist/utils/colors.js +0 -11
- package/dist/utils/colors.js.map +0 -1
- package/dist/utils/css-types.d.ts +0 -7
- package/dist/utils/dotize.d.ts +0 -26
- package/dist/utils/dotize.js +0 -122
- package/dist/utils/dotize.js.map +0 -1
- package/dist/utils/filter-base-props.d.ts +0 -15
- package/dist/utils/filter-base-props.js +0 -45
- package/dist/utils/filter-base-props.js.map +0 -1
- package/dist/utils/get-display-name.d.ts +0 -7
- package/dist/utils/get-display-name.js +0 -10
- package/dist/utils/get-display-name.js.map +0 -1
- package/dist/utils/has-keys.js +0 -13
- package/dist/utils/has-keys.js.map +0 -1
- package/dist/utils/is-dev-env.js +0 -19
- package/dist/utils/is-dev-env.js.map +0 -1
- package/dist/utils/is-valid-element-type.js +0 -15
- package/dist/utils/is-valid-element-type.js.map +0 -1
- package/dist/utils/merge-styles.js.map +0 -1
- package/dist/utils/mod-attrs.d.ts +0 -8
- package/dist/utils/mod-attrs.js +0 -21
- package/dist/utils/mod-attrs.js.map +0 -1
- package/dist/utils/process-tokens.d.ts +0 -21
- package/dist/utils/process-tokens.js +0 -91
- package/dist/utils/process-tokens.js.map +0 -1
- package/dist/utils/resolve-recipes.d.ts +0 -17
- package/dist/utils/resolve-recipes.js.map +0 -1
- package/dist/utils/selector-transform.js +0 -32
- package/dist/utils/selector-transform.js.map +0 -1
- package/dist/utils/string.js +0 -8
- package/dist/utils/string.js.map +0 -1
- package/dist/utils/styles.d.ts +0 -101
- package/dist/utils/styles.js +0 -223
- package/dist/utils/styles.js.map +0 -1
- package/dist/utils/typography.d.ts +0 -47
- package/dist/utils/typography.js +0 -43
- package/dist/utils/typography.js.map +0 -1
- package/dist/utils/warnings.d.ts +0 -16
- package/dist/utils/warnings.js +0 -16
- package/dist/utils/warnings.js.map +0 -1
- package/dist/zero/css-writer.d.ts +0 -45
- package/dist/zero/css-writer.js +0 -74
- package/dist/zero/css-writer.js.map +0 -1
- package/dist/zero/extractor.d.ts +0 -24
- package/dist/zero/extractor.js.map +0 -1
- package/docs/runtime.md +0 -341
package/README.md
CHANGED
|
@@ -17,21 +17,32 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
Tasty is a styling engine for design systems that generates deterministic CSS for stateful components.
|
|
20
|
+
Tasty is a styling engine for design systems that generates deterministic CSS for stateful components.
|
|
21
21
|
|
|
22
|
-
It
|
|
22
|
+
It compiles state maps into **mutually exclusive selectors**, so for a given property and component state, one branch wins by construction instead of competing through cascade and specificity.
|
|
23
|
+
|
|
24
|
+
That is the core guarantee: component styling resolves from declared state logic, not from source-order accidents or specificity fights.
|
|
25
|
+
|
|
26
|
+
Tasty fits best when you are building a design system or component library with intersecting states, variants, tokens, sub-elements, responsive rules, and extension semantics that need to stay predictable over time.
|
|
27
|
+
|
|
28
|
+
On top of that foundation, Tasty gives teams a governed styling model: a CSS-like DSL, tokens, recipes, typed style props, sub-elements, and multiple rendering modes.
|
|
29
|
+
|
|
30
|
+
- **New here?** Start with [Comparison](docs/comparison.md) if you are evaluating fit.
|
|
31
|
+
- **Adopting Tasty?** Read the [Adoption Guide](docs/adoption.md).
|
|
32
|
+
- **Want the mechanism first?** Jump to [How It Actually Works](#how-it-actually-works).
|
|
33
|
+
- **Ready to build?** Go to [Getting Started](docs/getting-started.md).
|
|
23
34
|
|
|
24
35
|
## Why Tasty
|
|
25
36
|
|
|
26
|
-
- **Deterministic composition, not cascade fights** —
|
|
27
|
-
- **Built for design-system teams** — Best fit for
|
|
28
|
-
- **A governed styling model, not just syntax sugar** —
|
|
29
|
-
- **DSL that still feels like CSS** —
|
|
37
|
+
- **Deterministic composition, not cascade fights** — Stateful styles resolve from the state map you declared, not from selector competition. See [How It Actually Works](#how-it-actually-works).
|
|
38
|
+
- **Built for design-system teams** — Best fit for reusable component systems with complex state interactions.
|
|
39
|
+
- **A governed styling model, not just syntax sugar** — Design-system authors define the styling language product teams consume.
|
|
40
|
+
- **DSL that still feels like CSS** — Familiar property names, less selector boilerplate. Start with the [Style DSL](docs/dsl.md), then use [Style Properties](docs/styles.md) as the handler reference.
|
|
30
41
|
|
|
31
42
|
### Supporting capabilities
|
|
32
43
|
|
|
33
|
-
- **Typed style props** — `styleProps`
|
|
34
|
-
- **
|
|
44
|
+
- **Typed style props and mod props** — `styleProps` exposes selected CSS properties as typed React props (`<Space flow="row" gap="2x">`); `modProps` does the same for modifier keys (`<Button isLoading size="large">`). Both support state maps and full TypeScript autocomplete. See [Style Props](#style-props) and [Mod Props](#mod-props).
|
|
45
|
+
- **Server-compatible by default, zero client JS in server-only contexts** — All `tasty()` components and style functions are hook-free. In server-only rendering (Next.js RSC, Astro without islands, SSG), they produce zero client JavaScript with the full feature set. Add SSR integration only when your app also has client-side hydration. Use `tastyStatic()` only when you need build-time extraction without React.
|
|
35
46
|
- **Broad modern CSS coverage** — Media queries, container queries, `@supports`, `:has()`, `@starting-style`, `@property`, `@keyframes`, and more. Features that do not fit the component model (such as `@layer` and `!important`) are intentionally left out.
|
|
36
47
|
- **Performance and caching** — Runtime mode injects CSS on demand, reuses chunks aggressively, and relies on multi-level caching so large component systems stay practical.
|
|
37
48
|
- **TypeScript-first and AI-friendly** — Style definitions are declarative, structurally consistent, and fully typed, which helps both humans and tooling understand advanced stateful styles without hidden cascade logic.
|
|
@@ -40,7 +51,7 @@ It fits best when a team is defining a house styling language for reusable compo
|
|
|
40
51
|
|
|
41
52
|
Modern component styling becomes fragile when multiple selectors can still win for the same property. Hover, disabled, theme, breakpoint, parent state, and root state rules start competing through specificity and source order.
|
|
42
53
|
|
|
43
|
-
Tasty replaces that competition with explicit state-map resolution. Each property compiles into mutually exclusive branches, so
|
|
54
|
+
Tasty replaces that competition with explicit state-map resolution. Each property compiles into mutually exclusive branches, so component styling stays deterministic as systems grow. For the full mechanism, jump to [How It Actually Works](#how-it-actually-works).
|
|
44
55
|
|
|
45
56
|
## Installation
|
|
46
57
|
|
|
@@ -63,10 +74,12 @@ yarn add @tenphi/tasty
|
|
|
63
74
|
|
|
64
75
|
## Start Here
|
|
65
76
|
|
|
77
|
+
For the fuller docs map beyond the quick routes above, start here:
|
|
78
|
+
|
|
66
79
|
- **[Comparison](docs/comparison.md)** — read this first if you are evaluating whether Tasty fits your team's styling model
|
|
67
80
|
- **[Adoption Guide](docs/adoption.md)** — understand who Tasty is for, where it fits, and how to introduce it incrementally
|
|
68
81
|
- **[Getting Started](docs/getting-started.md)** — the canonical onboarding path: install, first component, optional shared `configure()`, ESLint, editor tooling, and rendering mode selection
|
|
69
|
-
- **[Style rendering pipeline](docs/
|
|
82
|
+
- **[Style rendering pipeline](docs/pipeline.md)** — see the selector model behind deterministic style resolution
|
|
70
83
|
- **[Docs Hub](docs/README.md)** — choose docs by role and task: runtime, zero-runtime, runtime SSR integration, design-system authoring, internals, and debugging
|
|
71
84
|
- **[Methodology](docs/methodology.md)** — the recommended component model and public API conventions for design-system code
|
|
72
85
|
|
|
@@ -95,7 +108,9 @@ const Card = tasty({
|
|
|
95
108
|
<Card>Hello World</Card>
|
|
96
109
|
```
|
|
97
110
|
|
|
98
|
-
Every value maps to CSS you'd recognize. This example is intentionally
|
|
111
|
+
Every value maps to CSS you'd recognize. This example is intentionally a simple first contact, not a tour of the whole DSL.
|
|
112
|
+
|
|
113
|
+
When you want a more design-system-shaped authoring model, Tasty also supports built-in units, tokens, recipes, state aliases, and color values such as `okhsl(...)` without extra runtime libraries.
|
|
99
114
|
|
|
100
115
|
Use `configure()` when you want to define shared tokens, state aliases, recipes, or other conventions for your app or design system. For a fuller onboarding path, follow [Getting Started](docs/getting-started.md).
|
|
101
116
|
|
|
@@ -163,58 +178,17 @@ configure({
|
|
|
163
178
|
|
|
164
179
|
Use `configure()` once when your app or design system needs shared aliases, tokens, recipes, or parser extensions. Predefined states turn complex selector logic into single tokens, so teams can write `@mobile` instead of repeating media query expressions in every component.
|
|
165
180
|
|
|
166
|
-
###
|
|
167
|
-
|
|
168
|
-
Beyond state resolution, Tasty can also expose selected style controls as typed component props. That lets design systems keep layout and composition inside governed component APIs instead of pushing teams toward wrapper elements or ad hoc styling escapes.
|
|
169
|
-
|
|
170
|
-
With `styleProps`, a component can expose the styles you choose as normal typed props. You can adjust layout, spacing, alignment, or positioning where the component is used while staying inside a typed, design-system-aware API.
|
|
171
|
-
|
|
172
|
-
```tsx
|
|
173
|
-
import { tasty, FLOW_STYLES, POSITION_STYLES } from '@tenphi/tasty';
|
|
174
|
-
|
|
175
|
-
const Space = tasty({
|
|
176
|
-
styles: {
|
|
177
|
-
display: 'flex',
|
|
178
|
-
flow: 'column',
|
|
179
|
-
gap: '1x',
|
|
180
|
-
},
|
|
181
|
-
styleProps: FLOW_STYLES,
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
const Button = tasty({
|
|
185
|
-
as: 'button',
|
|
186
|
-
styles: {
|
|
187
|
-
padding: '1.5x 3x',
|
|
188
|
-
fill: '#primary',
|
|
189
|
-
color: '#primary-text',
|
|
190
|
-
radius: true,
|
|
191
|
-
},
|
|
192
|
-
styleProps: POSITION_STYLES,
|
|
193
|
-
});
|
|
194
|
-
```
|
|
181
|
+
### Props as the public API
|
|
195
182
|
|
|
196
|
-
|
|
183
|
+
`styleProps` exposes selected CSS properties as typed React props, and `modProps` does the same for modifier keys. Together they let design systems define a governed, typed component API without wrapper elements or `styles` overrides:
|
|
197
184
|
|
|
198
185
|
```tsx
|
|
199
186
|
<Space flow="row" gap="2x" placeItems="center">
|
|
200
|
-
<
|
|
201
|
-
<Button placeSelf="end">Add Item</Button>
|
|
202
|
-
</Space>
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
The same props also support state maps, so responsive values use the exact same API:
|
|
206
|
-
|
|
207
|
-
```tsx
|
|
208
|
-
<Space
|
|
209
|
-
flow={{ '': 'column', '@tablet': 'row' }}
|
|
210
|
-
gap={{ '': '2x', '@tablet': '4x' }}
|
|
211
|
-
>
|
|
212
|
-
<Sidebar />
|
|
213
|
-
<Content />
|
|
187
|
+
<Button isLoading size="large" placeSelf="end">Submit</Button>
|
|
214
188
|
</Space>
|
|
215
189
|
```
|
|
216
190
|
|
|
217
|
-
|
|
191
|
+
See [Style Props](#style-props) and [Mod Props](#mod-props) below, or the full reference in [React API](docs/react-api.md#style-props).
|
|
218
192
|
|
|
219
193
|
## Choose a Styling Approach
|
|
220
194
|
|
|
@@ -222,16 +196,17 @@ Once you understand the component model, pick the rendering mode that matches yo
|
|
|
222
196
|
|
|
223
197
|
| Approach | Entry point | Best for | Trade-off |
|
|
224
198
|
|----------|-------------|----------|-----------|
|
|
225
|
-
| **Runtime** | `@tenphi/tasty` |
|
|
226
|
-
| **
|
|
199
|
+
| **Runtime (default)** | `tasty()` from `@tenphi/tasty` | All React apps — server-rendered by default, zero client JS until you need interactivity | Full feature set; CSS computed during React rendering (server or client) |
|
|
200
|
+
| **Runtime + SSR integration** | Add `@tenphi/tasty/ssr/*` | Apps with client-side hydration (Next.js client components, Astro islands) | Adds CSS deduplication, FOUC prevention, and client cache hydration |
|
|
201
|
+
| **Zero-runtime** | `tastyStatic()` from `@tenphi/tasty/static` | Non-React frameworks or when you need build-time extraction without React | Requires the Babel plugin; no component-level `styleProps` or runtime-only APIs |
|
|
227
202
|
|
|
228
|
-
|
|
203
|
+
All `tasty()` components are hook-free and work as React Server Components. In server-only contexts — Next.js RSC without `'use client'`, Astro without `client:*` directives, and other SSG setups — they produce the same end result as `tastyStatic()` (static HTML + CSS, zero client JavaScript) but with the full feature set including `styleProps`, sub-elements, and variants. SSR integration is only needed when your app also has client-side rendering. See [Getting Started](docs/getting-started.md#choosing-a-rendering-mode), [Zero Runtime](docs/tasty-static.md), and [Server-Side Rendering](docs/ssr.md).
|
|
229
204
|
|
|
230
205
|
## How It Actually Works
|
|
231
206
|
|
|
232
207
|
This is the core idea that makes everything else possible.
|
|
233
208
|
|
|
234
|
-
For the end-to-end architecture — parsing state keys, building exclusive conditions, merging by output, and materializing selectors and at-rules — see **[Style rendering pipeline](docs/
|
|
209
|
+
For the end-to-end architecture — parsing state keys, building exclusive conditions, merging by output, and materializing selectors and at-rules — see **[Style rendering pipeline](docs/pipeline.md)**.
|
|
235
210
|
|
|
236
211
|
### The structural problem with normal CSS
|
|
237
212
|
|
|
@@ -327,7 +302,7 @@ Every rule is guarded by the negation of higher-priority rules. No two rules can
|
|
|
327
302
|
|
|
328
303
|
By absorbing selector complexity, Tasty makes advanced CSS patterns practical again — nested container queries, multi-condition `@supports` gates, and combined root-state/media branches. You stay in pure CSS instead of relying on JavaScript workarounds, so the browser can optimize layout, painting, and transitions natively. Tasty keeps the solution in CSS while removing much of the selector bookkeeping that is hard to maintain by hand.
|
|
329
304
|
|
|
330
|
-
[Try it in the
|
|
305
|
+
[Try it in the playground →](https://tasty.style/playground)
|
|
331
306
|
|
|
332
307
|
## Capabilities
|
|
333
308
|
|
|
@@ -373,7 +348,7 @@ Every style property accepts a state mapping object. Keys can be combined with b
|
|
|
373
348
|
| Feature query | `@supports(display: grid)` | `@supports (display: grid)` |
|
|
374
349
|
| Entry animation | `@starting` | `@starting-style` |
|
|
375
350
|
|
|
376
|
-
Combine with `&` (AND), `|` (OR), `!` (NOT):
|
|
351
|
+
Combine with `&` (AND), `|` (OR), `!` (NOT), `^` (XOR):
|
|
377
352
|
|
|
378
353
|
```tsx
|
|
379
354
|
fill: {
|
|
@@ -385,220 +360,109 @@ fill: {
|
|
|
385
360
|
|
|
386
361
|
### Sub-Element Styling
|
|
387
362
|
|
|
388
|
-
|
|
363
|
+
Compound components can style inner parts from the parent definition with capitalized keys in `styles` and optional `elements` declarations, producing typed sub-components like `<Card.Title />` instead of separate wrapper components or ad hoc class naming.
|
|
389
364
|
|
|
390
|
-
|
|
391
|
-
const Card = tasty({
|
|
392
|
-
styles: {
|
|
393
|
-
padding: '4x',
|
|
394
|
-
Title: { preset: 'h3', color: '#primary' },
|
|
395
|
-
Content: { color: '#text', preset: 't2' },
|
|
396
|
-
},
|
|
397
|
-
elements: { Title: 'h2', Content: 'div' },
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
<Card>
|
|
401
|
-
<Card.Title>Heading</Card.Title>
|
|
402
|
-
<Card.Content>Body text</Card.Content>
|
|
403
|
-
</Card>
|
|
404
|
-
```
|
|
365
|
+
Sub-elements share the root state context by default, so keys like `:hover`, modifiers, root states, and media queries resolve as one coordinated styling block. Use `@own(...)` when a sub-element should react to its own state, and use the `$` selector affix when you need precise descendant targeting.
|
|
405
366
|
|
|
406
|
-
Sub-
|
|
367
|
+
See [React API - Sub-element Styling](docs/react-api.md#sub-element-styling), [Style DSL - Advanced States](docs/dsl.md#advanced-states--prefix), and [Methodology](docs/methodology.md#component-architecture-root--sub-elements).
|
|
407
368
|
|
|
408
|
-
|
|
369
|
+
### Style Props
|
|
409
370
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
Class selectors are also supported, but modifiers/pseudo-classes are usually the better default in design-system code.
|
|
413
|
-
|
|
414
|
-
Use the sub-element selector `$` when you need precise descendant targeting to avoid leakage in deeply nested component trees.
|
|
415
|
-
|
|
416
|
-
### Variants
|
|
417
|
-
|
|
418
|
-
Variants are designed to keep single-component CSS lean. Instead of generating dozens of static button classes up front, define all versions once and let runtime usage decide what CSS is actually emitted.
|
|
371
|
+
`styleProps` exposes selected CSS properties as typed React props. Components control which properties to open up; consumers get layout and composition knobs without `styles` overrides. Supports state maps for responsive values.
|
|
419
372
|
|
|
420
373
|
```tsx
|
|
421
|
-
const
|
|
422
|
-
styles: {
|
|
423
|
-
|
|
424
|
-
default: { fill: '#primary', color: '#on-primary' },
|
|
425
|
-
danger: { fill: '#danger', color: '#on-danger' },
|
|
426
|
-
outline: { fill: 'transparent', border: '1bw solid #primary' },
|
|
427
|
-
},
|
|
374
|
+
const Space = tasty({
|
|
375
|
+
styles: { display: 'flex', flow: 'column', gap: '1x' },
|
|
376
|
+
styleProps: FLOW_STYLES,
|
|
428
377
|
});
|
|
429
378
|
|
|
430
|
-
<
|
|
379
|
+
<Space flow="row" gap={{ '': '2x', '@tablet': '4x' }}>
|
|
431
380
|
```
|
|
432
381
|
|
|
433
|
-
|
|
382
|
+
See [React API - Style Props](docs/react-api.md#style-props) and [Methodology - styleProps](docs/methodology.md#styleprops-as-the-public-api).
|
|
434
383
|
|
|
435
|
-
|
|
384
|
+
### Mod Props
|
|
436
385
|
|
|
437
|
-
|
|
438
|
-
configure({
|
|
439
|
-
recipes: {
|
|
440
|
-
card: { padding: '4x', fill: '#surface', radius: '1r', border: true },
|
|
441
|
-
elevated: { shadow: '0 2x 4x #shadow' },
|
|
442
|
-
},
|
|
443
|
-
});
|
|
386
|
+
`modProps` exposes modifier keys as typed React props — the modifier equivalent of `styleProps`. Accepts an array of key names or an object with type descriptors (`Boolean`, `String`, `Number`, or enum arrays) for full TypeScript autocomplete.
|
|
444
387
|
|
|
445
|
-
|
|
388
|
+
```tsx
|
|
389
|
+
const Button = tasty({
|
|
390
|
+
as: 'button',
|
|
391
|
+
modProps: { isLoading: Boolean, size: ['sm', 'md', 'lg'] as const },
|
|
446
392
|
styles: {
|
|
447
|
-
|
|
448
|
-
|
|
393
|
+
fill: { '': '#primary', isLoading: '#primary.5' },
|
|
394
|
+
padding: { '': '2x 4x', 'size=sm': '1x 2x' },
|
|
449
395
|
},
|
|
450
396
|
});
|
|
451
|
-
```
|
|
452
397
|
|
|
453
|
-
|
|
398
|
+
<Button isLoading size="lg">Submit</Button>
|
|
399
|
+
```
|
|
454
400
|
|
|
455
|
-
|
|
401
|
+
See [React API - Mod Props](docs/react-api.md#mod-props) and [Methodology - modProps](docs/methodology.md#modprops-and-mods).
|
|
456
402
|
|
|
457
|
-
|
|
403
|
+
### Variants
|
|
458
404
|
|
|
459
|
-
|
|
405
|
+
Variants let one component expose named visual versions without pre-generating a separate class for every possible combination. In runtime mode, Tasty emits only the variant CSS that is actually used.
|
|
460
406
|
|
|
461
|
-
|
|
462
|
-
const Pulse = tasty({
|
|
463
|
-
styles: {
|
|
464
|
-
animation: 'pulse 2s infinite',
|
|
465
|
-
transform: 'scale($pulse-scale)',
|
|
466
|
-
'@keyframes': {
|
|
467
|
-
pulse: {
|
|
468
|
-
'0%, 100%': { '$pulse-scale': 1 },
|
|
469
|
-
'50%': { '$pulse-scale': 1.05 },
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
},
|
|
473
|
-
});
|
|
474
|
-
```
|
|
407
|
+
See [React API - Variants](docs/react-api.md#variants).
|
|
475
408
|
|
|
476
|
-
|
|
409
|
+
### Recipes
|
|
477
410
|
|
|
478
|
-
|
|
411
|
+
Recipes are reusable style bundles defined in `configure({ recipes })` and applied with the `recipe` style property. They are useful when your design system wants shared state logic or visual presets without forcing every component to repeat the same style map.
|
|
479
412
|
|
|
480
|
-
|
|
413
|
+
Use `/` to post-apply recipes after local styles when recipe states should win the final merge order, and use `none` to skip base recipes entirely.
|
|
481
414
|
|
|
482
|
-
|
|
415
|
+
See [Style DSL - Recipes](docs/dsl.md#recipes) and [Configuration - recipes](docs/configuration.md#recipes).
|
|
483
416
|
|
|
484
|
-
|
|
485
|
-
'@properties': {
|
|
486
|
-
'$pulse-scale': { syntax: '<number>', inherits: false, initialValue: 1 },
|
|
487
|
-
},
|
|
488
|
-
```
|
|
417
|
+
### Auto-Inferred `@property`
|
|
489
418
|
|
|
490
|
-
|
|
419
|
+
Tasty usually removes the need to hand-author CSS [`@property`](https://developer.mozilla.org/en-US/docs/Web/CSS/@property) rules. When a custom property receives a concrete value, Tasty infers its syntax and registers the matching `@property` automatically, which makes transitions and animations on custom properties work without extra boilerplate.
|
|
491
420
|
|
|
492
|
-
|
|
421
|
+
If you prefer explicit control, disable inference with `configure({ autoPropertyTypes: false })` or declare the properties yourself.
|
|
493
422
|
|
|
494
|
-
|
|
495
|
-
import { useStyles, useGlobalStyles, useRawCSS } from '@tenphi/tasty';
|
|
423
|
+
See [Style DSL - Properties (`@property`)](docs/dsl.md#properties-property).
|
|
496
424
|
|
|
497
|
-
|
|
498
|
-
const { className } = useStyles({ padding: '2x', fill: '#surface' });
|
|
499
|
-
useGlobalStyles('body', { margin: '0' });
|
|
500
|
-
useRawCSS('@font-face { font-family: "Custom"; src: url(...); }');
|
|
425
|
+
### Explicit `@properties`
|
|
501
426
|
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
```
|
|
427
|
+
Use explicit `@properties` only when you need to override defaults such as `inherits: false` or a custom `initialValue`.
|
|
505
428
|
|
|
506
|
-
|
|
429
|
+
See [Style DSL - Properties (`@property`)](docs/dsl.md#properties-property).
|
|
507
430
|
|
|
508
|
-
|
|
431
|
+
### Style Functions
|
|
509
432
|
|
|
510
|
-
|
|
511
|
-
import { tastyStatic } from '@tenphi/tasty/static';
|
|
433
|
+
When you do not need a full component wrapper, use the style functions directly: `useStyles` for local class names, `useGlobalStyles` for selector-scoped global CSS, `useRawCSS` for raw rules, plus `useKeyframes`, `useProperty`, `useFontFace`, and `useCounterStyle` for animation, custom-property, font, and counter-style primitives. All style functions are hook-free and work in React Server Components.
|
|
512
434
|
|
|
513
|
-
|
|
514
|
-
padding: '4x',
|
|
515
|
-
fill: '#surface',
|
|
516
|
-
radius: '1r',
|
|
517
|
-
color: { '': '#text', '@dark': '#text-on-dark' },
|
|
518
|
-
});
|
|
435
|
+
See [React API - Style Functions](docs/react-api.md#style-functions).
|
|
519
436
|
|
|
520
|
-
|
|
521
|
-
<div className={card}>Static styles, zero runtime</div>
|
|
522
|
-
```
|
|
437
|
+
### Zero-Runtime Mode
|
|
523
438
|
|
|
524
|
-
|
|
439
|
+
Use `tastyStatic` when you want the same DSL and state model, but with CSS extracted at build time and no styling runtime in the client bundle. It is a strong fit for static sites, landing pages, and other build-time-first setups.
|
|
525
440
|
|
|
526
|
-
|
|
527
|
-
module.exports = {
|
|
528
|
-
plugins: [
|
|
529
|
-
['@tenphi/tasty/babel-plugin', {
|
|
530
|
-
output: 'public/tasty.css',
|
|
531
|
-
config: {
|
|
532
|
-
states: { '@dark': '@root(schema=dark)' },
|
|
533
|
-
},
|
|
534
|
-
}],
|
|
535
|
-
],
|
|
536
|
-
};
|
|
537
|
-
```
|
|
441
|
+
See [Zero Runtime (tastyStatic)](docs/tasty-static.md) and [Getting Started - Choosing a rendering mode](docs/getting-started.md#choosing-a-rendering-mode).
|
|
538
442
|
|
|
539
443
|
### `tasty` vs `tastyStatic`
|
|
540
444
|
|
|
541
|
-
|
|
542
|
-
|---|---|---|
|
|
543
|
-
| **Output** | React component | CSS class name |
|
|
544
|
-
| **CSS injection** | Runtime `<style>` tags | Build-time extraction |
|
|
545
|
-
| **Runtime cost** | Style generation on mount | None |
|
|
546
|
-
| **Generated CSS scope** | Only styles/variants used at runtime | All extracted static styles at build time |
|
|
547
|
-
| **Dynamic values** | Fully supported | Via CSS custom properties |
|
|
548
|
-
| **Sub-elements** | Built-in (`<C.Title>`) | Manual (`data-element`) |
|
|
549
|
-
| **Variants** | Built-in (`variants` option) | Separate static styles |
|
|
550
|
-
| **Framework** | React | Any (requires Babel) |
|
|
551
|
-
| **Best for** | Interactive apps with reusable stateful components, design systems | Static sites, SSG, landing pages |
|
|
445
|
+
`tasty()` returns React components that compute CSS during rendering. In server-only contexts, this produces static HTML + CSS with zero client JavaScript — the same end result as `tastyStatic()` but with the full feature set. `tastyStatic()` returns class names and extracts CSS during the build via a Babel plugin, with no React dependency at runtime. Both share the same DSL, tokens, units, state mappings, and recipes. Use `tasty()` as the default for any React-based setup; use `tastyStatic()` when you need build-time extraction without React.
|
|
552
446
|
|
|
553
|
-
|
|
447
|
+
See [Zero Runtime (tastyStatic)](docs/tasty-static.md), [React API](docs/react-api.md), and [Comparison - Build-time vs runtime](docs/comparison.md#build-time-vs-runtime).
|
|
554
448
|
|
|
555
449
|
### Server-Side Rendering
|
|
556
450
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
**Next.js setup:**
|
|
451
|
+
`tasty()` components already work on the server without any SSR integration — they are hook-free and render as React Server Components by default. In server-only contexts (Next.js RSC, Astro without islands), they produce zero client JavaScript with the full feature set.
|
|
560
452
|
|
|
561
|
-
|
|
562
|
-
// app/tasty-registry.tsx
|
|
563
|
-
'use client';
|
|
564
|
-
|
|
565
|
-
import { TastyRegistry } from '@tenphi/tasty/ssr/next';
|
|
453
|
+
SSR integration (`TastyRegistry`, `tastyIntegration`) adds CSS batching, deduplication across component trees, FOUC prevention, and client cache hydration. Use it when your app also has client-side rendering:
|
|
566
454
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
children: React.ReactNode;
|
|
571
|
-
}) {
|
|
572
|
-
return <TastyRegistry>{children}</TastyRegistry>;
|
|
573
|
-
}
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
```tsx
|
|
577
|
-
// app/layout.tsx
|
|
578
|
-
import TastyStyleRegistry from './tasty-registry';
|
|
579
|
-
|
|
580
|
-
export default function RootLayout({
|
|
581
|
-
children,
|
|
582
|
-
}: {
|
|
583
|
-
children: React.ReactNode;
|
|
584
|
-
}) {
|
|
585
|
-
return (
|
|
586
|
-
<html>
|
|
587
|
-
<body>
|
|
588
|
-
<TastyStyleRegistry>{children}</TastyStyleRegistry>
|
|
589
|
-
</body>
|
|
590
|
-
</html>
|
|
591
|
-
);
|
|
592
|
-
}
|
|
593
|
-
```
|
|
455
|
+
- `@tenphi/tasty/ssr/next` for Next.js App Router (mixed server + client components)
|
|
456
|
+
- `@tenphi/tasty/ssr/astro` for Astro (with or without islands)
|
|
457
|
+
- The core SSR API for other React SSR setups
|
|
594
458
|
|
|
595
|
-
See the [full SSR guide](docs/ssr.md)
|
|
459
|
+
See the [full SSR guide](docs/ssr.md).
|
|
596
460
|
|
|
597
461
|
## Entry Points
|
|
598
462
|
|
|
599
463
|
| Import | Description | Platform |
|
|
600
464
|
|--------|-------------|----------|
|
|
601
|
-
| `@tenphi/tasty` | Runtime style engine (`tasty`,
|
|
465
|
+
| `@tenphi/tasty` | Runtime style engine (`tasty`, style functions, `configure`) | Browser |
|
|
602
466
|
| `@tenphi/tasty/static` | Zero-runtime static styles (`tastyStatic`) | Browser |
|
|
603
467
|
| `@tenphi/tasty/core` | Lower-level internals (config, parser, pipeline, injector, style handlers) for tooling and advanced use | Browser / Node |
|
|
604
468
|
| `@tenphi/tasty/babel-plugin` | Babel plugin for zero-runtime CSS extraction | Node |
|
|
@@ -606,7 +470,8 @@ See the [full SSR guide](docs/ssr.md) for Astro integration, streaming SSR, gene
|
|
|
606
470
|
| `@tenphi/tasty/next` | Next.js integration wrapper | Node |
|
|
607
471
|
| `@tenphi/tasty/ssr` | Core SSR API (collector, context, hydration) | Node |
|
|
608
472
|
| `@tenphi/tasty/ssr/next` | Next.js App Router SSR integration | Node |
|
|
609
|
-
| `@tenphi/tasty/ssr/astro` | Astro
|
|
473
|
+
| `@tenphi/tasty/ssr/astro` | Astro integration + middleware | Node |
|
|
474
|
+
| `@tenphi/tasty/ssr/astro-client` | Astro client-side cache hydration | Browser |
|
|
610
475
|
|
|
611
476
|
## Browser Requirements
|
|
612
477
|
|
|
@@ -624,11 +489,13 @@ All sizes measured with [size-limit](https://github.com/ai/size-limit) — minif
|
|
|
624
489
|
|
|
625
490
|
| Entry point | Size |
|
|
626
491
|
|-------------|------|
|
|
627
|
-
| `@tenphi/tasty` (runtime + SSR) |
|
|
628
|
-
| `@tenphi/tasty/core` (runtime, no SSR) |
|
|
629
|
-
| `@tenphi/tasty/static` (zero-runtime) |
|
|
492
|
+
| `@tenphi/tasty` (runtime + SSR) | 50.19 kB |
|
|
493
|
+
| `@tenphi/tasty/core` (runtime, no SSR) | 47.76 kB |
|
|
494
|
+
| `@tenphi/tasty/static` (zero-runtime) | 16.43 kB |
|
|
495
|
+
| `@tenphi/tasty/zero` (programmatic extraction) | 29.6 kB |
|
|
496
|
+
| `@tenphi/tasty/babel-plugin` (Babel plugin entry) | 43.7 kB |
|
|
630
497
|
|
|
631
|
-
Run `pnpm size`
|
|
498
|
+
Run `pnpm size` to reproduce (outputs may shift slightly with releases).
|
|
632
499
|
|
|
633
500
|
### Runtime Benchmarks
|
|
634
501
|
|
|
@@ -746,7 +613,7 @@ Start from the docs hub if you want the shortest path to the right guide for you
|
|
|
746
613
|
### Reference
|
|
747
614
|
|
|
748
615
|
- **[Style DSL](docs/dsl.md)** — The Tasty style language: state maps, tokens, units, color syntax, extending semantics, recipes, keyframes, and @property
|
|
749
|
-
- **[
|
|
616
|
+
- **[React API](docs/react-api.md)** — React-specific API: `tasty()` factory, component props, variants, sub-elements, and style functions
|
|
750
617
|
- **[Configuration](docs/configuration.md)** — Global configuration: tokens, recipes, custom units, style handlers, and TypeScript extensions
|
|
751
618
|
- **[Style Properties](docs/styles.md)** — Complete reference for all enhanced style properties: syntax, values, modifiers, and recommendations
|
|
752
619
|
|
|
@@ -757,7 +624,7 @@ Start from the docs hub if you want the shortest path to the right guide for you
|
|
|
757
624
|
|
|
758
625
|
### Internals
|
|
759
626
|
|
|
760
|
-
- **[Style rendering pipeline](docs/
|
|
627
|
+
- **[Style rendering pipeline](docs/pipeline.md)** — How `Styles` become mutually exclusive CSS rules: parse → exclusives → combinations → handlers → merge → materialize (`src/pipeline/`)
|
|
761
628
|
- **[Style Injector](docs/injector.md)** — Internal CSS injection engine: `inject()`, `injectGlobal()`, `injectRawCSS()`, `keyframes()`, deduplication, reference counting, cleanup, SSR support, and Shadow DOM
|
|
762
629
|
- **[Debug Utilities](docs/debug.md)** — Runtime CSS inspection via `tastyDebug`: CSS extraction, element inspection, cache metrics, chunk breakdown, and performance monitoring
|
|
763
630
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
-
|
|
3
2
|
//#region src/ssr/async-storage.ts
|
|
4
3
|
/**
|
|
5
4
|
* AsyncLocalStorage integration for SSR collector discovery.
|
|
@@ -9,27 +8,37 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
9
8
|
* The middleware calls runWithCollector() around the render, and
|
|
10
9
|
* useStyles() calls getSSRCollector() to find it.
|
|
11
10
|
*
|
|
11
|
+
* Uses globalThis to ensure the AsyncLocalStorage instance is shared
|
|
12
|
+
* across module instances — frameworks like Astro may load middleware
|
|
13
|
+
* and page components from separate module graphs.
|
|
14
|
+
*
|
|
12
15
|
* This module imports from 'node:async_hooks' — it must be excluded
|
|
13
16
|
* from client bundles via the build configuration.
|
|
14
17
|
*/
|
|
15
|
-
const
|
|
18
|
+
const ALS_KEY = "__tasty_ssr_als__";
|
|
19
|
+
function getSharedStorage() {
|
|
20
|
+
const g = globalThis;
|
|
21
|
+
if (!g[ALS_KEY]) g[ALS_KEY] = new AsyncLocalStorage();
|
|
22
|
+
return g[ALS_KEY];
|
|
23
|
+
}
|
|
16
24
|
/**
|
|
17
25
|
* Run a function with a ServerStyleCollector bound to the current
|
|
18
26
|
* async context. All useStyles() calls within `fn` (and any async
|
|
19
27
|
* continuations) will find this collector via getSSRCollector().
|
|
20
28
|
*/
|
|
21
29
|
function runWithCollector(collector, fn) {
|
|
22
|
-
return
|
|
30
|
+
return getSharedStorage().run(collector, fn);
|
|
23
31
|
}
|
|
24
32
|
/**
|
|
25
33
|
* Retrieve the ServerStyleCollector bound to the current async context.
|
|
26
34
|
* Returns null when called outside of runWithCollector() or on the client.
|
|
27
35
|
*/
|
|
28
36
|
function getSSRCollector() {
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
const storage = getSharedStorage();
|
|
38
|
+
if (typeof storage?.getStore !== "function") return null;
|
|
39
|
+
return storage.getStore() ?? null;
|
|
31
40
|
}
|
|
32
|
-
|
|
33
41
|
//#endregion
|
|
34
|
-
export {
|
|
35
|
-
|
|
42
|
+
export { runWithCollector as n, getSSRCollector as t };
|
|
43
|
+
|
|
44
|
+
//# sourceMappingURL=async-storage-B7_o6FKt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-storage-B7_o6FKt.js","names":[],"sources":["../src/ssr/async-storage.ts"],"sourcesContent":["/**\n * AsyncLocalStorage integration for SSR collector discovery.\n *\n * Used by Astro middleware and generic framework integrations where\n * the library cannot wrap the React tree with a context provider.\n * The middleware calls runWithCollector() around the render, and\n * useStyles() calls getSSRCollector() to find it.\n *\n * Uses globalThis to ensure the AsyncLocalStorage instance is shared\n * across module instances — frameworks like Astro may load middleware\n * and page components from separate module graphs.\n *\n * This module imports from 'node:async_hooks' — it must be excluded\n * from client bundles via the build configuration.\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nimport type { ServerStyleCollector } from './collector';\n\nconst ALS_KEY = '__tasty_ssr_als__';\n\nfunction getSharedStorage(): AsyncLocalStorage<ServerStyleCollector> {\n const g = globalThis as Record<string, unknown>;\n if (!g[ALS_KEY]) {\n g[ALS_KEY] = new AsyncLocalStorage<ServerStyleCollector>();\n }\n return g[ALS_KEY] as AsyncLocalStorage<ServerStyleCollector>;\n}\n\n/**\n * Run a function with a ServerStyleCollector bound to the current\n * async context. All useStyles() calls within `fn` (and any async\n * continuations) will find this collector via getSSRCollector().\n */\nexport function runWithCollector<T>(\n collector: ServerStyleCollector,\n fn: () => T,\n): T {\n return getSharedStorage().run(collector, fn);\n}\n\n/**\n * Retrieve the ServerStyleCollector bound to the current async context.\n * Returns null when called outside of runWithCollector() or on the client.\n */\nexport function getSSRCollector(): ServerStyleCollector | null {\n const storage = getSharedStorage();\n if (typeof storage?.getStore !== 'function') return null;\n return storage.getStore() ?? null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAoBA,MAAM,UAAU;AAEhB,SAAS,mBAA4D;CACnE,MAAM,IAAI;AACV,KAAI,CAAC,EAAE,SACL,GAAE,WAAW,IAAI,mBAAyC;AAE5D,QAAO,EAAE;;;;;;;AAQX,SAAgB,iBACd,WACA,IACG;AACH,QAAO,kBAAkB,CAAC,IAAI,WAAW,GAAG;;;;;;AAO9C,SAAgB,kBAA+C;CAC7D,MAAM,UAAU,kBAAkB;AAClC,KAAI,OAAO,SAAS,aAAa,WAAY,QAAO;AACpD,QAAO,QAAQ,UAAU,IAAI"}
|