@tenphi/tasty 3.11.0 → 3.11.1

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.
@@ -19,22 +19,25 @@ If the styles depend on props, keep `tasty()`: rendered only on the server, it a
19
19
 
20
20
  Build-time extraction is part of the main `@tenphi/tasty` package but requires additional peer dependencies depending on your setup:
21
21
 
22
- | Dependency | Version | Required for |
23
- | ---------------------------- | ------- | ------------------------------------------------------------------------------ |
24
- | `@babel/core` | >= 7.24 | Babel plugin (`@tenphi/tasty/babel-plugin`) |
25
- | `@babel/helper-plugin-utils` | >= 7.24 | Babel plugin |
26
- | `@babel/types` | >= 7.24 | Babel plugin |
27
- | `jiti` | >= 2.6 | Babel plugin and Next.js wrapper (imported on load, even without `configFile`) |
28
- | `babel-loader` | any | Next.js wrapper (`@tenphi/tasty/zero/next`) |
22
+ | Dependency | Version | Required for |
23
+ | ---------------------------- | ------- | ---------------------------------------------------- |
24
+ | `@babel/core` | >= 7.24 | Babel plugin (`@tenphi/tasty/babel-plugin`) |
25
+ | `@babel/helper-plugin-utils` | >= 7.24 | Babel plugin |
26
+ | `@babel/types` | >= 7.24 | Babel plugin |
27
+ | `jiti` | >= 2.6 | `configFile` only (Babel plugin and Next.js wrapper) |
28
+ | `babel-loader` | any | Next.js wrapper (`@tenphi/tasty/zero/next`) |
29
29
 
30
- The Babel packages and `jiti` are optional peer dependencies of `@tenphi/tasty`; `babel-loader` is resolved from your project. Install what your setup requires:
30
+ The Babel packages and `jiti` are optional peer dependencies of `@tenphi/tasty`; `babel-loader` is resolved from your project. `jiti` is loaded only to read a `configFile`, so a setup that passes `config` directly does not need it; without it, `configFile` fails with an error that says to install it. Install what your setup requires:
31
31
 
32
32
  ```bash
33
33
  # Any Babel-based setup (Vite, custom Babel config, etc.)
34
- pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types jiti
34
+ pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types
35
35
 
36
36
  # Next.js
37
- pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types jiti babel-loader
37
+ pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types babel-loader
38
+
39
+ # Either, with configFile
40
+ pnpm add -D jiti
38
41
  ```
39
42
 
40
43
  ---
