@tenphi/cookbook 0.17.1 → 0.18.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.
- package/dist/cli.js +39 -9
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/content.d.ts +3 -0
- package/dist/content.js +3 -0
- package/dist/eslint-plugin.d.ts +2 -2
- package/dist/eslint-plugin.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/docs/ai-agents.md +15 -4
- package/docs/authoring.mdx +42 -8
- package/docs/cli.md +43 -1
- package/docs/configuration.md +64 -11
- package/docs/content-sources.md +26 -0
- package/docs/customization-rules.md +11 -0
- package/docs/deployment.md +20 -3
- package/docs/examples.md +5 -2
- package/docs/getting-started.md +9 -6
- package/docs/index.md +31 -8
- package/docs/migration.md +98 -5
- package/docs/plugins.md +120 -0
- package/docs/publishing.md +153 -0
- package/docs/quality-checks.md +71 -0
- package/docs/recipes.md +116 -0
- package/docs/theme-and-components.md +510 -66
- package/docs/troubleshooting.md +89 -0
- package/package.json +7 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: Theme
|
|
2
|
+
title: Theme reference
|
|
3
3
|
description: Build an accessible Glaze palette, customize Tasty tokens, and use the supported Astro components.
|
|
4
4
|
sidebar:
|
|
5
5
|
order: 5
|
|
@@ -26,20 +26,25 @@ cover the configuration language accepted by `theme.styles`:
|
|
|
26
26
|
* [Tasty methodology](./upstream/tasty/docs/methodology.md) for the design-system
|
|
27
27
|
patterns behind roots, sub-elements, and controlled overrides.
|
|
28
28
|
|
|
29
|
+
For the short brand, logo, and font path, start with the
|
|
30
|
+
[configuration recipes](./recipes.md). This reference covers semantic colors,
|
|
31
|
+
typography, tokens, every configurable style tree, and custom components. Read
|
|
32
|
+
the [customization rules](./customization-rules.md) before adding styles.
|
|
33
|
+
|
|
29
34
|
## Brand color
|
|
30
35
|
|
|
31
36
|
The default brand is a calm blue with 68% OKHSL saturation. Set a brand color
|
|
32
37
|
with Glaze's `from` declaration:
|
|
33
38
|
|
|
34
39
|
```ts
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
+
import { defineDocsConfig } from "@tenphi/cookbook/config";
|
|
41
|
+
|
|
42
|
+
export default defineDocsConfig({
|
|
43
|
+
theme: { brand: { from: "#2f5bff" } },
|
|
44
|
+
});
|
|
40
45
|
```
|
|
41
46
|
|
|
42
|
-
Add a contrast target when the brand appears as text
|
|
47
|
+
Add a contrast target when the brand appears as text:
|
|
43
48
|
|
|
44
49
|
```ts
|
|
45
50
|
theme: {
|
|
@@ -50,9 +55,12 @@ theme: {
|
|
|
50
55
|
}
|
|
51
56
|
```
|
|
52
57
|
|
|
53
|
-
The
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
The brand supplies the hue and saturation seed. Cookbook derives separate text,
|
|
59
|
+
filled-control, and focus roles from it. Small accent text and filled controls
|
|
60
|
+
use stronger default APCA floors (75 normally, 90 in high contrast), and diagnostics
|
|
61
|
+
also enforce WCAG 4.5:1 / 7:1 on their actual backgrounds. Higher authored brand
|
|
62
|
+
targets are retained. Glaze adjusts tones only as far as these floors require;
|
|
63
|
+
dark and high-contrast schemes resolve independently.
|
|
56
64
|
|
|
57
65
|
Cookbook rejects a normal APCA target below 45 unless
|
|
58
66
|
`unsafeContrast: true` is present. That escape hatch is intentionally visible
|
|
@@ -118,8 +126,8 @@ white tint does not become vivid dark chrome when its tone is inverted.
|
|
|
118
126
|
|
|
119
127
|
Components consume semantic colors consistently: `surface`, `header`, `surface-2`,
|
|
120
128
|
`surface-3`, `text`, `heading`, `text-soft`, `border`, `border-strong`, `accent-text`,
|
|
121
|
-
`accent-surface`, `accent-surface-text`, and `focus`.
|
|
122
|
-
these as `#surface`, `#text`, `#border`, and so on; the Astro shell consumes the
|
|
129
|
+
`accent-surface`, `accent-surface-text`, `logo-surface`, `logo-mark`, and `focus`.
|
|
130
|
+
Tasty components can use these as `#surface`, `#text`, `#border`, and so on; the Astro shell consumes the
|
|
123
131
|
same resolved values. Glaze also generates hover and pressed states, subtle
|
|
124
132
|
accent fills, overlays, shadows, and the orange, green, blue, purple, and red
|
|
125
133
|
roles used by Starlight content components. No browser color mixes or
|
|
@@ -206,15 +214,20 @@ theme: {
|
|
|
206
214
|
}
|
|
207
215
|
```
|
|
208
216
|
|
|
209
|
-
The short form
|
|
210
|
-
|
|
217
|
+
The short form follows the regular and strong weights in your configured
|
|
218
|
+
presets, including heading and custom preset references. It requests normal and
|
|
219
|
+
italic styles, prefers a variable range, and falls back to real static weights
|
|
220
|
+
when ranges are unavailable. A font without italics produces a build warning;
|
|
221
|
+
choose another family or select only its supported styles. To control the
|
|
222
|
+
request exactly, list weights or ascending variable ranges and styles. Google
|
|
223
|
+
Fonts must support them; see the
|
|
211
224
|
[Google Fonts CSS API](https://developers.google.com/fonts/docs/css2) for its
|
|
212
225
|
available styles and weight syntax.
|
|
213
226
|
|
|
214
227
|
```ts
|
|
215
228
|
theme: {
|
|
216
229
|
fonts: {
|
|
217
|
-
body: { google: "Inter", weights: [400,
|
|
230
|
+
body: { google: "Inter", weights: ["400 750"], styles: ["normal", "italic"] }
|
|
218
231
|
}
|
|
219
232
|
}
|
|
220
233
|
```
|
|
@@ -240,10 +253,38 @@ theme: {
|
|
|
240
253
|
|
|
241
254
|
The `body` role also feeds navigation and small text. `heading` feeds `h1`
|
|
242
255
|
through `h6`, while `code` covers code text. Each role has a system fallback.
|
|
243
|
-
Cookbook emits
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
256
|
+
Cookbook emits font faces through Tasty with `font-display: swap`. Google CSS
|
|
257
|
+
and font files are downloaded at build time and cached in
|
|
258
|
+
`<Astro cacheDir>/cookbook-fonts`. Files are served from your own site's
|
|
259
|
+
`_cookbook/fonts/` path by default, including the deployment base. Visitors make
|
|
260
|
+
no Google Fonts requests. Existing local-file definitions keep working.
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
theme: {
|
|
264
|
+
fonts: { body: "Inter" },
|
|
265
|
+
fontLoading: {
|
|
266
|
+
google: "self-hosted", // or "remote" to keep Google's font CDN URLs
|
|
267
|
+
cache: "reuse", // "refresh" to fetch again; "offline" to forbid network
|
|
268
|
+
display: "swap" // also auto, block, fallback, optional
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The first build requires network access. Preserve the Astro cache between CI
|
|
274
|
+
runs; `offline` fails with an actionable message when an entry is missing or
|
|
275
|
+
corrupt. Cache entries are content-verified and keyed by the exact request.
|
|
276
|
+
`refresh` deliberately updates them. For a fully checked-in font source, copy
|
|
277
|
+
licensed files into `public/fonts/` and use the local form. Only `wght` and
|
|
278
|
+
`ital` axes are requested; use local variable files and Tasty typography styles
|
|
279
|
+
for other axes. Styles and weights that do not exist are rejected for explicit
|
|
280
|
+
requests. For static fonts, browsers select their nearest real weight;
|
|
281
|
+
intermediate weights require a variable font.
|
|
282
|
+
|
|
283
|
+
Migration: name-only Google font configuration now downloads the required
|
|
284
|
+
weights and italics and serves them locally. This increases the initial build's
|
|
285
|
+
font downloads and removes visitors' external font dependency. Set
|
|
286
|
+
`fontLoading.google: "remote"` to retain CDN delivery. Existing CSS-variable
|
|
287
|
+
weights that cannot be resolved from presets require explicit `weights`.
|
|
247
288
|
|
|
248
289
|
### Adjust presets
|
|
249
290
|
|
|
@@ -316,6 +357,53 @@ bridge. Customize either kind by name under `theme.styles`; the configuration
|
|
|
316
357
|
is resolved before CSS generation, so this is not a selector-based CSS
|
|
317
358
|
override.
|
|
318
359
|
|
|
360
|
+
> **Direct styles, without a specificity battle.** Cookbook merges your partial
|
|
361
|
+
> style object with the component's base styles before Tasty extracts CSS. The
|
|
362
|
+
> generated stylesheet reflects that result; changing a supported property
|
|
363
|
+
> does not add a competing rule just to beat the original. You can customize
|
|
364
|
+
> existing elements without long selectors or `!important`.
|
|
365
|
+
|
|
366
|
+
Start with the area you want to change, then use the complete sub-element table
|
|
367
|
+
below to find its exact anatomy:
|
|
368
|
+
|
|
369
|
+
| Page area | Style names to inspect |
|
|
370
|
+
| ----------------------------- | ------------------------------------------------------------------------------------ |
|
|
371
|
+
| Header, title, and navigation | `HeaderFrame`, `StarlightHeader`, `SiteLogo`, `HeaderLinks`, `TopNavigation` |
|
|
372
|
+
| Sidebar and mobile menu | `Sidebar`, `MobileMenuToggle`, `MobileNavigationTabs`, `MobileMenuFooter` |
|
|
373
|
+
| Article text and headings | `Markdown`, `MarkdownHeading`, `Heading`, `MainContent` |
|
|
374
|
+
| Code and diagrams | `MarkdownCodeBlock`, `MarkdownInlineCode`, `SyntaxHighlight`, `CodeGroup`, `Mermaid` |
|
|
375
|
+
| Search | `SearchButton`, `Search`, `SearchResults` |
|
|
376
|
+
| Table of contents | `TableOfContents`, `MobileTableOfContents`, `TableOfContentsLayout` |
|
|
377
|
+
| Cards, notes, and tabs | `Card`, `StarlightCard`, `StarlightAside`, `Tabs` |
|
|
378
|
+
| Footer and page controls | `Footer`, `Pagination`, `PageActions`, `ThemeSelect` |
|
|
379
|
+
|
|
380
|
+
For example, this changes a typography role and one named element without
|
|
381
|
+
copying a component's full style tree:
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
theme: {
|
|
385
|
+
presets: { h2: { fontSize: "1.75rem" } },
|
|
386
|
+
styles: {
|
|
387
|
+
Sidebar: {
|
|
388
|
+
LinkLabel: {
|
|
389
|
+
preset: "body",
|
|
390
|
+
whiteSpace: { "": "nowrap", "@mobile": "normal" }
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
The `@mobile` value sits with the default value in one Tasty state map. Shared
|
|
398
|
+
tokens and presets keep the component aligned with the rest of the site, while
|
|
399
|
+
Glaze resolves semantic colors across the configured schemes and contrast
|
|
400
|
+
modes.
|
|
401
|
+
|
|
402
|
+
In a generated site, run `npm run validate` (or the matching package manager's
|
|
403
|
+
command) after editing `docs.config.ts`. It checks TypeScript theme properties,
|
|
404
|
+
then runs Cookbook's preflight and production output checks. A misspelled
|
|
405
|
+
preset or built-in sub-element property fails type checking.
|
|
406
|
+
|
|
319
407
|
Provide only the root and named
|
|
320
408
|
[sub-element](./upstream/tasty/docs/dsl.md#sub-element) properties you want to
|
|
321
409
|
override. Cookbook deep-merges that partial style object into the complete
|
|
@@ -358,43 +446,62 @@ is merged into the base inside Cookbook.
|
|
|
358
446
|
Every configurable surface accepts styles at the root plus these named Tasty
|
|
359
447
|
sub-elements:
|
|
360
448
|
|
|
361
|
-
| Configuration name | Named sub-elements
|
|
362
|
-
| ----------------------- |
|
|
363
|
-
| `Card` | `Heading2`, `Heading3`, `Paragraph`
|
|
364
|
-
| `Callout` | `Title`, `Body`, `Tip`, `Caution`, `Danger`
|
|
365
|
-
| `CodeGroup` | `Caption`, `Pre`, `Code`
|
|
366
|
-
| `Tab` | `Heading`, `Hidden`, `HiddenHeading`
|
|
367
|
-
| `
|
|
368
|
-
| `
|
|
369
|
-
| `
|
|
370
|
-
| `
|
|
371
|
-
| `
|
|
372
|
-
| `
|
|
373
|
-
| `
|
|
374
|
-
| `
|
|
375
|
-
| `
|
|
376
|
-
| `
|
|
377
|
-
| `
|
|
378
|
-
| `
|
|
379
|
-
| `
|
|
380
|
-
| `
|
|
381
|
-
| `
|
|
382
|
-
| `
|
|
383
|
-
| `
|
|
384
|
-
| `
|
|
385
|
-
| `
|
|
386
|
-
| `
|
|
387
|
-
| `
|
|
388
|
-
| `
|
|
389
|
-
| `
|
|
390
|
-
| `
|
|
391
|
-
| `
|
|
392
|
-
| `
|
|
393
|
-
| `
|
|
394
|
-
| `
|
|
395
|
-
| `
|
|
396
|
-
| `
|
|
397
|
-
| `
|
|
449
|
+
| Configuration name | Named sub-elements |
|
|
450
|
+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
451
|
+
| `Card` | `Heading2`, `Heading3`, `Paragraph` |
|
|
452
|
+
| `Callout` | `Title`, `Body`, `Tip`, `Caution`, `Danger` |
|
|
453
|
+
| `CodeGroup` | `Caption`, `Pre`, `Code` |
|
|
454
|
+
| `Tab` | `Heading`, `Hidden`, `HiddenHeading` |
|
|
455
|
+
| `MobileTableOfContents` | `Summary`, `List`, `NestedList`, `Item`, `Link`, `HoverLink`, `Focus` |
|
|
456
|
+
| `PageActions` | `Control`, `Hover`, `Focus`, `Pending`, `Status` |
|
|
457
|
+
| `Footer` | `Meta`, `LoneMetaItem`, `MetaLink`, `HoverMetaLink`, `Credit`, `CreditLink`, `HoverCreditLink` |
|
|
458
|
+
| `Hero` | `Visual`, `Stack`, `Copy`, `Title`, `Tagline`, `Actions`, `Action`, `HoverAction`, `PrimaryAction`, `SecondaryAction`, `MinimalAction`, `ActionIcon` |
|
|
459
|
+
| `LanguageSelect` | `Label`, `HoverLabel`, `LabelIcon`, `Select`, `Caret`, `Option` |
|
|
460
|
+
| `Logo` | `Svg`, `Mark` |
|
|
461
|
+
| `SiteLogo` | `Image`, `Light`, `Dark` |
|
|
462
|
+
| `MarkdownCodeBlock` | `Pre`, `CopyButton`, `HoverCopyButton`, `CopiedButton`, `CopyIcon`, `CopiedIcon`, `Code`, `Diff`, `DiffCode`, `DiffLine`, `EmptyDiffLine`, `InsertedLine`, `DeletedLine` |
|
|
463
|
+
| `MarkdownHeading` | `Heading`, `Heading1`, `Heading2`, `Heading3`, `Heading4`, `Heading5`, `Heading6`, `Link`, `RevealedLink`, `HoverLink`, `LinkIcon`, `CopiedLink`, `CopiedLinkIcon`, `CopiedIcon` |
|
|
464
|
+
| `MarkdownInlineCode` | None |
|
|
465
|
+
| `MarkdownTable` | `Table`, `Cell`, `LastBodyRowCell`, `HeaderCell`, `Scroll` |
|
|
466
|
+
| `Mermaid` | `Diagram`, `Text`, `MonoText` |
|
|
467
|
+
| `MobileMenuFooter` | `Social` |
|
|
468
|
+
| `MobileMenuToggle` | `Control`, `Icon`, `Section`, `Page`, `HoverControl`, `ActiveControl` |
|
|
469
|
+
| `MobileNavigationTabs` | `Trigger`, `Marker`, `Caret`, `ExpandedCaret`, `Label`, `List`, `Item`, `Link`, `HoverLink`, `CurrentLink` |
|
|
470
|
+
| `MobileTableOfContents` | `Item`, `Link`, `LinkLabel`, `HoverLink`, `CurrentLink`, `CurrentIndicator` |
|
|
471
|
+
| `PackageVersion` | None |
|
|
472
|
+
| `VersionSwitcher` | `Trigger`, `Panel`, `OpenPanel`, `Link`, `CurrentLink` |
|
|
473
|
+
| `Preview` | `Caption`, `Stage`, `Frame`, `Code`, `Summary`, `Pre` |
|
|
474
|
+
| `Sidebar` | `Backdrop`, `OpenBackdrop`, `MobileHeading`, `HomeLink`, `HomeLogo`, `HomeLabel`, `Close`, `HoverClose`, `CloseIcon`, `CurrentLink`, `OpenPane`, `EnteredPane`, `Content`, `Tree`, `List`, `Item`, `TopLevelSpacing`, `GroupSpacing`, `NestedItem`, `SectionHeading`, `Control`, `Summary`, `GroupLabel`, `GroupLabelText`, `Link`, `LinkLabel`, `InteractiveControl`, `SummaryMarker`, `Caret`, `ExpandedCaret`, `LinkedSummary`, `GroupLink`, `LinkedSectionHeading`, `SectionLink`, `Badge`, `TopLevelLink` |
|
|
475
|
+
| `SocialIcons` | `Link`, `HoverLink`, `Icon` |
|
|
476
|
+
| `StarlightHeader` | `Primary`, `TitleAndSearch`, `Title`, `LogoLink`, `Logo`, `SiteTitle`, `Search`, `SearchElement`, `Tools`, `ToolItem`, `Social`, `MobileTheme` |
|
|
477
|
+
| `TableOfContentsLayout` | `WithMobile`, `Content` |
|
|
478
|
+
| `SearchButton` | `PendingShortcut`, `Label`, `Shortcut`, `Hover`, `Active`, `NativeIcon`, `Icon` |
|
|
479
|
+
| `Layout` | `Islands`, `LockedPage`, `Light`, `Auto` |
|
|
480
|
+
| `HeaderLinks` | `Desktop`, `DesktopLink`, `Link`, `HoverLink`, `PrimaryLink`, `HoverPrimaryLink`, `Trigger`, `HoverTrigger`, `Panel`, `PanelNavigation`, `PanelLink`, `FirstPanelLink`, `Close`, `HoverClose` |
|
|
481
|
+
| `Heading` | `Level1`, `Level2`, `Level3`, `Level4`, `Level5`, `Level6`, `PageTitle` |
|
|
482
|
+
| `HeaderFrame` | None |
|
|
483
|
+
| `PageFrame` | `MainFrame`, `SidebarFrame`, `Columns` |
|
|
484
|
+
| `Steps` | `Item`, `Marker` |
|
|
485
|
+
| `Tabs` | `List`, `Button`, `SelectedButton`, `FocusedButton` |
|
|
486
|
+
| `TableOfContents` | `Heading`, `List`, `Item`, `Link`, `LinkLabel`, `HoverLink`, `CurrentLink` |
|
|
487
|
+
| `ThemeSelect` | `Trigger`, `HoverTrigger`, `ActiveTrigger`, `Icon`, `Panel`, `OpenPanel`, `Section`, `SectionSpacing`, `SectionLabel`, `Option`, `HoverOption`, `CheckedOption`, `FocusedOption`, `Input`, `OptionIcon`, `Checkmark`, `SelectedCheckmark` |
|
|
488
|
+
| `TopNavigation` | `Scrollbar`, `Link`, `HoverLink`, `CurrentLink`, `ActiveIndicator` |
|
|
489
|
+
| `Document` | `All`, `Body`, `Control`, `Pointer`, `ResponsiveWidth`, `ResponsiveHeight`, `Hidden`, `DesktopBlock`, `DesktopFlex`, `ScreenReaderOnly`, `Strong`, `Link`, `NarrowBlock`, `MobileBlock`, `Code`, `FocusRing`, `CurrentLink`, `SearchOpen` |
|
|
490
|
+
| `MainPane` | `WithSidebars` |
|
|
491
|
+
| `MainContent` | `ContentSpacing`, `Container`, `Panel`, `FirstPanel`, `BodyPanel` |
|
|
492
|
+
| `Banner` | `Link` |
|
|
493
|
+
| `SkipLink` | `Focus` |
|
|
494
|
+
| `Search` | `Status`, `Dialog`, `CloseIcon`, `OpenDialog`, `Backdrop`, `Frame`, `Container`, `Close`, `HoverClose`, `ActiveClose` |
|
|
495
|
+
| `Pagination` | `Link`, `NextLink`, `NextIcon`, `NextLabel`, `HoverLink`, `ActiveLink`, `Title`, `LoneNextLink`, `NativeIcon`, `Icon`, `PreviousIconRtl`, `NextIconRtl` |
|
|
496
|
+
| `Markdown` | `Block`, `BlockSpacing`, `HeadingSpacing`, `List`, `CompactItem`, `ListItem`, `DefinitionTerm`, `DefinitionDescription`, `Link`, `HoverLink`, `Quote`, `Rule`, `Details`, `HoverDetails`, `Summary`, `OpenSummary`, `SummaryMarker`, `SummaryIcon`, `OpenSummaryIcon`, `Code` |
|
|
497
|
+
| `MermaidSource` | None |
|
|
498
|
+
| `StarlightAside` | `Note`, `Tip`, `Caution`, `Danger`, `Title`, `Icon`, `FirstContent` |
|
|
499
|
+
| `StarlightCard` | `Title` |
|
|
500
|
+
| `StarlightLinkCard` | `Hover`, `Stack`, `Link`, `LinkOverlay`, `DescriptionAndIcon` |
|
|
501
|
+
| `StarlightBadge` | None |
|
|
502
|
+
| `StarlightSteps` | `Item`, `Counter`, `Connector` |
|
|
503
|
+
| `SyntaxHighlight` | `Scroll`, `Wrap`, `Marker`, `Comment`, `Punctuation`, `Keyword`, `String`, `Token`, `Property`, `Number`, `Function`, `Value`, `Operator`, `Text`, `Bg`, `Inserted`, `Deleted`, `Italic`, `Strong`, `Underline` |
|
|
504
|
+
| `SearchResults` | `Form`, `Input`, `Clear`, `Results`, `Result`, `ResultLink`, `SearchIcon`, `ClearIcon`, `SuppressedClear`, `Message`, `List`, `Title`, `Excerpt`, `NestedResult`, `Match`, `More`, `HoverMore` |
|
|
398
505
|
|
|
399
506
|
`COOKBOOK_COMPONENT_NAMES` publishes the configuration names, and
|
|
400
507
|
`COOKBOOK_COMPONENT_SUB_ELEMENTS` publishes the complete sub-element lists for
|
|
@@ -431,6 +538,10 @@ same.
|
|
|
431
538
|
Register custom names and their partial Tasty objects in `theme.customStyles`.
|
|
432
539
|
Built-in names belong in `theme.styles` and reject misspelled sub-elements.
|
|
433
540
|
Custom names can also target a matching user-authored `data-tasty-anatomy` attribute.
|
|
541
|
+
The name must match the string passed to `defineComponent()` or
|
|
542
|
+
`resolveComponentStyles()`, or the `data-tasty-anatomy` value. A production
|
|
543
|
+
build warns when a configured custom name has no matching component style
|
|
544
|
+
resolver or rendered anatomy attribute.
|
|
434
545
|
|
|
435
546
|
The default renderer runs Tasty in Astro extract mode. Direct components and
|
|
436
547
|
the remaining document/vendor bridge styles are collected into shared static
|
|
@@ -476,8 +587,8 @@ import { Card, Logo, Preview, Steps, Tabs } from "@tenphi/cookbook/components";
|
|
|
476
587
|
|
|
477
588
|
See [Authoring components](./authoring.mdx) for complete examples and props.
|
|
478
589
|
|
|
479
|
-
* `Preview` isolates HTML and
|
|
480
|
-
|
|
590
|
+
* `Preview` isolates HTML, CSS, and optional JavaScript in a sandboxed iframe.
|
|
591
|
+
The frame never receives same-origin access to the documentation page.
|
|
481
592
|
|
|
482
593
|
Use MDX only for repository content you control. Locked package content remains
|
|
483
594
|
Markdown-only unless the consumer explicitly sets `trust: "mdx"` for that
|
|
@@ -505,7 +616,84 @@ is needed for static components. Set shared tokens, presets, and states in
|
|
|
505
616
|
`docs.config.ts` before rendering. Import the styling entry point in component
|
|
506
617
|
modules; configuration files should use the main `@tenphi/cookbook` entry point.
|
|
507
618
|
|
|
508
|
-
### A
|
|
619
|
+
### A shared site logo
|
|
620
|
+
|
|
621
|
+
Set `site.logo` once to use your artwork in the header and mobile drawer:
|
|
622
|
+
|
|
623
|
+
```ts
|
|
624
|
+
site: {
|
|
625
|
+
title: "Acme",
|
|
626
|
+
logo: "./assets/acme.svg"
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
Paths are local files relative to the resolved project root, just like
|
|
631
|
+
`site.favicon`. Cookbook reads the intrinsic dimensions and copies the image to
|
|
632
|
+
a content-hashed URL under the deployment base. SVG, PNG, JPEG, WebP, AVIF, and
|
|
633
|
+
GIF are supported. Missing or invalid files fail during setup.
|
|
634
|
+
|
|
635
|
+
```ts
|
|
636
|
+
site: {
|
|
637
|
+
title: "Acme",
|
|
638
|
+
logo: {
|
|
639
|
+
light: "./assets/acme-light.svg",
|
|
640
|
+
dark: "./assets/acme-dark.svg",
|
|
641
|
+
alt: "Acme documentation",
|
|
642
|
+
href: "/",
|
|
643
|
+
decorative: true
|
|
644
|
+
},
|
|
645
|
+
favicon: "./assets/acme-icon.svg"
|
|
646
|
+
}
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
Use `src` for one image, or both `light` and `dark`. Variants follow the
|
|
650
|
+
appearance control and the system preference in Auto mode. They must share an
|
|
651
|
+
aspect ratio to prevent layout shifts. Optional `width` and `height` describe
|
|
652
|
+
intrinsic dimensions; Tasty controls display size. Customize
|
|
653
|
+
`theme.styles.SiteLogo` and its complete anatomy: `Image`, `Light`, and `Dark`.
|
|
654
|
+
Wide wordmarks retain their proportions within the header.
|
|
655
|
+
|
|
656
|
+
The logo is decorative by default because the neighboring title labels the
|
|
657
|
+
site. Set `decorative: false` and `alt` when the image itself carries meaningful
|
|
658
|
+
text. The header logo link still has a name when the image is decorative.
|
|
659
|
+
`href` defaults to the localized documentation home; it accepts a root-relative
|
|
660
|
+
documentation route or HTTP(S) destination. The header title and drawer use the
|
|
661
|
+
same destination. `site.logo: false` removes the mark from both locations.
|
|
662
|
+
|
|
663
|
+
A logo does not change the favicon or touch icons. Configure `site.favicon`
|
|
664
|
+
separately for square artwork; the default Cookbook icon set remains in place
|
|
665
|
+
until changed. `Logo` remains available as the standalone Cookbook book mark.
|
|
666
|
+
|
|
667
|
+
The built-in mark uses `theme.palette["logo-surface"]` and `theme.palette["logo-mark"]`.
|
|
668
|
+
Both default to Glaze `mode: "fixed"`: the brand background and light book keep
|
|
669
|
+
their polarity in dark mode while respecting Glaze's tone boundaries and
|
|
670
|
+
high-contrast settings. The mark-to-background contrast floor is 3:1 normally
|
|
671
|
+
and 4.5:1 in high contrast. These colors are separate from interactive accents.
|
|
672
|
+
For example, to customize the logo background while retaining brand hue:
|
|
673
|
+
|
|
674
|
+
```ts
|
|
675
|
+
theme: {
|
|
676
|
+
brand: { from: "#315efb" },
|
|
677
|
+
palette: {
|
|
678
|
+
"logo-surface": {
|
|
679
|
+
base: "logo-mark",
|
|
680
|
+
tone: 40,
|
|
681
|
+
saturation: 0.8,
|
|
682
|
+
mode: "fixed",
|
|
683
|
+
contrast: { wcag: [3, 4.5] },
|
|
684
|
+
},
|
|
685
|
+
"logo-mark": { tone: 100, saturation: 0, mode: "fixed" },
|
|
686
|
+
},
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
Custom image assets keep their authored colors; use `light`/`dark` files when
|
|
691
|
+
you want distinct artwork. Header and drawer home links center logos with the
|
|
692
|
+
site title regardless of their aspect ratio. Use `theme.styles.SiteLogo` for
|
|
693
|
+
image size and `theme.styles.StarlightHeader.SiteTitle` / `Sidebar.HomeLink`
|
|
694
|
+
for typography; they do not need baseline offsets for a different preset.
|
|
695
|
+
|
|
696
|
+
### Advanced site title markup
|
|
509
697
|
|
|
510
698
|
To put your own logo and title in one home link, create
|
|
511
699
|
`docs/components/site-title.ts`:
|
|
@@ -559,20 +747,20 @@ const { siteTitle, siteTitleHref } = Astro.locals.starlightRoute;
|
|
|
559
747
|
</SiteTitleRoot>
|
|
560
748
|
```
|
|
561
749
|
|
|
562
|
-
Register the replacement in `docs.config.ts` and
|
|
750
|
+
Register the replacement in `docs.config.ts` and disable the shared mark.
|
|
751
|
+
A `SiteTitle` override affects the header; use `site.logo` above for ordinary
|
|
752
|
+
branding shared with the drawer. For custom drawer markup, override `Sidebar`.
|
|
563
753
|
The custom component supports root styles plus its complete list of named
|
|
564
754
|
sub-elements: `Logo` and `Label`.
|
|
565
755
|
|
|
566
756
|
```ts
|
|
757
|
+
site: { logo: false },
|
|
567
758
|
components: {
|
|
568
759
|
overrides: {
|
|
569
760
|
SiteTitle: "./docs/components/SiteTitle.astro"
|
|
570
761
|
}
|
|
571
762
|
},
|
|
572
763
|
theme: {
|
|
573
|
-
styles: {
|
|
574
|
-
StarlightHeader: { LogoLink: { hide: true } }
|
|
575
|
-
},
|
|
576
764
|
customStyles: {
|
|
577
765
|
ProjectSiteTitle: { Logo: { color: "#text" } }
|
|
578
766
|
}
|
|
@@ -756,8 +944,264 @@ left-aligned navigation links with a `1bw` gap, without primary button variants.
|
|
|
756
944
|
`HeaderLinks.PanelLink` styles the menu rows; `FirstPanelLink` reserves space
|
|
757
945
|
for the close button. The inset divider above the tabs belongs to `TopNavigation`.
|
|
758
946
|
|
|
759
|
-
The table of contents is hidden below 72rem
|
|
760
|
-
`
|
|
761
|
-
|
|
947
|
+
The desktop table of contents is hidden below 72rem. Set
|
|
948
|
+
`tableOfContents: { mobile: true }` to show an optional compact disclosure there.
|
|
949
|
+
`MobileTableOfContents` owns its summary and links; `TableOfContentsLayout`
|
|
950
|
+
controls placement. `Layout` controls shared
|
|
762
951
|
navigation dimensions and the drawer's scroll lock; `PageFrame` styles the
|
|
763
952
|
page container and content columns.
|
|
953
|
+
|
|
954
|
+
### Header control shape
|
|
955
|
+
|
|
956
|
+
Header buttons and the mobile drawer close button use the independent
|
|
957
|
+
`$header-control-radius` token, which defaults to `999px` for pill and circular
|
|
958
|
+
shapes. Set it to `8px` for the same corners as the default content controls:
|
|
959
|
+
|
|
960
|
+
```ts
|
|
961
|
+
theme: {
|
|
962
|
+
tokens: { "$header-control-radius": "8px" }
|
|
963
|
+
}
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
`$radius` continues to control code-copy buttons, navigation items, and other
|
|
967
|
+
content controls. Individual `theme.styles` overrides still take precedence.
|
|
968
|
+
The mobile header divider spans the viewport while its content keeps the
|
|
969
|
+
configured horizontal padding.
|
|
970
|
+
|
|
971
|
+
### Add palette colors and reference other roles
|
|
972
|
+
|
|
973
|
+
Every `theme.palette` entry participates in one Glaze color graph. Use lowercase
|
|
974
|
+
names with hyphens; a role named `review-panel` becomes the Tasty token
|
|
975
|
+
`#review-panel`. Declaration order does not matter. References can target custom
|
|
976
|
+
colors or built-in roles, including header, border, overlay, and syntax colors.
|
|
977
|
+
|
|
978
|
+
```ts
|
|
979
|
+
theme: {
|
|
980
|
+
brand: { from: "#315efb" },
|
|
981
|
+
palette: {
|
|
982
|
+
"review-ink": {
|
|
983
|
+
base: "review-panel",
|
|
984
|
+
tone: [4, 0],
|
|
985
|
+
saturation: 0.05,
|
|
986
|
+
contrast: { wcag: [7, 10] },
|
|
987
|
+
},
|
|
988
|
+
"review-panel": { base: "surface", tone: "-2", saturation: 0.05 },
|
|
989
|
+
},
|
|
990
|
+
styles: {
|
|
991
|
+
Callout: { fill: "#review-panel", color: "#review-ink" },
|
|
992
|
+
},
|
|
993
|
+
},
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
Relative and absolute declarations inherit the brand's hue and saturation.
|
|
997
|
+
Use saturation factors from `0` (neutral) to `1` (full seed saturation), and
|
|
998
|
+
`hue` to choose a different hue. All roles resolve for light, dark, and both
|
|
999
|
+
high-contrast modes. Configuration diagnostics and rendering use the same graph.
|
|
1000
|
+
Missing references and cycles fail with the color name; layered configurations
|
|
1001
|
+
resolve references after merging.
|
|
1002
|
+
|
|
1003
|
+
`textSoft` remains an alias for `text-soft`. Use either spelling, but do not
|
|
1004
|
+
configure both. The names `current`, `constructor`, and `prototype` are reserved.
|
|
1005
|
+
Declaring a built-in name intentionally overrides that role; use a project
|
|
1006
|
+
prefix for additional roles to avoid future naming collisions.
|
|
1007
|
+
|
|
1008
|
+
When a status role such as `info` uses a mix or shadow definition, its derived
|
|
1009
|
+
`info-text` defaults to neutral, contrast-corrected text. Override `info-text`
|
|
1010
|
+
explicitly for a colored label; the mix/shadow dependency graph stays intact.
|
|
1011
|
+
A shadow status also uses a neutral derived surface, because Glaze does not allow
|
|
1012
|
+
a shadow to be a mix target. Override the surface separately when needed.
|
|
1013
|
+
|
|
1014
|
+
### Register units and recipes
|
|
1015
|
+
|
|
1016
|
+
Register custom units and flat recipes in `theme`; Cookbook configures Tasty
|
|
1017
|
+
before evaluating your components:
|
|
1018
|
+
|
|
1019
|
+
```ts
|
|
1020
|
+
theme: {
|
|
1021
|
+
brand: { from: "#315efb" },
|
|
1022
|
+
palette: {
|
|
1023
|
+
"review-panel": { base: "surface", tone: "-2", saturation: 0.05 },
|
|
1024
|
+
"review-ink": { base: "review-panel", tone: 0, contrast: { wcag: [7, 10] } },
|
|
1025
|
+
},
|
|
1026
|
+
units: { rh: "6px" },
|
|
1027
|
+
recipes: {
|
|
1028
|
+
"review-panel": {
|
|
1029
|
+
fill: "#review-panel",
|
|
1030
|
+
color: "#review-ink",
|
|
1031
|
+
padding: "2rh",
|
|
1032
|
+
radius: "3px",
|
|
1033
|
+
},
|
|
1034
|
+
},
|
|
1035
|
+
customStyles: { DemoBadge: { Label: { color: "#review-ink" } } },
|
|
1036
|
+
},
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
```ts
|
|
1040
|
+
import { defineComponent } from "@tenphi/cookbook/styling";
|
|
1041
|
+
|
|
1042
|
+
export const DemoBadge = defineComponent("DemoBadge", {
|
|
1043
|
+
as: "aside",
|
|
1044
|
+
elements: { Label: "strong" },
|
|
1045
|
+
styles: {
|
|
1046
|
+
display: "block",
|
|
1047
|
+
recipe: "review-panel",
|
|
1048
|
+
Label: { preset: "h4" },
|
|
1049
|
+
},
|
|
1050
|
+
});
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
Use `<DemoBadge><DemoBadge.Label>Review ready</DemoBadge.Label></DemoBadge>` in
|
|
1054
|
+
MDX. Keep these styled components server-rendered: their CSS is extracted at
|
|
1055
|
+
build time. Add behavior with a small client script targeting the rendered
|
|
1056
|
+
markup. This recipe produces 12px padding. Units merge by name, with the later
|
|
1057
|
+
configuration winning. Recipes merge using Tasty `mergeStyles`, including state
|
|
1058
|
+
maps. Recipes are flat: define named sub-elements on the owning component, and
|
|
1059
|
+
compose recipes with `recipe: "base elevated"` rather than referencing a recipe
|
|
1060
|
+
inside another recipe. `none` is a reserved recipe name. Cookbook's built-in
|
|
1061
|
+
units are `x`, `r`, `cr`, and `bw`; overriding one changes its meaning globally.
|
|
1062
|
+
|
|
1063
|
+
Keep editor and linter validation synchronized with your configuration:
|
|
1064
|
+
|
|
1065
|
+
```ts
|
|
1066
|
+
// tasty.config.ts
|
|
1067
|
+
import { createValidationConfig } from "@tenphi/cookbook/eslint-plugin";
|
|
1068
|
+
import docs from "./docs.config";
|
|
1069
|
+
export default createValidationConfig(docs.theme);
|
|
1070
|
+
```
|
|
1071
|
+
|
|
1072
|
+
### Configure Glaze adaptation
|
|
1073
|
+
|
|
1074
|
+
`theme.glaze` accepts `lightTone`, `darkTone`, `darkDesaturation`, `autoFlip`,
|
|
1075
|
+
`pastel`, `inferRole`, and `shadowTuning`. Tone windows accept `[lo, hi]`, `false`
|
|
1076
|
+
for the full range, or the advanced `{ lo, hi, eps }` form. Continue to use
|
|
1077
|
+
`theme.contrastLevel` for manual contrast interpolation. Cookbook always emits
|
|
1078
|
+
all four appearance variants.
|
|
1079
|
+
|
|
1080
|
+
```ts
|
|
1081
|
+
theme: {
|
|
1082
|
+
glaze: { lightTone: [10, 100], darkTone: [15, 95] },
|
|
1083
|
+
palette: {
|
|
1084
|
+
"accent-surface-subtle": {
|
|
1085
|
+
type: "mix", base: "surface", target: "accent-surface", value: [12, 20],
|
|
1086
|
+
},
|
|
1087
|
+
shadow: {
|
|
1088
|
+
type: "shadow", bg: "surface", fg: "text", intensity: [12, 24],
|
|
1089
|
+
tuning: { alphaMax: 0.3 },
|
|
1090
|
+
},
|
|
1091
|
+
},
|
|
1092
|
+
},
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
Palette roles accept Glaze's regular, mix, and shadow declarations. Mix and
|
|
1096
|
+
shadow references use the same graph as other roles. Native Glaze restrictions
|
|
1097
|
+
still apply, including the requirement for shadow backgrounds and foregrounds
|
|
1098
|
+
to reference non-shadow colors. `shadowTuning` exposes `saturationFactor`,
|
|
1099
|
+
`maxSaturation`, `lightnessFactor`, `lightnessBounds`, `minGapTarget`, `alphaMax`,
|
|
1100
|
+
and `bgHueBlend`; a role's own `tuning` takes precedence.
|
|
1101
|
+
|
|
1102
|
+
### Built-in palette inventory
|
|
1103
|
+
|
|
1104
|
+
Every generated role below can be overridden in `theme.palette`. Names map
|
|
1105
|
+
directly to Tasty `#name` tokens. `COOKBOOK_PALETTE_NAMES`, exported from
|
|
1106
|
+
`@tenphi/docs`, lists the same roles for tooling.
|
|
1107
|
+
|
|
1108
|
+
| Area | Roles |
|
|
1109
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1110
|
+
| Surfaces | `surface`, `header`, `overlay`, `surface-2`, `surface-3`, `surface-2-hover`, `surface-2-pressed`, `surface-3-hover`, `surface-3-pressed` |
|
|
1111
|
+
| Reading | `text`, `heading`, `text-soft` (alias `textSoft`), `text-muted` |
|
|
1112
|
+
| Brand and focus | `accent-text`, `accent-surface`, `accent-surface-text`, `accent-surface-subtle`, `accent-surface-2-subtle`, `logo-surface`, `logo-mark`, `focus` |
|
|
1113
|
+
| Borders and effects | `border`, `border-strong`, `shadow`, `clear` |
|
|
1114
|
+
| Status | `info`, `success`, `warning`, `danger`, each with `-text` and `-surface` variants |
|
|
1115
|
+
| Additional hues | `orange`, `green`, `blue`, `purple`, `red`, each with `-text` and `-surface` variants |
|
|
1116
|
+
| Syntax | `syntax-bg`, `syntax-text`, `syntax-comment`, `syntax-punctuation`, `syntax-keyword`, `syntax-string`, `syntax-token`, `syntax-property`, `syntax-number`, `syntax-function`, `syntax-value`, `syntax-operator` |
|
|
1117
|
+
|
|
1118
|
+
## Contrast checks and troubleshooting
|
|
1119
|
+
|
|
1120
|
+
Cookbook checks text, headings, muted reading text, brand links, filled-control
|
|
1121
|
+
labels, status text on its tinted surface, focus rings on each elevated
|
|
1122
|
+
surface, and every palette declaration with a contrast floor. The same Glaze
|
|
1123
|
+
resolution powers rendering and `cookbook doctor`, in light, dark, and both
|
|
1124
|
+
high-contrast modes. Manual `theme.contrastLevel` targets interpolate with
|
|
1125
|
+
Glaze's contrast level.
|
|
1126
|
+
|
|
1127
|
+
`resolveDocsTheme(theme).contrastChecks` lists each foreground/background pair,
|
|
1128
|
+
mode, metric, target, measured value, and pass result. APCA uses display-channel
|
|
1129
|
+
luminance; WCAG ratios use the sRGB transfer function. Transparent foregrounds
|
|
1130
|
+
are composited onto their background before measuring. These checks cover
|
|
1131
|
+
Cookbook's semantic pairs; test actual pages after changing component styles,
|
|
1132
|
+
backgrounds, typography, or layout.
|
|
1133
|
+
|
|
1134
|
+
A `DOCS_SEMANTIC_CONTRAST_UNMET` or `DOCS_BRAND_CONTRAST_UNMET` error names the
|
|
1135
|
+
pair, mode, and required target. Adjust that pair's `theme.palette` declarations:
|
|
1136
|
+
use an absolute tone for reading text, reduce saturation when needed, and keep
|
|
1137
|
+
`autoFlip` enabled when the solver needs to cross its base. A fixed middle-tone
|
|
1138
|
+
button fill may make its label's contrast impossible. Cookbook's default
|
|
1139
|
+
brand fill adapts to avoid this, including for orange, yellow, and pale brands.
|
|
1140
|
+
Focus uses a WCAG 3:1 floor (4.5:1 in high contrast) against the surface ramp.
|
|
1141
|
+
|
|
1142
|
+
Keep contrast requirements when adjusting colors. Extreme custom tone windows,
|
|
1143
|
+
fixed colors, or opacity can prevent a requested floor from being met. A palette
|
|
1144
|
+
check does not replace keyboard, screen-reader, and rendered-page testing.
|
|
1145
|
+
|
|
1146
|
+
## Customize shared page surfaces
|
|
1147
|
+
|
|
1148
|
+
Each bridge has a complete base style tree; supply only the properties you
|
|
1149
|
+
want to change. Sub-elements keep their selectors and all other defaults.
|
|
1150
|
+
For example, a compact search dialog and quieter pagination need no CSS:
|
|
1151
|
+
|
|
1152
|
+
```ts
|
|
1153
|
+
theme: {
|
|
1154
|
+
styles: {
|
|
1155
|
+
Search: { Dialog: { inlineSize: "max 32rem" } },
|
|
1156
|
+
SearchResults: { ResultLink: { color: "#accent-text" } },
|
|
1157
|
+
Pagination: { Link: { padding: "1.5x", fill: "#surface" } },
|
|
1158
|
+
Banner: { padding: "1x 2x" },
|
|
1159
|
+
Markdown: { Quote: { color: "#text", inlinePadding: "3x start" } },
|
|
1160
|
+
},
|
|
1161
|
+
}
|
|
1162
|
+
```
|
|
1163
|
+
|
|
1164
|
+
`Document` owns resets, base typography, generic controls, responsive media,
|
|
1165
|
+
and accessibility utilities. `MainPane` and `MainContent` own the content
|
|
1166
|
+
layout. `Markdown` owns prose, lists, links, quotations, and disclosure
|
|
1167
|
+
anatomy. `Search` owns the dialog; `SearchResults` owns the Pagefind UI.
|
|
1168
|
+
The `Starlight*` trees style compatible upstream component markup; Cookbook's
|
|
1169
|
+
own `Card`, `Callout`, and `Steps` use their respective trees.
|
|
1170
|
+
|
|
1171
|
+
Custom components created with `defineComponent()` receive `theme.customStyles`
|
|
1172
|
+
overrides during server rendering. Units, recipes, states, and presets are
|
|
1173
|
+
resolved there and emitted as static CSS. Cookbook ships no Tasty/Glaze browser
|
|
1174
|
+
runtime, theme configuration, or style hydration setup. Browser scripts and
|
|
1175
|
+
`client:*` islands must not import Cookbook styling, Tasty, or Glaze; the build
|
|
1176
|
+
rejects these imports. Attach small interaction scripts to server-rendered markup
|
|
1177
|
+
or pass already-styled static markup into a client island.
|
|
1178
|
+
|
|
1179
|
+
Code fences and `CodeGroup` use the same `MarkdownCodeBlock` style tree. Its
|
|
1180
|
+
root `$copy-button-size` defaults to `2rem`; the copy control and vertical
|
|
1181
|
+
padding share it, keeping equal top, right, and bottom insets on one-line
|
|
1182
|
+
snippets. The padding follows the `code` preset's line height. Override it with
|
|
1183
|
+
`theme.styles.MarkdownCodeBlock` when changing the control size or code layout.
|
|
1184
|
+
|
|
1185
|
+
### Syntax highlighting and isolated previews
|
|
1186
|
+
|
|
1187
|
+
Shiki classifies code; Tasty renders every token using Glaze's semantic syntax
|
|
1188
|
+
colors. Customize token rules with `theme.styles.SyntaxHighlight`, or their
|
|
1189
|
+
colors with `theme.palette` (for example `syntax-keyword`). Code fences, including
|
|
1190
|
+
MDX and diff blocks, use classes without inline style attributes. Custom Shiki
|
|
1191
|
+
transformers should emit classes; unsupported inline declarations fail with a
|
|
1192
|
+
configuration hint.
|
|
1193
|
+
|
|
1194
|
+
The production build rejects style attributes, style blocks (including inside
|
|
1195
|
+
shadow-root templates), and non-Tasty stylesheets throughout documentation HTML.
|
|
1196
|
+
It parses actual markup, so escaped examples and strings in scripts are allowed.
|
|
1197
|
+
The explicit exception is the separate document in a sandboxed `Preview` iframe;
|
|
1198
|
+
it cannot access its parent's origin. Configure its size with
|
|
1199
|
+
`theme.styles.Preview.Frame`. The documentation shell supports the CSP directive
|
|
1200
|
+
`style-src-attr 'none'`. A host's CSP may also restrict the preview document; when
|
|
1201
|
+
using that directive, authored previews must use style blocks rather than style
|
|
1202
|
+
attributes.
|
|
1203
|
+
|
|
1204
|
+
Search uses an owned, keyboard-accessible dialog with Pagefind's indexing and
|
|
1205
|
+
results UI. Its clear-button sizing is adapted to `SearchResults.Input` styles,
|
|
1206
|
+
so the browser does not need inline layout declarations. The adapter is checked
|
|
1207
|
+
against the pinned Pagefind UI version during builds.
|