@tenphi/tasty 0.0.0-snapshot.e9718c0 → 0.0.0-snapshot.ec4d6f3
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 +101 -231
- package/dist/{ssr/async-storage.js → async-storage-DKK-wTD4.js} +17 -8
- package/dist/async-storage-DKK-wTD4.js.map +1 -0
- package/dist/{ssr/collector.js → collector-CW4jZxLo.js} +99 -39
- package/dist/collector-CW4jZxLo.js.map +1 -0
- package/dist/{ssr/collector.d.ts → collector-DYA5AOwr.d.ts} +38 -15
- package/dist/config-BtK9fUaz.d.ts +945 -0
- package/dist/config-DxBPtu-V.js +10981 -0
- package/dist/config-DxBPtu-V.js.map +1 -0
- package/dist/context-CA8YKeMn.js +24 -0
- package/dist/context-CA8YKeMn.js.map +1 -0
- package/dist/core/index.d.ts +5 -34
- package/dist/core/index.js +6 -27
- package/dist/core-BakA5V89.js +1598 -0
- package/dist/core-BakA5V89.js.map +1 -0
- package/dist/{zero/extractor.js → css-writer-w6bzEFb-.js} +149 -13
- package/dist/css-writer-w6bzEFb-.js.map +1 -0
- package/dist/{ssr/format-global-rules.js → format-global-rules-DklyaXv-.js} +3 -3
- package/dist/format-global-rules-DklyaXv-.js.map +1 -0
- package/dist/format-rules-BAJyIyAZ.js +143 -0
- package/dist/format-rules-BAJyIyAZ.js.map +1 -0
- package/dist/hydrate-B2BwrnYb.js +45 -0
- package/dist/hydrate-B2BwrnYb.js.map +1 -0
- package/dist/index-B9ih23uv.d.ts +1295 -0
- package/dist/index-BYtnj_gA.d.ts +1778 -0
- package/dist/index.d.ts +5 -49
- package/dist/index.js +731 -33
- package/dist/index.js.map +1 -0
- package/dist/keyframes-oSX5T5lm.js +595 -0
- package/dist/keyframes-oSX5T5lm.js.map +1 -0
- package/dist/{utils/merge-styles.d.ts → merge-styles-BZV-XAwX.d.ts} +3 -3
- package/dist/{utils/merge-styles.js → merge-styles-RmK1DOSt.js} +4 -6
- package/dist/merge-styles-RmK1DOSt.js.map +1 -0
- package/dist/{utils/resolve-recipes.js → resolve-recipes-CxyDLx9x.js} +5 -8
- package/dist/resolve-recipes-CxyDLx9x.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 +114 -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 +6 -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 +26 -101
- package/dist/zero/babel.js +180 -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 +174 -1
- package/docs/debug.md +11 -9
- package/docs/design-system.md +47 -12
- package/docs/dsl.md +267 -10
- package/docs/getting-started.md +10 -10
- package/docs/injector.md +43 -27
- package/docs/methodology.md +145 -6
- package/docs/pipeline.md +744 -0
- package/docs/react-api.md +581 -0
- package/docs/ssr.md +144 -82
- package/docs/styles.md +68 -24
- package/docs/tasty-static.md +118 -2
- package/package.json +34 -13
- package/tasty.config.ts +2 -0
- 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/PIPELINE.md +0 -519
- package/docs/runtime.md +0 -341
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<strong>Deterministic styling for stateful component systems.</strong><br>
|
|
9
|
-
A design-system styling engine that compiles component states into mutually exclusive selectors.
|
|
9
|
+
A design-system styling engine that compiles component states into mutually exclusive selectors, so complex components stay predictable as they evolve.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -17,21 +17,35 @@
|
|
|
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
|
+
The practical payoff shows up later: adding states, variants, and overrides stays inside the state map instead of reopening selector logic by hand.
|
|
27
|
+
|
|
28
|
+
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.
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
- **New here?** Start with [Comparison](docs/comparison.md) if you are evaluating fit.
|
|
33
|
+
- **Adopting Tasty?** Read the [Adoption Guide](docs/adoption.md).
|
|
34
|
+
- **Want the mechanism first?** Jump to [How It Actually Works](#how-it-actually-works).
|
|
35
|
+
- **Ready to build?** Go to [Getting Started](docs/getting-started.md).
|
|
23
36
|
|
|
24
37
|
## Why Tasty
|
|
25
38
|
|
|
26
|
-
- **Deterministic composition, not cascade fights** —
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
39
|
+
- **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).
|
|
40
|
+
- **Easier to extend over time** — When components gain new states, variants, or overrides, you update declared branches instead of re-deriving selector interactions by hand.
|
|
41
|
+
- **Built for design-system teams** — Best fit for reusable component systems with complex state interactions.
|
|
42
|
+
- **A governed styling model, not just syntax sugar** — Design-system authors define the styling language product teams consume.
|
|
43
|
+
- **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
44
|
|
|
31
45
|
### Supporting capabilities
|
|
32
46
|
|
|
33
|
-
- **Typed style props** — `styleProps`
|
|
34
|
-
- **
|
|
47
|
+
- **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).
|
|
48
|
+
- **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
49
|
- **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
50
|
- **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
51
|
- **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 +54,7 @@ It fits best when a team is defining a house styling language for reusable compo
|
|
|
40
54
|
|
|
41
55
|
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
56
|
|
|
43
|
-
Tasty replaces that competition with explicit state-map resolution. Each property compiles into mutually exclusive branches, so
|
|
57
|
+
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
58
|
|
|
45
59
|
## Installation
|
|
46
60
|
|
|
@@ -63,10 +77,12 @@ yarn add @tenphi/tasty
|
|
|
63
77
|
|
|
64
78
|
## Start Here
|
|
65
79
|
|
|
80
|
+
For the fuller docs map beyond the quick routes above, start here:
|
|
81
|
+
|
|
66
82
|
- **[Comparison](docs/comparison.md)** — read this first if you are evaluating whether Tasty fits your team's styling model
|
|
67
83
|
- **[Adoption Guide](docs/adoption.md)** — understand who Tasty is for, where it fits, and how to introduce it incrementally
|
|
68
84
|
- **[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/
|
|
85
|
+
- **[Style rendering pipeline](docs/pipeline.md)** — see the selector model behind deterministic style resolution
|
|
70
86
|
- **[Docs Hub](docs/README.md)** — choose docs by role and task: runtime, zero-runtime, runtime SSR integration, design-system authoring, internals, and debugging
|
|
71
87
|
- **[Methodology](docs/methodology.md)** — the recommended component model and public API conventions for design-system code
|
|
72
88
|
|
|
@@ -95,7 +111,9 @@ const Card = tasty({
|
|
|
95
111
|
<Card>Hello World</Card>
|
|
96
112
|
```
|
|
97
113
|
|
|
98
|
-
Every value maps to CSS you'd recognize. This example is intentionally
|
|
114
|
+
Every value maps to CSS you'd recognize. This example is intentionally a simple first contact, not a tour of the whole DSL.
|
|
115
|
+
|
|
116
|
+
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
117
|
|
|
100
118
|
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
119
|
|
|
@@ -163,58 +181,17 @@ configure({
|
|
|
163
181
|
|
|
164
182
|
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
183
|
|
|
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.
|
|
184
|
+
### Props as the public API
|
|
169
185
|
|
|
170
|
-
|
|
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
|
-
```
|
|
195
|
-
|
|
196
|
-
Now you can compose layout and tweak component positioning directly in JSX:
|
|
186
|
+
`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
187
|
|
|
198
188
|
```tsx
|
|
199
189
|
<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 />
|
|
190
|
+
<Button isLoading size="large" placeSelf="end">Submit</Button>
|
|
214
191
|
</Space>
|
|
215
192
|
```
|
|
216
193
|
|
|
217
|
-
|
|
194
|
+
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
195
|
|
|
219
196
|
## Choose a Styling Approach
|
|
220
197
|
|
|
@@ -222,16 +199,17 @@ Once you understand the component model, pick the rendering mode that matches yo
|
|
|
222
199
|
|
|
223
200
|
| Approach | Entry point | Best for | Trade-off |
|
|
224
201
|
|----------|-------------|----------|-----------|
|
|
225
|
-
| **Runtime** | `@tenphi/tasty` |
|
|
226
|
-
| **
|
|
202
|
+
| **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) |
|
|
203
|
+
| **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 |
|
|
204
|
+
| **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
205
|
|
|
228
|
-
|
|
206
|
+
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
207
|
|
|
230
208
|
## How It Actually Works
|
|
231
209
|
|
|
232
210
|
This is the core idea that makes everything else possible.
|
|
233
211
|
|
|
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/
|
|
212
|
+
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
213
|
|
|
236
214
|
### The structural problem with normal CSS
|
|
237
215
|
|
|
@@ -327,7 +305,7 @@ Every rule is guarded by the negation of higher-priority rules. No two rules can
|
|
|
327
305
|
|
|
328
306
|
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
307
|
|
|
330
|
-
[Try it in the
|
|
308
|
+
[Try it in the playground →](https://tasty.style/playground)
|
|
331
309
|
|
|
332
310
|
## Capabilities
|
|
333
311
|
|
|
@@ -373,7 +351,7 @@ Every style property accepts a state mapping object. Keys can be combined with b
|
|
|
373
351
|
| Feature query | `@supports(display: grid)` | `@supports (display: grid)` |
|
|
374
352
|
| Entry animation | `@starting` | `@starting-style` |
|
|
375
353
|
|
|
376
|
-
Combine with `&` (AND), `|` (OR), `!` (NOT):
|
|
354
|
+
Combine with `&` (AND), `|` (OR), `!` (NOT), `^` (XOR):
|
|
377
355
|
|
|
378
356
|
```tsx
|
|
379
357
|
fill: {
|
|
@@ -385,220 +363,109 @@ fill: {
|
|
|
385
363
|
|
|
386
364
|
### Sub-Element Styling
|
|
387
365
|
|
|
388
|
-
|
|
366
|
+
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
367
|
|
|
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
|
-
```
|
|
368
|
+
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
369
|
|
|
406
|
-
Sub-
|
|
370
|
+
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
371
|
|
|
408
|
-
|
|
372
|
+
### Style Props
|
|
409
373
|
|
|
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.
|
|
374
|
+
`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
375
|
|
|
420
376
|
```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
|
-
},
|
|
377
|
+
const Space = tasty({
|
|
378
|
+
styles: { display: 'flex', flow: 'column', gap: '1x' },
|
|
379
|
+
styleProps: FLOW_STYLES,
|
|
428
380
|
});
|
|
429
381
|
|
|
430
|
-
<
|
|
382
|
+
<Space flow="row" gap={{ '': '2x', '@tablet': '4x' }}>
|
|
431
383
|
```
|
|
432
384
|
|
|
433
|
-
|
|
385
|
+
See [React API - Style Props](docs/react-api.md#style-props) and [Methodology - styleProps](docs/methodology.md#styleprops-as-the-public-api).
|
|
434
386
|
|
|
435
|
-
|
|
387
|
+
### Mod Props
|
|
436
388
|
|
|
437
|
-
|
|
438
|
-
configure({
|
|
439
|
-
recipes: {
|
|
440
|
-
card: { padding: '4x', fill: '#surface', radius: '1r', border: true },
|
|
441
|
-
elevated: { shadow: '0 2x 4x #shadow' },
|
|
442
|
-
},
|
|
443
|
-
});
|
|
389
|
+
`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
390
|
|
|
445
|
-
|
|
391
|
+
```tsx
|
|
392
|
+
const Button = tasty({
|
|
393
|
+
as: 'button',
|
|
394
|
+
modProps: { isLoading: Boolean, size: ['sm', 'md', 'lg'] as const },
|
|
446
395
|
styles: {
|
|
447
|
-
|
|
448
|
-
|
|
396
|
+
fill: { '': '#primary', isLoading: '#primary.5' },
|
|
397
|
+
padding: { '': '2x 4x', 'size=sm': '1x 2x' },
|
|
449
398
|
},
|
|
450
399
|
});
|
|
451
|
-
```
|
|
452
400
|
|
|
453
|
-
|
|
401
|
+
<Button isLoading size="lg">Submit</Button>
|
|
402
|
+
```
|
|
454
403
|
|
|
455
|
-
|
|
404
|
+
See [React API - Mod Props](docs/react-api.md#mod-props) and [Methodology - modProps](docs/methodology.md#modprops-and-mods).
|
|
456
405
|
|
|
457
|
-
|
|
406
|
+
### Variants
|
|
458
407
|
|
|
459
|
-
|
|
408
|
+
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
409
|
|
|
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
|
-
```
|
|
410
|
+
See [React API - Variants](docs/react-api.md#variants).
|
|
475
411
|
|
|
476
|
-
|
|
412
|
+
### Recipes
|
|
477
413
|
|
|
478
|
-
|
|
414
|
+
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
415
|
|
|
480
|
-
|
|
416
|
+
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
417
|
|
|
482
|
-
|
|
418
|
+
See [Style DSL - Recipes](docs/dsl.md#recipes) and [Configuration - recipes](docs/configuration.md#recipes).
|
|
483
419
|
|
|
484
|
-
|
|
485
|
-
'@properties': {
|
|
486
|
-
'$pulse-scale': { syntax: '<number>', inherits: false, initialValue: 1 },
|
|
487
|
-
},
|
|
488
|
-
```
|
|
420
|
+
### Auto-Inferred `@property`
|
|
489
421
|
|
|
490
|
-
|
|
422
|
+
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
423
|
|
|
492
|
-
|
|
424
|
+
If you prefer explicit control, disable inference with `configure({ autoPropertyTypes: false })` or declare the properties yourself.
|
|
493
425
|
|
|
494
|
-
|
|
495
|
-
import { useStyles, useGlobalStyles, useRawCSS } from '@tenphi/tasty';
|
|
426
|
+
See [Style DSL - Properties (`@property`)](docs/dsl.md#properties-property).
|
|
496
427
|
|
|
497
|
-
|
|
498
|
-
const { className } = useStyles({ padding: '2x', fill: '#surface' });
|
|
499
|
-
useGlobalStyles('body', { margin: '0' });
|
|
500
|
-
useRawCSS('@font-face { font-family: "Custom"; src: url(...); }');
|
|
428
|
+
### Explicit `@properties`
|
|
501
429
|
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
```
|
|
430
|
+
Use explicit `@properties` only when you need to override defaults such as `inherits: false` or a custom `initialValue`.
|
|
505
431
|
|
|
506
|
-
|
|
432
|
+
See [Style DSL - Properties (`@property`)](docs/dsl.md#properties-property).
|
|
507
433
|
|
|
508
|
-
|
|
434
|
+
### Style Functions
|
|
509
435
|
|
|
510
|
-
|
|
511
|
-
import { tastyStatic } from '@tenphi/tasty/static';
|
|
436
|
+
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
437
|
|
|
513
|
-
|
|
514
|
-
padding: '4x',
|
|
515
|
-
fill: '#surface',
|
|
516
|
-
radius: '1r',
|
|
517
|
-
color: { '': '#text', '@dark': '#text-on-dark' },
|
|
518
|
-
});
|
|
438
|
+
See [React API - Style Functions](docs/react-api.md#style-functions).
|
|
519
439
|
|
|
520
|
-
|
|
521
|
-
<div className={card}>Static styles, zero runtime</div>
|
|
522
|
-
```
|
|
440
|
+
### Zero-Runtime Mode
|
|
523
441
|
|
|
524
|
-
|
|
442
|
+
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
443
|
|
|
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
|
-
```
|
|
444
|
+
See [Zero Runtime (tastyStatic)](docs/tasty-static.md) and [Getting Started - Choosing a rendering mode](docs/getting-started.md#choosing-a-rendering-mode).
|
|
538
445
|
|
|
539
446
|
### `tasty` vs `tastyStatic`
|
|
540
447
|
|
|
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 |
|
|
448
|
+
`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
449
|
|
|
553
|
-
|
|
450
|
+
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
451
|
|
|
555
452
|
### Server-Side Rendering
|
|
556
453
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
**Next.js setup:**
|
|
454
|
+
`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
455
|
|
|
561
|
-
|
|
562
|
-
// app/tasty-registry.tsx
|
|
563
|
-
'use client';
|
|
564
|
-
|
|
565
|
-
import { TastyRegistry } from '@tenphi/tasty/ssr/next';
|
|
456
|
+
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
457
|
|
|
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
|
-
```
|
|
458
|
+
- `@tenphi/tasty/ssr/next` for Next.js App Router (mixed server + client components)
|
|
459
|
+
- `@tenphi/tasty/ssr/astro` for Astro (with or without islands)
|
|
460
|
+
- The core SSR API for other React SSR setups
|
|
594
461
|
|
|
595
|
-
See the [full SSR guide](docs/ssr.md)
|
|
462
|
+
See the [full SSR guide](docs/ssr.md).
|
|
596
463
|
|
|
597
464
|
## Entry Points
|
|
598
465
|
|
|
599
466
|
| Import | Description | Platform |
|
|
600
467
|
|--------|-------------|----------|
|
|
601
|
-
| `@tenphi/tasty` | Runtime style engine (`tasty`,
|
|
468
|
+
| `@tenphi/tasty` | Runtime style engine (`tasty`, style functions, `configure`) | Browser |
|
|
602
469
|
| `@tenphi/tasty/static` | Zero-runtime static styles (`tastyStatic`) | Browser |
|
|
603
470
|
| `@tenphi/tasty/core` | Lower-level internals (config, parser, pipeline, injector, style handlers) for tooling and advanced use | Browser / Node |
|
|
604
471
|
| `@tenphi/tasty/babel-plugin` | Babel plugin for zero-runtime CSS extraction | Node |
|
|
@@ -606,7 +473,8 @@ See the [full SSR guide](docs/ssr.md) for Astro integration, streaming SSR, gene
|
|
|
606
473
|
| `@tenphi/tasty/next` | Next.js integration wrapper | Node |
|
|
607
474
|
| `@tenphi/tasty/ssr` | Core SSR API (collector, context, hydration) | Node |
|
|
608
475
|
| `@tenphi/tasty/ssr/next` | Next.js App Router SSR integration | Node |
|
|
609
|
-
| `@tenphi/tasty/ssr/astro` | Astro
|
|
476
|
+
| `@tenphi/tasty/ssr/astro` | Astro integration + middleware | Node |
|
|
477
|
+
| `@tenphi/tasty/ssr/astro-client` | Astro client-side cache hydration | Browser |
|
|
610
478
|
|
|
611
479
|
## Browser Requirements
|
|
612
480
|
|
|
@@ -624,11 +492,13 @@ All sizes measured with [size-limit](https://github.com/ai/size-limit) — minif
|
|
|
624
492
|
|
|
625
493
|
| Entry point | Size |
|
|
626
494
|
|-------------|------|
|
|
627
|
-
| `@tenphi/tasty` (runtime + SSR) |
|
|
628
|
-
| `@tenphi/tasty/core` (runtime, no SSR) |
|
|
629
|
-
| `@tenphi/tasty/static` (zero-runtime) |
|
|
495
|
+
| `@tenphi/tasty` (runtime + SSR) | 50.19 kB |
|
|
496
|
+
| `@tenphi/tasty/core` (runtime, no SSR) | 47.76 kB |
|
|
497
|
+
| `@tenphi/tasty/static` (zero-runtime) | 16.43 kB |
|
|
498
|
+
| `@tenphi/tasty/zero` (programmatic extraction) | 29.6 kB |
|
|
499
|
+
| `@tenphi/tasty/babel-plugin` (Babel plugin entry) | 43.7 kB |
|
|
630
500
|
|
|
631
|
-
Run `pnpm size`
|
|
501
|
+
Run `pnpm size` to reproduce (outputs may shift slightly with releases).
|
|
632
502
|
|
|
633
503
|
### Runtime Benchmarks
|
|
634
504
|
|
|
@@ -746,7 +616,7 @@ Start from the docs hub if you want the shortest path to the right guide for you
|
|
|
746
616
|
### Reference
|
|
747
617
|
|
|
748
618
|
- **[Style DSL](docs/dsl.md)** — The Tasty style language: state maps, tokens, units, color syntax, extending semantics, recipes, keyframes, and @property
|
|
749
|
-
- **[
|
|
619
|
+
- **[React API](docs/react-api.md)** — React-specific API: `tasty()` factory, component props, variants, sub-elements, and style functions
|
|
750
620
|
- **[Configuration](docs/configuration.md)** — Global configuration: tokens, recipes, custom units, style handlers, and TypeScript extensions
|
|
751
621
|
- **[Style Properties](docs/styles.md)** — Complete reference for all enhanced style properties: syntax, values, modifiers, and recommendations
|
|
752
622
|
|
|
@@ -757,7 +627,7 @@ Start from the docs hub if you want the shortest path to the right guide for you
|
|
|
757
627
|
|
|
758
628
|
### Internals
|
|
759
629
|
|
|
760
|
-
- **[Style rendering pipeline](docs/
|
|
630
|
+
- **[Style rendering pipeline](docs/pipeline.md)** — How `Styles` become mutually exclusive CSS rules: parse → exclusives → combinations → handlers → merge → materialize (`src/pipeline/`)
|
|
761
631
|
- **[Style Injector](docs/injector.md)** — Internal CSS injection engine: `inject()`, `injectGlobal()`, `injectRawCSS()`, `keyframes()`, deduplication, reference counting, cleanup, SSR support, and Shadow DOM
|
|
762
632
|
- **[Debug Utilities](docs/debug.md)** — Runtime CSS inspection via `tastyDebug`: CSS extraction, element inspection, cache metrics, chunk breakdown, and performance monitoring
|
|
763
633
|
|
|
@@ -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-DKK-wTD4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-storage-DKK-wTD4.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;CACV,IAAI,CAAC,EAAE,UACL,EAAE,WAAW,IAAI,kBAAwC;CAE3D,OAAO,EAAE;AACX;;;;;;AAOA,SAAgB,iBACd,WACA,IACG;CACH,OAAO,iBAAiB,CAAC,CAAC,IAAI,WAAW,EAAE;AAC7C;;;;;AAMA,SAAgB,kBAA+C;CAC7D,MAAM,UAAU,iBAAiB;CACjC,IAAI,OAAO,SAAS,aAAa,YAAY,OAAO;CACpD,OAAO,QAAQ,SAAS,KAAK;AAC/B"}
|