@@ -173,7 +176,7 @@ module.exports = {
173
176
  | -------------------------- | ------------------------------------------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
174
177
  | `output` | `string` | `'tasty.css'` | Path for generated CSS file |
175
178
  | `mode` | `'file' \| 'inject'` | `'file'` | `'file'` writes CSS to disk; `'inject'` embeds CSS inline in JS (see [Inject Mode](#inject-mode)) |
176
- | `configFile` | `string` | — | Absolute path to a TS/JS module that default-exports a `TastyZeroConfig` object. JSON-serializable alternative to `config` — required for Turbopack. |
179
+ | `configFile` | `string` | — | Absolute path to a TS/JS module that default-exports a `TastyZeroConfig` object. JSON-serializable alternative to `config` — required for Turbopack. Loaded with the optional `jiti` peer. |
177
180
  | `config` | `TastyZeroConfig \| () => TastyZeroConfig` | `{}` | Inline config object or factory function. Takes precedence over `configFile`. |
178
181
  | `configDeps` | `string[]` | `[]` | Absolute file paths that affect config (for cache invalidation) |
179
182
  | `injectImport` | `boolean` | `true` | Replace `@tenphi/tasty/static` imports with an import of the generated CSS file. Set to `false` to manage CSS imports manually. |
@@ -185,7 +188,8 @@ module.exports = {
185
188
  | `config.keyframes` | `Record<string, KeyframesSteps>` | — | Global `@keyframes` definitions available to all `tastyStatic` calls |
186
189
  | `config.fontFaces` | `Record<string, FontFaceInput>` | — | Global `@font-face` definitions |
187
190
  | `config.counterStyles` | `Record<string, CounterStyleDescriptors>` | — | Global `@counter-style` definitions |
188
- | `config.units` | `Record<string, string \| UnitHandler>` | — | Custom units for the style parser (merged with built-ins). E.g. `{ em: 'em', vw: 'vw' }` |
191
+ | `config.properties` | `Record<string, PropertyDefinition>` | — | Global `@property` definitions, written with Tasty's [default properties](dsl.md#default-properties) |
192
+ | `config.units` | `Record<string, string \| UnitHandler>` | — | Custom units for the style parser (merged with built-ins). E.g. `{ u: 'var(--u)' }` makes `2u` compile to `calc(2 * var(--u))`. Native CSS units need no entry |
189
193
  | `config.functions` | `Record<string, FunctionDefinition \| Function>` | — | Custom functions (merged). Bare keys → parse functions; `$$name` keys → declarative CSS `@function` definitions |
190
194
  | `config.polyfills` | `{ functions?: boolean }` | `{}` | Opt-in polyfills. `functions: true` inlines `@function` calls into plain CSS at build time |
191
195
  | `config.plugins` | `TastyPlugin[]` | — | Plugins that extend tasty with custom functions, units, states, and handlers |
@@ -286,7 +290,7 @@ export default withTastyZero({
286
290
 
287
291
  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.
288
292
 
289
- 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.
293
+ 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`, which must be installed.
290
294
 
291
295
  **Requirements**: `babel-loader` must be installed in your project (see [Requirements](#requirements)):
292
296
 
@@ -331,7 +335,7 @@ extractStylesWithChunks({ display: 'flex', gap: '1u' });
331
335
 
332
336
  `configure()` takes the same options as the Babel plugin's `config` (see [Plugin Options](#plugin-options)) and replaces the previous configuration on each call; `resetConfig()` returns to the defaults. Options that shape the extracted rules apply — `states`, `units`, parse `functions`, `handlers`, `replaceTokens`, `recipes`, `plugins`, `namePrefix`. Definitions that become at-rules or global CSS of their own are not emitted with the rules: `tokens`, `globalStyles`, `fontFaces`, `counterStyles`, `properties` and `$$` `@function` definitions. Render tokens and global styles with `extractStylesForSelector(':root', tokens)` and `extractStylesForSelector(selector, styles)`.
333
337
 
334
- `extractConfigProperties()` returns the `@property` rules the Babel plugin writes at the top of its output: Tasty's default set (`#border`, `#outline`, `$gap`, `$radius`, `$transition`, …) overlaid with the configured `properties`. Emit them once per stylesheet. Style handlers read several of these tokens with no fallback of their own (`border: true` reads `#border`, `transition` reads `$transition`), so without them those declarations resolve to nothing.
338
+ `extractConfigProperties()` returns the `@property` rules the Babel plugin writes at the top of its output: Tasty's [default set](dsl.md#default-properties) (`#border`, `#outline`, `$gap`, `$radius`, `$transition`, …) overlaid with the configured `properties`, or with the `properties` map you pass it. Emit them once per stylesheet. Style handlers read several of these tokens with no fallback of their own (`border: true` reads `#border`, `transition` reads `$transition`), so without them those declarations resolve to nothing.
335
339
 
336
340
  The configuration is process-wide and shared with the Babel plugin and the runtime `configure()` from `@tenphi/tasty`. The extractors re-apply their own configuration when the Babel plugin replaced it, but not after a runtime `configure()` — don't mix the runtime and build-time configuration in one process.
337
341
 
@@ -438,13 +442,19 @@ The `@tenphi/tasty/static` import becomes an import of the generated file (relat
438
442
  ```css
439
443
  /* Generated by @tenphi/tasty/zero - DO NOT EDIT */
440
444
 
445
+ @property --tasty-second-fill-color {
446
+ syntax: '<color>';
447
+ inherits: false;
448
+ initial-value: transparent;
449
+ }
450
+
441
451
  @property --current-color {
442
452
  syntax: '<color>';
443
453
  inherits: true;
444
454
  initial-value: currentcolor;
445
455
  }
446
456
 
447
- /* …the rest of Tasty's default @property rules (--gap, --radius, --white-color, …) */
457
+ /* …the rest of Tasty's default @property rules (--white-color, --border-color, --gap, --transition, …), then config.properties */
448
458
 
449
459
  .ts3f783b.ts3f783b {
450
460
  color: var(--white-color);
@@ -465,7 +475,7 @@ The `@tenphi/tasty/static` import becomes an import of the generated file (relat
465
475
  }
466
476
  ```
467
477
 
468
- Styles are split into chunks (here appearance and spacing), each with its own class. Color tokens compile to custom properties: `#purple` becomes `var(--purple-color)`. Define it in `config.tokens` and the plugin writes it to `:root` at the top of the same file. Units are literal (`2x` is `16px`). Selector-mode rules use the selector as written, without the doubled specificity of class rules.
478
+ The file starts with Tasty's [default `@property` rules](dsl.md#default-properties) and your `config.properties`, written once. Styles are split into chunks (here appearance and spacing), each with its own class. Color tokens compile to custom properties: `#purple` becomes `var(--purple-color)`. Define it in `config.tokens` and the plugin writes it to `:root` at the top of the same file. Units are literal (`2x` is `16px`). Selector-mode rules use the selector as written, without the doubled specificity of class rules.
469
479
 
470
480
  ---
471
481
 
@@ -537,6 +547,11 @@ tastyStatic('.heading', { preset: 'h1' });
537
547
  ```tsx
538
548
  import { injectCSS as _$i } from '@tenphi/tasty/static/inject';
539
549
 
550
+ _$i(
551
+ '@property',
552
+ '@property --tasty-second-fill-color { … }\n@property --current-color { … }\n…',
553
+ );
554
+
540
555
  const button =
541
556
  (_$i(
542
557
  'tsa903d6 ts070801',
@@ -553,6 +568,8 @@ const button =
553
568
  _$i('.heading', '.heading { font-size: var(--h1-font-size, …); … }');
554
569
  ```
555
570
 
571
+ Each file that calls `tastyStatic()` starts by injecting Tasty's default `@property` rules and your `config.properties` under the `@property` id. `injectCSS()` skips an id it has already injected, so the page gets them once.
572
+
556
573
  ### Dev Mode / HMR
557
574
 
558
575
  Class names are content-hashed (`ts` + MD5). When styles change, a new hash produces a new `_$i` call that injects fresh CSS. The injector deduplicates by id, so unchanged styles are skipped. Old CSS stays in the DOM but is harmless since no elements reference those class names.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/tasty",
3
- "version": "3.11.0",
3
+ "version": "3.11.1",
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",