@tenphi/tasty 3.0.2 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/{babel-R2qT7yLN.d.ts → babel-D8dm92E_.d.ts} +2 -2
- package/dist/{collector-D8o4Wdq-.d.ts → collector-BFuqdF2F.d.ts} +2 -2
- package/dist/{collector-BpkjNQDo.js → collector-Di3C8btw.js} +3 -3
- package/dist/{collector-BpkjNQDo.js.map → collector-Di3C8btw.js.map} +1 -1
- package/dist/{config-DOCuTykY.js → config-BrDt11hO.js} +861 -290
- package/dist/config-BrDt11hO.js.map +1 -0
- package/dist/{config-De8L9NWM.d.ts → config-DH7I0Ggx.d.ts} +73 -2
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +6 -6
- package/dist/{core-p6iTbQnn.js → core-YWn1zgh4.js} +9 -10
- package/dist/core-YWn1zgh4.js.map +1 -0
- package/dist/{css-writer-BHjTF0YN.js → css-writer-CQYbT4g_.js} +3 -3
- package/dist/{css-writer-BHjTF0YN.js.map → css-writer-CQYbT4g_.js.map} +1 -1
- package/dist/{format-rules-Cb0YIjyS.js → format-rules-DdmLdntR.js} +11 -9
- package/dist/format-rules-DdmLdntR.js.map +1 -0
- package/dist/{hydrate-xnaB3SDm.js → hydrate-D2ivfS-B.js} +2 -2
- package/dist/{hydrate-xnaB3SDm.js.map → hydrate-D2ivfS-B.js.map} +1 -1
- package/dist/{index-DzGxoeyN.d.ts → index-DljBkZhV.d.ts} +59 -6
- package/dist/{index-KUYya3x7.d.ts → index-LC3O3Jj4.d.ts} +102 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +62 -8
- package/dist/index.js.map +1 -1
- package/dist/{keyframes-DiXjNoBZ.js → keyframes-CoLLjBcd.js} +2 -2
- package/dist/{keyframes-DiXjNoBZ.js.map → keyframes-CoLLjBcd.js.map} +1 -1
- package/dist/{merge-styles-DLm4wdnb.d.ts → merge-styles-Cx_6ySBv.d.ts} +2 -2
- package/dist/{merge-styles-B0lMso5W.js → merge-styles-bdh7-1uh.js} +2 -2
- package/dist/{merge-styles-B0lMso5W.js.map → merge-styles-bdh7-1uh.js.map} +1 -1
- package/dist/{resolve-recipes-C9nAuwgR.js → resolve-recipes-9JYSgubn.js} +3 -3
- package/dist/{resolve-recipes-C9nAuwgR.js.map → resolve-recipes-9JYSgubn.js.map} +1 -1
- package/dist/ssr/astro-client.js +1 -1
- package/dist/ssr/astro.js +3 -3
- package/dist/ssr/index.d.ts +1 -1
- package/dist/ssr/index.js +3 -3
- package/dist/ssr/next.d.ts +1 -1
- package/dist/ssr/next.js +4 -4
- package/dist/static/index.d.ts +2 -2
- package/dist/static/index.js +1 -1
- package/dist/zero/babel.d.ts +1 -1
- package/dist/zero/babel.js +4 -4
- 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/configuration.md +137 -6
- package/docs/dsl.md +99 -2
- package/docs/injector.md +11 -0
- package/docs/styles.md +3 -1
- package/package.json +6 -6
- package/dist/config-DOCuTykY.js.map +0 -1
- package/dist/core-p6iTbQnn.js.map +0 -1
- package/dist/format-rules-Cb0YIjyS.js.map +0 -1
package/docs/dsl.md
CHANGED
|
@@ -111,7 +111,7 @@ const List = tasty({
|
|
|
111
111
|
Named color prefixed with `#` that maps to CSS custom properties. Supports opacity with `.N` suffix:
|
|
112
112
|
|
|
113
113
|
```jsx
|
|
114
|
-
fill: '#purple.5' // → var(--purple-color)
|
|
114
|
+
fill: '#purple.5' // → oklch(from var(--purple-color) l c h / .5)
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
### Modifier
|
|
@@ -133,11 +133,108 @@ Modifiers can also be exposed as top-level component props via `modProps` — se
|
|
|
133
133
|
color: '#purple', // Full opacity
|
|
134
134
|
color: '#purple.5', // 50% opacity
|
|
135
135
|
color: '#purple.05', // 5% opacity
|
|
136
|
+
color: '#purple.$fade', // Opacity from a custom property
|
|
136
137
|
fill: '#current', // → currentcolor
|
|
137
|
-
fill: '#current.5', // → color-mix(in oklab, currentcolor 50%, transparent)
|
|
138
138
|
color: '(#primary, #secondary)', // Fallback syntax
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
+
The suffix sets the alpha on the token's color with CSS relative color syntax:
|
|
142
|
+
|
|
143
|
+
```jsx
|
|
144
|
+
fill: '#purple.5';
|
|
145
|
+
// → oklch(from var(--purple-color) l c h / .5)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The channels are copied over and the alpha slot is written, which asks nothing of
|
|
149
|
+
the color beyond *being* a color. That means the suffix works on every one of
|
|
150
|
+
these:
|
|
151
|
+
|
|
152
|
+
- a token holding a `color-mix()`, a `light-dark()`, or a `color()` in a space
|
|
153
|
+
Tasty cannot convert — none of which have channels to decompose
|
|
154
|
+
- `#current`, which resolves to `currentcolor`
|
|
155
|
+
- a `--name-color` variable declared in your own CSS, with no Tasty token
|
|
156
|
+
definition and no companion variable behind it
|
|
157
|
+
|
|
158
|
+
Two properties follow from writing the alpha slot rather than compositing:
|
|
159
|
+
|
|
160
|
+
- **Alpha is replaced, not multiplied.** A token holding `rgb(255 0 0 / .8)`
|
|
161
|
+
faded to `.5` is alpha `.5`, not `.4`.
|
|
162
|
+
- **The alpha may be a number or a percentage.** `#purple.$fade` emits
|
|
163
|
+
`/ var(--fade)` unchanged, so it works whether `$fade` holds `.5` or `50%` —
|
|
164
|
+
which is what `--*-opacity` properties are registered to accept.
|
|
165
|
+
|
|
166
|
+
### `#current` composes instead
|
|
167
|
+
|
|
168
|
+
`#current` is the one exception, and the difference is deliberate. A token *names*
|
|
169
|
+
a color, so fading it sets its alpha. `currentcolor` is the color an element
|
|
170
|
+
**inherits**, which an ancestor may already have faded — `#current.4` means "40%
|
|
171
|
+
of what reaches me":
|
|
172
|
+
|
|
173
|
+
```jsx
|
|
174
|
+
fill: '#current.4';
|
|
175
|
+
// → color-mix(in oklab, currentcolor 40%, transparent)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
So a `#current` fade nested inside another one composes: a label at `#current.4`
|
|
179
|
+
with a fill of `#current.18` under it lands at `.072`. Color ramps built on
|
|
180
|
+
`#current` depend on that — replacing would double the opacity of every nested
|
|
181
|
+
step. Because a `color-mix()` percentage cannot be a `<number>`, an opacity
|
|
182
|
+
custom property used as `#current.$fade` must hold a unitless number; a token
|
|
183
|
+
accepts either form.
|
|
184
|
+
|
|
185
|
+
The space is always `oklch`, whatever [`colorSpace`](configuration.md#color-space)
|
|
186
|
+
is set to: it is unbounded, so a wide-gamut color survives a round trip that a
|
|
187
|
+
gamut-limited space would clamp.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## CSS Color Functions
|
|
192
|
+
|
|
193
|
+
Every CSS color function is recognized as a color, so it lands in the color slot
|
|
194
|
+
of whichever style property you use it in — and tokens inside it are expanded:
|
|
195
|
+
|
|
196
|
+
```jsx
|
|
197
|
+
fill: 'color-mix(in oklab, #primary 50%, #surface)',
|
|
198
|
+
color: 'light-dark(#dark, #light)',
|
|
199
|
+
color: 'contrast-color(#primary)',
|
|
200
|
+
fill: 'color(display-p3 1 .5 0)',
|
|
201
|
+
border: '1bw solid oklch(from #primary l c h / 50%)', // relative color syntax
|
|
202
|
+
shadow: '0 0 1x color-mix(in oklab, #dark 20%, transparent)',
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`light-dark()` is the one exception to "always a color": CSS lets it pick between
|
|
206
|
+
values of any type, so it is treated as a color only when its arguments are
|
|
207
|
+
colors. `padding: 'light-dark(1x, 2x)'` still reaches the padding slot.
|
|
208
|
+
|
|
209
|
+
A color token defined as one of these functions takes the
|
|
210
|
+
[opacity suffix](#color-tokens--opacity) like any other:
|
|
211
|
+
|
|
212
|
+
```jsx
|
|
213
|
+
const Card = tasty({
|
|
214
|
+
styles: {
|
|
215
|
+
'#brand': 'color-mix(in oklab, #primary 50%, #surface)',
|
|
216
|
+
fill: '#brand.5',
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
A [replace token](configuration.md#replace-tokens-parse-time-substitution) is
|
|
222
|
+
substituted while parsing, so its color is right there to fade in place. A
|
|
223
|
+
channel function takes the alpha after a slash; a derived function has no alpha
|
|
224
|
+
channel, so it gets wrapped:
|
|
225
|
+
|
|
226
|
+
```jsx
|
|
227
|
+
configure({
|
|
228
|
+
replaceTokens: {
|
|
229
|
+
'#solid': 'hsl(220 90% 50%)',
|
|
230
|
+
'#adaptive': 'light-dark(#dark, #light)',
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
fill: '#solid.5'; // → hsl(220 90% 50% / .5)
|
|
235
|
+
fill: '#adaptive.5'; // → oklch(from light-dark(…) l c h / .5)
|
|
236
|
+
```
|
|
237
|
+
|
|
141
238
|
---
|
|
142
239
|
|
|
143
240
|
## Built-in Units
|
package/docs/injector.md
CHANGED
|
@@ -300,6 +300,17 @@ const styleRule: StyleResult = {
|
|
|
300
300
|
};
|
|
301
301
|
```
|
|
302
302
|
|
|
303
|
+
### Batched Injection
|
|
304
|
+
|
|
305
|
+
`configure({ batchInjection: true })` queues every sheet write — component
|
|
306
|
+
rules, global rules, raw CSS and at-rules — into one FIFO and applies them
|
|
307
|
+
together, so the document is style-invalidated once per flush instead of once per
|
|
308
|
+
component. `<TastyBatchProvider>` flushes in `useInsertionEffect`, before any
|
|
309
|
+
layout effect, so a queued write can never be observed by a measurement. See
|
|
310
|
+
[Batched injection](configuration.md#batched-injection) for the modes and the
|
|
311
|
+
ordering guarantee. `flushStyles()` applies pending writes on demand; every read
|
|
312
|
+
API here calls it for you.
|
|
313
|
+
|
|
303
314
|
### Deduplication & Performance
|
|
304
315
|
|
|
305
316
|
```typescript
|
package/docs/styles.md
CHANGED
|
@@ -254,6 +254,7 @@ Background color with design token support. Preferred over `backgroundColor` and
|
|
|
254
254
|
| `"#purple.10"` | Token color at 10% opacity |
|
|
255
255
|
| `"#surface #primary.10"` | Background `#surface` with `#primary.10` overlay (two colors enable smooth transitions between both) |
|
|
256
256
|
| `"rgb(255 128 0)"` | CSS color value |
|
|
257
|
+
| `"color-mix(in oklab, #primary 50%, #surface)"` | CSS color function — see [CSS Color Functions](dsl.md#css-color-functions) |
|
|
257
258
|
| `true` | Default fill color |
|
|
258
259
|
|
|
259
260
|
When two colors are provided, the first sets the background color and the second is applied as an overlay gradient layer. This enables independent CSS transitions on each color. The overlay is only applied when no explicit `image` or `backgroundImage` is set.
|
|
@@ -286,9 +287,10 @@ Text color with design token support.
|
|
|
286
287
|
| `"#current"` | Current inherited color |
|
|
287
288
|
| `"#current.5"` | Current inherited color at 50% opacity |
|
|
288
289
|
| `"(#primary, #secondary)"` | Fallback: use `#primary`, fall back to `#secondary` |
|
|
290
|
+
| `"light-dark(#dark, #light)"` | CSS color function — see [CSS Color Functions](dsl.md#css-color-functions) |
|
|
289
291
|
| `true` | `currentColor` |
|
|
290
292
|
|
|
291
|
-
When set to a named color token, also sets `$current-color` and `$current-color-{colorSpace}` custom properties for downstream use (suffix depends on the configured `colorSpace`, default `oklch`).
|
|
293
|
+
When set to a named color token, also sets `$current-color` and `$current-color-{colorSpace}` custom properties for downstream use (suffix depends on the configured `colorSpace`, default `oklch`). An opacity suffix does not move the companion: `color="#purple.5"` still reports `#purple`'s channels, since components carry no alpha.
|
|
292
294
|
|
|
293
295
|
### `svgFill`
|
|
294
296
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenphi/tasty",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "A design-system-integrated styling system and DSL for concise, state-aware UI styling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -178,19 +178,19 @@
|
|
|
178
178
|
"name": "main (import *)",
|
|
179
179
|
"path": "dist/index.js",
|
|
180
180
|
"import": "*",
|
|
181
|
-
"limit": "
|
|
181
|
+
"limit": "59 kB"
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
"name": "core (import *)",
|
|
185
185
|
"path": "dist/core/index.js",
|
|
186
186
|
"import": "*",
|
|
187
|
-
"limit": "
|
|
187
|
+
"limit": "55.75 kB"
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
190
|
"name": "static",
|
|
191
191
|
"path": "dist/static/index.js",
|
|
192
192
|
"import": "*",
|
|
193
|
-
"limit": "
|
|
193
|
+
"limit": "19.25 kB"
|
|
194
194
|
},
|
|
195
195
|
{
|
|
196
196
|
"name": "zero",
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
"path",
|
|
202
202
|
"crypto"
|
|
203
203
|
],
|
|
204
|
-
"limit": "33.
|
|
204
|
+
"limit": "33.75 kB"
|
|
205
205
|
},
|
|
206
206
|
{
|
|
207
207
|
"name": "babel-plugin",
|
|
@@ -212,7 +212,7 @@
|
|
|
212
212
|
"path",
|
|
213
213
|
"crypto"
|
|
214
214
|
],
|
|
215
|
-
"limit": "
|
|
215
|
+
"limit": "52 kB"
|
|
216
216
|
}
|
|
217
217
|
],
|
|
218
218
|
"scripts": {
|