@tenphi/tasty 0.14.1 → 0.15.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 +73 -214
- package/dist/core/index.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/pipeline/index.js +21 -10
- package/dist/pipeline/index.js.map +1 -1
- package/dist/tasty.d.ts +24 -891
- package/dist/tasty.js +20 -7
- package/dist/tasty.js.map +1 -1
- package/docs/README.md +1 -1
- package/docs/adoption.md +1 -1
- package/docs/comparison.md +1 -1
- package/docs/design-system.md +8 -2
- package/docs/dsl.md +42 -0
- package/docs/methodology.md +68 -4
- package/docs/runtime.md +81 -25
- package/docs/styles.md +19 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,20 +17,31 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
Tasty is a styling engine for design systems that generates deterministic CSS for stateful components.
|
|
20
|
+
Tasty is a styling engine for design systems that generates deterministic CSS for stateful components.
|
|
21
21
|
|
|
22
|
-
It
|
|
22
|
+
It compiles state maps into **mutually exclusive selectors**, so for a given property and component state, one branch wins by construction instead of competing through cascade and specificity.
|
|
23
|
+
|
|
24
|
+
That is the core guarantee: component styling resolves from declared state logic, not from source-order accidents or specificity fights.
|
|
25
|
+
|
|
26
|
+
Tasty fits best when you are building a design system or component library with intersecting states, variants, tokens, sub-elements, responsive rules, and extension semantics that need to stay predictable over time.
|
|
27
|
+
|
|
28
|
+
On top of that foundation, Tasty gives teams a governed styling model: a CSS-like DSL, tokens, recipes, typed style props, sub-elements, and multiple rendering modes.
|
|
29
|
+
|
|
30
|
+
- **New here?** Start with [Comparison](docs/comparison.md) if you are evaluating fit.
|
|
31
|
+
- **Adopting Tasty?** Read the [Adoption Guide](docs/adoption.md).
|
|
32
|
+
- **Want the mechanism first?** Jump to [How It Actually Works](#how-it-actually-works).
|
|
33
|
+
- **Ready to build?** Go to [Getting Started](docs/getting-started.md).
|
|
23
34
|
|
|
24
35
|
## Why Tasty
|
|
25
36
|
|
|
26
|
-
- **Deterministic composition, not cascade fights** —
|
|
27
|
-
- **Built for design-system teams** — Best fit for
|
|
28
|
-
- **A governed styling model, not just syntax sugar** —
|
|
29
|
-
- **DSL that still feels like CSS** —
|
|
37
|
+
- **Deterministic composition, not cascade fights** — Stateful styles resolve from the state map you declared, not from selector competition. See [How It Actually Works](#how-it-actually-works).
|
|
38
|
+
- **Built for design-system teams** — Best fit for reusable component systems with complex state interactions.
|
|
39
|
+
- **A governed styling model, not just syntax sugar** — Design-system authors define the styling language product teams consume.
|
|
40
|
+
- **DSL that still feels like CSS** — Familiar property names, less selector boilerplate. Start with the [Style DSL](docs/dsl.md), then use [Style Properties](docs/styles.md) as the handler reference.
|
|
30
41
|
|
|
31
42
|
### Supporting capabilities
|
|
32
43
|
|
|
33
|
-
- **Typed style props** — `styleProps`
|
|
44
|
+
- **Typed style props and mod props** — `styleProps` exposes selected CSS properties as typed React props (`<Space flow="row" gap="2x">`); `modProps` does the same for modifier keys (`<Button isLoading size="large">`). Both support state maps and full TypeScript autocomplete. See [Style Props](#style-props) and [Mod Props](#mod-props).
|
|
34
45
|
- **Runtime, SSR, and zero-runtime options** — Use `tasty()` for runtime React components, add SSR integrations when your framework renders that runtime on the server, or use `tastyStatic()` when you specifically want build-time extraction instead of runtime styling.
|
|
35
46
|
- **Broad modern CSS coverage** — Media queries, container queries, `@supports`, `:has()`, `@starting-style`, `@property`, `@keyframes`, and more. Features that do not fit the component model (such as `@layer` and `!important`) are intentionally left out.
|
|
36
47
|
- **Performance and caching** — Runtime mode injects CSS on demand, reuses chunks aggressively, and relies on multi-level caching so large component systems stay practical.
|
|
@@ -40,7 +51,7 @@ It fits best when a team is defining a house styling language for reusable compo
|
|
|
40
51
|
|
|
41
52
|
Modern component styling becomes fragile when multiple selectors can still win for the same property. Hover, disabled, theme, breakpoint, parent state, and root state rules start competing through specificity and source order.
|
|
42
53
|
|
|
43
|
-
Tasty replaces that competition with explicit state-map resolution. Each property compiles into mutually exclusive branches, so
|
|
54
|
+
Tasty replaces that competition with explicit state-map resolution. Each property compiles into mutually exclusive branches, so component styling stays deterministic as systems grow. For the full mechanism, jump to [How It Actually Works](#how-it-actually-works).
|
|
44
55
|
|
|
45
56
|
## Installation
|
|
46
57
|
|
|
@@ -63,6 +74,8 @@ yarn add @tenphi/tasty
|
|
|
63
74
|
|
|
64
75
|
## Start Here
|
|
65
76
|
|
|
77
|
+
For the fuller docs map beyond the quick routes above, start here:
|
|
78
|
+
|
|
66
79
|
- **[Comparison](docs/comparison.md)** — read this first if you are evaluating whether Tasty fits your team's styling model
|
|
67
80
|
- **[Adoption Guide](docs/adoption.md)** — understand who Tasty is for, where it fits, and how to introduce it incrementally
|
|
68
81
|
- **[Getting Started](docs/getting-started.md)** — the canonical onboarding path: install, first component, optional shared `configure()`, ESLint, editor tooling, and rendering mode selection
|
|
@@ -95,7 +108,9 @@ const Card = tasty({
|
|
|
95
108
|
<Card>Hello World</Card>
|
|
96
109
|
```
|
|
97
110
|
|
|
98
|
-
Every value maps to CSS you'd recognize. This example is intentionally
|
|
111
|
+
Every value maps to CSS you'd recognize. This example is intentionally a simple first contact, not a tour of the whole DSL.
|
|
112
|
+
|
|
113
|
+
When you want a more design-system-shaped authoring model, Tasty also supports built-in units, tokens, recipes, state aliases, and color values such as `okhsl(...)` without extra runtime libraries.
|
|
99
114
|
|
|
100
115
|
Use `configure()` when you want to define shared tokens, state aliases, recipes, or other conventions for your app or design system. For a fuller onboarding path, follow [Getting Started](docs/getting-started.md).
|
|
101
116
|
|
|
@@ -163,58 +178,17 @@ configure({
|
|
|
163
178
|
|
|
164
179
|
Use `configure()` once when your app or design system needs shared aliases, tokens, recipes, or parser extensions. Predefined states turn complex selector logic into single tokens, so teams can write `@mobile` instead of repeating media query expressions in every component.
|
|
165
180
|
|
|
166
|
-
###
|
|
181
|
+
### Props as the public API
|
|
167
182
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
With `styleProps`, a component can expose the styles you choose as normal typed props. You can adjust layout, spacing, alignment, or positioning where the component is used while staying inside a typed, design-system-aware API.
|
|
171
|
-
|
|
172
|
-
```tsx
|
|
173
|
-
import { tasty, FLOW_STYLES, POSITION_STYLES } from '@tenphi/tasty';
|
|
174
|
-
|
|
175
|
-
const Space = tasty({
|
|
176
|
-
styles: {
|
|
177
|
-
display: 'flex',
|
|
178
|
-
flow: 'column',
|
|
179
|
-
gap: '1x',
|
|
180
|
-
},
|
|
181
|
-
styleProps: FLOW_STYLES,
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
const Button = tasty({
|
|
185
|
-
as: 'button',
|
|
186
|
-
styles: {
|
|
187
|
-
padding: '1.5x 3x',
|
|
188
|
-
fill: '#primary',
|
|
189
|
-
color: '#primary-text',
|
|
190
|
-
radius: true,
|
|
191
|
-
},
|
|
192
|
-
styleProps: POSITION_STYLES,
|
|
193
|
-
});
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Now you can compose layout and tweak component positioning directly in JSX:
|
|
183
|
+
`styleProps` exposes selected CSS properties as typed React props, and `modProps` does the same for modifier keys. Together they let design systems define a governed, typed component API without wrapper elements or `styles` overrides:
|
|
197
184
|
|
|
198
185
|
```tsx
|
|
199
186
|
<Space flow="row" gap="2x" placeItems="center">
|
|
200
|
-
<
|
|
201
|
-
<Button placeSelf="end">Add Item</Button>
|
|
202
|
-
</Space>
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
The same props also support state maps, so responsive values use the exact same API:
|
|
206
|
-
|
|
207
|
-
```tsx
|
|
208
|
-
<Space
|
|
209
|
-
flow={{ '': 'column', '@tablet': 'row' }}
|
|
210
|
-
gap={{ '': '2x', '@tablet': '4x' }}
|
|
211
|
-
>
|
|
212
|
-
<Sidebar />
|
|
213
|
-
<Content />
|
|
187
|
+
<Button isLoading size="large" placeSelf="end">Submit</Button>
|
|
214
188
|
</Space>
|
|
215
189
|
```
|
|
216
190
|
|
|
217
|
-
|
|
191
|
+
See [Style Props](#style-props) and [Mod Props](#mod-props) below, or the full reference in [Runtime API](docs/runtime.md#style-props).
|
|
218
192
|
|
|
219
193
|
## Choose a Styling Approach
|
|
220
194
|
|
|
@@ -385,214 +359,99 @@ fill: {
|
|
|
385
359
|
|
|
386
360
|
### Sub-Element Styling
|
|
387
361
|
|
|
388
|
-
|
|
362
|
+
Compound components can style inner parts from the parent definition with capitalized keys in `styles` and optional `elements` declarations, producing typed sub-components like `<Card.Title />` instead of separate wrapper components or ad hoc class naming.
|
|
389
363
|
|
|
390
|
-
|
|
391
|
-
const Card = tasty({
|
|
392
|
-
styles: {
|
|
393
|
-
padding: '4x',
|
|
394
|
-
Title: { preset: 'h3', color: '#primary' },
|
|
395
|
-
Content: { color: '#text', preset: 't2' },
|
|
396
|
-
},
|
|
397
|
-
elements: { Title: 'h2', Content: 'div' },
|
|
398
|
-
});
|
|
364
|
+
Sub-elements share the root state context by default, so keys like `:hover`, modifiers, root states, and media queries resolve as one coordinated styling block. Use `@own(...)` when a sub-element should react to its own state, and use the `$` selector affix when you need precise descendant targeting.
|
|
399
365
|
|
|
400
|
-
|
|
401
|
-
<Card.Title>Heading</Card.Title>
|
|
402
|
-
<Card.Content>Body text</Card.Content>
|
|
403
|
-
</Card>
|
|
404
|
-
```
|
|
366
|
+
See [Runtime API - Sub-element Styling](docs/runtime.md#sub-element-styling), [Style DSL - Advanced States](docs/dsl.md#advanced-states--prefix), and [Methodology](docs/methodology.md#component-architecture-root--sub-elements).
|
|
405
367
|
|
|
406
|
-
|
|
368
|
+
### Style Props
|
|
407
369
|
|
|
408
|
-
|
|
370
|
+
`styleProps` exposes selected CSS properties as typed React props. Components control which properties to open up; consumers get layout and composition knobs without `styles` overrides. Supports state maps for responsive values.
|
|
409
371
|
|
|
410
|
-
|
|
372
|
+
```tsx
|
|
373
|
+
const Space = tasty({
|
|
374
|
+
styles: { display: 'flex', flow: 'column', gap: '1x' },
|
|
375
|
+
styleProps: FLOW_STYLES,
|
|
376
|
+
});
|
|
411
377
|
|
|
412
|
-
|
|
378
|
+
<Space flow="row" gap={{ '': '2x', '@tablet': '4x' }}>
|
|
379
|
+
```
|
|
413
380
|
|
|
414
|
-
|
|
381
|
+
See [Runtime API - Style Props](docs/runtime.md#style-props) and [Methodology - styleProps](docs/methodology.md#styleprops-as-the-public-api).
|
|
415
382
|
|
|
416
|
-
###
|
|
383
|
+
### Mod Props
|
|
417
384
|
|
|
418
|
-
|
|
385
|
+
`modProps` exposes modifier keys as typed React props — the modifier equivalent of `styleProps`. Accepts an array of key names or an object with type descriptors (`Boolean`, `String`, `Number`, or enum arrays) for full TypeScript autocomplete.
|
|
419
386
|
|
|
420
387
|
```tsx
|
|
421
388
|
const Button = tasty({
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
389
|
+
as: 'button',
|
|
390
|
+
modProps: { isLoading: Boolean, size: ['sm', 'md', 'lg'] as const },
|
|
391
|
+
styles: {
|
|
392
|
+
fill: { '': '#primary', isLoading: '#primary.5' },
|
|
393
|
+
padding: { '': '2x 4x', 'size=sm': '1x 2x' },
|
|
427
394
|
},
|
|
428
395
|
});
|
|
429
396
|
|
|
430
|
-
<Button
|
|
397
|
+
<Button isLoading size="lg">Submit</Button>
|
|
431
398
|
```
|
|
432
399
|
|
|
433
|
-
|
|
400
|
+
See [Runtime API - Mod Props](docs/runtime.md#mod-props) and [Methodology - modProps](docs/methodology.md#modprops-and-mods).
|
|
434
401
|
|
|
435
|
-
|
|
402
|
+
### Variants
|
|
436
403
|
|
|
437
|
-
|
|
438
|
-
configure({
|
|
439
|
-
recipes: {
|
|
440
|
-
card: { padding: '4x', fill: '#surface', radius: '1r', border: true },
|
|
441
|
-
elevated: { shadow: '0 2x 4x #shadow' },
|
|
442
|
-
},
|
|
443
|
-
});
|
|
404
|
+
Variants let one component expose named visual versions without pre-generating a separate class for every possible combination. In runtime mode, Tasty emits only the variant CSS that is actually used.
|
|
444
405
|
|
|
445
|
-
|
|
446
|
-
styles: {
|
|
447
|
-
recipe: 'card elevated',
|
|
448
|
-
color: '#text',
|
|
449
|
-
},
|
|
450
|
-
});
|
|
451
|
-
```
|
|
406
|
+
See [Runtime API - Variants](docs/runtime.md#variants).
|
|
452
407
|
|
|
453
|
-
|
|
408
|
+
### Recipes
|
|
454
409
|
|
|
455
|
-
|
|
410
|
+
Recipes are reusable style bundles defined in `configure({ recipes })` and applied with the `recipe` style property. They are useful when your design system wants shared state logic or visual presets without forcing every component to repeat the same style map.
|
|
456
411
|
|
|
457
|
-
|
|
412
|
+
Use `/` to post-apply recipes after local styles when recipe states should win the final merge order, and use `none` to skip base recipes entirely.
|
|
458
413
|
|
|
459
|
-
|
|
414
|
+
See [Style DSL - Recipes](docs/dsl.md#recipes) and [Configuration - recipes](docs/configuration.md#recipes).
|
|
460
415
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
animation: 'pulse 2s infinite',
|
|
465
|
-
transform: 'scale($pulse-scale)',
|
|
466
|
-
'@keyframes': {
|
|
467
|
-
pulse: {
|
|
468
|
-
'0%, 100%': { '$pulse-scale': 1 },
|
|
469
|
-
'50%': { '$pulse-scale': 1.05 },
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
},
|
|
473
|
-
});
|
|
474
|
-
```
|
|
416
|
+
### Auto-Inferred `@property`
|
|
417
|
+
|
|
418
|
+
Tasty usually removes the need to hand-author CSS [`@property`](https://developer.mozilla.org/en-US/docs/Web/CSS/@property) rules. When a custom property receives a concrete value, Tasty infers its syntax and registers the matching `@property` automatically, which makes transitions and animations on custom properties work without extra boilerplate.
|
|
475
419
|
|
|
476
|
-
|
|
420
|
+
If you prefer explicit control, disable inference with `configure({ autoPropertyTypes: false })` or declare the properties yourself.
|
|
477
421
|
|
|
478
|
-
|
|
422
|
+
See [Style DSL - Properties (`@property`)](docs/dsl.md#properties-property).
|
|
479
423
|
|
|
480
424
|
### Explicit `@properties`
|
|
481
425
|
|
|
482
|
-
|
|
426
|
+
Use explicit `@properties` only when you need to override defaults such as `inherits: false` or a custom `initialValue`.
|
|
483
427
|
|
|
484
|
-
|
|
485
|
-
'@properties': {
|
|
486
|
-
'$pulse-scale': { syntax: '<number>', inherits: false, initialValue: 1 },
|
|
487
|
-
},
|
|
488
|
-
```
|
|
428
|
+
See [Style DSL - Properties (`@property`)](docs/dsl.md#properties-property).
|
|
489
429
|
|
|
490
430
|
### React Hooks
|
|
491
431
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
```tsx
|
|
495
|
-
import { useStyles, useGlobalStyles, useRawCSS } from '@tenphi/tasty';
|
|
496
|
-
|
|
497
|
-
function App() {
|
|
498
|
-
const { className } = useStyles({ padding: '2x', fill: '#surface' });
|
|
499
|
-
useGlobalStyles('body', { margin: '0' });
|
|
500
|
-
useRawCSS('@font-face { font-family: "Custom"; src: url(...); }');
|
|
432
|
+
When you do not need a full component wrapper, use the hooks directly: `useStyles` for local class names, `useGlobalStyles` for selector-scoped global CSS, `useRawCSS` for raw rules, plus `useKeyframes` and `useProperty` for animation and custom-property primitives.
|
|
501
433
|
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
```
|
|
434
|
+
See [Runtime API - Hooks](docs/runtime.md#hooks).
|
|
505
435
|
|
|
506
436
|
### Zero-Runtime Mode
|
|
507
437
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
```tsx
|
|
511
|
-
import { tastyStatic } from '@tenphi/tasty/static';
|
|
512
|
-
|
|
513
|
-
const card = tastyStatic({
|
|
514
|
-
padding: '4x',
|
|
515
|
-
fill: '#surface',
|
|
516
|
-
radius: '1r',
|
|
517
|
-
color: { '': '#text', '@dark': '#text-on-dark' },
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
// card is a CSS class name string
|
|
521
|
-
<div className={card}>Static styles, zero runtime</div>
|
|
522
|
-
```
|
|
438
|
+
Use `tastyStatic` when you want the same DSL and state model, but with CSS extracted at build time and no styling runtime in the client bundle. It is a strong fit for static sites, landing pages, and other build-time-first setups.
|
|
523
439
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
```js
|
|
527
|
-
module.exports = {
|
|
528
|
-
plugins: [
|
|
529
|
-
['@tenphi/tasty/babel-plugin', {
|
|
530
|
-
output: 'public/tasty.css',
|
|
531
|
-
config: {
|
|
532
|
-
states: { '@dark': '@root(schema=dark)' },
|
|
533
|
-
},
|
|
534
|
-
}],
|
|
535
|
-
],
|
|
536
|
-
};
|
|
537
|
-
```
|
|
440
|
+
See [Zero Runtime (tastyStatic)](docs/tasty-static.md) and [Getting Started - Choosing a rendering mode](docs/getting-started.md#choosing-a-rendering-mode).
|
|
538
441
|
|
|
539
442
|
### `tasty` vs `tastyStatic`
|
|
540
443
|
|
|
541
|
-
|
|
542
|
-
|---|---|---|
|
|
543
|
-
| **Output** | React component | CSS class name |
|
|
544
|
-
| **CSS injection** | Runtime `<style>` tags | Build-time extraction |
|
|
545
|
-
| **Runtime cost** | Style generation on mount | None |
|
|
546
|
-
| **Generated CSS scope** | Only styles/variants used at runtime | All extracted static styles at build time |
|
|
547
|
-
| **Dynamic values** | Fully supported | Via CSS custom properties |
|
|
548
|
-
| **Sub-elements** | Built-in (`<C.Title>`) | Manual (`data-element`) |
|
|
549
|
-
| **Variants** | Built-in (`variants` option) | Separate static styles |
|
|
550
|
-
| **Framework** | React | Any (requires Babel) |
|
|
551
|
-
| **Best for** | Interactive apps with reusable stateful components, design systems | Static sites, SSG, landing pages |
|
|
444
|
+
`tasty()` returns React components and injects CSS on demand at runtime. `tastyStatic()` returns class names and extracts CSS during the build. Both share the same DSL, tokens, units, state mappings, and recipes, so the main choice is runtime flexibility versus build-time extraction.
|
|
552
445
|
|
|
553
|
-
|
|
446
|
+
See [Zero Runtime (tastyStatic)](docs/tasty-static.md), [Runtime API](docs/runtime.md), and [Comparison - Build-time vs runtime](docs/comparison.md#build-time-vs-runtime).
|
|
554
447
|
|
|
555
448
|
### Server-Side Rendering
|
|
556
449
|
|
|
557
|
-
SSR
|
|
558
|
-
|
|
559
|
-
**Next.js setup:**
|
|
560
|
-
|
|
561
|
-
```tsx
|
|
562
|
-
// app/tasty-registry.tsx
|
|
563
|
-
'use client';
|
|
564
|
-
|
|
565
|
-
import { TastyRegistry } from '@tenphi/tasty/ssr/next';
|
|
450
|
+
SSR layers on top of runtime `tasty()` rather than introducing a separate styling model. Existing components stay unchanged while Tasty collects CSS during server rendering and hydrates the cache on the client.
|
|
566
451
|
|
|
567
|
-
|
|
568
|
-
children,
|
|
569
|
-
}: {
|
|
570
|
-
children: React.ReactNode;
|
|
571
|
-
}) {
|
|
572
|
-
return <TastyRegistry>{children}</TastyRegistry>;
|
|
573
|
-
}
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
```tsx
|
|
577
|
-
// app/layout.tsx
|
|
578
|
-
import TastyStyleRegistry from './tasty-registry';
|
|
579
|
-
|
|
580
|
-
export default function RootLayout({
|
|
581
|
-
children,
|
|
582
|
-
}: {
|
|
583
|
-
children: React.ReactNode;
|
|
584
|
-
}) {
|
|
585
|
-
return (
|
|
586
|
-
<html>
|
|
587
|
-
<body>
|
|
588
|
-
<TastyStyleRegistry>{children}</TastyStyleRegistry>
|
|
589
|
-
</body>
|
|
590
|
-
</html>
|
|
591
|
-
);
|
|
592
|
-
}
|
|
593
|
-
```
|
|
452
|
+
Use `@tenphi/tasty/ssr/next` for Next.js App Router, `@tenphi/tasty/ssr/astro` for Astro, or the core SSR API for other React SSR setups.
|
|
594
453
|
|
|
595
|
-
See the [full SSR guide](docs/ssr.md)
|
|
454
|
+
See the [full SSR guide](docs/ssr.md).
|
|
596
455
|
|
|
597
456
|
## Entry Points
|
|
598
457
|
|
package/dist/core/index.d.ts
CHANGED
|
@@ -16,11 +16,11 @@ import { TastyPlugin, TastyPluginFactory } from "../plugins/types.js";
|
|
|
16
16
|
import { TastyConfig, configure, getConfig, getGlobalKeyframes, getGlobalRecipes, hasGlobalKeyframes, hasGlobalRecipes, hasStylesGenerated, isConfigLocked, isTestEnvironment, resetConfig } from "../config.js";
|
|
17
17
|
import { okhslFunc, okhslPlugin } from "../plugins/okhsl-plugin.js";
|
|
18
18
|
import { CHUNK_NAMES, ChunkInfo, ChunkName, STYLE_TO_CHUNK, categorizeStyleKeys } from "../chunks/definitions.js";
|
|
19
|
-
import { PropertyOptions, allocateClassName, cleanup, createInjector, destroy, getCssText, getCssTextForNode, getIsTestEnvironment, getRawCSSText, inject, injectGlobal, injectRawCSS, injector, isPropertyDefined, keyframes, property, trackRef } from "../injector/index.js";
|
|
20
19
|
import { BASE_STYLES, BLOCK_INNER_STYLES, BLOCK_OUTER_STYLES, BLOCK_STYLES, COLOR_STYLES, CONTAINER_STYLES, DIMENSION_STYLES, FLOW_STYLES, INNER_STYLES, OUTER_STYLES, POSITION_STYLES, TEXT_STYLES } from "../styles/list.js";
|
|
21
20
|
import { BaseStyleProps, BlockInnerStyleProps, BlockOuterStyleProps, BlockStyleProps, ColorStyleProps, ContainerStyleProps, DimensionStyleProps, FlowStyleProps, GlobalStyledProps, InnerStyleProps, ModValue, Mods, OuterStyleProps, PositionStyleProps, Props, ShortGridStyles, TagName, TastyExtensionConfig, TastyThemeNames, TextStyleProps, TokenValue, Tokens } from "../types.js";
|
|
22
21
|
import { styleHandlers } from "../styles/predefined.js";
|
|
23
22
|
import "../styles/index.js";
|
|
23
|
+
import { PropertyOptions, allocateClassName, cleanup, createInjector, destroy, getCssText, getCssTextForNode, getIsTestEnvironment, getRawCSSText, inject, injectGlobal, injectRawCSS, injector, isPropertyDefined, keyframes, property, trackRef } from "../injector/index.js";
|
|
24
24
|
import { filterBaseProps } from "../utils/filter-base-props.js";
|
|
25
25
|
import { color } from "../utils/colors.js";
|
|
26
26
|
import { _modAttrs } from "../utils/mod-attrs.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -16,10 +16,9 @@ import { TastyPlugin, TastyPluginFactory } from "./plugins/types.js";
|
|
|
16
16
|
import { TastyConfig, configure, getConfig, getGlobalKeyframes, getGlobalRecipes, hasGlobalKeyframes, hasGlobalRecipes, hasStylesGenerated, isConfigLocked, isTestEnvironment, resetConfig } from "./config.js";
|
|
17
17
|
import { okhslFunc, okhslPlugin } from "./plugins/okhsl-plugin.js";
|
|
18
18
|
import { CHUNK_NAMES, ChunkInfo, ChunkName, STYLE_TO_CHUNK, categorizeStyleKeys } from "./chunks/definitions.js";
|
|
19
|
-
import { PropertyOptions, allocateClassName, cleanup, createInjector, destroy, getCssText, getCssTextForNode, getIsTestEnvironment, getRawCSSText, inject, injectGlobal, injectRawCSS, injector, isPropertyDefined, keyframes, property, trackRef } from "./injector/index.js";
|
|
20
19
|
import { BASE_STYLES, BLOCK_INNER_STYLES, BLOCK_OUTER_STYLES, BLOCK_STYLES, COLOR_STYLES, CONTAINER_STYLES, DIMENSION_STYLES, FLOW_STYLES, INNER_STYLES, OUTER_STYLES, POSITION_STYLES, TEXT_STYLES } from "./styles/list.js";
|
|
21
20
|
import { AllBaseProps, BaseProps, BasePropsWithoutChildren, BaseStyleProps, BlockInnerStyleProps, BlockOuterStyleProps, BlockStyleProps, ColorStyleProps, ContainerStyleProps, DimensionStyleProps, FlowStyleProps, GlobalStyledProps, InnerStyleProps, ModValue, Mods, OuterStyleProps, PositionStyleProps, Props, ShortGridStyles, TagName, TastyExtensionConfig, TastyThemeNames, TextStyleProps, TokenValue, Tokens } from "./types.js";
|
|
22
|
-
import { AllBasePropsWithMods, Element, ElementsDefinition, SubElementDefinition, SubElementProps, TastyElementOptions, TastyElementProps, TastyProps, VariantMap, WithVariant, tasty } from "./tasty.js";
|
|
21
|
+
import { AllBasePropsWithMods, Element, ElementsDefinition, ModPropDef, ModPropsInput, ResolveModPropDef, ResolveModProps, SubElementDefinition, SubElementProps, TastyElementOptions, TastyElementProps, TastyProps, VariantMap, WithVariant, tasty } from "./tasty.js";
|
|
23
22
|
import { UseStylesOptions, UseStylesResult, useStyles } from "./hooks/useStyles.js";
|
|
24
23
|
import { useGlobalStyles } from "./hooks/useGlobalStyles.js";
|
|
25
24
|
import { useRawCSS } from "./hooks/useRawCSS.js";
|
|
@@ -27,6 +26,7 @@ import { useKeyframes } from "./hooks/useKeyframes.js";
|
|
|
27
26
|
import { UsePropertyOptions, useProperty } from "./hooks/useProperty.js";
|
|
28
27
|
import { getDisplayName } from "./utils/get-display-name.js";
|
|
29
28
|
import { styleHandlers } from "./styles/predefined.js";
|
|
29
|
+
import { PropertyOptions, allocateClassName, cleanup, createInjector, destroy, getCssText, getCssTextForNode, getIsTestEnvironment, getRawCSSText, inject, injectGlobal, injectRawCSS, injector, isPropertyDefined, keyframes, property, trackRef } from "./injector/index.js";
|
|
30
30
|
import { filterBaseProps } from "./utils/filter-base-props.js";
|
|
31
31
|
import { color } from "./utils/colors.js";
|
|
32
32
|
import { _modAttrs } from "./utils/mod-attrs.js";
|
|
@@ -45,5 +45,5 @@ declare module './utils/css-types' {
|
|
|
45
45
|
interface CSSProperties extends CSSProperties$1 {}
|
|
46
46
|
}
|
|
47
47
|
//#endregion
|
|
48
|
-
export { type AllBaseProps, type AllBasePropsWithMods, AtRuleContext, BASE_STYLES, BLOCK_INNER_STYLES, BLOCK_OUTER_STYLES, BLOCK_STYLES, type BaseProps, type BasePropsWithoutChildren, BaseStyleProps, BlockInnerStyleProps, BlockOuterStyleProps, BlockStyleProps, Bucket, CHUNK_NAMES, COLOR_STYLES, CONTAINER_STYLES, CSSMap, CSSProperties, CUSTOM_UNITS, CacheMetrics, ChunkInfo, ChunkName, ColorSpace, ColorStyleProps, ConditionNode, ConfigTokenValue, ConfigTokens, ContainerStyleProps, DIMENSION_STYLES, DIRECTIONS, DimensionStyleProps, DisposeFunction, Element, type ElementsDefinition, FLOW_STYLES, FlowStyleProps, GlobalStyledProps, INNER_STYLES, InjectResult, InnerStyleProps, KeyframesCacheEntry, KeyframesInfo, KeyframesResult, KeyframesSteps, ModValue, Mods, NoType, NotSelector, OUTER_STYLES, OuterStyleProps, POSITION_STYLES, ParseStateKeyOptions, ParsedAdvancedState, ParsedColor, ParserOptions, PositionStyleProps, ProcessedStyle, PropertyDefinition, PropertyOptions, Props, RawCSSResult, RawStyleHandler, RecipeStyles, RenderResult, RootRegistry, RuleInfo, STYLE_TO_CHUNK, Selector, SheetInfo, SheetManager, ShortGridStyles, StateParserContext, StyleDetails, StyleDetailsPart, StyleHandler, StyleHandlerDefinition, StyleHandlerResult, StyleInjector, StyleInjectorConfig, StyleMap, StyleParser, StylePropValue, StyleResult, StyleRule, StyleValue, StyleValueStateMap, Styles, StylesInterface, StylesWithoutSelectors, type SubElementDefinition, type SubElementProps, SuffixForSelector, TEXT_STYLES, TagName, TastyConfig, type TastyElementOptions, type TastyElementProps, TastyExtensionConfig, TastyNamedColors, TastyPlugin, TastyPluginFactory, TastyPresetNames, type TastyProps, TastyThemeNames, TextStyleProps, TokenValue, Tokens, TypographyPreset, UnitHandler, type UsePropertyOptions, type UseStylesOptions, type UseStylesResult, type VariantMap, type WithVariant, allocateClassName, categorizeStyleKeys, cleanup, color, configure, createInjector, createStateParserContext, customFunc, deprecationWarning, destroy, dotize, filterBaseProps, filterMods, generateTypographyTokens, getConfig, getCssText, getCssTextForNode, getDisplayName, getGlobalFuncs, getGlobalKeyframes, getGlobalParser, getGlobalPredefinedStates, getGlobalPredefinedTokens, getGlobalRecipes, getIsTestEnvironment, getNamedColorHex, getRawCSSText, getRgbValuesFromRgbaString, hasGlobalKeyframes, hasGlobalRecipes, hasStylesGenerated, hexToRgb, hslToRgbValues, inject, injectGlobal, injectRawCSS, injector, isConfigLocked, isPropertyDefined, isSelector, isTestEnvironment, keyframes, mergeStyles, _modAttrs as modAttrs, normalizeColorTokenValue, okhslFunc, okhslPlugin, parseColor, parseStateKey, parseStyle, processTokens, property, renderStyles, resetConfig, resetGlobalPredefinedTokens, resolveRecipes, setGlobalPredefinedStates, setGlobalPredefinedTokens, strToRgb, stringifyStyles, stringifyTokens, styleHandlers, tasty, tastyDebug, trackRef, useGlobalStyles, useKeyframes, useProperty, useRawCSS, useStyles, warn };
|
|
48
|
+
export { type AllBaseProps, type AllBasePropsWithMods, AtRuleContext, BASE_STYLES, BLOCK_INNER_STYLES, BLOCK_OUTER_STYLES, BLOCK_STYLES, type BaseProps, type BasePropsWithoutChildren, BaseStyleProps, BlockInnerStyleProps, BlockOuterStyleProps, BlockStyleProps, Bucket, CHUNK_NAMES, COLOR_STYLES, CONTAINER_STYLES, CSSMap, CSSProperties, CUSTOM_UNITS, CacheMetrics, ChunkInfo, ChunkName, ColorSpace, ColorStyleProps, ConditionNode, ConfigTokenValue, ConfigTokens, ContainerStyleProps, DIMENSION_STYLES, DIRECTIONS, DimensionStyleProps, DisposeFunction, Element, type ElementsDefinition, FLOW_STYLES, FlowStyleProps, GlobalStyledProps, INNER_STYLES, InjectResult, InnerStyleProps, KeyframesCacheEntry, KeyframesInfo, KeyframesResult, KeyframesSteps, type ModPropDef, type ModPropsInput, ModValue, Mods, NoType, NotSelector, OUTER_STYLES, OuterStyleProps, POSITION_STYLES, ParseStateKeyOptions, ParsedAdvancedState, ParsedColor, ParserOptions, PositionStyleProps, ProcessedStyle, PropertyDefinition, PropertyOptions, Props, RawCSSResult, RawStyleHandler, RecipeStyles, RenderResult, type ResolveModPropDef, type ResolveModProps, RootRegistry, RuleInfo, STYLE_TO_CHUNK, Selector, SheetInfo, SheetManager, ShortGridStyles, StateParserContext, StyleDetails, StyleDetailsPart, StyleHandler, StyleHandlerDefinition, StyleHandlerResult, StyleInjector, StyleInjectorConfig, StyleMap, StyleParser, StylePropValue, StyleResult, StyleRule, StyleValue, StyleValueStateMap, Styles, StylesInterface, StylesWithoutSelectors, type SubElementDefinition, type SubElementProps, SuffixForSelector, TEXT_STYLES, TagName, TastyConfig, type TastyElementOptions, type TastyElementProps, TastyExtensionConfig, TastyNamedColors, TastyPlugin, TastyPluginFactory, TastyPresetNames, type TastyProps, TastyThemeNames, TextStyleProps, TokenValue, Tokens, TypographyPreset, UnitHandler, type UsePropertyOptions, type UseStylesOptions, type UseStylesResult, type VariantMap, type WithVariant, allocateClassName, categorizeStyleKeys, cleanup, color, configure, createInjector, createStateParserContext, customFunc, deprecationWarning, destroy, dotize, filterBaseProps, filterMods, generateTypographyTokens, getConfig, getCssText, getCssTextForNode, getDisplayName, getGlobalFuncs, getGlobalKeyframes, getGlobalParser, getGlobalPredefinedStates, getGlobalPredefinedTokens, getGlobalRecipes, getIsTestEnvironment, getNamedColorHex, getRawCSSText, getRgbValuesFromRgbaString, hasGlobalKeyframes, hasGlobalRecipes, hasStylesGenerated, hexToRgb, hslToRgbValues, inject, injectGlobal, injectRawCSS, injector, isConfigLocked, isPropertyDefined, isSelector, isTestEnvironment, keyframes, mergeStyles, _modAttrs as modAttrs, normalizeColorTokenValue, okhslFunc, okhslPlugin, parseColor, parseStateKey, parseStyle, processTokens, property, renderStyles, resetConfig, resetGlobalPredefinedTokens, resolveRecipes, setGlobalPredefinedStates, setGlobalPredefinedTokens, strToRgb, stringifyStyles, stringifyTokens, styleHandlers, tasty, tastyDebug, trackRef, useGlobalStyles, useKeyframes, useProperty, useRawCSS, useStyles, warn };
|
|
49
49
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/pipeline/index.js
CHANGED
|
@@ -170,7 +170,8 @@ function getAllSelectors(key, styles) {
|
|
|
170
170
|
* Supports:
|
|
171
171
|
* - Direct child: '>'
|
|
172
172
|
* - Chained elements: '>Body>Row>'
|
|
173
|
-
* - HTML tags: '
|
|
173
|
+
* - HTML tags (no key injection): 'h1', '>ul>li', 'button:hover'
|
|
174
|
+
* - Universal selector: '*', 'h1 *'
|
|
174
175
|
* - Pseudo-elements on root: '::before'
|
|
175
176
|
* - Pseudo on sub-element: '@::before', '>@:hover'
|
|
176
177
|
* - Classes: '.active', '>@.active'
|
|
@@ -207,6 +208,7 @@ function processAffix(affix, key) {
|
|
|
207
208
|
*/
|
|
208
209
|
const VALID_TOKEN_PATTERNS = [
|
|
209
210
|
/^[>+~]/,
|
|
211
|
+
/^\*/,
|
|
210
212
|
/^[A-Z][a-zA-Z0-9]*/,
|
|
211
213
|
/^@/,
|
|
212
214
|
/^::?[a-z][a-z0-9-]*(?:\([^)]*\))?/,
|
|
@@ -341,12 +343,13 @@ function processSinglePattern(pattern, key) {
|
|
|
341
343
|
* The tokenizer handles these token types in order:
|
|
342
344
|
* 1. Whitespace (skipped)
|
|
343
345
|
* 2. Combinators: >, +, ~ (add surrounding spaces)
|
|
344
|
-
* 3.
|
|
345
|
-
* 4.
|
|
346
|
-
* 5.
|
|
347
|
-
* 6.
|
|
348
|
-
* 7.
|
|
349
|
-
* 8.
|
|
346
|
+
* 3. Universal selector: * (keep as-is with spacing)
|
|
347
|
+
* 4. Uppercase names: Body, Row (convert to [data-element="..."])
|
|
348
|
+
* 5. @ placeholder (keep for later replacement)
|
|
349
|
+
* 6. Pseudo: :hover, ::before (attach to previous token)
|
|
350
|
+
* 7. Tags: a, div, button (keep as-is with spacing)
|
|
351
|
+
* 8. Classes: .active (attach to previous element/tag/placeholder)
|
|
352
|
+
* 9. Attributes: [type="text"] (keep as-is)
|
|
350
353
|
*
|
|
351
354
|
* @param pattern - The raw selector pattern to transform
|
|
352
355
|
* @returns Transformed pattern with proper CSS selector syntax
|
|
@@ -375,6 +378,13 @@ function transformPattern(pattern) {
|
|
|
375
378
|
i++;
|
|
376
379
|
continue;
|
|
377
380
|
}
|
|
381
|
+
if (char === "*") {
|
|
382
|
+
if (result && lastCh !== " ") result += " ";
|
|
383
|
+
result += "*";
|
|
384
|
+
lastCh = "*";
|
|
385
|
+
i++;
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
378
388
|
if (/[A-Z]/.test(char)) {
|
|
379
389
|
const nameStart = i;
|
|
380
390
|
while (i < pattern.length && /[a-zA-Z0-9]/.test(pattern[i])) i++;
|
|
@@ -449,7 +459,8 @@ function transformPattern(pattern) {
|
|
|
449
459
|
* |----------------|-------------|---------|--------|
|
|
450
460
|
* | Combinator (>, +, ~) | Yes | `'>Body>'` | `> [data-element="Body"] > [el]` |
|
|
451
461
|
* | Uppercase element | Yes | `'>Body>Row'` | `> [el1] > [el2] [key]` |
|
|
452
|
-
* | Lowercase tag |
|
|
462
|
+
* | Lowercase tag | No | `'h1'` | ` h1` |
|
|
463
|
+
* | Universal (*) | No | `'h1 *'` | ` h1 *` |
|
|
453
464
|
* | Pseudo (:hover, ::before) | No | `'::before'` | `::before` |
|
|
454
465
|
* | Class (.active) | No | `'.active'` | `.active` |
|
|
455
466
|
* | Attribute ([type]) | No | `'[type="text"]'` | `[type="text"]` |
|
|
@@ -460,7 +471,8 @@ function transformPattern(pattern) {
|
|
|
460
471
|
* @example
|
|
461
472
|
* shouldInjectKey('>') // → true (trailing combinator)
|
|
462
473
|
* shouldInjectKey('>Body>Row') // → true (ends with element)
|
|
463
|
-
* shouldInjectKey('
|
|
474
|
+
* shouldInjectKey('h1') // → false (ends with tag)
|
|
475
|
+
* shouldInjectKey('*') // → false (universal selector)
|
|
464
476
|
* shouldInjectKey('::before') // → false (ends with pseudo)
|
|
465
477
|
* shouldInjectKey('.active') // → false (ends with class)
|
|
466
478
|
* shouldInjectKey('a:hover') // → false (ends with pseudo)
|
|
@@ -470,7 +482,6 @@ function shouldInjectKey(pattern) {
|
|
|
470
482
|
const trimmed = pattern.trim();
|
|
471
483
|
if (/[>+~]$/.test(trimmed)) return true;
|
|
472
484
|
if (/(?:^|[\s>+~\]:])[A-Z][a-zA-Z0-9]*$/.test(trimmed)) return true;
|
|
473
|
-
if (/(?<![:.])(?:^|[\s>+~])[a-z][a-z0-9-]*$/.test(trimmed)) return true;
|
|
474
485
|
return false;
|
|
475
486
|
}
|
|
476
487
|
/**
|