@tenphi/tasty 0.0.0-snapshot.cfcf770 → 0.0.0-snapshot.d2dcdeb
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 +25 -19
- package/dist/compute-styles.js +6 -28
- package/dist/compute-styles.js.map +1 -1
- package/dist/config.d.ts +41 -1
- package/dist/config.js +92 -7
- package/dist/config.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/debug.js +4 -4
- package/dist/debug.js.map +1 -1
- package/dist/hooks/useCounterStyle.d.ts +3 -17
- package/dist/hooks/useCounterStyle.js +55 -35
- package/dist/hooks/useCounterStyle.js.map +1 -1
- package/dist/hooks/useFontFace.d.ts +3 -1
- package/dist/hooks/useFontFace.js +21 -24
- package/dist/hooks/useFontFace.js.map +1 -1
- package/dist/hooks/useGlobalStyles.d.ts +18 -2
- package/dist/hooks/useGlobalStyles.js +51 -40
- package/dist/hooks/useGlobalStyles.js.map +1 -1
- package/dist/hooks/useKeyframes.d.ts +4 -2
- package/dist/hooks/useKeyframes.js +42 -50
- package/dist/hooks/useKeyframes.js.map +1 -1
- package/dist/hooks/useProperty.d.ts +4 -2
- package/dist/hooks/useProperty.js +29 -41
- package/dist/hooks/useProperty.js.map +1 -1
- package/dist/hooks/useRawCSS.d.ts +13 -44
- package/dist/hooks/useRawCSS.js +90 -21
- package/dist/hooks/useRawCSS.js.map +1 -1
- package/dist/hooks/useStyles.d.ts +4 -4
- package/dist/hooks/useStyles.js +7 -5
- package/dist/hooks/useStyles.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/injector/index.js +1 -1
- package/dist/injector/index.js.map +1 -1
- package/dist/injector/injector.d.ts +9 -7
- package/dist/injector/injector.js +126 -38
- package/dist/injector/injector.js.map +1 -1
- package/dist/injector/sheet-manager.js +4 -2
- package/dist/injector/sheet-manager.js.map +1 -1
- package/dist/injector/types.d.ts +11 -2
- package/dist/pipeline/parseStateKey.js +4 -4
- package/dist/pipeline/parseStateKey.js.map +1 -1
- package/dist/plugins/types.d.ts +12 -1
- package/dist/rsc-cache.js +79 -0
- package/dist/rsc-cache.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 +89 -10
- package/dist/ssr/astro.js +112 -27
- package/dist/ssr/astro.js.map +1 -1
- package/dist/ssr/async-storage.js +14 -4
- package/dist/ssr/async-storage.js.map +1 -1
- package/dist/ssr/collect-auto-properties.js +28 -9
- package/dist/ssr/collect-auto-properties.js.map +1 -1
- package/dist/ssr/collector.d.ts +5 -13
- package/dist/ssr/collector.js +27 -15
- package/dist/ssr/collector.js.map +1 -1
- package/dist/ssr/context.js +16 -0
- package/dist/ssr/context.js.map +1 -0
- package/dist/ssr/hydrate.d.ts +20 -13
- package/dist/ssr/hydrate.js +24 -28
- package/dist/ssr/hydrate.js.map +1 -1
- package/dist/ssr/index.d.ts +3 -3
- package/dist/ssr/index.js +4 -4
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next.d.ts +7 -4
- package/dist/ssr/next.js +7 -6
- package/dist/ssr/next.js.map +1 -1
- package/dist/ssr/ssr-collector-ref.js +19 -2
- package/dist/ssr/ssr-collector-ref.js.map +1 -1
- package/dist/tasty.d.ts +1 -1
- package/dist/tasty.js +9 -4
- package/dist/tasty.js.map +1 -1
- package/dist/utils/deps-equal.js +15 -0
- package/dist/utils/deps-equal.js.map +1 -0
- package/dist/utils/hash.js +14 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/typography.d.ts +21 -10
- package/dist/utils/typography.js +1 -1
- package/dist/utils/typography.js.map +1 -1
- package/dist/zero/babel.d.ts +7 -108
- package/dist/zero/babel.js +36 -12
- package/dist/zero/babel.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/adoption.md +5 -3
- package/docs/comparison.md +24 -25
- package/docs/configuration.md +69 -1
- package/docs/design-system.md +22 -10
- package/docs/dsl.md +3 -3
- package/docs/getting-started.md +10 -10
- package/docs/injector.md +9 -7
- package/docs/methodology.md +2 -2
- package/docs/{runtime.md → react-api.md} +17 -32
- package/docs/ssr.md +125 -39
- package/docs/tasty-static.md +14 -2
- package/package.json +9 -3
package/docs/design-system.md
CHANGED
|
@@ -84,25 +84,37 @@ configure({
|
|
|
84
84
|
|
|
85
85
|
### Typography presets
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
Pass typography presets directly to `configure()` — they are converted to tokens automatically:
|
|
88
88
|
|
|
89
89
|
```tsx
|
|
90
|
-
import { configure
|
|
90
|
+
import { configure } from '@tenphi/tasty';
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
configure({
|
|
93
|
+
presets: {
|
|
94
|
+
h1: { fontSize: '2rem', lineHeight: '1.2', letterSpacing: '-0.02em', fontWeight: 700 },
|
|
95
|
+
t2: { fontSize: '0.875rem', lineHeight: '1.5', letterSpacing: 'normal', fontWeight: 400 },
|
|
96
|
+
},
|
|
95
97
|
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Preset values support state maps for responsive or theme-aware typography:
|
|
96
101
|
|
|
102
|
+
```tsx
|
|
97
103
|
configure({
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
presets: {
|
|
105
|
+
t2: {
|
|
106
|
+
fontSize: '0.875rem',
|
|
107
|
+
lineHeight: '1.5',
|
|
108
|
+
fontWeight: { '': 400, '@dark': 300 },
|
|
109
|
+
},
|
|
100
110
|
},
|
|
101
111
|
});
|
|
102
112
|
```
|
|
103
113
|
|
|
104
114
|
Then use `preset: 'h1'` or `preset: 't2'` in any component's styles.
|
|
105
115
|
|
|
116
|
+
> You can also call `generateTypographyTokens()` manually and spread the result into `tokens` for more control — `presets` is just a shorthand.
|
|
117
|
+
|
|
106
118
|
### Registering brand fonts
|
|
107
119
|
|
|
108
120
|
Register your design system's custom fonts via `configure({ fontFace })` so every component can reference them:
|
|
@@ -334,7 +346,7 @@ Usage:
|
|
|
334
346
|
|
|
335
347
|
Sub-elements share the root component's state context by default. A `disabled` modifier on `<Card>` affects `Title`, `Content`, and `Footer` styles automatically — no prop drilling. For the full mental model, see [Methodology — Component architecture](methodology.md#component-architecture-root--sub-elements).
|
|
336
348
|
|
|
337
|
-
For sub-element syntax details (selector affix `$`, `@own()`, `elements` config), see [
|
|
349
|
+
For sub-element syntax details (selector affix `$`, `@own()`, `elements` config), see [React API — Sub-element Styling](react-api.md#sub-element-styling).
|
|
338
350
|
|
|
339
351
|
---
|
|
340
352
|
|
|
@@ -404,7 +416,7 @@ ds/
|
|
|
404
416
|
index.ts # Recipe definitions (imported by config.ts)
|
|
405
417
|
tokens/
|
|
406
418
|
colors.ts # Color token definitions
|
|
407
|
-
typography.ts # Typography presets
|
|
419
|
+
typography.ts # Typography presets for configure({ presets })
|
|
408
420
|
spacing.ts # Spacing token definitions
|
|
409
421
|
index.ts # Public API: re-exports components + configure
|
|
410
422
|
```
|
|
@@ -418,7 +430,7 @@ The key principle: `config.ts` imports tokens and recipes, calls `configure()`,
|
|
|
418
430
|
- **[Methodology](methodology.md)** — The recommended patterns for structuring Tasty components
|
|
419
431
|
- **[Getting Started](getting-started.md)** — Installation, first component, tooling setup
|
|
420
432
|
- **[Style DSL](dsl.md)** — State maps, tokens, units, extending semantics, keyframes, @property
|
|
421
|
-
- **[
|
|
433
|
+
- **[React API](react-api.md)** — `tasty()` factory, component props, variants, sub-elements, style functions
|
|
422
434
|
- **[Configuration](configuration.md)** — Full `configure()` API: tokens, recipes, custom units, style handlers
|
|
423
435
|
- **[Adoption Guide](adoption.md)** — Who should adopt Tasty, incremental phases, what changes for product engineers
|
|
424
436
|
- **[Style Properties](styles.md)** — Complete reference for all enhanced style properties
|
package/docs/dsl.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
This is the Tasty style language reference — the value syntax, state mappings, tokens, units, extending semantics, and special declarations that apply to both runtime `tasty()` and build-time `tastyStatic()`.
|
|
4
4
|
|
|
5
|
-
For the runtime React API (`tasty()`, hooks, component props), see [
|
|
5
|
+
For the runtime React API (`tasty()`, hooks, component props), see [React API](react-api.md). For all enhanced style properties, see [Style Properties](styles.md). For global configuration, see [Configuration](configuration.md).
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -107,7 +107,7 @@ mods={{ hovered: true, theme: 'danger' }}
|
|
|
107
107
|
// → data-hovered="" data-theme="danger"
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
Modifiers can also be exposed as top-level component props via `modProps` — see [Runtime — Mod Props](
|
|
110
|
+
Modifiers can also be exposed as top-level component props via `modProps` — see [Runtime — Mod Props](react-api.md#mod-props).
|
|
111
111
|
|
|
112
112
|
---
|
|
113
113
|
|
|
@@ -681,7 +681,7 @@ For a complete reference of all enhanced style properties — syntax, values, mo
|
|
|
681
681
|
|
|
682
682
|
## Learn more
|
|
683
683
|
|
|
684
|
-
- **[
|
|
684
|
+
- **[React API](react-api.md)** — `tasty()` factory, component props, variants, sub-elements, style functions
|
|
685
685
|
- **[Methodology](methodology.md)** — Recommended patterns: root + sub-elements, styleProps, tokens, wrapping
|
|
686
686
|
- **[Configuration](configuration.md)** — Tokens, recipes, custom units, style handlers, TypeScript extensions
|
|
687
687
|
- **[Style Properties](styles.md)** — Complete reference for all enhanced style properties
|
package/docs/getting-started.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Getting Started
|
|
2
2
|
|
|
3
|
-
This guide walks you from zero to a working Tasty component, then through the optional shared configuration and tooling layers. It is the right starting point when you already want to try Tasty in code. If you are still deciding whether Tasty fits your team, start with [Comparison](comparison.md) and [Adoption Guide](adoption.md) first. For a feature overview, see the [README](../README.md). For the full style language reference, see the [Style DSL](dsl.md). For the React API, see the [
|
|
3
|
+
This guide walks you from zero to a working Tasty component, then through the optional shared configuration and tooling layers. It is the right starting point when you already want to try Tasty in code. If you are still deciding whether Tasty fits your team, start with [Comparison](comparison.md) and [Adoption Guide](adoption.md) first. For a feature overview, see the [README](../README.md). For the full style language reference, see the [Style DSL](dsl.md). For the React API, see the [React API](react-api.md). For the rest of the docs by role or task, see the [Docs Hub](README.md).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -179,19 +179,19 @@ export default [
|
|
|
179
179
|
|
|
180
180
|
## Choosing a rendering mode
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
`tasty()` is the default for all React apps. All `tasty()` components and style functions are hook-free and work as React Server Components without `'use client'`. In server-only contexts, they produce zero client JavaScript with the full feature set.
|
|
183
183
|
|
|
184
184
|
| Approach | Entry point | Best for | Trade-off |
|
|
185
185
|
|------|-------------|----------|-----------|
|
|
186
|
-
| **Runtime** | `tasty()` from `@tenphi/tasty` |
|
|
187
|
-
| **
|
|
186
|
+
| **Runtime (default)** | `tasty()` from `@tenphi/tasty` | All React apps — server-rendered by default, zero client JS until you need interactivity | Full feature set (styleProps, sub-elements, variants); CSS computed during rendering |
|
|
187
|
+
| **Runtime + SSR integration** | Add `@tenphi/tasty/ssr/*` | Apps with client-side hydration (Next.js client components, Astro islands) | Adds CSS batching, deduplication, FOUC prevention, and client cache hydration |
|
|
188
|
+
| **Zero-runtime** | `tastyStatic()` from `@tenphi/tasty/static` | Non-React frameworks or build-time extraction without React | Requires Babel plugin; no `styleProps` or runtime-only APIs |
|
|
188
189
|
|
|
189
|
-
Both share the same DSL, tokens, units, and state mappings.
|
|
190
|
+
Both `tasty()` and `tastyStatic()` share the same DSL, tokens, units, and state mappings.
|
|
190
191
|
|
|
191
|
-
- Runtime is the default and requires no extra setup beyond `@tenphi/tasty`.
|
|
192
|
-
-
|
|
193
|
-
- Zero-runtime requires the Babel plugin and additional peer dependencies. See [Zero Runtime (tastyStatic)](tasty-static.md).
|
|
194
|
-
- SSR works with existing `tasty()` components — wrap your app with a registry, middleware, or collector. See [Server-Side Rendering](ssr.md).
|
|
192
|
+
- **Runtime** is the default and requires no extra setup beyond `@tenphi/tasty`. In server-only contexts (Next.js RSC, Astro without `client:*` directives, SSG), `tasty()` produces static HTML + CSS with zero client JavaScript — the same end result as `tastyStatic()` but with the full feature set. For example, `tasty()` + `tastyIntegration()` in Astro without islands gives you the complete API with zero JS shipped.
|
|
193
|
+
- **SSR integration** is only needed when your app also has client-side rendering. Add `@tenphi/tasty/ssr/next`, `@tenphi/tasty/ssr/astro`, or the core SSR API to get CSS deduplication and cache hydration. See [Server-Side Rendering](ssr.md).
|
|
194
|
+
- **Zero-runtime** requires the Babel plugin and additional peer dependencies. Use it when you need build-time extraction without a React runtime. See [Zero Runtime (tastyStatic)](tasty-static.md).
|
|
195
195
|
|
|
196
196
|
---
|
|
197
197
|
|
|
@@ -200,7 +200,7 @@ Both share the same DSL, tokens, units, and state mappings.
|
|
|
200
200
|
- **[Docs Hub](README.md)** — Pick the next guide by role, styling approach, or task
|
|
201
201
|
- **[Methodology](methodology.md)** — The recommended patterns for structuring Tasty components: sub-elements, styleProps, tokens, extension
|
|
202
202
|
- **[Style DSL](dsl.md)** — State maps, tokens, units, extending semantics, keyframes, @property
|
|
203
|
-
- **[
|
|
203
|
+
- **[React API](react-api.md)** — `tasty()` factory, component props, variants, sub-elements, style functions
|
|
204
204
|
- **[Building a Design System](design-system.md)** — Practical guide to building a DS layer with Tasty: tokens, recipes, primitives, compound components
|
|
205
205
|
- **[Adoption Guide](adoption.md)** — Roll out Tasty inside an existing design system or platform team
|
|
206
206
|
- **[Comparison](comparison.md)** — Evaluate Tasty against other styling systems
|
package/docs/injector.md
CHANGED
|
@@ -115,11 +115,13 @@ dispose();
|
|
|
115
115
|
|
|
116
116
|
### `useRawCSS(css, options?)` or `useRawCSS(factory, deps, options?)`
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
Inject raw CSS without parsing. Hook-free — works in client components, SSR, and React Server Components.
|
|
119
119
|
|
|
120
120
|
Supports two overloads:
|
|
121
|
-
- **Static CSS**: `useRawCSS(cssString, options?)`
|
|
122
|
-
- **Factory function**: `useRawCSS(() => cssString, deps, options?)`
|
|
121
|
+
- **Static CSS**: `useRawCSS(cssString, options?)` — content-based deduplication
|
|
122
|
+
- **Factory function**: `useRawCSS(() => cssString, deps, options?)` — factory called on every invocation, dedup handled internally
|
|
123
|
+
|
|
124
|
+
Use the `id` option for update tracking — when the CSS changes for the same id, the previous injection is replaced:
|
|
123
125
|
|
|
124
126
|
```tsx
|
|
125
127
|
import { useRawCSS } from '@tenphi/tasty';
|
|
@@ -132,7 +134,7 @@ function GlobalReset() {
|
|
|
132
134
|
return null;
|
|
133
135
|
}
|
|
134
136
|
|
|
135
|
-
// Dynamic CSS with factory function
|
|
137
|
+
// Dynamic CSS with factory function and update tracking
|
|
136
138
|
function ThemeStyles({ theme }: { theme: 'dark' | 'light' }) {
|
|
137
139
|
useRawCSS(() => `
|
|
138
140
|
body {
|
|
@@ -140,7 +142,7 @@ function ThemeStyles({ theme }: { theme: 'dark' | 'light' }) {
|
|
|
140
142
|
background: ${theme === 'dark' ? '#000' : '#fff'};
|
|
141
143
|
color: ${theme === 'dark' ? '#fff' : '#000'};
|
|
142
144
|
}
|
|
143
|
-
`, [theme]);
|
|
145
|
+
`, [theme], { id: 'theme-body' });
|
|
144
146
|
|
|
145
147
|
return null;
|
|
146
148
|
}
|
|
@@ -525,7 +527,7 @@ const StyledButton = tasty({
|
|
|
525
527
|
// 4. dispose() is called when component unmounts
|
|
526
528
|
```
|
|
527
529
|
|
|
528
|
-
For most development, you'll use the [
|
|
530
|
+
For most development, you'll use the [React API](./react-api.md) rather than the injector directly. The injector provides the high-performance foundation that makes Tasty's declarative styling possible.
|
|
529
531
|
|
|
530
532
|
---
|
|
531
533
|
|
|
@@ -539,4 +541,4 @@ Direct injector usage is recommended for:
|
|
|
539
541
|
- **Performance-critical scenarios** where you need direct control
|
|
540
542
|
- **Testing utilities** that need to inject or extract CSS
|
|
541
543
|
|
|
542
|
-
For regular component styling, prefer the [`tasty()` API](./
|
|
544
|
+
For regular component styling, prefer the [`tasty()` API](./react-api.md) which provides a more developer-friendly interface.
|
package/docs/methodology.md
CHANGED
|
@@ -214,7 +214,7 @@ The array form is simpler but types all values as `ModValue`:
|
|
|
214
214
|
modProps: ['isLoading', 'isSelected'] as const,
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
-
For the full API reference, see [Runtime — Mod Props](
|
|
217
|
+
For the full API reference, see [Runtime — Mod Props](react-api.md#mod-props).
|
|
218
218
|
|
|
219
219
|
---
|
|
220
220
|
|
|
@@ -610,7 +610,7 @@ The `elements` prop gives you typed sub-components with automatic `data-element`
|
|
|
610
610
|
- **[Getting Started](getting-started.md)** — Installation, first component, tooling setup
|
|
611
611
|
- **[Building a Design System](design-system.md)** — Practical guide to building a DS layer with Tasty
|
|
612
612
|
- **[Style DSL](dsl.md)** — State maps, tokens, units, extending semantics, keyframes, @property
|
|
613
|
-
- **[
|
|
613
|
+
- **[React API](react-api.md)** — `tasty()` factory, component props, variants, sub-elements, style functions
|
|
614
614
|
- **[Configuration](configuration.md)** — Full `configure()` API: tokens, recipes, custom units, style handlers
|
|
615
615
|
- **[Style Properties](styles.md)** — Complete reference for all enhanced style properties
|
|
616
616
|
- **[Adoption Guide](adoption.md)** — Who should adopt Tasty, incremental phases, what changes for product engineers
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# React API
|
|
2
2
|
|
|
3
|
-
The React-specific `tasty()` component factory, component props, and
|
|
3
|
+
The React-specific `tasty()` component factory, component props, and style functions. All Tasty style functions — `tasty()` components, `useStyles()`, `useGlobalStyles()`, `useRawCSS()`, `useKeyframes()`, `useProperty()`, `useFontFace()`, and `useCounterStyle()` — are hook-free and compatible with React Server Components. No `'use client'` directive needed. For the shared style language (state maps, tokens, units, extending semantics), see [Style DSL](dsl.md). For global configuration, see [Configuration](configuration.md). For the broader docs map, see the [Docs Hub](README.md).
|
|
4
|
+
|
|
5
|
+
> **Note:** This file was previously named `runtime.md`. All functionality documented here works in both server and client contexts — "runtime" referred to style computation during React rendering, not to client-side JavaScript.
|
|
4
6
|
|
|
5
7
|
---
|
|
6
8
|
|
|
@@ -351,11 +353,15 @@ On the client, CSS is injected synchronously into the DOM (idempotent via the in
|
|
|
351
353
|
|
|
352
354
|
---
|
|
353
355
|
|
|
354
|
-
##
|
|
356
|
+
## Style Functions
|
|
357
|
+
|
|
358
|
+
All style functions below are plain functions (not React hooks) and can be used in any environment: client components, SSR with a `ServerStyleCollector`, and React Server Components. They retain their `use` prefix for backward compatibility, but do not use any React hooks internally.
|
|
359
|
+
|
|
360
|
+
In server-only contexts (Next.js RSC without `'use client'`, Astro without `client:*` directives, SSG), components that use only Tasty style functions produce zero client JavaScript. Tasty never forces the `'use client'` boundary — that decision belongs to your component when it needs React interactivity (state, effects, event handlers).
|
|
355
361
|
|
|
356
362
|
### useStyles
|
|
357
363
|
|
|
358
|
-
Generate a className from a style object. Thin wrapper around `computeStyles()
|
|
364
|
+
Generate a className from a style object. Thin wrapper around `computeStyles()`:
|
|
359
365
|
|
|
360
366
|
```tsx
|
|
361
367
|
import { useStyles } from '@tenphi/tasty';
|
|
@@ -373,7 +379,7 @@ function MyComponent() {
|
|
|
373
379
|
|
|
374
380
|
### useGlobalStyles
|
|
375
381
|
|
|
376
|
-
Inject global styles for a CSS selector:
|
|
382
|
+
Inject global styles for a CSS selector. Accepts an optional third argument with an `id` for update tracking — when the styles change, the previous injection is disposed and the new one is injected:
|
|
377
383
|
|
|
378
384
|
```tsx
|
|
379
385
|
import { useGlobalStyles } from '@tenphi/tasty';
|
|
@@ -391,7 +397,7 @@ function ThemeStyles() {
|
|
|
391
397
|
|
|
392
398
|
### useRawCSS
|
|
393
399
|
|
|
394
|
-
Inject raw CSS strings:
|
|
400
|
+
Inject raw CSS strings. Accepts an optional `id` in the options for update tracking — when the CSS changes for the same id, the previous injection is replaced:
|
|
395
401
|
|
|
396
402
|
```tsx
|
|
397
403
|
import { useRawCSS } from '@tenphi/tasty';
|
|
@@ -425,7 +431,7 @@ function Spinner() {
|
|
|
425
431
|
}
|
|
426
432
|
```
|
|
427
433
|
|
|
428
|
-
`useKeyframes()` also supports a factory function
|
|
434
|
+
`useKeyframes()` also supports a factory function. The deps array is accepted for backward compatibility but the factory is called on every invocation — deduplication is handled internally by content hash:
|
|
429
435
|
|
|
430
436
|
```tsx
|
|
431
437
|
function Pulse({ scale }: { scale: number }) {
|
|
@@ -521,43 +527,22 @@ function EmojiList() {
|
|
|
521
527
|
}
|
|
522
528
|
```
|
|
523
529
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
```tsx
|
|
527
|
-
function DynamicList({ marker }: { marker: string }) {
|
|
528
|
-
const styleName = useCounterStyle(
|
|
529
|
-
() => ({
|
|
530
|
-
system: 'cyclic',
|
|
531
|
-
symbols: `"${marker}"`,
|
|
532
|
-
suffix: '" "',
|
|
533
|
-
}),
|
|
534
|
-
[marker],
|
|
535
|
-
);
|
|
536
|
-
|
|
537
|
-
return <ol style={{ listStyleType: styleName }}>...</ol>;
|
|
538
|
-
}
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
Signatures:
|
|
530
|
+
Signature:
|
|
542
531
|
|
|
543
532
|
```ts
|
|
544
533
|
function useCounterStyle(
|
|
545
534
|
descriptors: CounterStyleDescriptors,
|
|
546
535
|
options?: { name?: string; root?: Document | ShadowRoot },
|
|
547
536
|
): string;
|
|
548
|
-
|
|
549
|
-
function useCounterStyle(
|
|
550
|
-
factory: () => CounterStyleDescriptors,
|
|
551
|
-
deps: readonly unknown[],
|
|
552
|
-
options?: { name?: string; root?: Document | ShadowRoot },
|
|
553
|
-
): string;
|
|
554
537
|
```
|
|
555
538
|
|
|
556
539
|
### Troubleshooting
|
|
557
540
|
|
|
558
541
|
- Styles are not updating: make sure `configure()` runs before first render, and verify the generated class name or global rule with [Debug Utilities](debug.md).
|
|
559
|
-
- SSR output looks wrong: check the [SSR guide](ssr.md) for collector setup.
|
|
542
|
+
- SSR output looks wrong: check the [SSR guide](ssr.md) for collector setup. All style functions discover the SSR collector via `AsyncLocalStorage` or the global getter registered by `TastyRegistry`.
|
|
560
543
|
- Animation/custom property issues: prefer `useKeyframes()` and `useProperty()` over raw CSS when you want Tasty to manage injection and SSR collection for you.
|
|
544
|
+
- For dynamic styles that change over the component lifecycle, use the `id` option in `useGlobalStyles()` and `useRawCSS()` to enable update tracking.
|
|
545
|
+
- RSC inline mode: CSS accumulated by standalone style functions (`useGlobalStyles`, `useRawCSS`, etc.) is flushed into inline `<style>` tags by the next `tasty()` component in the render tree. If your page uses only standalone style functions without any `tasty()` component, the CSS will not be emitted. Ensure at least one `tasty()` component is present in each RSC render tree.
|
|
561
546
|
|
|
562
547
|
---
|
|
563
548
|
|
package/docs/ssr.md
CHANGED
|
@@ -18,7 +18,7 @@ The Astro integration (`@tenphi/tasty/ssr/astro`) has no additional dependencies
|
|
|
18
18
|
|
|
19
19
|
## How It Works
|
|
20
20
|
|
|
21
|
-
`tasty()` components are hook-free and use `computeStyles()` internally — a synchronous, framework-agnostic function. On the server, `computeStyles()`
|
|
21
|
+
`tasty()` components are hook-free and use `computeStyles()` internally — a synchronous, framework-agnostic function. On the server, `computeStyles()` discovers a `ServerStyleCollector` via a registered getter (module-level for Next.js, `globalThis` for Astro/generic frameworks using `AsyncLocalStorage`) and collects CSS into it instead of trying to access the DOM. On the client, CSS is injected synchronously into the DOM during render; the injector's content-based cache makes this idempotent. The collector accumulates all styles, serializes them as `<style>` tags and a cache state script in the HTML. On the client, `hydrateTastyCache()` pre-populates the injector cache so that `computeStyles()` skips the rendering pipeline entirely during hydration.
|
|
22
22
|
|
|
23
23
|
```
|
|
24
24
|
Server Client
|
|
@@ -83,14 +83,20 @@ That's it. All `tasty()` components inside the tree automatically get SSR suppor
|
|
|
83
83
|
### How it works
|
|
84
84
|
|
|
85
85
|
- `TastyRegistry` is a `'use client'` component, but Next.js still server-renders it on initial page load. The `'use client'` boundary is required solely to access `useServerInsertedHTML` — **not** because `tasty()` components need the client.
|
|
86
|
-
- During SSR, `TastyRegistry` creates a `ServerStyleCollector` and registers it via a module-level
|
|
86
|
+
- During SSR, `TastyRegistry` creates a `ServerStyleCollector` and registers it via a module-level getter (not `globalThis` — this avoids leaking between Next.js's separate RSC and SSR module graphs). It also wraps children in a React context provider so that hooks inside the SSR tree can discover the collector. All style functions — `tasty()` components, `computeStyles()`, `useStyles()`, `useGlobalStyles()`, `useRawCSS()`, `useKeyframes()`, `useProperty()`, `useFontFace()`, and `useCounterStyle()` — discover the collector through the module-level getter or context provider.
|
|
87
87
|
- `TastyRegistry` uses `useServerInsertedHTML` to flush collected CSS into the HTML stream as `<style data-tasty-ssr>` tags. This is fully streaming-compatible — styles are injected alongside each Suspense boundary as it resolves.
|
|
88
|
-
- A companion `<script>` tag
|
|
89
|
-
- When the module loads on the client, `hydrateTastyCache()` runs automatically and pre-populates the injector cache. During hydration, `computeStyles()` hits the cache and skips the entire pipeline.
|
|
88
|
+
- A companion inline `<script>` tag merges the `cacheKey → className` mapping into `window.__TASTY_SSR_CACHE__` for each flush. This streaming-friendly approach accumulates cache entries incrementally as Suspense boundaries resolve.
|
|
89
|
+
- When the `@tenphi/tasty/ssr/next` module loads on the client, `hydrateTastyCache()` runs automatically from `window.__TASTY_SSR_CACHE__` and pre-populates the injector cache. During hydration, `computeStyles()` hits the cache and skips the entire pipeline.
|
|
90
90
|
|
|
91
|
-
### Using
|
|
91
|
+
### Using Tasty in Server Components
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
All Tasty style functions are hook-free and do not require `'use client'`. They can be used directly in React Server Components:
|
|
94
|
+
|
|
95
|
+
- `tasty()` components — dynamic `styleProps` like `<Grid flow="column">` work normally
|
|
96
|
+
- `useStyles()`, `useGlobalStyles()`, `useRawCSS()` — inject styles by class or selector
|
|
97
|
+
- `useKeyframes()`, `useProperty()`, `useFontFace()`, `useCounterStyle()` — inject ancillary CSS rules
|
|
98
|
+
|
|
99
|
+
During SSR, all functions discover the collector via the same global getter registered by `TastyRegistry` — no React context or client boundary needed. In RSC mode without a collector (e.g., Astro zero-setup), CSS is accumulated in a per-request cache and flushed into an inline `<style>` tag by the next `tasty()` component in the tree. Ensure at least one `tasty()` component is present in every RSC render tree — standalone style functions alone cannot emit their CSS without a `tasty()` component to trigger the flush.
|
|
94
100
|
|
|
95
101
|
### Options
|
|
96
102
|
|
|
@@ -116,18 +122,17 @@ The nonce is automatically applied to all `<style>` and `<script>` tags injected
|
|
|
116
122
|
|
|
117
123
|
## Astro
|
|
118
124
|
|
|
119
|
-
|
|
125
|
+
Tasty offers three levels of Astro integration. Choose the one that matches your needs:
|
|
120
126
|
|
|
121
|
-
|
|
127
|
+
| Setup | Config needed | Deduplication | Hooks work | Client JS |
|
|
128
|
+
|---|---|---|---|---|
|
|
129
|
+
| Zero setup | None | Per render tree | Yes (within each tree) | None |
|
|
130
|
+
| `tastyIntegration({ islands: false })` | One line | Cross-tree | Yes | None |
|
|
131
|
+
| `tastyIntegration()` | One line | Cross-tree | Yes | Auto-hydration |
|
|
122
132
|
|
|
123
|
-
|
|
124
|
-
// src/middleware.ts
|
|
125
|
-
import { tastyMiddleware } from '@tenphi/tasty/ssr/astro';
|
|
126
|
-
|
|
127
|
-
export const onRequest = tastyMiddleware();
|
|
128
|
-
```
|
|
133
|
+
### Zero setup (static pages)
|
|
129
134
|
|
|
130
|
-
|
|
135
|
+
`tasty()` components work in Astro with **no configuration**. Each component emits its own inline `<style>` tag during server rendering via the RSC inline path. Just import and use:
|
|
131
136
|
|
|
132
137
|
```tsx
|
|
133
138
|
// src/components/Card.tsx
|
|
@@ -153,51 +158,118 @@ import Card from '../components/Card.tsx';
|
|
|
153
158
|
|
|
154
159
|
<html>
|
|
155
160
|
<body>
|
|
156
|
-
<Card>
|
|
157
|
-
<Card client:load>Island card — styles hydrated on client</Card>
|
|
161
|
+
<Card>Styled with zero setup</Card>
|
|
158
162
|
</body>
|
|
159
163
|
</html>
|
|
160
164
|
```
|
|
161
165
|
|
|
162
|
-
|
|
166
|
+
**Trade-offs**: Styles are deduplicated within each React render tree, but Astro renders separate component trees independently, so shared CSS (tokens, `@property` rules) may appear more than once. All style functions (`useGlobalStyles`, `useRawCSS`, `useKeyframes`, `useProperty`, `useFontFace`, `useCounterStyle`) work in zero-setup mode — their CSS is accumulated in the RSC cache and flushed by the next `tasty()` component in the tree.
|
|
163
167
|
|
|
164
|
-
|
|
168
|
+
Best for quick prototyping, small static sites, or trying Tasty out in Astro.
|
|
165
169
|
|
|
166
|
-
|
|
167
|
-
- **Islands** (`client:load`, `client:visible`, etc.): Styles are collected during SSR the same way. On the client, importing `@tenphi/tasty/ssr/astro` auto-hydrates the cache from `<script data-tasty-cache>`. The island's `computeStyles()` calls hit the cache during hydration.
|
|
170
|
+
### Astro Integration (recommended)
|
|
168
171
|
|
|
169
|
-
|
|
172
|
+
For production use, add `tastyIntegration()` to your Astro config. This registers middleware automatically and, by default, injects client-side hydration for islands.
|
|
170
173
|
|
|
171
|
-
|
|
174
|
+
#### With islands (default)
|
|
172
175
|
|
|
173
|
-
```
|
|
174
|
-
//
|
|
175
|
-
import '
|
|
176
|
-
import
|
|
176
|
+
```ts
|
|
177
|
+
// astro.config.mjs
|
|
178
|
+
import { defineConfig } from 'astro/config';
|
|
179
|
+
import react from '@astrojs/react';
|
|
180
|
+
import { tastyIntegration } from '@tenphi/tasty/ssr/astro';
|
|
177
181
|
|
|
178
|
-
|
|
179
|
-
|
|
182
|
+
export default defineConfig({
|
|
183
|
+
integrations: [react(), tastyIntegration()],
|
|
180
184
|
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This gives you:
|
|
188
|
+
|
|
189
|
+
- A `ServerStyleCollector` per request via `AsyncLocalStorage`, deduplicating CSS across all React trees on the page
|
|
190
|
+
- A single consolidated `<style data-tasty-ssr>` injected into `</head>`
|
|
191
|
+
- A `<script data-tasty-cache>` tag with the `cacheKey -> className` map for client hydration
|
|
192
|
+
- Auto-injected client hydration script (via `injectScript('before-hydration')`) so islands skip the style pipeline during hydration -- no need to import anything manually in each island component
|
|
181
193
|
|
|
182
|
-
|
|
194
|
+
All style functions (`useGlobalStyles`, `useRawCSS`, `useKeyframes`, `useProperty`, `useFontFace`, `useCounterStyle`) work on the server.
|
|
195
|
+
|
|
196
|
+
```astro
|
|
197
|
+
---
|
|
198
|
+
// src/pages/index.astro
|
|
199
|
+
import Card from '../components/Card.tsx';
|
|
200
|
+
import Interactive from '../components/Interactive.tsx';
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
<html>
|
|
204
|
+
<body>
|
|
205
|
+
<Card>Static -- styles in <style data-tasty-ssr></Card>
|
|
206
|
+
<Interactive client:load>Island -- cache hydrated automatically</Interactive>
|
|
207
|
+
</body>
|
|
208
|
+
</html>
|
|
183
209
|
```
|
|
184
210
|
|
|
185
|
-
|
|
211
|
+
#### Static only (no client JS)
|
|
212
|
+
|
|
213
|
+
If your site has no `client:*` islands, skip the hydration script and cache transfer:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
// astro.config.mjs
|
|
217
|
+
import { defineConfig } from 'astro/config';
|
|
218
|
+
import react from '@astrojs/react';
|
|
219
|
+
import { tastyIntegration } from '@tenphi/tasty/ssr/astro';
|
|
220
|
+
|
|
221
|
+
export default defineConfig({
|
|
222
|
+
integrations: [react(), tastyIntegration({ islands: false })],
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
This gives the same middleware deduplication and hook support, but ships zero client-side JavaScript. No `<script data-tasty-cache>` is emitted.
|
|
227
|
+
|
|
228
|
+
### Manual middleware (advanced)
|
|
229
|
+
|
|
230
|
+
If you need to compose Tasty's middleware with other middleware (e.g., via `sequence()`), use `tastyMiddleware()` directly:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
// src/middleware.ts
|
|
234
|
+
import { sequence } from 'astro:middleware';
|
|
235
|
+
import { tastyMiddleware } from '@tenphi/tasty/ssr/astro';
|
|
236
|
+
|
|
237
|
+
export const onRequest = sequence(
|
|
238
|
+
tastyMiddleware(),
|
|
239
|
+
myOtherMiddleware,
|
|
240
|
+
);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
For island hydration with manual middleware, import the client module in a shared entry point or in each island:
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
import '@tenphi/tasty/ssr/astro-client';
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
#### Options
|
|
186
250
|
|
|
187
251
|
```ts
|
|
188
|
-
// Skip cache state transfer
|
|
252
|
+
// Skip cache state transfer (static-only, no islands)
|
|
189
253
|
export const onRequest = tastyMiddleware({ transferCache: false });
|
|
190
254
|
```
|
|
191
255
|
|
|
256
|
+
### How it works
|
|
257
|
+
|
|
258
|
+
Astro's `@astrojs/react` renderer calls `renderToString()` for each React component without wrapping the tree in a provider. The middleware creates a `ServerStyleCollector` and binds it via `AsyncLocalStorage`. All `computeStyles()` calls within the request discover this collector automatically.
|
|
259
|
+
|
|
260
|
+
- **Static components** (no `client:*`): Styles are collected during `renderToString` and injected into `</head>` as a single `<style>` tag. No JavaScript is shipped.
|
|
261
|
+
- **Islands** (`client:load`, `client:visible`, etc.): Styles are collected during SSR the same way. On the client, the hydration script (auto-injected by `tastyIntegration()` or manually via `@tenphi/tasty/ssr/astro-client`) reads the cache state from `<script data-tasty-cache>` and pre-populates the injector. The island's `computeStyles()` calls hit the cache during hydration.
|
|
262
|
+
- The middleware reads the full response body, then injects the collected CSS into `</head>` before sending the final HTML.
|
|
263
|
+
|
|
192
264
|
### CSP nonce
|
|
193
265
|
|
|
194
|
-
|
|
266
|
+
Call `configure({ nonce: '...' })` before any rendering happens. The middleware reads the nonce and applies it to injected `<style>` and `<script>` tags.
|
|
195
267
|
|
|
196
268
|
---
|
|
197
269
|
|
|
198
270
|
## Generic Framework Integration
|
|
199
271
|
|
|
200
|
-
Any React-based framework can integrate using `runWithCollector`, which binds a `ServerStyleCollector` to the current async context via `AsyncLocalStorage`. All
|
|
272
|
+
Any React-based framework can integrate using `runWithCollector`, which binds a `ServerStyleCollector` to the current async context via `AsyncLocalStorage`. All style function calls within the render automatically discover the collector.
|
|
201
273
|
|
|
202
274
|
```tsx
|
|
203
275
|
import {
|
|
@@ -279,7 +351,8 @@ const stream = await runWithCollector(collector, () =>
|
|
|
279
351
|
|---|---|
|
|
280
352
|
| `@tenphi/tasty/ssr` | Core SSR API: `ServerStyleCollector`, `runWithCollector`, `hydrateTastyCache` |
|
|
281
353
|
| `@tenphi/tasty/ssr/next` | Next.js App Router: `TastyRegistry` component |
|
|
282
|
-
| `@tenphi/tasty/ssr/astro` | Astro: `
|
|
354
|
+
| `@tenphi/tasty/ssr/astro` | Astro: `tastyIntegration`, `tastyMiddleware` |
|
|
355
|
+
| `@tenphi/tasty/ssr/astro-client` | Astro: client-side cache hydration (auto-injected by integration, or import manually) |
|
|
283
356
|
|
|
284
357
|
### `ServerStyleCollector`
|
|
285
358
|
|
|
@@ -290,9 +363,14 @@ Server-safe style collector. One instance per request.
|
|
|
290
363
|
| `allocateClassName(cacheKey)` | Allocate a sequential class name (`t0`, `t1`, ...) for a cache key. Returns `{ className, isNewAllocation }`. |
|
|
291
364
|
| `collectChunk(cacheKey, className, rules)` | Record CSS rules for a chunk. Deduplicated by `cacheKey`. |
|
|
292
365
|
| `collectKeyframes(name, css)` | Record a `@keyframes` rule. Deduplicated by name. |
|
|
366
|
+
| `allocateKeyframeName(providedName?)` | Allocate a keyframe name. Returns `providedName` if given, otherwise generates one (`k0`, `k1`, ...). |
|
|
293
367
|
| `collectProperty(name, css)` | Record a `@property` rule. Deduplicated by name. |
|
|
294
368
|
| `collectFontFace(key, css)` | Record a `@font-face` rule. Deduplicated by content hash. |
|
|
295
369
|
| `collectCounterStyle(name, css)` | Record a `@counter-style` rule. Deduplicated by name. |
|
|
370
|
+
| `allocateCounterStyleName(providedName?)` | Allocate a counter-style name. Returns `providedName` if given, otherwise generates one (`cs0`, `cs1`, ...). |
|
|
371
|
+
| `collectGlobalStyles(key, css)` | Record global styles (from `useGlobalStyles`). Deduplicated by key. |
|
|
372
|
+
| `collectRawCSS(key, css)` | Record raw CSS text (from `useRawCSS`). Deduplicated by key. |
|
|
373
|
+
| `collectInternals()` | Collect internal `@property` rules, `:root` token defaults, `@font-face`, and `@counter-style` rules from the global config. Called automatically on first chunk collection; idempotent. |
|
|
296
374
|
| `getCSS()` | Get all collected CSS as a single string. For non-streaming SSR. |
|
|
297
375
|
| `flushCSS()` | Get only CSS collected since the last flush. For streaming SSR. |
|
|
298
376
|
| `getCacheState()` | Serialize `{ entries: Record<cacheKey, className>, classCounter }` for client hydration. |
|
|
@@ -306,9 +384,17 @@ Next.js App Router component. Props:
|
|
|
306
384
|
| `children` | `ReactNode` | required | Application tree |
|
|
307
385
|
| `transferCache` | `boolean` | `true` | Embed cache state script for zero-cost hydration |
|
|
308
386
|
|
|
387
|
+
### `tastyIntegration(options?)`
|
|
388
|
+
|
|
389
|
+
Astro integration factory. Registers middleware and optionally injects client hydration.
|
|
390
|
+
|
|
391
|
+
| Option | Type | Default | Description |
|
|
392
|
+
|---|---|---|---|
|
|
393
|
+
| `islands` | `boolean` | `true` | When `true`, injects client hydration script and enables `transferCache`. When `false`, no client JS is shipped. |
|
|
394
|
+
|
|
309
395
|
### `tastyMiddleware(options?)`
|
|
310
396
|
|
|
311
|
-
Astro middleware factory.
|
|
397
|
+
Astro middleware factory. Use for manual middleware composition.
|
|
312
398
|
|
|
313
399
|
| Option | Type | Default | Description |
|
|
314
400
|
|---|---|---|---|
|
|
@@ -320,7 +406,7 @@ Pre-populate the client injector cache. When called without arguments, reads fro
|
|
|
320
406
|
|
|
321
407
|
### `runWithCollector(collector, fn)`
|
|
322
408
|
|
|
323
|
-
Run a function with a `ServerStyleCollector` bound to the current async context via `AsyncLocalStorage`. All `
|
|
409
|
+
Run a function with a `ServerStyleCollector` bound to the current async context via `AsyncLocalStorage`. All style function calls within `fn` (and async continuations) — including `computeStyles()`, `useStyles()`, `useGlobalStyles()`, `useRawCSS()`, `useKeyframes()`, `useProperty()`, `useFontFace()`, and `useCounterStyle()` — will find this collector.
|
|
324
410
|
|
|
325
411
|
---
|
|
326
412
|
|
|
@@ -328,11 +414,11 @@ Run a function with a `ServerStyleCollector` bound to the current async context
|
|
|
328
414
|
|
|
329
415
|
### Styles flash on page load (FOUC)
|
|
330
416
|
|
|
331
|
-
The `TastyRegistry` or `
|
|
417
|
+
The `TastyRegistry` or `tastyIntegration` is missing. Ensure your layout wraps the app with `TastyRegistry` (Next.js) or that `tastyIntegration()` is in your Astro config (or `tastyMiddleware()` is registered manually).
|
|
332
418
|
|
|
333
419
|
### Hydration mismatch warnings
|
|
334
420
|
|
|
335
|
-
Class names are deterministic for the same render order. If you see mismatches, ensure `hydrateTastyCache()` runs before React hydration. For Next.js, this is automatic. For Astro, import `@tenphi/tasty/ssr/astro` in your island components. For custom setups, call `hydrateTastyCache()` before `hydrateRoot()`.
|
|
421
|
+
Class names are deterministic for the same render order. If you see mismatches, ensure `hydrateTastyCache()` runs before React hydration. For Next.js, this is automatic. For Astro with `tastyIntegration()`, this is also automatic. For manual Astro middleware setups, import `@tenphi/tasty/ssr/astro-client` in your island components. For custom setups, call `hydrateTastyCache()` before `hydrateRoot()`.
|
|
336
422
|
|
|
337
423
|
### Styles duplicated after hydration
|
|
338
424
|
|
package/docs/tasty-static.md
CHANGED
|
@@ -161,11 +161,23 @@ module.exports = {
|
|
|
161
161
|
| `configFile` | `string` | — | Absolute path to a TS/JS module that default-exports a `TastyZeroConfig` object. JSON-serializable alternative to `config` — required for Turbopack. |
|
|
162
162
|
| `config` | `TastyZeroConfig \| () => TastyZeroConfig` | `{}` | Inline config object or factory function. Takes precedence over `configFile`. |
|
|
163
163
|
| `configDeps` | `string[]` | `[]` | Absolute file paths that affect config (for cache invalidation) |
|
|
164
|
-
| `
|
|
164
|
+
| `injectImport` | `boolean` | `true` | Replace `@tenphi/tasty/static` imports with an import of the generated CSS file. Set to `false` to manage CSS imports manually. |
|
|
165
|
+
| `config.states` | `Record<string, string>` | `{}` | Predefined state aliases (e.g. `{ '@mobile': '@media(w < 768px)' }`) |
|
|
165
166
|
| `config.devMode` | `boolean` | `false` | Add source comments to CSS |
|
|
167
|
+
| `config.tokens` | `ConfigTokens` | — | Design tokens injected as CSS custom properties on `:root`. Values are parsed through the Tasty DSL. Supports state maps for responsive/themed tokens. |
|
|
168
|
+
| `config.replaceTokens` | `Record<string, string \| number>` | — | Parse-time token substitution. Keys use `$name` for custom properties and `#name` for color tokens. |
|
|
166
169
|
| `config.recipes` | `Record<string, RecipeStyles>` | `{}` | Predefined style recipes |
|
|
170
|
+
| `config.keyframes` | `Record<string, KeyframesSteps>` | — | Global `@keyframes` definitions available to all `tastyStatic` calls |
|
|
167
171
|
| `config.fontFace` | `Record<string, FontFaceInput>` | — | Global `@font-face` definitions |
|
|
168
172
|
| `config.counterStyle` | `Record<string, CounterStyleDescriptors>` | — | Global `@counter-style` definitions |
|
|
173
|
+
| `config.units` | `Record<string, string \| UnitHandler>` | — | Custom units for the style parser (merged with built-ins). E.g. `{ em: 'em', vw: 'vw' }` |
|
|
174
|
+
| `config.funcs` | `Record<string, Function>` | — | Custom functions for the style parser (merged with existing) |
|
|
175
|
+
| `config.plugins` | `TastyPlugin[]` | — | Plugins that extend tasty with custom functions, units, states, and handlers |
|
|
176
|
+
| `config.handlers` | `Record<string, StyleHandlerDefinition>` | — | Custom style handlers that transform style properties into CSS declarations |
|
|
177
|
+
| `config.presets` | `Record<string, TypographyPreset>` | — | Typography presets — shorthand for `generateTypographyTokens()`. Generated tokens merge under explicit `tokens`. |
|
|
178
|
+
| `config.globalStyles` | `Record<string, Styles>` | — | Global Tasty styles keyed by CSS selector. Supports the full style syntax. |
|
|
179
|
+
| `config.autoPropertyTypes` | `boolean` | `true` | Automatically infer and register CSS `@property` declarations from values |
|
|
180
|
+
| `config.parserCacheSize` | `number` | `1000` | Parser LRU cache size. Larger values improve performance for builds with many unique style values |
|
|
169
181
|
|
|
170
182
|
---
|
|
171
183
|
|
|
@@ -516,5 +528,5 @@ const card = tastyStatic({
|
|
|
516
528
|
|
|
517
529
|
- [Docs Hub](README.md) — Choose the right guide by task or rendering mode
|
|
518
530
|
- [Style DSL](dsl.md) — State maps, tokens, units, extending semantics (shared by runtime and static)
|
|
519
|
-
- [
|
|
531
|
+
- [React API](react-api.md) — Runtime styling: `tasty()` factory, component props, variants, sub-elements, style functions
|
|
520
532
|
- [Configuration](configuration.md) — Global configuration: tokens, recipes, custom units, and style handlers
|