@tenphi/tasty 0.0.0-snapshot.26b4630 → 0.0.0-snapshot.2705ab9
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 +315 -159
- package/dist/chunks/cacheKey.js +16 -8
- package/dist/chunks/cacheKey.js.map +1 -1
- package/dist/chunks/definitions.d.ts +1 -1
- package/dist/chunks/definitions.js +2 -3
- package/dist/chunks/definitions.js.map +1 -1
- package/dist/chunks/renderChunk.js +31 -32
- package/dist/chunks/renderChunk.js.map +1 -1
- package/dist/config.d.ts +98 -12
- package/dist/config.js +134 -33
- package/dist/config.js.map +1 -1
- package/dist/core/index.d.ts +11 -10
- package/dist/core/index.js +8 -7
- package/dist/counter-style/index.js +51 -0
- package/dist/counter-style/index.js.map +1 -0
- package/dist/debug.d.ts +26 -141
- package/dist/debug.js +356 -635
- package/dist/debug.js.map +1 -1
- package/dist/font-face/index.js +63 -0
- package/dist/font-face/index.js.map +1 -0
- package/dist/hooks/resolve-ssr-collector.js +15 -0
- package/dist/hooks/resolve-ssr-collector.js.map +1 -0
- package/dist/hooks/useCounterStyle.d.ts +50 -0
- package/dist/hooks/useCounterStyle.js +47 -0
- package/dist/hooks/useCounterStyle.js.map +1 -0
- package/dist/hooks/useFontFace.d.ts +43 -0
- package/dist/hooks/useFontFace.js +71 -0
- package/dist/hooks/useFontFace.js.map +1 -0
- package/dist/hooks/useGlobalStyles.d.ts +3 -0
- package/dist/hooks/useGlobalStyles.js +24 -1
- package/dist/hooks/useGlobalStyles.js.map +1 -1
- package/dist/hooks/useKeyframes.js +14 -3
- package/dist/hooks/useKeyframes.js.map +1 -1
- package/dist/hooks/useProperty.js +32 -13
- package/dist/hooks/useProperty.js.map +1 -1
- package/dist/hooks/useRawCSS.js +9 -1
- package/dist/hooks/useRawCSS.js.map +1 -1
- package/dist/hooks/useStyles.d.ts +5 -0
- package/dist/hooks/useStyles.js +115 -46
- package/dist/hooks/useStyles.js.map +1 -1
- package/dist/index.d.ts +22 -11
- package/dist/index.js +10 -7
- package/dist/injector/index.d.ts +28 -2
- package/dist/injector/index.js +27 -1
- package/dist/injector/index.js.map +1 -1
- package/dist/injector/injector.d.ts +28 -1
- package/dist/injector/injector.js +93 -32
- package/dist/injector/injector.js.map +1 -1
- package/dist/injector/sheet-manager.d.ts +16 -7
- package/dist/injector/sheet-manager.js +31 -11
- package/dist/injector/sheet-manager.js.map +1 -1
- package/dist/injector/types.d.ts +70 -1
- package/dist/parser/classify.js +5 -4
- package/dist/parser/classify.js.map +1 -1
- package/dist/parser/const.js +17 -1
- package/dist/parser/const.js.map +1 -1
- package/dist/parser/parser.js +1 -1
- package/dist/pipeline/conditions.js +14 -8
- package/dist/pipeline/conditions.js.map +1 -1
- package/dist/pipeline/index.d.ts +3 -1
- package/dist/pipeline/index.js +137 -69
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/materialize.js +404 -208
- package/dist/pipeline/materialize.js.map +1 -1
- package/dist/pipeline/parseStateKey.d.ts +1 -1
- package/dist/pipeline/parseStateKey.js +37 -20
- package/dist/pipeline/parseStateKey.js.map +1 -1
- package/dist/pipeline/simplify.js +111 -152
- package/dist/pipeline/simplify.js.map +1 -1
- package/dist/pipeline/warnings.js +18 -0
- package/dist/pipeline/warnings.js.map +1 -0
- package/dist/plugins/okhsl-plugin.js +2 -275
- package/dist/plugins/okhsl-plugin.js.map +1 -1
- package/dist/plugins/types.d.ts +9 -2
- package/dist/properties/index.js +82 -17
- package/dist/properties/index.js.map +1 -1
- package/dist/properties/property-type-resolver.d.ts +24 -0
- package/dist/properties/property-type-resolver.js +91 -0
- package/dist/properties/property-type-resolver.js.map +1 -0
- package/dist/ssr/astro.d.ts +29 -0
- package/dist/ssr/astro.js +65 -0
- package/dist/ssr/astro.js.map +1 -0
- package/dist/ssr/async-storage.d.ts +17 -0
- package/dist/ssr/async-storage.js +35 -0
- package/dist/ssr/async-storage.js.map +1 -0
- package/dist/ssr/collect-auto-properties.js +40 -0
- package/dist/ssr/collect-auto-properties.js.map +1 -0
- package/dist/ssr/collector.d.ts +102 -0
- package/dist/ssr/collector.js +227 -0
- package/dist/ssr/collector.js.map +1 -0
- package/dist/ssr/context.d.ts +8 -0
- package/dist/ssr/context.js +14 -0
- package/dist/ssr/context.js.map +1 -0
- package/dist/ssr/format-global-rules.js +22 -0
- package/dist/ssr/format-global-rules.js.map +1 -0
- package/dist/ssr/format-keyframes.js +70 -0
- package/dist/ssr/format-keyframes.js.map +1 -0
- package/dist/ssr/format-property.js +50 -0
- package/dist/ssr/format-property.js.map +1 -0
- package/dist/ssr/format-rules.js +73 -0
- package/dist/ssr/format-rules.js.map +1 -0
- package/dist/ssr/hydrate.d.ts +22 -0
- package/dist/ssr/hydrate.js +50 -0
- package/dist/ssr/hydrate.js.map +1 -0
- package/dist/ssr/index.d.ts +5 -0
- package/dist/ssr/index.js +12 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/ssr/next.d.ts +45 -0
- package/dist/ssr/next.js +71 -0
- package/dist/ssr/next.js.map +1 -0
- package/dist/ssr/ssr-collector-ref.js +12 -0
- package/dist/ssr/ssr-collector-ref.js.map +1 -0
- package/dist/states/index.js +12 -257
- package/dist/states/index.js.map +1 -1
- package/dist/styles/align.d.ts +1 -1
- package/dist/styles/align.js.map +1 -1
- package/dist/styles/border.d.ts +1 -1
- package/dist/styles/border.js +2 -2
- package/dist/styles/border.js.map +1 -1
- package/dist/styles/color.d.ts +2 -2
- package/dist/styles/color.js +9 -5
- package/dist/styles/color.js.map +1 -1
- package/dist/styles/createStyle.js +25 -22
- package/dist/styles/createStyle.js.map +1 -1
- package/dist/styles/fade.d.ts +1 -1
- package/dist/styles/fade.js.map +1 -1
- package/dist/styles/fill.d.ts +14 -16
- package/dist/styles/fill.js +6 -5
- package/dist/styles/fill.js.map +1 -1
- package/dist/styles/flow.d.ts +3 -3
- package/dist/styles/flow.js.map +1 -1
- package/dist/styles/index.js +1 -1
- package/dist/styles/justify.d.ts +1 -1
- package/dist/styles/justify.js.map +1 -1
- package/dist/styles/predefined.d.ts +0 -2
- package/dist/styles/predefined.js +1 -4
- package/dist/styles/predefined.js.map +1 -1
- package/dist/styles/preset.d.ts +5 -0
- package/dist/styles/preset.js +48 -47
- package/dist/styles/preset.js.map +1 -1
- package/dist/styles/radius.d.ts +1 -1
- package/dist/styles/radius.js.map +1 -1
- package/dist/styles/scrollbar.d.ts +9 -5
- package/dist/styles/scrollbar.js +25 -82
- package/dist/styles/scrollbar.js.map +1 -1
- package/dist/styles/shadow.d.ts +2 -2
- package/dist/styles/shadow.js.map +1 -1
- package/dist/styles/transition.d.ts +1 -1
- package/dist/styles/transition.js +1 -1
- package/dist/styles/transition.js.map +1 -1
- package/dist/styles/types.d.ts +70 -21
- package/dist/tasty.d.ts +30 -893
- package/dist/tasty.js +60 -19
- package/dist/tasty.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/utils/cache-wrapper.js +4 -8
- package/dist/utils/cache-wrapper.js.map +1 -1
- package/dist/utils/color-math.d.ts +46 -0
- package/dist/utils/color-math.js +749 -0
- package/dist/utils/color-math.js.map +1 -0
- package/dist/utils/color-space.d.ts +5 -0
- package/dist/utils/color-space.js +229 -0
- package/dist/utils/color-space.js.map +1 -0
- package/dist/utils/colors.d.ts +1 -1
- package/dist/utils/colors.js +3 -1
- package/dist/utils/colors.js.map +1 -1
- package/dist/utils/css-types.d.ts +1 -1
- package/dist/utils/dotize.d.ts +1 -1
- package/dist/utils/has-keys.js +13 -0
- package/dist/utils/has-keys.js.map +1 -0
- package/dist/utils/mod-attrs.js +2 -2
- package/dist/utils/mod-attrs.js.map +1 -1
- package/dist/utils/process-tokens.d.ts +3 -13
- package/dist/utils/process-tokens.js +18 -98
- package/dist/utils/process-tokens.js.map +1 -1
- package/dist/utils/selector-transform.js +32 -0
- package/dist/utils/selector-transform.js.map +1 -0
- package/dist/utils/string.js.map +1 -1
- package/dist/utils/styles.d.ts +4 -88
- package/dist/utils/styles.js +34 -398
- package/dist/utils/styles.js.map +1 -1
- package/dist/utils/typography.d.ts +24 -13
- package/dist/utils/typography.js +14 -16
- package/dist/utils/typography.js.map +1 -1
- package/dist/zero/babel.d.ts +67 -8
- package/dist/zero/babel.js +109 -17
- package/dist/zero/babel.js.map +1 -1
- package/dist/zero/extractor.js +118 -1
- package/dist/zero/extractor.js.map +1 -1
- package/dist/zero/next.d.ts +44 -30
- package/dist/zero/next.js +102 -38
- package/dist/zero/next.js.map +1 -1
- package/docs/PIPELINE.md +519 -0
- package/docs/README.md +31 -0
- package/docs/adoption.md +296 -0
- package/docs/comparison.md +420 -0
- package/docs/configuration.md +326 -0
- package/docs/debug.md +318 -0
- package/docs/design-system.md +424 -0
- package/docs/dsl.md +673 -0
- package/docs/getting-started.md +217 -0
- package/docs/injector.md +528 -0
- package/docs/methodology.md +567 -0
- package/docs/runtime.md +485 -0
- package/docs/ssr.md +384 -0
- package/docs/styles.md +579 -0
- package/docs/tasty-static.md +433 -0
- package/package.json +98 -28
- package/dist/styles/styledScrollbar.d.ts +0 -47
- package/dist/styles/styledScrollbar.js +0 -38
- package/dist/styles/styledScrollbar.js.map +0 -1
- package/dist/tokens/typography.d.ts +0 -19
- package/dist/tokens/typography.js +0 -237
- package/dist/tokens/typography.js.map +0 -1
- package/dist/utils/hsl-to-rgb.js +0 -38
- package/dist/utils/hsl-to-rgb.js.map +0 -1
- package/dist/utils/okhsl-to-rgb.js +0 -296
- package/dist/utils/okhsl-to-rgb.js.map +0 -1
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
# Zero Runtime Mode (tastyStatic)
|
|
2
|
+
|
|
3
|
+
`tastyStatic` is a build-time utility for generating CSS with zero runtime overhead. It's designed for static sites, no-JS websites, and performance-critical applications where you want to eliminate all runtime styling code. For the broader docs map, see the [Docs Hub](README.md).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## When to Use
|
|
8
|
+
|
|
9
|
+
- **Static site generation (SSG)** — Pre-render all styles at build time
|
|
10
|
+
- **No-JavaScript websites** — CSS works without any JS runtime
|
|
11
|
+
- **Performance-critical pages** — Zero runtime overhead for styling
|
|
12
|
+
- **Landing pages** — Minimal bundle size with pre-generated CSS
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
The zero-runtime mode is part of the main `@tenphi/tasty` package but requires additional peer dependencies depending on your setup:
|
|
17
|
+
|
|
18
|
+
| Dependency | Version | Required for |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `@babel/core` | >= 7.24 | Babel plugin (`@tenphi/tasty/babel-plugin`) |
|
|
21
|
+
| `@babel/helper-plugin-utils` | >= 7.24 | Babel plugin |
|
|
22
|
+
| `@babel/types` | >= 7.24 | Babel plugin |
|
|
23
|
+
| `jiti` | >= 2.6 | Next.js wrapper (`@tenphi/tasty/next`) when using `configFile` option |
|
|
24
|
+
|
|
25
|
+
All of these are declared as optional peer dependencies of `@tenphi/tasty`. Install only what your setup requires:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# For any Babel-based setup (Vite, custom Babel config, etc.)
|
|
29
|
+
pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types
|
|
30
|
+
|
|
31
|
+
# For Next.js with TypeScript config file
|
|
32
|
+
pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types jiti
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Basic Usage
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { tastyStatic } from '@tenphi/tasty/static';
|
|
43
|
+
|
|
44
|
+
// Define styles - returns StaticStyle object
|
|
45
|
+
const button = tastyStatic({
|
|
46
|
+
display: 'inline-flex',
|
|
47
|
+
padding: '2x 4x',
|
|
48
|
+
fill: '#purple',
|
|
49
|
+
color: '#white',
|
|
50
|
+
radius: '1r',
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Use in JSX - works via toString() coercion
|
|
54
|
+
<button className={button}>Click me</button>
|
|
55
|
+
|
|
56
|
+
// Or access className explicitly
|
|
57
|
+
<button className={button.className}>Click me</button>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## API Reference
|
|
63
|
+
|
|
64
|
+
### tastyStatic(styles)
|
|
65
|
+
|
|
66
|
+
Creates a `StaticStyle` object from a styles definition.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const card = tastyStatic({
|
|
70
|
+
padding: '4x',
|
|
71
|
+
fill: '#white',
|
|
72
|
+
border: true,
|
|
73
|
+
radius: true,
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### tastyStatic(base, styles)
|
|
78
|
+
|
|
79
|
+
Extends an existing `StaticStyle` with additional styles. Uses `mergeStyles` internally for proper nested selector handling.
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
const button = tastyStatic({
|
|
83
|
+
padding: '2x 4x',
|
|
84
|
+
fill: '#blue',
|
|
85
|
+
Icon: { color: '#white' },
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const primaryButton = tastyStatic(button, {
|
|
89
|
+
fill: '#purple',
|
|
90
|
+
Icon: { opacity: 0.8 },
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### tastyStatic(selector, styles)
|
|
95
|
+
|
|
96
|
+
Generates global styles for a CSS selector. The call is removed from the bundle after transformation.
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
tastyStatic('body', {
|
|
100
|
+
fill: '#surface',
|
|
101
|
+
color: '#text',
|
|
102
|
+
preset: 't3',
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## StaticStyle Object
|
|
109
|
+
|
|
110
|
+
| Property | Type | Description |
|
|
111
|
+
|----------|------|-------------|
|
|
112
|
+
| `className` | `string` | Space-separated class names for use in JSX |
|
|
113
|
+
| `styles` | `Styles` | The original (or merged) styles object |
|
|
114
|
+
| `toString()` | `() => string` | Returns `className` for string coercion |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Babel Plugin Configuration
|
|
119
|
+
|
|
120
|
+
### Basic Configuration
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
// babel.config.js
|
|
124
|
+
module.exports = {
|
|
125
|
+
plugins: [
|
|
126
|
+
['@tenphi/tasty/babel-plugin', {
|
|
127
|
+
output: 'public/tasty.css',
|
|
128
|
+
}]
|
|
129
|
+
]
|
|
130
|
+
};
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
These examples use `data-schema="dark"` as the root-state convention. If your app already uses a different root attribute such as `data-theme`, keep the same alias pattern and swap the attribute name consistently in your zero-runtime config.
|
|
134
|
+
|
|
135
|
+
### With Configuration
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
module.exports = {
|
|
139
|
+
plugins: [
|
|
140
|
+
['@tenphi/tasty/babel-plugin', {
|
|
141
|
+
output: 'public/tasty.css',
|
|
142
|
+
config: {
|
|
143
|
+
states: {
|
|
144
|
+
'@mobile': '@media(w < 768px)',
|
|
145
|
+
'@tablet': '@media(w < 1024px)',
|
|
146
|
+
'@dark': '@root(schema=dark)',
|
|
147
|
+
},
|
|
148
|
+
devMode: true,
|
|
149
|
+
},
|
|
150
|
+
}]
|
|
151
|
+
]
|
|
152
|
+
};
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Plugin Options
|
|
156
|
+
|
|
157
|
+
| Option | Type | Default | Description |
|
|
158
|
+
|--------|------|---------|-------------|
|
|
159
|
+
| `output` | `string` | `'tasty.css'` | Path for generated CSS file |
|
|
160
|
+
| `configFile` | `string` | — | Absolute path to a TS/JS module that default-exports a `TastyZeroConfig` object. JSON-serializable alternative to `config` — required for Turbopack. |
|
|
161
|
+
| `config` | `TastyZeroConfig \| () => TastyZeroConfig` | `{}` | Inline config object or factory function. Takes precedence over `configFile`. |
|
|
162
|
+
| `configDeps` | `string[]` | `[]` | Absolute file paths that affect config (for cache invalidation) |
|
|
163
|
+
| `config.states` | `Record<string, string>` | `{}` | Predefined state aliases |
|
|
164
|
+
| `config.devMode` | `boolean` | `false` | Add source comments to CSS |
|
|
165
|
+
| `config.recipes` | `Record<string, RecipeStyles>` | `{}` | Predefined style recipes |
|
|
166
|
+
| `config.fontFace` | `Record<string, FontFaceInput>` | — | Global `@font-face` definitions |
|
|
167
|
+
| `config.counterStyle` | `Record<string, CounterStyleDescriptors>` | — | Global `@counter-style` definitions |
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Recipes
|
|
172
|
+
|
|
173
|
+
Recipes work with `tastyStatic` the same way as with runtime `tasty`:
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
// babel.config.js
|
|
177
|
+
module.exports = {
|
|
178
|
+
plugins: [
|
|
179
|
+
['@tenphi/tasty/babel-plugin', {
|
|
180
|
+
output: 'public/tasty.css',
|
|
181
|
+
config: {
|
|
182
|
+
recipes: {
|
|
183
|
+
card: { padding: '4x', fill: '#surface', radius: '1r', border: true },
|
|
184
|
+
elevated: { shadow: '2x 2x 4x #shadow' },
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
}]
|
|
188
|
+
]
|
|
189
|
+
};
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { tastyStatic } from '@tenphi/tasty/static';
|
|
194
|
+
|
|
195
|
+
const card = tastyStatic({
|
|
196
|
+
recipe: 'card elevated',
|
|
197
|
+
color: '#text',
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
<div className={card}>Styled card</div>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Next.js Integration
|
|
206
|
+
|
|
207
|
+
The `withTastyZero` wrapper configures both **webpack** and **Turbopack** automatically. No `--webpack` flag is needed — it works with whichever bundler Next.js uses.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// next.config.ts
|
|
211
|
+
import { withTastyZero } from '@tenphi/tasty/next';
|
|
212
|
+
|
|
213
|
+
export default withTastyZero({
|
|
214
|
+
output: 'public/tasty.css',
|
|
215
|
+
configFile: './app/tasty-zero.config.ts',
|
|
216
|
+
configDeps: ['./app/theme.ts'],
|
|
217
|
+
})({
|
|
218
|
+
reactStrictMode: true,
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### `withTastyZero` Options
|
|
223
|
+
|
|
224
|
+
| Option | Type | Default | Description |
|
|
225
|
+
|--------|------|---------|-------------|
|
|
226
|
+
| `output` | `string` | `'public/tasty.css'` | Output path for CSS relative to project root |
|
|
227
|
+
| `enabled` | `boolean` | `true` | Enable/disable the plugin |
|
|
228
|
+
| `configFile` | `string` | — | Path to a TS/JS module that default-exports `TastyZeroConfig`. Recommended for Turbopack compatibility. |
|
|
229
|
+
| `config` | `TastyZeroConfig` | — | Inline config object. For static configs that don't change during dev. |
|
|
230
|
+
| `configDeps` | `string[]` | `[]` | Extra files the config depends on (for cache invalidation) |
|
|
231
|
+
|
|
232
|
+
### Turbopack Support
|
|
233
|
+
|
|
234
|
+
Starting with Next.js 16, Turbopack is the default bundler. `withTastyZero` supports it out of the box by injecting `turbopack.rules` with `babel-loader` and JSON-serializable options.
|
|
235
|
+
|
|
236
|
+
The `configFile` option is key for Turbopack — it passes a file path (JSON-serializable) instead of a function, and the Babel plugin loads the config internally via jiti.
|
|
237
|
+
|
|
238
|
+
**Requirements**: `babel-loader` must be installed in your project:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
pnpm add babel-loader
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### CSS Injection
|
|
245
|
+
|
|
246
|
+
`withTastyZero` automatically injects the generated CSS into your app. Every file that imports from `@tenphi/tasty/static` gets its import replaced with an import of the output CSS file at build time. No manual CSS import is needed.
|
|
247
|
+
|
|
248
|
+
The generated CSS file (e.g. `public/tasty.css`) is created as an empty stub before the first build if it doesn't exist, so there's no chicken-and-egg problem with fresh clones or CI builds. Add it to `.gitignore`:
|
|
249
|
+
|
|
250
|
+
```gitignore
|
|
251
|
+
public/tasty.css
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Vite Integration
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// vite.config.ts
|
|
260
|
+
import { defineConfig } from 'vite';
|
|
261
|
+
import react from '@vitejs/plugin-react';
|
|
262
|
+
|
|
263
|
+
export default defineConfig({
|
|
264
|
+
plugins: [
|
|
265
|
+
react({
|
|
266
|
+
babel: {
|
|
267
|
+
plugins: [
|
|
268
|
+
['@tenphi/tasty/babel-plugin', {
|
|
269
|
+
output: 'public/tasty.css',
|
|
270
|
+
config: {
|
|
271
|
+
states: { '@mobile': '@media(w < 768px)' },
|
|
272
|
+
},
|
|
273
|
+
}],
|
|
274
|
+
],
|
|
275
|
+
},
|
|
276
|
+
}),
|
|
277
|
+
],
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Build Transformation
|
|
284
|
+
|
|
285
|
+
### Before (Source Code)
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
import { tastyStatic } from '@tenphi/tasty/static';
|
|
289
|
+
|
|
290
|
+
const button = tastyStatic({
|
|
291
|
+
padding: '2x 4x',
|
|
292
|
+
fill: '#purple',
|
|
293
|
+
color: '#white',
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
tastyStatic('.heading', { preset: 'h1' });
|
|
297
|
+
|
|
298
|
+
export const Button = () => <button className={button}>Click</button>;
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### After (Production Build)
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
const button = {
|
|
305
|
+
className: 'ts3f2a1b ts8c4d2e',
|
|
306
|
+
styles: { padding: '2x 4x', fill: '#purple', color: '#white' },
|
|
307
|
+
toString() { return this.className; }
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
export const Button = () => <button className={button}>Click</button>;
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Generated CSS (tasty.css)
|
|
314
|
+
|
|
315
|
+
```css
|
|
316
|
+
/* Generated by @tenphi/tasty/zero - DO NOT EDIT */
|
|
317
|
+
|
|
318
|
+
.ts3f2a1b.ts3f2a1b {
|
|
319
|
+
padding: 16px 32px;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.ts8c4d2e.ts8c4d2e {
|
|
323
|
+
background: #9370db;
|
|
324
|
+
color: #fff;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.heading.heading {
|
|
328
|
+
font-size: 2.5rem;
|
|
329
|
+
font-weight: 700;
|
|
330
|
+
line-height: 1.2;
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Style Extension
|
|
337
|
+
|
|
338
|
+
```tsx
|
|
339
|
+
// Base button
|
|
340
|
+
const button = tastyStatic({
|
|
341
|
+
display: 'inline-flex',
|
|
342
|
+
padding: '2x 4x',
|
|
343
|
+
radius: '1r',
|
|
344
|
+
fill: '#gray.20',
|
|
345
|
+
color: '#text',
|
|
346
|
+
transition: 'fill 0.15s',
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Variants
|
|
350
|
+
const primaryButton = tastyStatic(button, {
|
|
351
|
+
fill: '#purple',
|
|
352
|
+
color: '#white',
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
const dangerButton = tastyStatic(button, {
|
|
356
|
+
fill: '#danger',
|
|
357
|
+
color: '#white',
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## State-based Styling
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
const card = tastyStatic({
|
|
367
|
+
padding: {
|
|
368
|
+
'': '4x',
|
|
369
|
+
'@mobile': '2x',
|
|
370
|
+
},
|
|
371
|
+
display: {
|
|
372
|
+
'': 'flex',
|
|
373
|
+
'@mobile': 'block',
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Extending Style Types (TypeScript)
|
|
381
|
+
|
|
382
|
+
If you add custom style properties, use module augmentation so `tastyStatic` recognizes them too. See [Extending Style Types](configuration.md#extending-style-types-typescript) in the configuration docs.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Limitations
|
|
387
|
+
|
|
388
|
+
1. **Static values only** — All style values must be known at build time
|
|
389
|
+
2. **No runtime props** — Cannot use `styleProps` or dynamic `styles` prop
|
|
390
|
+
3. **No mods at runtime** — Modifiers must be defined statically
|
|
391
|
+
4. **Build-time transformation required** — Babel plugin must process files
|
|
392
|
+
|
|
393
|
+
### Workarounds
|
|
394
|
+
|
|
395
|
+
For dynamic styling needs, combine with regular CSS or CSS variables:
|
|
396
|
+
|
|
397
|
+
```tsx
|
|
398
|
+
const card = tastyStatic({
|
|
399
|
+
padding: '4x',
|
|
400
|
+
fill: 'var(--card-bg, #white)',
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
<div
|
|
404
|
+
className={card}
|
|
405
|
+
style={{ '--card-bg': isActive ? '#purple' : '#white' }}
|
|
406
|
+
/>
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Best Practices
|
|
412
|
+
|
|
413
|
+
1. **Define base styles** for common patterns, then extend for variants
|
|
414
|
+
2. **Use selector mode** for global/body styles
|
|
415
|
+
3. **Enable devMode** in development for easier debugging
|
|
416
|
+
4. **Configure states** for consistent responsive breakpoints
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## Common Issues
|
|
421
|
+
|
|
422
|
+
- No CSS file is generated: make sure the Babel plugin actually runs for files importing `@tenphi/tasty/static`, and verify the `output` path is writable.
|
|
423
|
+
- Styles stay dynamic by mistake: `tastyStatic()` only supports build-time-known values. Move runtime values to CSS variables or switch that component to runtime `tasty()`.
|
|
424
|
+
- Turbopack config behaves inconsistently: prefer `configFile` over inline functions so the setup stays JSON-serializable.
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Related
|
|
429
|
+
|
|
430
|
+
- [Docs Hub](README.md) — Choose the right guide by task or rendering mode
|
|
431
|
+
- [Style DSL](dsl.md) — State maps, tokens, units, extending semantics (shared by runtime and static)
|
|
432
|
+
- [Runtime API](runtime.md) — Runtime styling: `tasty()` factory, component props, variants, sub-elements, hooks
|
|
433
|
+
- [Configuration](configuration.md) — Global configuration: tokens, recipes, custom units, and style handlers
|
package/package.json
CHANGED
|
@@ -1,52 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenphi/tasty",
|
|
3
|
-
"version": "0.0.0-snapshot.
|
|
3
|
+
"version": "0.0.0-snapshot.2705ab9",
|
|
4
4
|
"description": "A design-system-integrated styling system and DSL for concise, state-aware UI styling",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
6
9
|
"exports": {
|
|
7
10
|
".": {
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
12
14
|
},
|
|
13
15
|
"./static": {
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
16
|
+
"types": "./dist/static/index.d.ts",
|
|
17
|
+
"import": "./dist/static/index.js",
|
|
18
|
+
"default": "./dist/static/index.js"
|
|
18
19
|
},
|
|
19
20
|
"./babel-plugin": {
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
21
|
+
"types": "./dist/zero/babel.d.ts",
|
|
22
|
+
"import": "./dist/zero/babel.js",
|
|
23
|
+
"default": "./dist/zero/babel.js"
|
|
24
24
|
},
|
|
25
25
|
"./zero": {
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
26
|
+
"types": "./dist/zero/index.d.ts",
|
|
27
|
+
"import": "./dist/zero/index.js",
|
|
28
|
+
"default": "./dist/zero/index.js"
|
|
30
29
|
},
|
|
31
30
|
"./next": {
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
31
|
+
"types": "./dist/zero/next.d.ts",
|
|
32
|
+
"import": "./dist/zero/next.js",
|
|
33
|
+
"default": "./dist/zero/next.js"
|
|
36
34
|
},
|
|
37
35
|
"./core": {
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
"types": "./dist/core/index.d.ts",
|
|
37
|
+
"import": "./dist/core/index.js",
|
|
38
|
+
"default": "./dist/core/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./ssr": {
|
|
41
|
+
"types": "./dist/ssr/index.d.ts",
|
|
42
|
+
"import": "./dist/ssr/index.js",
|
|
43
|
+
"default": "./dist/ssr/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./ssr/next": {
|
|
46
|
+
"types": "./dist/ssr/next.d.ts",
|
|
47
|
+
"import": "./dist/ssr/next.js",
|
|
48
|
+
"default": "./dist/ssr/next.js"
|
|
49
|
+
},
|
|
50
|
+
"./ssr/astro": {
|
|
51
|
+
"types": "./dist/ssr/astro.d.ts",
|
|
52
|
+
"import": "./dist/ssr/astro.js",
|
|
53
|
+
"default": "./dist/ssr/astro.js"
|
|
42
54
|
},
|
|
43
55
|
"./tasty.config": "./tasty.config.ts"
|
|
44
56
|
},
|
|
45
57
|
"files": [
|
|
46
58
|
"dist",
|
|
59
|
+
"docs",
|
|
47
60
|
"tasty.config.ts"
|
|
48
61
|
],
|
|
49
|
-
"sideEffects":
|
|
62
|
+
"sideEffects": [
|
|
63
|
+
"./dist/ssr/index.js",
|
|
64
|
+
"./dist/ssr/next.js",
|
|
65
|
+
"./dist/ssr/astro.js"
|
|
66
|
+
],
|
|
50
67
|
"engines": {
|
|
51
68
|
"node": ">=20"
|
|
52
69
|
},
|
|
@@ -60,10 +77,14 @@
|
|
|
60
77
|
"lint:fix": "eslint src --fix",
|
|
61
78
|
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
62
79
|
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
80
|
+
"size": "size-limit",
|
|
81
|
+
"bench": "vitest bench",
|
|
63
82
|
"prepublishOnly": "pnpm run build",
|
|
64
83
|
"changeset": "changeset",
|
|
65
84
|
"version": "changeset version",
|
|
66
|
-
"release": "changeset publish"
|
|
85
|
+
"release": "changeset publish",
|
|
86
|
+
"hygiene": "pnpm lint && pnpm format:check && pnpm typecheck",
|
|
87
|
+
"hygiene:fix": "pnpm lint:fix && pnpm format && pnpm typecheck"
|
|
67
88
|
},
|
|
68
89
|
"repository": {
|
|
69
90
|
"type": "git",
|
|
@@ -90,6 +111,7 @@
|
|
|
90
111
|
"@babel/core": "^7.24.0",
|
|
91
112
|
"@babel/helper-plugin-utils": "^7.24.0",
|
|
92
113
|
"@babel/types": "^7.24.0",
|
|
114
|
+
"jiti": "^2.6.1",
|
|
93
115
|
"react": "^18.0.0 || ^19.0.0"
|
|
94
116
|
},
|
|
95
117
|
"peerDependenciesMeta": {
|
|
@@ -104,6 +126,9 @@
|
|
|
104
126
|
},
|
|
105
127
|
"react": {
|
|
106
128
|
"optional": true
|
|
129
|
+
},
|
|
130
|
+
"jiti": {
|
|
131
|
+
"optional": true
|
|
107
132
|
}
|
|
108
133
|
},
|
|
109
134
|
"dependencies": {
|
|
@@ -114,6 +139,8 @@
|
|
|
114
139
|
"@changesets/changelog-github": "^0.5.2",
|
|
115
140
|
"@changesets/cli": "^2.29.8",
|
|
116
141
|
"@eslint/js": "^10.0.1",
|
|
142
|
+
"@size-limit/esbuild": "^12.0.0",
|
|
143
|
+
"@size-limit/file": "^12.0.0",
|
|
117
144
|
"@testing-library/jest-dom": "^6.9.1",
|
|
118
145
|
"@testing-library/react": "^16.3.2",
|
|
119
146
|
"@types/babel__core": "^7.20.5",
|
|
@@ -126,6 +153,7 @@
|
|
|
126
153
|
"jsdom": "^28.1.0",
|
|
127
154
|
"prettier": "^3.8.1",
|
|
128
155
|
"react": "^19.0.0",
|
|
156
|
+
"size-limit": "^12.0.0",
|
|
129
157
|
"tsdown": "^0.20.3",
|
|
130
158
|
"typescript": "^5.9.3",
|
|
131
159
|
"typescript-eslint": "^8.56.0",
|
|
@@ -136,5 +164,47 @@
|
|
|
136
164
|
"esbuild"
|
|
137
165
|
]
|
|
138
166
|
},
|
|
139
|
-
"packageManager": "pnpm@10.
|
|
167
|
+
"packageManager": "pnpm@10.32.1",
|
|
168
|
+
"size-limit": [
|
|
169
|
+
{
|
|
170
|
+
"name": "main (import *)",
|
|
171
|
+
"path": "dist/index.js",
|
|
172
|
+
"import": "*",
|
|
173
|
+
"limit": "47 kB"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "core (import *)",
|
|
177
|
+
"path": "dist/core/index.js",
|
|
178
|
+
"import": "*",
|
|
179
|
+
"limit": "45 kB"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "static",
|
|
183
|
+
"path": "dist/static/index.js",
|
|
184
|
+
"import": "*",
|
|
185
|
+
"limit": "2 kB"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"name": "zero",
|
|
189
|
+
"path": "dist/zero/index.js",
|
|
190
|
+
"import": "*",
|
|
191
|
+
"ignore": [
|
|
192
|
+
"fs",
|
|
193
|
+
"path",
|
|
194
|
+
"crypto"
|
|
195
|
+
],
|
|
196
|
+
"limit": "28 kB"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"name": "babel-plugin",
|
|
200
|
+
"path": "dist/zero/babel.js",
|
|
201
|
+
"import": "*",
|
|
202
|
+
"ignore": [
|
|
203
|
+
"fs",
|
|
204
|
+
"path",
|
|
205
|
+
"crypto"
|
|
206
|
+
],
|
|
207
|
+
"limit": "40 kB"
|
|
208
|
+
}
|
|
209
|
+
]
|
|
140
210
|
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
//#region src/styles/styledScrollbar.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* @deprecated `styledScrollbar` is deprecated. Use `scrollbar` instead.
|
|
4
|
-
*/
|
|
5
|
-
declare function styledScrollbarStyle({
|
|
6
|
-
styledScrollbar: val
|
|
7
|
-
}: {
|
|
8
|
-
styledScrollbar: any;
|
|
9
|
-
}): ({
|
|
10
|
-
$: string;
|
|
11
|
-
display: string;
|
|
12
|
-
'scrollbar-width'?: undefined;
|
|
13
|
-
} | {
|
|
14
|
-
'scrollbar-width': string;
|
|
15
|
-
$?: undefined;
|
|
16
|
-
display?: undefined;
|
|
17
|
-
})[] | ({
|
|
18
|
-
$: string;
|
|
19
|
-
width: string;
|
|
20
|
-
height: string;
|
|
21
|
-
'background-color'?: undefined;
|
|
22
|
-
'border-radius'?: undefined;
|
|
23
|
-
border?: undefined;
|
|
24
|
-
'background-clip'?: undefined;
|
|
25
|
-
} | {
|
|
26
|
-
$: string;
|
|
27
|
-
'background-color': string;
|
|
28
|
-
width?: undefined;
|
|
29
|
-
height?: undefined;
|
|
30
|
-
'border-radius'?: undefined;
|
|
31
|
-
border?: undefined;
|
|
32
|
-
'background-clip'?: undefined;
|
|
33
|
-
} | {
|
|
34
|
-
$: string;
|
|
35
|
-
'background-color': string;
|
|
36
|
-
'border-radius': string;
|
|
37
|
-
border: string;
|
|
38
|
-
'background-clip': string;
|
|
39
|
-
width?: undefined;
|
|
40
|
-
height?: undefined;
|
|
41
|
-
})[] | null;
|
|
42
|
-
declare namespace styledScrollbarStyle {
|
|
43
|
-
var __lookupStyles: string[];
|
|
44
|
-
}
|
|
45
|
-
//#endregion
|
|
46
|
-
export { styledScrollbarStyle };
|
|
47
|
-
//# sourceMappingURL=styledScrollbar.d.ts.map
|