@tenphi/cookbook 0.28.0 → 0.30.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 +13 -11
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/docs/ai-agents.md +5 -3
- package/docs/architecture.md +10 -7
- package/docs/authoring.mdx +94 -36
- package/docs/cli.md +92 -33
- package/docs/component-styles.md +286 -282
- package/docs/configuration.md +232 -153
- package/docs/content-sources.md +39 -21
- package/docs/custom-components.md +117 -169
- package/docs/customization-rules.md +23 -14
- package/docs/deployment.md +101 -53
- package/docs/es/getting-started.md +7 -5
- package/docs/es/index.md +1 -1
- package/docs/examples.md +65 -28
- package/docs/fonts-and-typography.md +32 -27
- package/docs/getting-started.md +17 -10
- package/docs/ja/getting-started.md +7 -5
- package/docs/ja/index.md +1 -1
- package/docs/migration.md +188 -65
- package/docs/plugins.md +28 -16
- package/docs/publishing.md +3 -2
- package/docs/quality-checks.md +18 -42
- package/docs/recipes.md +38 -54
- package/docs/ru/getting-started.md +7 -5
- package/docs/ru/index.md +1 -1
- package/docs/site-navigation.md +47 -47
- package/docs/theme-and-components.md +126 -59
- package/docs/troubleshooting.md +4 -3
- package/docs/upstream/manifest.json +2 -2
- package/docs/upstream/tasty/README.md +404 -381
- package/docs/upstream/tasty/docs/README.md +4 -1
- package/docs/upstream/tasty/docs/adoption.md +25 -17
- package/docs/upstream/tasty/docs/ai-agents.md +42 -34
- package/docs/upstream/tasty/docs/comparison.md +9 -8
- package/docs/upstream/tasty/docs/configuration.md +187 -69
- package/docs/upstream/tasty/docs/debug.md +3 -2
- package/docs/upstream/tasty/docs/design-system.md +117 -15
- package/docs/upstream/tasty/docs/dsl.md +211 -117
- package/docs/upstream/tasty/docs/getting-started.md +81 -24
- package/docs/upstream/tasty/docs/injector.md +41 -40
- package/docs/upstream/tasty/docs/methodology.md +46 -21
- package/docs/upstream/tasty/docs/migration-v3.md +3 -3
- package/docs/upstream/tasty/docs/pipeline.md +111 -116
- package/docs/upstream/tasty/docs/plugins.md +21 -41
- package/docs/upstream/tasty/docs/react-api.md +73 -10
- package/docs/upstream/tasty/docs/runtime-benchmarks.md +46 -46
- package/docs/upstream/tasty/docs/ssr.md +92 -66
- package/docs/upstream/tasty/docs/styles.md +37 -17
- package/docs/upstream/tasty/docs/tasty-static.md +175 -57
- package/docs/zh/getting-started.md +7 -5
- package/docs/zh/index.md +1 -1
- package/package.json +3 -3
|
@@ -8,30 +8,38 @@ Choose `tastyStatic` specifically when styles must be generated during the build
|
|
|
8
8
|
|
|
9
9
|
## When to Use
|
|
10
10
|
|
|
11
|
-
- **
|
|
12
|
-
- **No
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
11
|
+
- **CSS that must exist before anything renders** — static sites, landing pages, and HTML served from a CDN get one stylesheet generated at build time
|
|
12
|
+
- **No React at runtime** — `tastyStatic` returns class names, so plain DOM code or any templating that sets `class` can use them; the [Programmatic API](#programmatic-api) covers frameworks Babel does not process
|
|
13
|
+
- **Class-name objects instead of components** — extend them with `tastyStatic(base, styles)` and pass them wherever a `className` goes
|
|
14
|
+
- **Self-contained packages** — [inject mode](#inject-mode) embeds the CSS in the JavaScript, so consumers have no stylesheet to wire up
|
|
15
|
+
|
|
16
|
+
If the styles depend on props, keep `tasty()`: rendered only on the server, it also ships no styling runtime (see [Server-Side Rendering](ssr.md)).
|
|
15
17
|
|
|
16
18
|
## Requirements
|
|
17
19
|
|
|
18
20
|
Build-time extraction is part of the main `@tenphi/tasty` package but requires additional peer dependencies depending on your setup:
|
|
19
21
|
|
|
20
|
-
| Dependency | Version
|
|
21
|
-
| ---------------------------- |
|
|
22
|
-
| `@babel/core` |
|
|
23
|
-
| `@babel/helper-plugin-utils` |
|
|
24
|
-
| `@babel/types` |
|
|
25
|
-
| `jiti` | >= 2.6
|
|
22
|
+
| Dependency | Version | Required for |
|
|
23
|
+
| ---------------------------- | ---------------------- | ---------------------------------------------------- |
|
|
24
|
+
| `@babel/core` | 7.24+ or 8 | Babel plugin (`@tenphi/tasty/babel-plugin`) |
|
|
25
|
+
| `@babel/helper-plugin-utils` | 7.24+ or 8 | Babel plugin |
|
|
26
|
+
| `@babel/types` | 7.24+ or 8 | Babel plugin |
|
|
27
|
+
| `jiti` | >= 2.6 | `configFile` only (Babel plugin and Next.js wrapper) |
|
|
28
|
+
| `babel-loader` | any (10+ with Babel 8) | Next.js wrapper (`@tenphi/tasty/zero/next`) |
|
|
29
|
+
|
|
30
|
+
Install the three Babel packages from the same major. Babel 8 itself needs Node 22.18+ or 24.11+, and `babel-loader` accepts it from version 10.
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
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:
|
|
28
33
|
|
|
29
34
|
```bash
|
|
30
|
-
#
|
|
35
|
+
# Any Babel-based setup (Vite, custom Babel config, etc.)
|
|
31
36
|
pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types
|
|
32
37
|
|
|
33
|
-
#
|
|
34
|
-
pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types
|
|
38
|
+
# Next.js
|
|
39
|
+
pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types babel-loader
|
|
40
|
+
|
|
41
|
+
# Either, with configFile
|
|
42
|
+
pnpm add -D jiti
|
|
35
43
|
```
|
|
36
44
|
|
|
37
45
|
---
|
|
@@ -52,13 +60,15 @@ const button = tastyStatic({
|
|
|
52
60
|
radius: '1r',
|
|
53
61
|
});
|
|
54
62
|
|
|
55
|
-
// Use in JSX
|
|
56
|
-
<button className={button}>Click me</button
|
|
63
|
+
// Use in JSX
|
|
64
|
+
<button className={button.className}>Click me</button>;
|
|
57
65
|
|
|
58
|
-
//
|
|
59
|
-
|
|
66
|
+
// toString() returns the class name, for template strings and plain JS
|
|
67
|
+
element.className = `${button} is-active`;
|
|
60
68
|
```
|
|
61
69
|
|
|
70
|
+
In TSX, pass `button.className`: React types `className` as `string`, so passing the `StaticStyle` object fails type-checking even though it works at runtime.
|
|
71
|
+
|
|
62
72
|
---
|
|
63
73
|
|
|
64
74
|
## API Reference
|
|
@@ -105,6 +115,8 @@ tastyStatic('body', {
|
|
|
105
115
|
});
|
|
106
116
|
```
|
|
107
117
|
|
|
118
|
+
The selector can be a list (`'.uni-checkbox, uni-checkbox'`): every item gets the states and sub-elements. Local `@keyframes` and `@starting` states work as in `tastyStatic(styles)`.
|
|
119
|
+
|
|
108
120
|
---
|
|
109
121
|
|
|
110
122
|
## StaticStyle Object
|
|
@@ -166,7 +178,7 @@ module.exports = {
|
|
|
166
178
|
| -------------------------- | ------------------------------------------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
167
179
|
| `output` | `string` | `'tasty.css'` | Path for generated CSS file |
|
|
168
180
|
| `mode` | `'file' \| 'inject'` | `'file'` | `'file'` writes CSS to disk; `'inject'` embeds CSS inline in JS (see [Inject Mode](#inject-mode)) |
|
|
169
|
-
| `configFile` | `string` | — | Absolute path to a TS/JS module that default-exports a `TastyZeroConfig` object. JSON-serializable alternative to `config` — required for Turbopack.
|
|
181
|
+
| `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. |
|
|
170
182
|
| `config` | `TastyZeroConfig \| () => TastyZeroConfig` | `{}` | Inline config object or factory function. Takes precedence over `configFile`. |
|
|
171
183
|
| `configDeps` | `string[]` | `[]` | Absolute file paths that affect config (for cache invalidation) |
|
|
172
184
|
| `injectImport` | `boolean` | `true` | Replace `@tenphi/tasty/static` imports with an import of the generated CSS file. Set to `false` to manage CSS imports manually. |
|
|
@@ -178,7 +190,8 @@ module.exports = {
|
|
|
178
190
|
| `config.keyframes` | `Record<string, KeyframesSteps>` | — | Global `@keyframes` definitions available to all `tastyStatic` calls |
|
|
179
191
|
| `config.fontFaces` | `Record<string, FontFaceInput>` | — | Global `@font-face` definitions |
|
|
180
192
|
| `config.counterStyles` | `Record<string, CounterStyleDescriptors>` | — | Global `@counter-style` definitions |
|
|
181
|
-
| `config.
|
|
193
|
+
| `config.properties` | `Record<string, PropertyDefinition>` | — | Global `@property` definitions, written with Tasty's [default properties](dsl.md#default-properties) |
|
|
194
|
+
| `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 |
|
|
182
195
|
| `config.functions` | `Record<string, FunctionDefinition \| Function>` | — | Custom functions (merged). Bare keys → parse functions; `$$name` keys → declarative CSS `@function` definitions |
|
|
183
196
|
| `config.polyfills` | `{ functions?: boolean }` | `{}` | Opt-in polyfills. `functions: true` inlines `@function` calls into plain CSS at build time |
|
|
184
197
|
| `config.plugins` | `TastyPlugin[]` | — | Plugins that extend tasty with custom functions, units, states, and handlers |
|
|
@@ -242,7 +255,7 @@ const card = tastyStatic({
|
|
|
242
255
|
color: '#text',
|
|
243
256
|
});
|
|
244
257
|
|
|
245
|
-
<div className={card}>Styled card</div>;
|
|
258
|
+
<div className={card.className}>Styled card</div>;
|
|
246
259
|
```
|
|
247
260
|
|
|
248
261
|
---
|
|
@@ -279,12 +292,12 @@ export default withTastyZero({
|
|
|
279
292
|
|
|
280
293
|
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.
|
|
281
294
|
|
|
282
|
-
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.
|
|
295
|
+
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.
|
|
283
296
|
|
|
284
|
-
**Requirements**: `babel-loader` must be installed in your project:
|
|
297
|
+
**Requirements**: `babel-loader` must be installed in your project (see [Requirements](#requirements)):
|
|
285
298
|
|
|
286
299
|
```bash
|
|
287
|
-
pnpm add babel-loader
|
|
300
|
+
pnpm add -D babel-loader
|
|
288
301
|
```
|
|
289
302
|
|
|
290
303
|
### CSS Injection
|
|
@@ -299,34 +312,107 @@ public/tasty.css
|
|
|
299
312
|
|
|
300
313
|
---
|
|
301
314
|
|
|
315
|
+
## Programmatic API
|
|
316
|
+
|
|
317
|
+
`@tenphi/tasty/zero` turns styles into CSS in Node without Babel or React — for build scripts, or CSS shipped to other frameworks:
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
import {
|
|
321
|
+
configure,
|
|
322
|
+
extractStylesForSelector,
|
|
323
|
+
extractStylesWithChunks,
|
|
324
|
+
} from '@tenphi/tasty/zero';
|
|
325
|
+
|
|
326
|
+
configure({
|
|
327
|
+
units: { u: 'var(--unit)' },
|
|
328
|
+
states: { '@dark': '@root(schema=dark)' },
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
extractStylesForSelector('.card', { padding: '2u', fill: '#surface' }).css;
|
|
332
|
+
// → '.card { padding: calc(2 * var(--unit)); background-color: … }'
|
|
333
|
+
|
|
334
|
+
extractStylesWithChunks({ display: 'flex', gap: '1u' });
|
|
335
|
+
// → [{ className: 'ts…', css: '.ts….ts… { … }' }]
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
`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)`.
|
|
339
|
+
|
|
340
|
+
`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.
|
|
341
|
+
|
|
342
|
+
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.
|
|
343
|
+
|
|
344
|
+
`extractStylesForSelector()` output starts with the `@keyframes` its rules animate — local `@keyframes` and configured `keyframes` — under hashed names the `animation` declarations are rewritten to. `extractStylesWithChunks()` returns class rules only.
|
|
345
|
+
|
|
346
|
+
`mergeStyles()` merges style objects with the rules `tasty(Base, { styles })` extends by — state maps with and without a `''` key, `null`, `false`, `'@inherit'` and sub-elements (see [Extending vs. Replacing State Maps](dsl.md#extending-vs-replacing-state-maps)) — so a build script can layer overrides onto source styles before extracting them, without React:
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
import { extractStylesForSelector, mergeStyles } from '@tenphi/tasty/zero';
|
|
350
|
+
|
|
351
|
+
const styles = mergeStyles(checkboxStyles, {
|
|
352
|
+
Indicator: { radius: '0.5r' },
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
extractStylesForSelector('.checkbox', styles).css;
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
To write the results to a file the way the Babel plugin does, use `createCSSWriter()`. It deduplicates blocks by key and prepends the generated-file header:
|
|
359
|
+
|
|
360
|
+
```ts
|
|
361
|
+
import {
|
|
362
|
+
createCSSWriter,
|
|
363
|
+
extractConfigProperties,
|
|
364
|
+
extractStylesWithChunks,
|
|
365
|
+
} from '@tenphi/tasty/zero';
|
|
366
|
+
|
|
367
|
+
const writer = createCSSWriter('dist/tasty.css', { devMode: true });
|
|
368
|
+
|
|
369
|
+
for (const prop of extractConfigProperties()) {
|
|
370
|
+
writer.add(`@property:${prop.name}`, prop.css);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
for (const chunk of extractStylesWithChunks({ display: 'flex', gap: '1u' })) {
|
|
374
|
+
writer.add(chunk.className, chunk.css, 'src/card.ts'); // source is a devMode comment
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
writer.write(); // also: has(key), getCSS(), clear(), getOutputPath()
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
302
382
|
## Vite Integration
|
|
303
383
|
|
|
384
|
+
`@vitejs/plugin-react` 6 no longer runs Babel; add it with `@rolldown/plugin-babel` (`pnpm add -D @rolldown/plugin-babel`):
|
|
385
|
+
|
|
304
386
|
```typescript
|
|
305
387
|
// vite.config.ts
|
|
306
388
|
import { defineConfig } from 'vite';
|
|
307
389
|
import react from '@vitejs/plugin-react';
|
|
390
|
+
import babel from '@rolldown/plugin-babel';
|
|
308
391
|
|
|
309
392
|
export default defineConfig({
|
|
310
393
|
plugins: [
|
|
311
|
-
react(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
},
|
|
394
|
+
react(),
|
|
395
|
+
babel({
|
|
396
|
+
plugins: [
|
|
397
|
+
[
|
|
398
|
+
'@tenphi/tasty/babel-plugin',
|
|
399
|
+
{
|
|
400
|
+
output: 'src/tasty.css',
|
|
401
|
+
config: {
|
|
402
|
+
states: { '@mobile': '@media(w < 768px)' },
|
|
321
403
|
},
|
|
322
|
-
|
|
404
|
+
},
|
|
323
405
|
],
|
|
324
|
-
|
|
406
|
+
],
|
|
325
407
|
}),
|
|
326
408
|
],
|
|
327
409
|
});
|
|
328
410
|
```
|
|
329
411
|
|
|
412
|
+
With `@vitejs/plugin-react` 5 or older, pass the same `plugins` array to `react({ babel: { plugins } })` instead.
|
|
413
|
+
|
|
414
|
+
Keep `output` outside `public/`: the plugin replaces each `@tenphi/tasty/static` import with an import of the generated file, and Vite does not let JavaScript import files from `public/`. Vite then bundles the CSS like any other stylesheet.
|
|
415
|
+
|
|
330
416
|
---
|
|
331
417
|
|
|
332
418
|
## Build Transformation
|
|
@@ -344,44 +430,67 @@ const button = tastyStatic({
|
|
|
344
430
|
|
|
345
431
|
tastyStatic('.heading', { preset: 'h1' });
|
|
346
432
|
|
|
347
|
-
export const Button = () => <button className={button}>Click</button>;
|
|
433
|
+
export const Button = () => <button className={button.className}>Click</button>;
|
|
348
434
|
```
|
|
349
435
|
|
|
350
436
|
### After (Production Build)
|
|
351
437
|
|
|
352
438
|
```tsx
|
|
439
|
+
import './tasty.css';
|
|
440
|
+
|
|
353
441
|
const button = {
|
|
354
|
-
className: '
|
|
442
|
+
className: 'ts3f783b ts070801',
|
|
355
443
|
styles: { padding: '2x 4x', fill: '#purple', color: '#white' },
|
|
356
444
|
toString() {
|
|
357
445
|
return this.className;
|
|
358
446
|
},
|
|
359
447
|
};
|
|
360
448
|
|
|
361
|
-
export const Button = () => <button className={button}>Click</button>;
|
|
449
|
+
export const Button = () => <button className={button.className}>Click</button>;
|
|
362
450
|
```
|
|
363
451
|
|
|
452
|
+
The `@tenphi/tasty/static` import becomes an import of the generated file (relative to the source file), and the selector-mode call is removed.
|
|
453
|
+
|
|
364
454
|
### Generated CSS (tasty.css)
|
|
365
455
|
|
|
366
456
|
```css
|
|
367
457
|
/* Generated by @tenphi/tasty/zero - DO NOT EDIT */
|
|
368
458
|
|
|
369
|
-
|
|
370
|
-
|
|
459
|
+
@property --tasty-second-fill-color {
|
|
460
|
+
syntax: '<color>';
|
|
461
|
+
inherits: false;
|
|
462
|
+
initial-value: transparent;
|
|
371
463
|
}
|
|
372
464
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
465
|
+
@property --current-color {
|
|
466
|
+
syntax: '<color>';
|
|
467
|
+
inherits: true;
|
|
468
|
+
initial-value: currentcolor;
|
|
376
469
|
}
|
|
377
470
|
|
|
378
|
-
.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
471
|
+
/* …the rest of Tasty's default @property rules (--white-color, --border-color, --gap, --transition, …), then config.properties */
|
|
472
|
+
|
|
473
|
+
.ts3f783b.ts3f783b {
|
|
474
|
+
color: var(--white-color);
|
|
475
|
+
--current-color: var(--white-color);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.ts3f783b.ts3f783b {
|
|
479
|
+
background-color: var(--purple-color);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
.ts070801.ts070801 {
|
|
483
|
+
padding: 16px 32px;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.heading {
|
|
487
|
+
font-size: var(--h1-font-size, var(--default-font-size));
|
|
488
|
+
/* …line-height, letter-spacing, font-weight, and the rest of the h1 preset */
|
|
382
489
|
}
|
|
383
490
|
```
|
|
384
491
|
|
|
492
|
+
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.
|
|
493
|
+
|
|
385
494
|
---
|
|
386
495
|
|
|
387
496
|
## Inject Mode
|
|
@@ -452,22 +561,29 @@ tastyStatic('.heading', { preset: 'h1' });
|
|
|
452
561
|
```tsx
|
|
453
562
|
import { injectCSS as _$i } from '@tenphi/tasty/static/inject';
|
|
454
563
|
|
|
564
|
+
_$i(
|
|
565
|
+
'@property',
|
|
566
|
+
'@property --tasty-second-fill-color { … }\n@property --current-color { … }\n…',
|
|
567
|
+
);
|
|
568
|
+
|
|
455
569
|
const button =
|
|
456
570
|
(_$i(
|
|
457
|
-
'
|
|
458
|
-
'.
|
|
571
|
+
'tsa903d6 ts070801',
|
|
572
|
+
'.tsa903d6.tsa903d6 { background-color: var(--purple-color); }\n.ts070801.ts070801 { padding: 16px 32px; }',
|
|
459
573
|
),
|
|
460
574
|
{
|
|
461
|
-
className: '
|
|
575
|
+
className: 'tsa903d6 ts070801',
|
|
462
576
|
styles: { padding: '2x 4x', fill: '#purple' },
|
|
463
577
|
toString() {
|
|
464
578
|
return this.className;
|
|
465
579
|
},
|
|
466
580
|
});
|
|
467
581
|
|
|
468
|
-
_$i('.heading', '.heading{font-size:
|
|
582
|
+
_$i('.heading', '.heading { font-size: var(--h1-font-size, …); … }');
|
|
469
583
|
```
|
|
470
584
|
|
|
585
|
+
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.
|
|
586
|
+
|
|
471
587
|
### Dev Mode / HMR
|
|
472
588
|
|
|
473
589
|
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.
|
|
@@ -525,7 +641,7 @@ const card = tastyStatic({
|
|
|
525
641
|
|
|
526
642
|
## Extending Style Types (TypeScript)
|
|
527
643
|
|
|
528
|
-
If you add custom style properties, use module augmentation so `tastyStatic` recognizes them too. See [
|
|
644
|
+
If you add custom style properties, use module augmentation so `tastyStatic` recognizes them too. See [TypeScript](configuration.md#typescript) in the configuration docs.
|
|
529
645
|
|
|
530
646
|
---
|
|
531
647
|
|
|
@@ -547,10 +663,12 @@ const card = tastyStatic({
|
|
|
547
663
|
});
|
|
548
664
|
|
|
549
665
|
<div
|
|
550
|
-
className={card}
|
|
551
|
-
style={
|
|
552
|
-
|
|
553
|
-
|
|
666
|
+
className={card.className}
|
|
667
|
+
style={
|
|
668
|
+
{
|
|
669
|
+
'--card-bg': isActive ? 'var(--purple-color)' : 'var(--white-color)',
|
|
670
|
+
} as React.CSSProperties
|
|
671
|
+
}
|
|
554
672
|
/>;
|
|
555
673
|
```
|
|
556
674
|
|
|
@@ -63,8 +63,6 @@ Cookbook 自带 Astro 渲染器,并会自动查找 `docs.config.ts`。如果
|
|
|
63
63
|
|
|
64
64
|
## 配置站点
|
|
65
65
|
|
|
66
|
-
可以先查看完整的[品牌、标志和字体示例](../recipes.md)。若要深入调整样式或添加组件,请阅读[自定义规则](../customization-rules.md)。这些规则和上游参考资料也包含在安装后的 Cookbook 包中。
|
|
67
|
-
|
|
68
66
|
在 `astro.config.ts` 旁创建 `docs.config.ts`:
|
|
69
67
|
|
|
70
68
|
```ts
|
|
@@ -83,9 +81,11 @@ export default defineDocsConfig({
|
|
|
83
81
|
});
|
|
84
82
|
```
|
|
85
83
|
|
|
86
|
-
修改 `theme.fonts` 可使用[按名称指定的 Google Fonts 或你自己的字体文件](../fonts-and-typography.md)。使用 `theme.presets` 调整排版细节,使用 `theme.styles` 调整内置元素,并结合 `defineComponent()` 与 `theme.customStyles` 添加新元素。[主题指南](../theme-and-components.md)介绍了起点;[组件样式参考](../component-styles.md)列出了全部可自定义部分。
|
|
84
|
+
修改 `theme.fonts` 可使用[按名称指定的 Google Fonts 或你自己的字体文件](../fonts-and-typography.md#change-font-families)。使用 `theme.presets` 调整排版细节,使用 `theme.styles` 调整内置元素,并结合 `defineComponent()` 与 `theme.customStyles` 添加新元素。[主题指南](../theme-and-components.md)介绍了起点;[组件样式参考](../component-styles.md)列出了全部可自定义部分。
|
|
85
|
+
|
|
86
|
+
完整的起点可参考[品牌、标志和字体示例](../recipes.md)。若要深入调整样式或添加组件,请阅读[自定义规则](../customization-rules.md)。这些规则和上游参考资料也包含在安装后的 Cookbook 包中。
|
|
87
87
|
|
|
88
|
-
集成和 CLI 读取同一份配置。支持的文件名依优先顺序为 `docs.config.ts`、`.mts`、`.js` 和 `.mjs`。在集成中显式传入的 `config` 对象优先;`configFile: false` 会关闭自动查找。若配置文件位于其他位置,可使用 `cookbook({ configFile: "./config/manual.ts" })` 和 `cookbook doctor --config ./config/manual.ts
|
|
88
|
+
集成和 CLI 读取同一份配置。支持的文件名依优先顺序为 `docs.config.ts`、`.mts`、`.js` 和 `.mjs`。在集成中显式传入的 `config` 对象优先;`configFile: false` 会关闭自动查找。若配置文件位于其他位置,可使用 `cookbook({ configFile: "./config/manual.ts" })` 和 `cookbook doctor --config ./config/manual.ts`。由于 `root` 相对于配置文件所在目录解析,该文件需要设置 `root: ".."`,才能继续从应用目录读取 `README.md` 和 `docs/`。
|
|
89
89
|
|
|
90
90
|
## 单体仓库的根目录
|
|
91
91
|
|
|
@@ -106,4 +106,6 @@ npm run validate
|
|
|
106
106
|
npm run preview
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
`validate` 会对项目进行类型检查、运行 Cookbook 预检、构建站点并检查输出。对于自行配置的项目,请添加 [CLI 命令](../cli.md)中列出的脚本,或运行 `npx @tenphi/cookbook doctor`。
|
|
110
|
+
|
|
111
|
+
其他指南目前仍以英文提供,包括[示例](../examples.md)、[内容编写组件](../authoring.mdx)、[AI 智能体工作流程](../ai-agents.md)、[部署](../deployment.md)和[按版本升级指南](../migration.md)。如果验证失败,请查看[故障排查](../troubleshooting.md)。
|
package/docs/zh/index.md
CHANGED
|
@@ -42,7 +42,7 @@ cd docs-site
|
|
|
42
42
|
npm run dev
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Cookbook 会直接读取原位置的文件。你也可以[创建新站点](./getting-started.md)、[为实际发布到 npm 的文件编写文档](./getting-started.md),或[将 Cookbook 加入现有 Astro 项目](./getting-started.md)。
|
|
45
|
+
Cookbook 会直接读取原位置的文件。你也可以[创建新站点](./getting-started.md#创建第一个站点)、[为实际发布到 npm 的文件编写文档](./getting-started.md#为已发布的-npm-包编写文档),或[将 Cookbook 加入现有 Astro 项目](./getting-started.md#加入现有-astro-项目)。
|
|
46
46
|
|
|
47
47
|
## 本站就是一个示例
|
|
48
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenphi/cookbook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "Repository-native static documentation for Astro",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"author": "Andrey Yamanov",
|
|
69
69
|
"license": "MIT",
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@tenphi/docs": "0.
|
|
72
|
-
"@tenphi/renderer": "0.
|
|
71
|
+
"@tenphi/docs": "0.30.0",
|
|
72
|
+
"@tenphi/renderer": "0.30.0"
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
75
|
"astro": "^7.3.2"
|