@tenphi/cookbook 0.21.4 → 0.22.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.
@@ -211,14 +211,16 @@ sidebar:
211
211
  label: Quick start
212
212
  order: 1
213
213
  group: Guides
214
+ badge: NEW
214
215
  ```
215
216
 
216
217
  `template: splash` uses a wider layout without sidebars by default. Set
217
218
  `tableOfContents` in that page's frontmatter to show its contents list.
218
219
 
219
220
  Set `sidebar: false` to omit a page from generated sidebars. `label`, `order`,
220
- and `group` affect both the default sidebar and autogenerated navigation
221
- directories. Relative hero images are validated, content-hashed, and copied
221
+ `group`, and `badge` affect both the default sidebar and autogenerated navigation
222
+ directories. A badge is plain text and also appears when a navigation item links
223
+ to the page, unless that item overrides it. Relative hero images are validated, content-hashed, and copied
222
224
  with the page's other local assets. Unrecognized frontmatter is preserved as graph entry `metadata`, outside the
223
225
  renderer frontmatter. Use `content.frontmatter: "reject"` to reject unrelated
224
226
  fields. Other supported fields include `aliases`, `template`, `hero`, `editUrl`,
@@ -361,6 +363,13 @@ also appears in the manual list or autogenerated directory. It remains in
361
363
  previous/next page navigation. A group with no remaining children becomes a
362
364
  regular page link.
363
365
 
366
+ Every navigation object, including manual and autogenerated groups, accepts a
367
+ plain-text `badge`, such as `{ label: "Offline support", link: "/offline-support",
368
+ badge: "NEW" }`. Links inherit `sidebar.badge` from their page's frontmatter;
369
+ an explicit `badge` overrides it, and `badge: ""` hides it. Badges use brand-derived
370
+ accent colors and support partial customization through `theme.styles.Sidebar.Badge`.
371
+ See [Sidebar badges](./site-navigation.md#sidebar-badges) for examples.
372
+
364
373
  Top-level sections stay flat; their linked headings navigate to their pages.
365
374
  For nested groups, clicking an unselected header or its chevron selects the parent
366
375
  page and opens its children, keeping them open if already expanded. Clicking the
@@ -660,7 +669,8 @@ translations: {
660
669
  },
661
670
  ```
662
671
 
663
- `navigation.<configured label>` translates named tabs and navigation groups.
672
+ `navigation.<configured label>` translates named tabs, navigation groups, and
673
+ explicitly configured sidebar badges.
664
674
  Automatically generated links use the title from the translated page.
665
675
  The supported keys below keep independent overrides, including similar labels:
666
676
  `auto` controls contrast, while `themeSelect.auto` controls color scheme;
@@ -56,6 +56,52 @@ follows a link. Keyboard focus stays in the drawer while it is open and returns
56
56
  to the menu control when it closes. Content and links remain readable if client
57
57
  JavaScript is unavailable.
58
58
 
59
+ ## Sidebar badges
60
+
61
+ Add a short `badge` beside a navigation link or group label:
62
+
63
+ ```ts
64
+ navigation: [
65
+ {
66
+ label: "Guides",
67
+ items: [
68
+ "/authentication",
69
+ { label: "Offline support", link: "/offline-support", badge: "NEW" },
70
+ "/deploying",
71
+ ],
72
+ },
73
+ ];
74
+ ```
75
+
76
+ To keep the badge with its page, set it in frontmatter instead:
77
+
78
+ ```yaml
79
+ sidebar:
80
+ badge: NEW
81
+ ```
82
+
83
+ Default and autogenerated sidebars, route strings, and linked navigation groups
84
+ inherit the page's badge. An explicit navigation `badge` overrides frontmatter;
85
+ use `badge: ""` to hide an inherited badge. Badges are plain text, including
86
+ characters such as `<`, and do not change pagination labels.
87
+
88
+ Badges use the brand-derived `accentText` and `accentSurfaceSubtle` palette roles
89
+ in every color scheme and contrast mode. Customize their appearance with a
90
+ partial [component style override](./component-styles.md):
91
+
92
+ ```ts
93
+ theme: {
94
+ styles: {
95
+ Sidebar: {
96
+ Badge: { radius: "0.5rem" },
97
+ },
98
+ },
99
+ }
100
+ ```
101
+
102
+ Translate explicitly configured badges with keys such as `"navigation.NEW"` in
103
+ `translations`. Frontmatter badges come from each locale's page.
104
+
59
105
  ## Contents, languages, and versions
