@tenphi/tasty 0.0.0-snapshot.27b6708 → 0.0.0-snapshot.28b6339
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 +38 -54
- package/dist/{babel-BUQGeOXA.d.ts → babel-Zs1Q03qt.d.ts} +2 -2
- package/dist/chunks/async-storage-DKK-wTD4.js.map +1 -0
- package/dist/chunks/build-config-Mk7waOsw.js +45 -0
- package/dist/chunks/build-config-Mk7waOsw.js.map +1 -0
- package/dist/{collector-DTahQUiV.js → chunks/collector-Ducc5l3E.js} +29 -15
- package/dist/chunks/collector-Ducc5l3E.js.map +1 -0
- package/dist/chunks/config-engine-tKK7WxJO.js +331 -0
- package/dist/chunks/config-engine-tKK7WxJO.js.map +1 -0
- package/dist/chunks/css-definitions-Crstltrf.js +1229 -0
- package/dist/chunks/css-definitions-Crstltrf.js.map +1 -0
- package/dist/chunks/css-resources-Cyl_axbI.js +149 -0
- package/dist/chunks/css-resources-Cyl_axbI.js.map +1 -0
- package/dist/chunks/debug-HyyLIf6O.js +543 -0
- package/dist/chunks/debug-HyyLIf6O.js.map +1 -0
- package/dist/chunks/dsl-D7kBow--.js +1771 -0
- package/dist/chunks/dsl-D7kBow--.js.map +1 -0
- package/dist/chunks/hydration-CLdVKcH2.js +59 -0
- package/dist/chunks/hydration-CLdVKcH2.js.map +1 -0
- package/dist/chunks/react-runtime-UlZcbsEN.js +877 -0
- package/dist/chunks/react-runtime-UlZcbsEN.js.map +1 -0
- package/dist/chunks/runtime-engine-D2WOLvd6.js +3439 -0
- package/dist/chunks/runtime-engine-D2WOLvd6.js.map +1 -0
- package/dist/chunks/runtime-state-DOeH6rsG.js +138 -0
- package/dist/chunks/runtime-state-DOeH6rsG.js.map +1 -0
- package/dist/{merge-styles-oklji0KB.js → chunks/shared-utils-Bgl8FNGJ.js} +64 -24
- package/dist/chunks/shared-utils-Bgl8FNGJ.js.map +1 -0
- package/dist/chunks/style-engine-C4ZcOAPb.js +6915 -0
- package/dist/chunks/style-engine-C4ZcOAPb.js.map +1 -0
- package/dist/{css-writer-B-J87ncv.js → chunks/zero-engine-D4Rluo7u.js} +3 -3
- package/dist/chunks/zero-engine-D4Rluo7u.js.map +1 -0
- package/dist/{collector-DUaHCcTS.d.ts → collector-hl5KNH7k.d.ts} +23 -3
- package/dist/{config-YsxGv4tq.d.ts → config-DWL1ZYue.d.ts} +150 -55
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +9 -6
- package/dist/{index-PqN-DIpn.d.ts → index-D9N9GV24.d.ts} +129 -93
- package/dist/index.d.ts +5 -5
- package/dist/index.js +11 -922
- package/dist/{merge-styles-CU7JbEwg.d.ts → merge-styles-C_oMoJVd.d.ts} +2 -2
- package/dist/ssr/astro-client.js +1 -1
- package/dist/ssr/astro-middleware-extract-static.d.ts +11 -0
- package/dist/ssr/astro-middleware-extract-static.js +9 -0
- package/dist/ssr/astro-middleware-extract-static.js.map +1 -0
- package/dist/ssr/astro-middleware-extract.d.ts +11 -0
- package/dist/ssr/astro-middleware-extract.js +9 -0
- package/dist/ssr/astro-middleware-extract.js.map +1 -0
- package/dist/ssr/astro-middleware-static.d.ts +3 -1
- package/dist/ssr/astro-middleware.d.ts +3 -1
- package/dist/ssr/astro.d.ts +45 -3
- package/dist/ssr/astro.js +158 -15
- package/dist/ssr/astro.js.map +1 -1
- package/dist/ssr/index.d.ts +7 -7
- package/dist/ssr/index.js +4 -4
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/next-config.d.ts +66 -0
- package/dist/ssr/next-config.js +135 -0
- package/dist/ssr/next-config.js.map +1 -0
- package/dist/ssr/next.d.ts +9 -2
- package/dist/ssr/next.js +27 -11
- package/dist/ssr/next.js.map +1 -1
- package/dist/static/index.d.ts +2 -2
- package/dist/static/index.js +1 -1
- package/dist/{index-Cd45t5NM.d.ts → types-jKZNpias.d.ts} +898 -803
- package/dist/zero/babel.d.ts +1 -1
- package/dist/zero/babel.js +25 -24
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/index.d.ts +1 -1
- package/dist/zero/index.js +1 -1
- package/dist/zero/next.d.ts +1 -1
- package/docs/README.md +5 -3
- package/docs/adoption.md +3 -3
- package/docs/ai-agents.md +83 -78
- package/docs/comparison.md +12 -12
- package/docs/configuration.md +47 -47
- package/docs/debug.md +19 -7
- package/docs/dsl.md +3 -3
- package/docs/getting-started.md +10 -10
- package/docs/injector.md +62 -25
- package/docs/methodology.md +3 -3
- package/docs/migration-v3.md +49 -49
- package/docs/plugins.md +37 -33
- package/docs/react-api.md +2 -2
- package/docs/runtime-benchmarks.md +351 -0
- package/docs/ssr.md +219 -61
- package/docs/styles.md +43 -11
- package/docs/tasty-static.md +136 -103
- package/package.json +80 -11
- package/dist/async-storage-DKK-wTD4.js.map +0 -1
- package/dist/collector-DTahQUiV.js.map +0 -1
- package/dist/config-B5kHzuNz.js +0 -12269
- package/dist/config-B5kHzuNz.js.map +0 -1
- package/dist/context-CA8YKeMn.js +0 -24
- package/dist/context-CA8YKeMn.js.map +0 -1
- package/dist/core-Dr4u1NVD.js +0 -1566
- package/dist/core-Dr4u1NVD.js.map +0 -1
- package/dist/css-writer-B-J87ncv.js.map +0 -1
- package/dist/format-global-rules-DklyaXv-.js +0 -22
- package/dist/format-global-rules-DklyaXv-.js.map +0 -1
- package/dist/format-rules-DKOA-6qu.js +0 -130
- package/dist/format-rules-DKOA-6qu.js.map +0 -1
- package/dist/hydrate-OeMX99We.js +0 -37
- package/dist/hydrate-OeMX99We.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/keyframes-CV8azJf3.js +0 -493
- package/dist/keyframes-CV8azJf3.js.map +0 -1
- package/dist/merge-styles-oklji0KB.js.map +0 -1
- package/dist/resolve-recipes-DTG81rzl.js +0 -144
- package/dist/resolve-recipes-DTG81rzl.js.map +0 -1
- /package/dist/{async-storage-DKK-wTD4.js → chunks/async-storage-DKK-wTD4.js} +0 -0
package/docs/ai-agents.md
CHANGED
|
@@ -16,7 +16,7 @@ Color tokens (`#name`), custom properties (`$name`), `preset` names, `recipe` na
|
|
|
16
16
|
const Card = tasty({ as: 'div', styles: { … }, styleProps: ['padding'] }); // new component
|
|
17
17
|
const Hero = tasty(Card, { styles: { … } }); // extend a component
|
|
18
18
|
const cls = useStyles({ … }); // ad-hoc class name
|
|
19
|
-
tastyStatic('.card', { … }); // build-time
|
|
19
|
+
tastyStatic('.card', { … }); // build-time extraction
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
- Wrap, don't pass styles per instance: ❌ `<Box styles={{ padding: '2x' }} />` → ✅ `const Box = tasty({ styles: { padding: '2x' } })`.
|
|
@@ -29,26 +29,28 @@ Keys are camelCase — a Tasty property or a real CSS property. No kebab-case, n
|
|
|
29
29
|
|
|
30
30
|
Prefer the Tasty shorthand over its CSS equivalents:
|
|
31
31
|
|
|
32
|
-
| Use
|
|
33
|
-
|
|
34
|
-
| `fill`
|
|
35
|
-
| `image`
|
|
36
|
-
| `border`
|
|
37
|
-
| `radius`
|
|
38
|
-
| `outline`
|
|
39
|
-
| `shadow`
|
|
40
|
-
| `padding`
|
|
41
|
-
| `margin`
|
|
42
|
-
| `inset`
|
|
43
|
-
| `width` / `height`
|
|
44
|
-
| `flow`
|
|
45
|
-
| `preset`
|
|
46
|
-
| `font`
|
|
47
|
-
| `scrollbar`
|
|
48
|
-
| `gridColumns` / `gridRows` / `gridAreas` | `gridTemplateColumns` / `Rows` / `Areas`
|
|
49
|
-
| `textOverflow: 'ellipsis / 3'`
|
|
50
|
-
| `hide: true`
|
|
51
|
-
| `flexGrow` / `flexShrink` / `flexBasis`
|
|
32
|
+
| Use | Instead of |
|
|
33
|
+
| ---------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
34
|
+
| `fill` | `backgroundColor`, `background` |
|
|
35
|
+
| `image` | `backgroundImage` |
|
|
36
|
+
| `border` | `borderColor`, `borderWidth`, `borderStyle`, `borderTop`/`Right`/`Bottom`/`Left` |
|
|
37
|
+
| `radius` | `borderRadius` |
|
|
38
|
+
| `outline` | `outlineColor`, `outlineWidth`, `outlineStyle`, `outlineOffset` |
|
|
39
|
+
| `shadow` | `boxShadow` |
|
|
40
|
+
| `padding` | `paddingTop`/`Right`/`Bottom`/`Left` |
|
|
41
|
+
| `margin` | `marginTop`/`Right`/`Bottom`/`Left` |
|
|
42
|
+
| `inset` | `top`, `right`, `bottom`, `left` |
|
|
43
|
+
| `width` / `height` | `minWidth`/`maxWidth`, `minHeight`/`maxHeight` |
|
|
44
|
+
| `flow` | `flexDirection`, `flexWrap`, `flexFlow`, `gridAutoFlow` |
|
|
45
|
+
| `preset` | `fontSize`, `lineHeight`, `letterSpacing`, `fontWeight`, `fontStyle`, `textTransform` |
|
|
46
|
+
| `font` | `fontFamily` |
|
|
47
|
+
| `scrollbar` | `scrollbarWidth`, `scrollbarColor`, `scrollbarGutter` |
|
|
48
|
+
| `gridColumns` / `gridRows` / `gridAreas` | `gridTemplateColumns` / `Rows` / `Areas` |
|
|
49
|
+
| `textOverflow: 'ellipsis / 3'` | `lineClamp` |
|
|
50
|
+
| `hide: true` | `display: 'none'` |
|
|
51
|
+
| `flexGrow` / `flexShrink` / `flexBasis` | `flex` |
|
|
52
|
+
|
|
53
|
+
Use logical category styles when layout must follow writing mode or direction: `blockSize`/`inlineSize`, `blockPadding`/`inlinePadding`, `blockMargin`/`inlineMargin`, `blockInset`/`inlineInset`, `blockScrollMargin`/`inlineScrollMargin`, `blockScrollPadding`/`inlineScrollPadding`, and `blockBorder`/`inlineBorder`. Use `start`/`end` value modifiers; do not replace them with physical sides. Native logical CSS properties remain valid as ordinary keys when an individual declaration is needed.
|
|
52
54
|
|
|
53
55
|
The last row goes the other way — longhands over the shorthand — because `flex` is lossy: it resets the components you omit to non-initial values (`flex: '0'` silently sets `flex-basis: 0%`) and cannot express `flexShrink: 0` at all. The longhands also carry separate state maps.
|
|
54
56
|
|
|
@@ -56,23 +58,23 @@ The last row goes the other way — longhands over the shorthand — because `fl
|
|
|
56
58
|
|
|
57
59
|
### Tokens
|
|
58
60
|
|
|
59
|
-
| Syntax
|
|
60
|
-
|
|
61
|
-
| `#name`
|
|
62
|
-
| `#name.50`
|
|
63
|
-
| `#name.$opacity`
|
|
64
|
-
| `#clear` / `#current` | `transparent` / `currentcolor`
|
|
65
|
-
| `$name`
|
|
66
|
-
| `(#a, #b)`
|
|
67
|
-
| `$$name` / `##name`
|
|
68
|
-
| `$$name(…)`
|
|
61
|
+
| Syntax | Meaning |
|
|
62
|
+
| --------------------- | ------------------------------------------------------------------------- |
|
|
63
|
+
| `#name` | color token → `var(--name-color)` |
|
|
64
|
+
| `#name.50` | token at 50% opacity (`0`–`100`) |
|
|
65
|
+
| `#name.$opacity` | opacity from a custom property |
|
|
66
|
+
| `#clear` / `#current` | `transparent` / `currentcolor` |
|
|
67
|
+
| `$name` | custom property → `var(--name)` |
|
|
68
|
+
| `(#a, #b)` | fallback chain |
|
|
69
|
+
| `$$name` / `##name` | the custom property _name_ (not its value) — inside `transition` |
|
|
70
|
+
| `$$name(…)` | call a CSS `@function` declared via `@function`, `useFunction`, or config |
|
|
69
71
|
|
|
70
72
|
- ❌ `#f5f5f5`, `rgb(0 0 0)`, `oklch(…)`, `okhsl(…)`, `red` → ✅ `#surface` (add the token to the config if it doesn't exist).
|
|
71
73
|
- ❌ `var(--gap)` → ✅ `$gap` · ❌ `$accent-color` → ✅ `#accent` · ❌ `transparent` → ✅ `#clear` · ❌ `currentColor` → ✅ `#current`.
|
|
72
74
|
- A `$name` must be declared as a `'$name': value` key in the same styles object, or in the config.
|
|
73
75
|
- Names are case-sensitive and start lowercase — `$myVar` → `--myVar`; a leading capital folds (`$Foo` → `--foo`). Prefer kebab-case.
|
|
74
76
|
- A `$name` reference is untyped: it fills the first free slot in a shorthand (`border: '1bw $my-style'` → the line style). Write colors as `#name`; `$name-color` is a fallback for pointing at a raw CSS custom property that holds a color.
|
|
75
|
-
- `preset` and `transition` take token
|
|
77
|
+
- `preset` and `transition` take token _names_, not values, so a `$name` cannot stand in for one (it warns in dev and is ignored).
|
|
76
78
|
|
|
77
79
|
### Units
|
|
78
80
|
|
|
@@ -86,7 +88,7 @@ Prefer units over raw pixels: `8px` → `1x` … `64px` → `8x`; `radius: '6px'
|
|
|
86
88
|
|
|
87
89
|
### `true`
|
|
88
90
|
|
|
89
|
-
`true` means "the design-system default" and is accepted **only** by: `border`, `radius`, `outline`, `shadow`, `padding`, `margin`, `gap`, `inset`, `width`, `height`, `fill`, `color`, `fade`, `preset`, `font`, `scrollbar`, `hide`. Anywhere else it is an error.
|
|
91
|
+
`true` means "the design-system default" and is accepted **only** by: `border`, `radius`, `outline`, `shadow`, `padding`, `margin`, `gap`, `inset`, `width`, `height`, `fill`, `color`, `fade`, `preset`, `font`, `scrollbar`, `scrollMargin`, `scrollPadding`, and the enhanced logical category styles listed above, plus `hide`. Anywhere else it is an error.
|
|
90
92
|
|
|
91
93
|
### `!important`
|
|
92
94
|
|
|
@@ -96,29 +98,31 @@ Never use it. Tasty owns specificity through doubled selectors and state orderin
|
|
|
96
98
|
|
|
97
99
|
A value is `[values…] [modifiers…]`, and several groups can be comma-separated (later groups override earlier ones). A group that names **direction** modifiers takes a **single** value, applied to every direction it names — per-side values come from comma groups. A group naming no direction keeps plain CSS shorthand order (1–4 values). (`inset` + `dock` is the one exception: a second value insets the spanned sides.) Only the modifiers a property knows are valid:
|
|
98
100
|
|
|
99
|
-
| Property
|
|
100
|
-
|
|
101
|
-
| `padding`, `margin`, `inset`, `fade` | `top` `right` `bottom` `left`
|
|
102
|
-
| `border`
|
|
103
|
-
|
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
| `
|
|
111
|
-
|
|
|
101
|
+
| Property | Modifiers |
|
|
102
|
+
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
|
|
103
|
+
| `padding`, `margin`, `inset`, `fade` | `top` `right` `bottom` `left` |
|
|
104
|
+
| `border` | the four directions + `solid` `dashed` `dotted` `double` `groove` `ridge` `inset` `outset` `none` `hidden` |
|
|
105
|
+
| logical axis spacing/inset styles | `start` `end` |
|
|
106
|
+
| `blockBorder`, `inlineBorder` | `start` `end` + the border style keywords above |
|
|
107
|
+
| `outline` | the style keywords above |
|
|
108
|
+
| `radius` | `top` `right` `bottom` `left` + shapes `round` `ellipse` `leaf` `backleaf` |
|
|
109
|
+
| `width`, `height`, `blockSize`, `inlineSize` | `min` `max` `fixed` |
|
|
110
|
+
| `flow` | `row` `column` `row-reverse` `column-reverse` `wrap` `nowrap` `dense` |
|
|
111
|
+
| `overflow` | `visible` `hidden` `scroll` `clip` `auto` `overlay` |
|
|
112
|
+
| `position` | `static` `relative` `absolute` `fixed` `sticky` |
|
|
113
|
+
| `shadow` | `inset` |
|
|
114
|
+
| `preset` | `name / strong` (or `bold`) `italic` `icon` `tight` |
|
|
115
|
+
| box properties | `longhand` — emit CSS longhands instead of the shorthand |
|
|
112
116
|
|
|
113
117
|
Directional modifiers beat placeholder zeros:
|
|
114
118
|
|
|
115
119
|
- ❌ `padding: '0 0 2x 0'` → ✅ `padding: '2x bottom'`
|
|
116
120
|
- ❌ `padding: '1x 1x 2x 1x'` → ✅ `padding: '1x, 2x bottom'`
|
|
117
|
-
- ❌ `border: '0 0 1bw 0'` — four tokens parse as
|
|
121
|
+
- ❌ `border: '0 0 1bw 0'` — four tokens parse as _one_ border value, so this renders no border at all → ✅ `border: '1bw bottom'`
|
|
118
122
|
- ❌ `padding: '2x 4x top right'` — a directional group takes one value, so `4x` is dropped → ✅ `padding: '2x top, 4x right'`
|
|
119
123
|
- ❌ `fade: '3x 1x top bottom'` → ✅ `fade: '3x top, 1x bottom'`
|
|
120
124
|
|
|
121
|
-
Value-only properties reject both colors and modifiers: `gap`, `columnGap`, `rowGap`, `opacity`, `zIndex`, `order`, `flexGrow`, `flexShrink`, `flexBasis`, `aspectRatio`, `lineClamp`, `tabSize`, `
|
|
125
|
+
Value-only properties reject both colors and modifiers: `gap`, `columnGap`, `rowGap`, `opacity`, `zIndex`, `order`, `flexGrow`, `flexShrink`, `flexBasis`, `aspectRatio`, `lineClamp`, and `tabSize`. Logical axis category styles accept one or two values in start/end order and the `start`, `end`, and `longhand` modifiers. `fill` and `color` take a color (plus `none` / `transparent`); `caretColor` and `accentColor` take a color only.
|
|
122
126
|
|
|
123
127
|
### `transition`
|
|
124
128
|
|
|
@@ -130,17 +134,17 @@ Use semantic names, not CSS property names: `fade` `fill` `color` `theme` `borde
|
|
|
130
134
|
|
|
131
135
|
A property value can be an object of `state: value`. Key order is priority — later keys win.
|
|
132
136
|
|
|
133
|
-
| Key
|
|
134
|
-
|
|
135
|
-
| `hovered`
|
|
136
|
-
| `theme=danger`
|
|
137
|
-
| `:hover`
|
|
138
|
-
| `.active`
|
|
139
|
-
| `[aria-expanded="true"]` | attribute selector
|
|
140
|
-
| `hovered & .active`
|
|
141
|
-
| `hovered \| focused`
|
|
142
|
-
| `!disabled`
|
|
143
|
-
| `hovered ^ focused`
|
|
137
|
+
| Key | Generated selector |
|
|
138
|
+
| ------------------------ | ----------------------------------------------- |
|
|
139
|
+
| `hovered` | `[data-hovered]` (boolean modifier from `mods`) |
|
|
140
|
+
| `theme=danger` | `[data-theme="danger"]` (value modifier) |
|
|
141
|
+
| `:hover` | pseudo-class |
|
|
142
|
+
| `.active` | class selector |
|
|
143
|
+
| `[aria-expanded="true"]` | attribute selector |
|
|
144
|
+
| `hovered & .active` | AND |
|
|
145
|
+
| `hovered \| focused` | OR (`,` also means OR) |
|
|
146
|
+
| `!disabled` | NOT |
|
|
147
|
+
| `hovered ^ focused` | XOR — exactly one (keep chains ≤ 4 operands) |
|
|
144
148
|
|
|
145
149
|
Precedence `!` > `^` > `|` > `&`; use parentheses to override.
|
|
146
150
|
|
|
@@ -148,7 +152,7 @@ Rules:
|
|
|
148
152
|
|
|
149
153
|
1. **`''` comes first.** The bare default is the lowest-priority state; placing it later would override everything above it.
|
|
150
154
|
2. **Every state map needs `''` or `_`** — except when extending (`tasty(Parent, …)`), where omitting `''` merges into the parent's states and including `''` replaces them wholesale.
|
|
151
|
-
3. **`_` is standalone-only** and always first (with `''` right after it, if present). `_` is a never-negated fallback floor for cases where a higher-priority branch may be
|
|
155
|
+
3. **`_` is standalone-only** and always first (with `''` right after it, if present). `_` is a never-negated fallback floor for cases where a higher-priority branch may be _unknown_ (`@supports`, container queries). If a map contains only `_` and `''`, drop the `''`.
|
|
152
156
|
4. **No nested maps:** ❌ `{ hovered: { pressed: 'x' } }` → ✅ `{ 'hovered & pressed': 'x' }`
|
|
153
157
|
5. **State keys never sit at the top level** of a styles object — `:hover`, `.active`, `[open]` belong inside a property value.
|
|
154
158
|
6. **Prefer automatic native states:** use `disabled` and `checked` in Tasty component styles instead of `[disabled]` and `[checked]`. The concise states track the corresponding native prop or attribute automatically.
|
|
@@ -159,16 +163,16 @@ color: { '': '#text', hovered: '#accent', disabled: '#text.40' }
|
|
|
159
163
|
|
|
160
164
|
Advanced states:
|
|
161
165
|
|
|
162
|
-
| Prefix
|
|
163
|
-
|
|
164
|
-
| `@media(…)`
|
|
165
|
-
| `@(…)`
|
|
166
|
-
| `@supports(…)` | feature query; `$` first argument tests a selector
|
|
167
|
-
| `@root(…)`
|
|
168
|
-
| `@parent(…)`
|
|
169
|
-
| `@own(…)`
|
|
170
|
-
| `@starting`
|
|
171
|
-
| `@name`
|
|
166
|
+
| Prefix | Use | Example |
|
|
167
|
+
| -------------- | -------------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
168
|
+
| `@media(…)` | media query; dimensions `w` `h`; types `@media:print` `:screen` `:all` `:speech` | `@media(w < 768px)`, `@media(600px <= w < 1200px)` |
|
|
169
|
+
| `@(…)` | container query; dimensions `w` `h` `is` `bs` | `@(layout, w >= 600px)`, `@($variant=primary)` |
|
|
170
|
+
| `@supports(…)` | feature query; `$` first argument tests a selector | `@supports(display: grid)`, `@supports($, :has(*))` |
|
|
171
|
+
| `@root(…)` | condition on `:root` | `@root(schema=dark)` |
|
|
172
|
+
| `@parent(…)` | condition on an ancestor; `, >` for the direct parent | `@parent(hovered, >)` |
|
|
173
|
+
| `@own(…)` | a sub-element's own state — **only inside sub-element styles** | `@own(:hover)` |
|
|
174
|
+
| `@starting` | `@starting-style` entry animation | `@starting` |
|
|
175
|
+
| `@name` | project state alias | `@mobile` |
|
|
172
176
|
|
|
173
177
|
- At root level write the selector directly: ❌ `'@own(:hover)'` → ✅ `':hover'`.
|
|
174
178
|
- `@name` aliases must exist in `states` in the config or be declared locally as an `'@name': '<state expression>'` key; alias keys start with `@` and their value must be a valid state expression.
|
|
@@ -188,14 +192,14 @@ styles: { Title: { preset: 'h3' }, Icon: { $: '>@:last-child', color: '#accent'
|
|
|
188
192
|
|
|
189
193
|
## 6. Special top-level keys
|
|
190
194
|
|
|
191
|
-
| Key
|
|
192
|
-
|
|
193
|
-
| `@keyframes`
|
|
194
|
-
| `@property`
|
|
195
|
-
| `@font-face`
|
|
196
|
-
| `@counter-style` | `{ name: descriptors }`
|
|
197
|
-
| `@function`
|
|
198
|
-
| `recipe`
|
|
195
|
+
| Key | Shape |
|
|
196
|
+
| ---------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
197
|
+
| `@keyframes` | `{ name: { '0%': styles, … } }` |
|
|
198
|
+
| `@property` | `{ '$name': { syntax, inherits, initialValue } }` |
|
|
199
|
+
| `@font-face` | `{ 'Family Name': descriptors \| descriptors[] }` |
|
|
200
|
+
| `@counter-style` | `{ name: descriptors }` |
|
|
201
|
+
| `@function` | `{ '$$name': { args, returns?, result, '$local'? } }` |
|
|
202
|
+
| `recipe` | a **string** of configured recipe names: `'card elevated'`, `'reset input / autofill'`, `'none / disabled'` |
|
|
199
203
|
|
|
200
204
|
At-rule keys match the real CSS at-rule names, so they are kebab-case, not camelCase. Inside `@function`, the callable is `$$name` but its parameters and local variables are `$name`:
|
|
201
205
|
|
|
@@ -214,6 +218,7 @@ The selector must be a string literal and valid CSS. Values must be static — s
|
|
|
214
218
|
|
|
215
219
|
- Token, preset, recipe, unit and `@alias` names exist in the project config.
|
|
216
220
|
- Tasty shorthand chosen over CSS longhands; `flexGrow`/`flexShrink`/`flexBasis` over `flex`; `hide: true` over `display: 'none'`.
|
|
221
|
+
- Logical category styles keep native `block`/`inline` declarations and accept `start`/`end`, never physical direction modifiers.
|
|
217
222
|
- Colors are `#tokens`, not hex/rgb/oklch/named; `$prop` not `var(--prop)`.
|
|
218
223
|
- Spacing uses `x`/`r`/`bw`/`ow` units; math uses `(…)`, not `calc(…)`.
|
|
219
224
|
- `true` only on the properties that accept it; no `!important`.
|
package/docs/comparison.md
CHANGED
|
@@ -259,12 +259,12 @@ Tasty is more opinionated.
|
|
|
259
259
|
|
|
260
260
|
It behaves less like "TypeScript that outputs CSS" and more like a **state-aware style compiler**. It is designed to encode higher-level styling semantics rather than only expose CSS primitives in typed form.
|
|
261
261
|
|
|
262
|
-
This also makes Tasty's
|
|
262
|
+
This also makes Tasty's delivery model notable:
|
|
263
263
|
|
|
264
|
-
- `tasty()` components are hook-free and work as React Server Components. In server-only contexts
|
|
265
|
-
- `tastyStatic()` with the Babel plugin produces static class
|
|
264
|
+
- `tasty()` components are hook-free and work as React Server Components. In server-only contexts, they produce HTML + CSS with zero Tasty styling runtime in the browser while retaining the full React feature set. Astro without islands is the concrete integration; server-only Next.js RSC uses the same architecture.
|
|
265
|
+
- `tastyStatic()` with the Babel plugin produces static class-name objects via build-time extraction, with no React dependency — the output works with any JavaScript framework.
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
React component features like `styleProps`, sub-element components, and dynamic variants are available in the `tasty()` path whether it renders on the server or in the browser. The `tastyStatic()` path is framework-agnostic but limited to the DSL, tokens, and state logic.
|
|
268
268
|
|
|
269
269
|
So the tradeoff is roughly:
|
|
270
270
|
|
|
@@ -326,28 +326,28 @@ So while Stitches and Emotion are strong tools for building components, Tasty is
|
|
|
326
326
|
|
|
327
327
|
That makes it narrower in audience, but deeper in architectural ambition.
|
|
328
328
|
|
|
329
|
-
There is also a fundamental architectural difference: Emotion and styled-components rely on React context and hooks internally, which means they require `'use client'` in modern React and cannot run as React Server Components. Tasty's style functions and `tasty()` components are hook-free, so they work as server components by default and
|
|
329
|
+
There is also a fundamental architectural difference: Emotion and styled-components rely on React context and hooks internally, which means they require `'use client'` in modern React and cannot run as React Server Components. Tasty's style functions and `tasty()` components are hook-free, so they work as server components by default and ship no Tasty styling runtime in server-only contexts. This is not a minor compatibility detail — it means Tasty-based components stay as server components until _your_ code needs interactivity, while Emotion and styled-components force the client boundary at the styling layer.
|
|
330
330
|
|
|
331
331
|
For teams evaluating runtime styling at scale, Tasty also documents its runtime benchmarks and caching model in the main [README](../README.md#performance). That matters, but it is still secondary to the core question of whether you want Tasty's deterministic selector model.
|
|
332
332
|
|
|
333
333
|
---
|
|
334
334
|
|
|
335
|
-
##
|
|
335
|
+
## Where styles are computed
|
|
336
336
|
|
|
337
337
|
Tasty is not limited to one execution model.
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
Zero-runtime delivery is an outcome, not a synonym for `tastyStatic()`. `tasty()` computes styles during React rendering, but that rendering can happen only on the server. In that case it produces HTML + CSS and ships **zero Tasty styling runtime** to the browser. The full feature set — `styleProps`, sub-elements, variants, state maps — remains available. Astro's `tastyIntegration({ islands: false })` is the explicit setup for this path. Server-only Next.js RSC follows the same architecture; verify the generated output for the target deployment.
|
|
340
340
|
|
|
341
341
|
Client JavaScript only enters the picture when a component needs React interactivity (state, effects, event handlers) — and that is the consuming component's decision, never Tasty's. Tasty never forces the `'use client'` boundary.
|
|
342
342
|
|
|
343
|
-
`tastyStatic()` with the Babel plugin
|
|
343
|
+
`tastyStatic()` with the Babel plugin reaches zero-runtime delivery differently: CSS is extracted **during the build**, without React. The output is framework-agnostic — any JavaScript framework can consume the resulting class names and CSS. This makes Tasty usable as the compiler layer underneath a design-system implementation, even outside the React ecosystem.
|
|
344
344
|
|
|
345
345
|
The tradeoff is that some capabilities — `styleProps`, sub-element components (`<Card.Title>`), dynamic variants — are tied to the `tasty()` path. The `tastyStatic()` path is best understood as extraction and compilation of the DSL, tokens, and state logic without a React dependency.
|
|
346
346
|
|
|
347
|
-
This
|
|
347
|
+
This gives Tasty two zero-runtime paths:
|
|
348
348
|
|
|
349
|
-
- `tasty()`
|
|
350
|
-
- `tastyStatic()` as a
|
|
349
|
+
- server-only `tasty()` for the full React component API, with CSS generated during server or static rendering
|
|
350
|
+
- `tastyStatic()` as a build-time compiler whose output works with any framework, including non-React ones
|
|
351
351
|
|
|
352
352
|
---
|
|
353
353
|
|
|
@@ -443,6 +443,6 @@ Tasty is most compelling when the problem is not just "how do we write styles,"
|
|
|
443
443
|
- [React API](react-api.md) — `tasty()` factory, component props, variants, sub-elements, style functions
|
|
444
444
|
- [Style Properties](styles.md) — complete reference for all enhanced style properties
|
|
445
445
|
- [Configuration](configuration.md) — tokens, recipes, custom units, style handlers, and TypeScript extensions
|
|
446
|
-
- [
|
|
446
|
+
- [Build-Time Extraction (`tastyStatic`)](tasty-static.md) — static styling with the Babel plugin
|
|
447
447
|
- [Adoption Guide](adoption.md) — where Tasty sits in the stack, incremental adoption, and what changes for product engineers
|
|
448
448
|
- [Server-Side Rendering](ssr.md) — SSR setup for Next.js, Astro, and generic frameworks
|
package/docs/configuration.md
CHANGED
|
@@ -47,35 +47,35 @@ These docs use `data-schema="dark"` in examples. If your app already standardize
|
|
|
47
47
|
|
|
48
48
|
## Options
|
|
49
49
|
|
|
50
|
-
| Option | Type | Default
|
|
51
|
-
| -------------------- | ------------------------------------------------ |
|
|
52
|
-
| `nonce` | `string` | -
|
|
53
|
-
| `maxRulesPerSheet` | `number` | `8192`
|
|
54
|
-
| `forceTextInjection` | `boolean` | auto (`true` in test envs)
|
|
55
|
-
| `devMode` | `boolean` | auto
|
|
56
|
-
| `states` | `Record<string, string>` | -
|
|
57
|
-
| `parserCacheSize` | `number` | `1000`
|
|
58
|
-
| `units` | `Record<string, string \| UnitHandler>` | Built-in
|
|
59
|
-
| `functions` | `Record<string, FunctionDefinition \| Function>` | -
|
|
60
|
-
| `handlers` | `Record<string, StyleHandlerDefinition>` | Built-in
|
|
61
|
-
| `propHandlers` | `Record<string, PropHandlerDefinition>` | -
|
|
62
|
-
| `baseStyleProps` | `readonly string[]` | -
|
|
63
|
-
| `tokens` | `Record<string, value \| stateMap>` | -
|
|
64
|
-
| `replaceTokens` | `Record<string, string \| number \| boolean>` | -
|
|
65
|
-
| `keyframes` | `Record<string, KeyframesSteps>` | -
|
|
66
|
-
| `properties` | `Record<string, PropertyDefinition>` | -
|
|
67
|
-
| `fontFaces` | `Record<string, FontFaceInput>` | -
|
|
68
|
-
| `counterStyles` | `Record<string, CounterStyleDescriptors>` | -
|
|
69
|
-
| `polyfills` | `{ functions?: boolean }` | `{}`
|
|
70
|
-
| `autoPropertyTypes` | `boolean` | `true`
|
|
71
|
-
| `recipes` | `Record<string, RecipeStyles>` | -
|
|
72
|
-
| `presets` | `Record<string, TypographyPreset>` | -
|
|
73
|
-
| `globalStyles` | `Record<string, Styles>` | -
|
|
74
|
-
| `plugins` | `TastyPlugin[]` | -
|
|
75
|
-
| `gc` | `GCConfig` | -
|
|
76
|
-
| `batchInjection` | `boolean \| 'always'` | `false`
|
|
77
|
-
| `colorSpace` | `'rgb' \| 'hsl' \| 'oklch'` | -
|
|
78
|
-
| `namePrefix` | `string` | `'t'` (
|
|
50
|
+
| Option | Type | Default | Description |
|
|
51
|
+
| -------------------- | ------------------------------------------------ | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `nonce` | `string` | - | CSP nonce for style elements |
|
|
53
|
+
| `maxRulesPerSheet` | `number` | `8192` | Maximum rules per injected stylesheet |
|
|
54
|
+
| `forceTextInjection` | `boolean` | auto (`true` in test envs) | Force text-node CSS injection instead of constructable stylesheets |
|
|
55
|
+
| `devMode` | `boolean` | auto | Enable development-mode features: performance metrics and debug info |
|
|
56
|
+
| `states` | `Record<string, string>` | - | Global state aliases for advanced state mapping |
|
|
57
|
+
| `parserCacheSize` | `number` | `1000` | Parser LRU cache size |
|
|
58
|
+
| `units` | `Record<string, string \| UnitHandler>` | Built-in | Custom units (merged with built-in). See [built-in units](dsl.md#built-in-units) |
|
|
59
|
+
| `functions` | `Record<string, FunctionDefinition \| Function>` | - | Custom functions (merged). Bare keys → parse functions; `$$name` keys → declarative CSS `@function` definitions |
|
|
60
|
+
| `handlers` | `Record<string, StyleHandlerDefinition>` | Built-in | Custom style handlers (replace built-in). See [Custom Style Handlers](#custom-style-handlers) |
|
|
61
|
+
| `propHandlers` | `Record<string, PropHandlerDefinition>` | - | Props middleware for every component — props in, props out. See [Props Middleware](#props-middleware) |
|
|
62
|
+
| `baseStyleProps` | `readonly string[]` | - | Style names exposed as props on **every** component. See [Base Style Props](#base-style-props) |
|
|
63
|
+
| `tokens` | `Record<string, value \| stateMap>` | - | Design tokens injected as `:root` CSS custom properties |
|
|
64
|
+
| `replaceTokens` | `Record<string, string \| number \| boolean>` | - | Parse-time token substitution (inline replacement). `boolean` is allowed for `#` color tokens |
|
|
65
|
+
| `keyframes` | `Record<string, KeyframesSteps>` | - | Global keyframes for animations |
|
|
66
|
+
| `properties` | `Record<string, PropertyDefinition>` | - | Global CSS @property definitions |
|
|
67
|
+
| `fontFaces` | `Record<string, FontFaceInput>` | - | Global @font-face definitions |
|
|
68
|
+
| `counterStyles` | `Record<string, CounterStyleDescriptors>` | - | Global @counter-style definitions |
|
|
69
|
+
| `polyfills` | `{ functions?: boolean }` | `{}` | Opt-in polyfills for not-yet-baseline features. `functions: true` inlines `@function` calls into plain CSS at parse time |
|
|
70
|
+
| `autoPropertyTypes` | `boolean` | `true` | Auto-infer and register `@property` types from values |
|
|
71
|
+
| `recipes` | `Record<string, RecipeStyles>` | - | Predefined style recipes (named style bundles) |
|
|
72
|
+
| `presets` | `Record<string, TypographyPreset>` | - | Typography presets — shorthand for `generateTypographyTokens()` |
|
|
73
|
+
| `globalStyles` | `Record<string, Styles>` | - | Global Tasty styles keyed by CSS selector |
|
|
74
|
+
| `plugins` | `TastyPlugin[]` | - | Plugins that bundle any of the above (processed in order; later override earlier, and direct config wins over all). See [Plugins](plugins.md) |
|
|
75
|
+
| `gc` | `GCConfig` | - | Garbage-collection tuning for unused styles (`{ touchInterval, capacity }`) |
|
|
76
|
+
| `batchInjection` | `boolean \| 'always'` | `false` | Defer stylesheet writes and apply them in one batch. See [Batched injection](#batched-injection) |
|
|
77
|
+
| `colorSpace` | `'rgb' \| 'hsl' \| 'oklch'` | - | **Deprecated** — no longer has any effect. See [Color space](#color-space) |
|
|
78
|
+
| `namePrefix` | `string` | `'t'` (`tasty`) / `'ts'` (build-time) | Prefix prepended to every generated identifier (class, keyframe, counter-style names). Must match `^[a-zA-Z_][a-zA-Z0-9_-]{0,31}$`. See [Name prefix](#name-prefix). |
|
|
79
79
|
|
|
80
80
|
---
|
|
81
81
|
|
|
@@ -150,7 +150,7 @@ All writes share one FIFO queue — component rules, global rules, raw CSS,
|
|
|
150
150
|
Draining it in insertion order keeps the sheet byte-identical to unbatched
|
|
151
151
|
output, which matters because equal-specificity rules resolve by document order.
|
|
152
152
|
|
|
153
|
-
###
|
|
153
|
+
### Client rendering, server rendering, and build-time extraction
|
|
154
154
|
|
|
155
155
|
**Server render — nothing to batch, safe to leave enabled.** SSR and RSC collect
|
|
156
156
|
CSS as text through `ServerStyleCollector`; the runtime injector never runs
|
|
@@ -175,12 +175,12 @@ tasty components to be worth it. `'always'` needs no provider and covers every
|
|
|
175
175
|
island, at the cost of the measurement hazard above. Either way, an island that
|
|
176
176
|
only re-hydrates server-rendered classes has nothing to batch.
|
|
177
177
|
|
|
178
|
-
**
|
|
178
|
+
**Build-time extraction (`tastyStatic`) — unaffected.** The Babel plugin never
|
|
179
179
|
touches the injector: the babel plugin emits either a CSS file import or an
|
|
180
180
|
`injectCSS()` call from `@tenphi/tasty/static/inject`, which appends text to a
|
|
181
181
|
single `<style data-tasty-static>` element. `batchInjection` only defers CSSOM
|
|
182
|
-
writes made by the
|
|
183
|
-
that mixes both, it still applies to the
|
|
182
|
+
writes made by the browser injector, so extracted styles are unchanged. In an app
|
|
183
|
+
that mixes both, it still applies to the `tasty()` half.
|
|
184
184
|
|
|
185
185
|
### `flushStyles()`
|
|
186
186
|
|
|
@@ -284,7 +284,7 @@ color syntax works on every `<color>`, including a `color-mix()`, a
|
|
|
284
284
|
|
|
285
285
|
## Name Prefix
|
|
286
286
|
|
|
287
|
-
Every identifier Tasty generates — class names, keyframe names, counter-style names — starts with a configurable prefix. The
|
|
287
|
+
Every identifier Tasty generates — class names, keyframe names, counter-style names — starts with a configurable prefix. The `tasty()` client, SSR, and RSC paths default to `'t'`; the build-time extraction path (`tastyStatic` via the Babel plugin) defaults to `'ts'` so extracted classes can never collide with `tasty()` classes when both are loaded on the same page.
|
|
288
288
|
|
|
289
289
|
```jsx
|
|
290
290
|
configure({
|
|
@@ -294,12 +294,12 @@ configure({
|
|
|
294
294
|
|
|
295
295
|
The prefix is prepended verbatim to the hash, so include any separator inside the prefix string itself:
|
|
296
296
|
|
|
297
|
-
| Setting
|
|
298
|
-
|
|
|
299
|
-
| `'t'` (
|
|
300
|
-
| `'ts'` (
|
|
301
|
-
| `'mb'`
|
|
302
|
-
| `'myapp-'`
|
|
297
|
+
| Setting | Class | Keyframe | Counter-style |
|
|
298
|
+
| --------------------------- | ------------- | -------------- | -------------- |
|
|
299
|
+
| `'t'` (`tasty` default) | `t1a2b3` | `tk1a2b3` | `tc1a2b3` |
|
|
300
|
+
| `'ts'` (build-time default) | `ts1a2b3` | `tsk1a2b3` | `tsc1a2b3` |
|
|
301
|
+
| `'mb'` | `mb1a2b3` | `mbk1a2b3` | `mbc1a2b3` |
|
|
302
|
+
| `'myapp-'` | `myapp-1a2b3` | `myapp-k1a2b3` | `myapp-c1a2b3` |
|
|
303
303
|
|
|
304
304
|
The single-letter discriminators (`k` for keyframes, `c` for counter-styles) keep the three kinds visually distinct in devtools — they are not required for correctness because CSS keeps these in separate namespaces.
|
|
305
305
|
|
|
@@ -309,12 +309,12 @@ The single-letter discriminators (`k` for keyframes, `c` for counter-styles) kee
|
|
|
309
309
|
- Validated at `configure()` time; an invalid prefix throws synchronously rather than silently producing broken hydration.
|
|
310
310
|
- Locked once styles have been generated, like all other config.
|
|
311
311
|
|
|
312
|
-
### Coexistence with
|
|
312
|
+
### Coexistence with build-time extraction
|
|
313
313
|
|
|
314
|
-
The
|
|
314
|
+
The `tasty()` and `tastyStatic()` paths **must use different prefixes** when both are loaded on the same page. Defaults already guarantee this; if you customize one, customize the other accordingly:
|
|
315
315
|
|
|
316
316
|
```jsx
|
|
317
|
-
// app config (
|
|
317
|
+
// app config (client / SSR / RSC)
|
|
318
318
|
configure({ namePrefix: 'mb' });
|
|
319
319
|
|
|
320
320
|
// tasty-zero.config.ts (Babel plugin)
|
|
@@ -352,7 +352,7 @@ configure({
|
|
|
352
352
|
- `#name` keys become `--name-color` custom properties
|
|
353
353
|
- Names keep their case, since CSS custom properties are case-sensitive: `$myVar` is `--myVar` and is referenced as `$myVar`. A leading capital is not supported and folds — `$Foo` and `#Purple` become `--foo` and `--purple-color` — so start names lowercase. Kebab-case (`$my-var`) remains the convention.
|
|
354
354
|
|
|
355
|
-
Tokens are automatically emitted in all
|
|
355
|
+
Tokens are automatically emitted in all delivery modes: client rendering, server rendering, and build-time extraction with the Babel plugin.
|
|
356
356
|
|
|
357
357
|
---
|
|
358
358
|
|
|
@@ -617,7 +617,7 @@ configure({
|
|
|
617
617
|
|
|
618
618
|
Each key is a CSS selector, and each value is a Tasty `Styles` object supporting the full style syntax including style properties, tokens, state maps, and selector-based sub-styling (e.g. `$: '> .app'` for elements outside React scope). Global styles are injected alongside `:root` tokens when the first style is rendered.
|
|
619
619
|
|
|
620
|
-
Global styles are automatically emitted in all
|
|
620
|
+
Global styles are automatically emitted in all delivery modes: client rendering, server rendering, and build-time extraction with the Babel plugin. Plugins can also provide `globalStyles`; they are merged per selector with config global styles (config wins on conflict).
|
|
621
621
|
|
|
622
622
|
---
|
|
623
623
|
|
|
@@ -625,7 +625,7 @@ Global styles are automatically emitted in all rendering modes: runtime (client)
|
|
|
625
625
|
|
|
626
626
|
CSS cannot transition or animate custom properties unless their type is declared via [`@property`](https://developer.mozilla.org/en-US/docs/Web/CSS/@property). Tasty handles this automatically — when a custom property is assigned a concrete value (e.g. `'$scale': 1`, `'$gap': '10px'`, `'#accent': 'purple'`), the type is inferred and a `@property` rule is registered.
|
|
627
627
|
|
|
628
|
-
This works across all declaration contexts: component styles, `@keyframes`, global config, and the
|
|
628
|
+
This works across all declaration contexts: component styles, `@keyframes`, global config, and build-time extraction with the Babel plugin. It also resolves `var()` chains — if `$a` references `var(--b)`, the type propagates once `--b` is resolved.
|
|
629
629
|
|
|
630
630
|
Supported types:
|
|
631
631
|
|
|
@@ -784,7 +784,7 @@ Handlers run at the very top of every component's render, before any prop is des
|
|
|
784
784
|
|
|
785
785
|
Handlers must be **pure** and must not mutate their input, and should memoize the styles they build per input value: style values are cached by object identity, so mutating one in place yields stale CSS, and a reference-stable object avoids re-serializing on every render.
|
|
786
786
|
|
|
787
|
-
Injected styles occupy the `styles` slot, so they beat a component's own default styles and lose to a style prop at the call site. Prop handlers do not apply to sub-elements or to
|
|
787
|
+
Injected styles occupy the `styles` slot, so they beat a component's own default styles and lose to a style prop at the call site. Prop handlers do not apply to sub-elements or to build-time `tastyStatic()`, which has no props.
|
|
788
788
|
|
|
789
789
|
See [Plugins → Props middleware](plugins.md#props-middleware) for the full contract and a worked example.
|
|
790
790
|
|
package/docs/debug.md
CHANGED
|
@@ -6,9 +6,7 @@ Runtime CSS inspection and diagnostics for the Tasty styling system. Inspect inj
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
`tastyDebug` is a diagnostic object that exposes Tasty's runtime CSS state. It is designed for development use
|
|
10
|
-
|
|
11
|
-
In development mode (`isDevEnv()` returns `true`), `tastyDebug` is automatically installed on `window.tastyDebug`. In production, install it manually when needed.
|
|
9
|
+
`tastyDebug` is a diagnostic object that exposes Tasty's runtime CSS state. It is designed for development use and can be installed on `window` explicitly when needed.
|
|
12
10
|
|
|
13
11
|
All methods **log to the console by default**. Pass `{ raw: true }` to suppress logging and only return data.
|
|
14
12
|
|
|
@@ -19,7 +17,6 @@ All methods **log to the console by default**. Pass `{ raw: true }` to suppress
|
|
|
19
17
|
## Quick Start
|
|
20
18
|
|
|
21
19
|
```typescript
|
|
22
|
-
// Auto-installed in dev mode. Otherwise:
|
|
23
20
|
import { tastyDebug } from '@tenphi/tasty';
|
|
24
21
|
tastyDebug.install();
|
|
25
22
|
|
|
@@ -54,6 +51,19 @@ interface DebugOptions {
|
|
|
54
51
|
|
|
55
52
|
When `raw` is `false` (the default), results are logged to the console **and** returned. When `raw` is `true`, results are returned silently.
|
|
56
53
|
|
|
54
|
+
### Environments Without a DOM
|
|
55
|
+
|
|
56
|
+
`tastyDebug` reads the document, so on a server — SSR, a Node REPL, a test
|
|
57
|
+
runner in the `node` environment — there is nothing for it to read. Every
|
|
58
|
+
method returns its empty result (`''`, an empty `InspectResult`, a summary of
|
|
59
|
+
zeroes, `metrics: null`) instead of throwing, and explains itself once with a
|
|
60
|
+
console warning. `{ raw: true }` suppresses that warning along with the rest of
|
|
61
|
+
the logging.
|
|
62
|
+
|
|
63
|
+
To see the styles a server render produced, read the `ServerStyleCollector`
|
|
64
|
+
instead — `collector.getCSS()` and `collector.getRenderedClassNames()`. See
|
|
65
|
+
[SSR](./ssr.md).
|
|
66
|
+
|
|
57
67
|
---
|
|
58
68
|
|
|
59
69
|
## API Reference
|
|
@@ -68,7 +78,7 @@ Retrieves CSS text for a given target. Logs the result with rule count and size.
|
|
|
68
78
|
|---|---|
|
|
69
79
|
| `'all'` | All tasty CSS (component + global + raw) |
|
|
70
80
|
| `'active'` | CSS for classes currently in the DOM |
|
|
71
|
-
| `'unused'` | CSS
|
|
81
|
+
| `'unused'` | CSS for injected classes no element carries (cached but not rendered) |
|
|
72
82
|
| `'global'` | Only global CSS (from `injectGlobal`) |
|
|
73
83
|
| `'page'` | All CSS on the page (including non-tasty) |
|
|
74
84
|
| `'t3a5f'` | CSS for a specific tasty class (class names are `t` + base36 hash) |
|
|
@@ -241,7 +251,9 @@ tastyDebug.cache();
|
|
|
241
251
|
|
|
242
252
|
### `cleanup(opts?): void`
|
|
243
253
|
|
|
244
|
-
|
|
254
|
+
Removes every injected style that is neither carried by an element nor pinned by
|
|
255
|
+
an outstanding `inject()` handle — the same set `summary()` reports as unused.
|
|
256
|
+
Equivalent to `gc({ force: true })`.
|
|
245
257
|
|
|
246
258
|
```typescript
|
|
247
259
|
tastyDebug.cleanup();
|
|
@@ -262,7 +274,7 @@ tastyDebug.help();
|
|
|
262
274
|
|
|
263
275
|
### `install(): void`
|
|
264
276
|
|
|
265
|
-
Attaches `tastyDebug` to `window.tastyDebug`.
|
|
277
|
+
Attaches `tastyDebug` to `window.tastyDebug`.
|
|
266
278
|
|
|
267
279
|
```typescript
|
|
268
280
|
import { tastyDebug } from '@tenphi/tasty';
|
package/docs/dsl.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
This is the language behind Tasty’s predictable state resolution. Every property can use a state map; later branches declare higher priority, and Tasty compiles them so only one generated selector can match.
|
|
4
4
|
|
|
5
|
-
The same value syntax, state maps, tokens, units, extension semantics, and special declarations apply to
|
|
5
|
+
The same value syntax, state maps, tokens, units, extension semantics, and special declarations apply to React `tasty()`—whether rendered on the client or server—and build-time `tastyStatic()`.
|
|
6
6
|
|
|
7
|
-
For the
|
|
7
|
+
For the React API (`tasty()`, style functions, 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).
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -1018,4 +1018,4 @@ For a complete reference of all enhanced style properties — syntax, values, mo
|
|
|
1018
1018
|
- **[Methodology](methodology.md)** — Recommended patterns: root + sub-elements, styleProps, tokens, wrapping
|
|
1019
1019
|
- **[Configuration](configuration.md)** — Tokens, recipes, custom units, style handlers, TypeScript extensions
|
|
1020
1020
|
- **[Style Properties](styles.md)** — Complete reference for all enhanced style properties
|
|
1021
|
-
- **[
|
|
1021
|
+
- **[Build-Time Extraction (`tastyStatic`)](tasty-static.md)** — Static styling with the Babel plugin
|