@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.
Files changed (54) hide show
  1. package/README.md +13 -11
  2. package/dist/index.d.ts +2 -2
  3. package/dist/index.js +2 -2
  4. package/docs/ai-agents.md +5 -3
  5. package/docs/architecture.md +10 -7
  6. package/docs/authoring.mdx +94 -36
  7. package/docs/cli.md +92 -33
  8. package/docs/component-styles.md +286 -282
  9. package/docs/configuration.md +232 -153
  10. package/docs/content-sources.md +39 -21
  11. package/docs/custom-components.md +117 -169
  12. package/docs/customization-rules.md +23 -14
  13. package/docs/deployment.md +101 -53
  14. package/docs/es/getting-started.md +7 -5
  15. package/docs/es/index.md +1 -1
  16. package/docs/examples.md +65 -28
  17. package/docs/fonts-and-typography.md +32 -27
  18. package/docs/getting-started.md +17 -10
  19. package/docs/ja/getting-started.md +7 -5
  20. package/docs/ja/index.md +1 -1
  21. package/docs/migration.md +188 -65
  22. package/docs/plugins.md +28 -16
  23. package/docs/publishing.md +3 -2
  24. package/docs/quality-checks.md +18 -42
  25. package/docs/recipes.md +38 -54
  26. package/docs/ru/getting-started.md +7 -5
  27. package/docs/ru/index.md +1 -1
  28. package/docs/site-navigation.md +47 -47
  29. package/docs/theme-and-components.md +126 -59
  30. package/docs/troubleshooting.md +4 -3
  31. package/docs/upstream/manifest.json +2 -2
  32. package/docs/upstream/tasty/README.md +404 -381
  33. package/docs/upstream/tasty/docs/README.md +4 -1
  34. package/docs/upstream/tasty/docs/adoption.md +25 -17
  35. package/docs/upstream/tasty/docs/ai-agents.md +42 -34
  36. package/docs/upstream/tasty/docs/comparison.md +9 -8
  37. package/docs/upstream/tasty/docs/configuration.md +187 -69
  38. package/docs/upstream/tasty/docs/debug.md +3 -2
  39. package/docs/upstream/tasty/docs/design-system.md +117 -15
  40. package/docs/upstream/tasty/docs/dsl.md +211 -117
  41. package/docs/upstream/tasty/docs/getting-started.md +81 -24
  42. package/docs/upstream/tasty/docs/injector.md +41 -40
  43. package/docs/upstream/tasty/docs/methodology.md +46 -21
  44. package/docs/upstream/tasty/docs/migration-v3.md +3 -3
  45. package/docs/upstream/tasty/docs/pipeline.md +111 -116
  46. package/docs/upstream/tasty/docs/plugins.md +21 -41
  47. package/docs/upstream/tasty/docs/react-api.md +73 -10
  48. package/docs/upstream/tasty/docs/runtime-benchmarks.md +46 -46
  49. package/docs/upstream/tasty/docs/ssr.md +92 -66
  50. package/docs/upstream/tasty/docs/styles.md +37 -17
  51. package/docs/upstream/tasty/docs/tasty-static.md +175 -57
  52. package/docs/zh/getting-started.md +7 -5
  53. package/docs/zh/index.md +1 -1
  54. 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
- - **Static site generation (SSG)** — Pre-render all styles at build time
12
- - **No-JavaScript websites** — CSS works without any JS runtime
13
- - **Performance-critical pages** — CSS extracted before the application renders
14
- - **Landing pages** — Minimal bundle size with pre-generated CSS
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 | Required for |
21
- | ---------------------------- | ------- | -------------------------------------------------------------------------- |
22
- | `@babel/core` | >= 7.24 | Babel plugin (`@tenphi/tasty/babel-plugin`) |
23
- | `@babel/helper-plugin-utils` | >= 7.24 | Babel plugin |
24
- | `@babel/types` | >= 7.24 | Babel plugin |
25
- | `jiti` | >= 2.6 | Next.js wrapper (`@tenphi/tasty/zero/next`) when using `configFile` option |
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
- All of these are declared as optional peer dependencies of `@tenphi/tasty`. Install only what your setup requires:
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
- # For any Babel-based setup (Vite, custom Babel config, etc.)
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
- # For Next.js with TypeScript config file
34
- pnpm add -D @babel/core @babel/helper-plugin-utils @babel/types jiti
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 - works via toString() coercion
56
- <button className={button}>Click me</button>
63
+ // Use in JSX
64
+ <button className={button.className}>Click me</button>;
57
65
 
58
- // Or access className explicitly
59
- <button className={button.className}>Click me</button>
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.units` | `Record<string, string \| UnitHandler>` | — | Custom units for the style parser (merged with built-ins). E.g. `{ em: 'em', vw: 'vw' }` |
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
- babel: {
313
- plugins: [
314
- [
315
- '@tenphi/tasty/babel-plugin',
316
- {
317
- output: 'public/tasty.css',
318
- config: {
319
- states: { '@mobile': '@media(w < 768px)' },
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: 'ts3f2a1b ts8c4d2e',
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
- .ts3f2a1b.ts3f2a1b {
370
- padding: 16px 32px;
459
+ @property --tasty-second-fill-color {
460
+ syntax: '<color>';
461
+ inherits: false;
462
+ initial-value: transparent;
371
463
  }
372
464
 
373
- .ts8c4d2e.ts8c4d2e {
374
- background: #9370db;
375
- color: #fff;
465
+ @property --current-color {
466
+ syntax: '<color>';
467
+ inherits: true;
468
+ initial-value: currentcolor;
376
469
  }
377
470
 
378
- .heading.heading {
379
- font-size: 2.5rem;
380
- font-weight: 700;
381
- line-height: 1.2;
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
- 'ts3f2a1b ts8c4d2e',
458
- '.ts3f2a1b.ts3f2a1b{padding:16px 32px}\n.ts8c4d2e.ts8c4d2e{background:#9370db}',
571
+ 'tsa903d6 ts070801',
572
+ '.tsa903d6.tsa903d6 { background-color: var(--purple-color); }\n.ts070801.ts070801 { padding: 16px 32px; }',
459
573
  ),
460
574
  {
461
- className: 'ts3f2a1b ts8c4d2e',
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:2.5rem;font-weight:700;line-height:1.2}');
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 [Extending Style Types](configuration.md#extending-style-types-typescript) in the configuration docs.
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
- '--card-bg': isActive ? 'var(--purple-color)' : 'var(--white-color)',
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
- 其他指南目前仍以英文提供,包括[示例](../examples.md)、[内容编写组件](../authoring.mdx)、[AI 智能体工作流程](../ai-agents.md)、[部署](../deployment.md)和[按版本升级指南](../migration.md)。如需可修改的完整配置,可从[示例配置](../recipes.md)开始。如果验证失败,请查看[故障排查](../troubleshooting.md)。
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.28.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.28.0",
72
- "@tenphi/renderer": "0.28.0"
71
+ "@tenphi/docs": "0.30.0",
72
+ "@tenphi/renderer": "0.30.0"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "astro": "^7.3.2"