60
106
 
61
107
  Desktop articles show an on-page table of contents. Enable an optional compact
@@ -278,7 +278,9 @@ theme: {
278
278
  ```
279
279
 
280
280
  `layout-width` caps and centers the complete documentation shell, while
281
- `content-width` limits the reading column inside it. `radius` is the control
281
+ `content-width` limits the reading column inside it. The column stays centered
282
+ as the viewport narrows: horizontal padding shrinks to 1.5rem before the column
283
+ itself shrinks. Mobile layouts use 1rem padding. `radius` is the control
282
284
  and navigation radius; `card-radius` is the larger surface radius. Keeping
283
285
  those roles separate makes a sharp control theme or a soft card theme possible
284
286
  without one-off component overrides.
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/tenphi/glaze/v2.0.0/assets/glaze.svg" width="128" height="128" alt="Glaze logo">
2
+ <img src="https://raw.githubusercontent.com/tenphi/glaze/v2.0.1/assets/glaze.svg" width="128" height="128" alt="Glaze logo">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Glaze</h1>
@@ -149,7 +149,7 @@ In Glaze, a **scheme variant** is one of `light`, `dark`, `lightContrast`, or
149
149
  * Keep the [API reference](docs/api.md) nearby for every method and option.
150
150
  * Read [OKHST in Glaze](docs/okhst.md) for the product-level color model, or
151
151
  the [full OKHST specification](https://github.com/tenphi/okhst) for its math.
152
- * [`AGENTS.md`](https://github.com/tenphi/glaze/blob/v2.0.0/AGENTS.md) — source-tree orientation for contributors.
152
+ * [`AGENTS.md`](https://github.com/tenphi/glaze/blob/v2.0.1/AGENTS.md) — source-tree orientation for contributors.
153
153
 
154
154
  ## License
155
155
 
@@ -1,18 +1,18 @@
1
1
  [
2
2
  {
3
3
  "name": "@tenphi/tasty",
4
- "version": "3.9.6",
4
+ "version": "3.9.9",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/tenphi/tasty",
7
- "ref": "v3.9.6",
7
+ "ref": "v3.9.9",
8
8
  "directory": "upstream/tasty"
9
9
  },
10
10
  {
11
11
  "name": "@tenphi/glaze",
12
- "version": "2.0.0",
12
+ "version": "2.0.1",
13
13
  "license": "MIT",
14
14
  "repository": "https://github.com/tenphi/glaze",
15
- "ref": "v2.0.0",
15
+ "ref": "v2.0.1",
16
16
  "directory": "upstream/glaze"
17
17
  }
18
18
  ]
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.9.6/assets/tasty.svg" width="128" height="128" alt="Tasty logo" />
2
+ <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.9.9/assets/tasty.svg" width="128" height="128" alt="Tasty logo" />
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Tasty</h1>
@@ -615,7 +615,7 @@ const tokens = theme.tasty(); // Ready-to-use Tasty tokens
615
615
  Syntax highlighting for Tasty styles in TypeScript, TSX, JavaScript, and JSX. Highlights color tokens, custom units, state keys, presets, and style properties inside `tasty()`, `tastyStatic()`, and related APIs.
616
616
 
617
617
  <p align="center">
618
- <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.9.6/assets/tasty-vscode-highlight.png" width="512" alt="Tasty VS Code syntax highlighting example" />
618
+ <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.9.9/assets/tasty-vscode-highlight.png" width="512" alt="Tasty VS Code syntax highlighting example" />
619
619
  </p>
620
620
 
621
621
  ## Built with Tasty
@@ -220,6 +220,8 @@ styles: { Title: { preset: 'h3' }, Icon: { $: '>@:last-child', color: '#accent'
220
220
  | `@function` | `{ '$$name': { args, returns?, result, '$local'? } }` |
221
221
  | `recipe` | a **string** of configured recipe names: `'card elevated'`, `'reset input / autofill'`, `'none / disabled'` |
222
222
 
223
+ `recipe` resolves on the component root and independently in each sub-element's styles: `styles: { Panel: { recipe: 'card elevated' } }` is supported. Configured recipe definitions must be flat and cannot contain their own `recipe` key; references inside recipe values are not recursively expanded. Compose names where the recipe is applied, not inside `configure({ recipes })`. See [Recipes](dsl.md#recipes).
224
+
223
225
  At-rule keys match the real CSS at-rule names, so they are kebab-case, not camelCase. Inside `@function`, the callable is `$$name` but its parameters and local variables are `$name`:
224
226
 
225
227
  ```jsx
@@ -549,7 +549,23 @@ configure({
549
549
  });
550
550
  ```
551
551
 
552
- Recipe values are flat tasty styles (no sub-element keys). They may contain base styles, tokens, local states, `@keyframes`, and `@property`. Recipes cannot reference other recipes.
552
+ Recipe values are flat tasty styles (no sub-element keys). They may contain base styles, tokens, local states, `@keyframes`, and `@property`.
553
+
554
+ **Recipes cannot reference other recipes.** A `recipe` key inside a configured recipe's value is not recursively resolved:
555
+
556
+ ```jsx
557
+ // Unsupported: applying 'elevatedCard' does not expand 'card elevated'.
558
+ configure({
559
+ recipes: {
560
+ elevatedCard: {
561
+ recipe: 'card elevated',
562
+ padding: '6x',
563
+ },
564
+ },
565
+ });
566
+ ```
567
+
568
+ Instead, compose the names where you apply the styles: `styles: { recipe: 'card elevated', padding: '6x' }`. Recipe references are resolved on the component root and independently inside each sub-element's styles (for example, `styles: { Panel: { recipe: 'card elevated' } }`). This sub-element support does not allow one recipe definition to inherit another. Tasty warns in development when a recipe definition contains a `recipe` key.
553
569
 
554
570
  For how to apply, compose, and override recipes in components, see [Recipes](dsl.md#recipes) in the Style DSL reference.
555
571
 
@@ -343,6 +343,26 @@ const ElevatedCard = tasty({
343
343
  });
344
344
  ```
345
345
 
346
+ **Where recipes resolve:**
347
+
348
+ The `recipe` property is resolved on the component root and independently inside each sub-element's styles:
349
+
350
+ ```jsx
351
+ const CardWithPanel = tasty({
352
+ styles: {
353
+ recipe: 'card',
354
+ Panel: {
355
+ recipe: 'card elevated',
356
+ padding: '2x', // Overrides the panel's base recipe padding
357
+ },
358
+ },
359
+ });
360
+ ```
361
+
362
+ At each level, base recipes are collected in name order (later recipes replace earlier values for the same property), then local styles are merged, then post recipes are merged. The merges with local styles and post recipes follow the [state-map extension and replacement rules](#extending-vs-replacing-state-maps).
363
+
364
+ Recipe definitions themselves cannot contain a `recipe` reference to another recipe: there is no recursive expansion or recipe inheritance. Compose names in the root or sub-element `recipe` property instead. See [Configuration — Recipes](configuration.md#recipes) for an unsupported nesting example.
365
+
346
366
  **Post-merge recipes (`/` separator):**
347
367
 
348
368
  Recipes listed after `/` are applied _after_ component styles using `mergeStyles`:
@@ -2,7 +2,7 @@
2
2
 
3
3
  This document describes the style rendering pipeline that transforms style objects into CSS rules. The pipeline ensures that each style value is applied to exactly one condition through exclusive condition building, boolean simplification, and intelligent CSS generation.
4
4
 
5
- **Implementation:** [`src/pipeline/`](https://github.com/tenphi/tasty/blob/v3.9.6/src/pipeline) — TypeScript file names below are relative to that directory.
5
+ **Implementation:** [`src/pipeline/`](https://github.com/tenphi/tasty/blob/v3.9.9/src/pipeline) — TypeScript file names below are relative to that directory.
6
6
 
7
7
  ## Overview
8
8
 
@@ -70,6 +70,8 @@ const Span = tasty({
70
70
 
71
71
  The wrapped component only needs to forward `className` (and ideally `style`/`ref`). Tasty-specific props (`qa`, `qaVal`, `mods`, `tokens`, `styleProps`, `modProps`, `tokenProps`) are consumed by Tasty and never leak to the DOM.
72
72
 
73
+ Props forwarded to the `as` component keep their declared types and requiredness. For example, a component with `position: 'top-right' | 'bottom-left'` accepts those values through `tasty({ as: Component })`; CSS positioning can still be set through `styles.position`. A prop explicitly listed in `styleProps` is consumed as a style value instead. The always-available base style props below are also consumed by Tasty, so keep component-specific prop names separate from those reserved names.
74
+
73
75
  ---
74
76
 
75
77
  ## Style Props
@@ -80,9 +80,9 @@ cold cases. These benchmarks do not include React, DOM work, stylesheet
80
80
  injection, style resolution, layout, or paint.
81
81
 
82
82
  The benchmark sources are colocated with the code they exercise:
83
- [`pipeline.bench.ts`](https://github.com/tenphi/tasty/blob/v3.9.6/src/pipeline/pipeline.bench.ts),
84
- [`parseStateKey.bench.ts`](https://github.com/tenphi/tasty/blob/v3.9.6/src/pipeline/parseStateKey.bench.ts), and the
85
- parser benchmark files under [`src/parser`](https://github.com/tenphi/tasty/blob/v3.9.6/src/parser).
83
+ [`pipeline.bench.ts`](https://github.com/tenphi/tasty/blob/v3.9.9/src/pipeline/pipeline.bench.ts),
84
+ [`parseStateKey.bench.ts`](https://github.com/tenphi/tasty/blob/v3.9.9/src/pipeline/parseStateKey.bench.ts), and the
85
+ parser benchmark files under [`src/parser`](https://github.com/tenphi/tasty/blob/v3.9.9/src/parser).
86
86
 
87
87
  ## Empty Wrapper Overhead
88
88
 
@@ -91,7 +91,7 @@ Skipping the style pipeline does not make a `tasty()` component free. Even
91
91
  tracks another fiber, and Tasty still processes and forwards the element's
92
92
  props.
93
93
 
94
- [`tasty-overhead.bench.tsx`](https://github.com/tenphi/tasty/blob/v3.9.6/src/tasty-overhead.bench.tsx) compares 10,000
94
+ [`tasty-overhead.bench.tsx`](https://github.com/tenphi/tasty/blob/v3.9.9/src/tasty-overhead.bench.tsx) compares 10,000
95
95
  raw `<div className>` siblings with 10,000 instances of one module-scoped
96
96
  `tasty({})` component. Both receive the same props, and the benchmark fails if
97
97
  they do not produce equivalent DOM.
@@ -125,7 +125,7 @@ snapshot experiment with controlled garbage collection.
125
125
 
126
126
  ## Cold Generation and Injection
127
127
 
128
- [`tasty-injection.bench.ts`](https://github.com/tenphi/tasty/blob/v3.9.6/src/tasty-injection.bench.ts) measures the extra
128
+ [`tasty-injection.bench.ts`](https://github.com/tenphi/tasty/blob/v3.9.9/src/tasty-injection.bench.ts) measures the extra
129
129
  work when Tasty must generate and inject CSS that an otherwise equivalent page
130
130
  already has. It does not compare different stylesheet insertion techniques.
131
131
 
@@ -201,7 +201,7 @@ and dialogs open. Both paths go through the state-map and ref-counting
201
201
  machinery rather than the parser, so a regression in them is invisible to every
202
202
  other benchmark here.
203
203
 
204
- [`tasty-interaction.bench.tsx`](https://github.com/tenphi/tasty/blob/v3.9.6/src/tasty-interaction.bench.tsx) pairs each
204
+ [`tasty-interaction.bench.tsx`](https://github.com/tenphi/tasty/blob/v3.9.9/src/tasty-interaction.bench.tsx) pairs each
205
205
  case with a raw-DOM equivalent driven by a hand-written stylesheet that
206
206
  produces the same computed color and background in both states. The benchmark
207
207
  fails if either arm resolves to anything else, so an arm that quietly rendered
@@ -255,7 +255,7 @@ reopening a menu re-pays the React wrapper, not the style pipeline.
255
255
  ## Page-Load Cold Start
256
256
 
257
257
  Every benchmark above deliberately excludes the network, module compilation and
258
- the first render. [`scripts/cold-start`](https://github.com/tenphi/tasty/blob/v3.9.6/scripts/cold-start) measures exactly
258
+ the first render. [`scripts/cold-start`](https://github.com/tenphi/tasty/blob/v3.9.9/scripts/cold-start) measures exactly
259
259
  those: what a visitor waits for between requesting a page and seeing styled
260
260
  content, in a real Chromium under CDP network and CPU throttling.
261
261
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/cookbook",
3
- "version": "0.21.4",
3
+ "version": "0.22.1",
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.21.4",
72
- "@tenphi/renderer": "0.21.4"
71
+ "@tenphi/docs": "0.22.1",
72
+ "@tenphi/renderer": "0.22.1"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "astro": "^7.3.2"