@tenphi/renderer 0.22.1 → 0.23.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 (81) hide show
  1. package/dist/client/code-copy.js +3 -3
  2. package/dist/client/code-copy.js.map +1 -1
  3. package/dist/client/heading-links.js +4 -4
  4. package/dist/client/heading-links.js.map +1 -1
  5. package/dist/client/navigation.js +3 -3
  6. package/dist/client/navigation.js.map +1 -1
  7. package/dist/client/search.js +1 -1
  8. package/dist/client/search.js.map +1 -1
  9. package/dist/client/table-of-contents.js +2 -2
  10. package/dist/client/table-of-contents.js.map +1 -1
  11. package/dist/components/Card.styles.js +1 -0
  12. package/dist/components/CodeGroup.astro +8 -1
  13. package/dist/components/CodeGroup.styles.js +1 -2
  14. package/dist/components/Document.styles.js +47 -31
  15. package/dist/components/EditLink.astro +1 -1
  16. package/dist/components/Header.styles.js +13 -13
  17. package/dist/components/HeaderLinks.astro +4 -8
  18. package/dist/components/HeaderLinks.styles.js +17 -17
  19. package/dist/components/Hero.styles.js +28 -30
  20. package/dist/components/Icon.astro +3 -3
  21. package/dist/components/LanguageSelect.styles.js +8 -8
  22. package/dist/components/MainContent.styles.js +3 -3
  23. package/dist/components/MainPane.styles.js +1 -1
  24. package/dist/components/MarkdownAlert.styles.js +16 -17
  25. package/dist/components/MarkdownCodeBlock.styles.js +31 -19
  26. package/dist/components/MarkdownContent.styles.js +47 -89
  27. package/dist/components/MarkdownHeading.styles.js +23 -24
  28. package/dist/components/MarkdownInlineCode.styles.js +1 -1
  29. package/dist/components/MarkdownTable.styles.js +5 -5
  30. package/dist/components/Mermaid.styles.js +4 -1
  31. package/dist/components/MermaidSource.styles.js +1 -1
  32. package/dist/components/MobileMenuFooter.styles.js +1 -1
  33. package/dist/components/MobileMenuToggle.styles.js +3 -3
  34. package/dist/components/MobileNavigationTabs.astro +3 -2
  35. package/dist/components/MobileNavigationTabs.styles.js +3 -3
  36. package/dist/components/MobileTableOfContents.styles.js +2 -2
  37. package/dist/components/PackageVersion.styles.js +1 -1
  38. package/dist/components/PageFrame.styles.js +6 -6
  39. package/dist/components/Pagination.astro +2 -2
  40. package/dist/components/Pagination.styles.js +10 -10
  41. package/dist/components/Preview.astro +3 -4
  42. package/dist/components/Preview.styles.js +2 -2
  43. package/dist/components/Search.styles.js +13 -13
  44. package/dist/components/SearchButton.styles.js +10 -10
  45. package/dist/components/SearchResults.styles.js +21 -31
  46. package/dist/components/SelectPopover.astro +6 -6
  47. package/dist/components/Sidebar.styles.js +58 -49
  48. package/dist/components/SidebarList.astro +9 -6
  49. package/dist/components/SiteLogo.astro +2 -2
  50. package/dist/components/SiteLogo.styles.js +4 -4
  51. package/dist/components/SyntaxHighlight.styles.js +69 -48
  52. package/dist/components/TableOfContents.styles.js +1 -1
  53. package/dist/components/TableOfContentsLayout.styles.js +7 -7
  54. package/dist/components/ThemeSelect.styles.js +12 -12
  55. package/dist/components/TopNavigation.styles.js +1 -1
  56. package/dist/components/VersionSwitcher.styles.js +1 -1
  57. package/dist/components/select-popover-styles.js +14 -14
  58. package/dist/components/tasty-states.js +10 -9
  59. package/dist/eslint-plugin.js +6 -9
  60. package/dist/eslint-plugin.js.map +1 -1
  61. package/dist/index.js +14 -11
  62. package/dist/index.js.map +1 -1
  63. package/dist/markdown/rendered-content.js +2 -2
  64. package/dist/markdown/rendered-content.js.map +1 -1
  65. package/dist/overrides/Header.astro +8 -12
  66. package/dist/overrides/Hero.astro +11 -6
  67. package/dist/overrides/MobileMenuFooter.astro +1 -1
  68. package/dist/overrides/MobileMenuToggle.astro +6 -5
  69. package/dist/overrides/PageFrame.astro +4 -3
  70. package/dist/overrides/Search.astro +7 -7
  71. package/dist/overrides/Sidebar.astro +2 -3
  72. package/dist/overrides/ThemeSelect.astro +2 -2
  73. package/dist/routes/Page.astro +11 -8
  74. package/dist/styling.js +1 -1
  75. package/dist/{tasty-states-_JhxFdK1.js → tasty-states-BIgiJQ3N.js} +7 -10
  76. package/dist/tasty-states-BIgiJQ3N.js.map +1 -0
  77. package/dist/theme/shiki-theme.d.ts.map +1 -1
  78. package/dist/theme/shiki-theme.js +37 -19
  79. package/dist/theme/shiki-theme.js.map +1 -1
  80. package/package.json +3 -3
  81. package/dist/tasty-states-_JhxFdK1.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  //#region src/markdown/rendered-content.ts
2
- const headingPattern = /<div\b[^>]*\bclass=["'][^"']*\bcookbook-heading-wrapper\b[^"']*["'][^>]*>[\s\S]*?<\/div>|<h([1-6])\b([^>]*)>([\s\S]*?)<\/h\1>/gi;
2
+ const headingPattern = /<div\b[^>]*\bdata-element=["']MarkdownHeading["'][^>]*>[\s\S]*?<\/div>|<h([1-6])\b([^>]*)>([\s\S]*?)<\/h\1>/gi;
3
3
  const idPattern = /\sid=(['"])(.*?)\1/i;
4
4
  const tags = /<[^>]*>/g;
5
5
  /** Wrap rendered headings with a visible, accessible permalink. */
@@ -9,7 +9,7 @@ function addHeadingPermalinks(html) {
9
9
  const id = idPattern.exec(attributes)?.[2];
10
10
  if (!id) return heading;
11
11
  const title = escapeAttribute(decodeEntities(content.replace(tags, "").trim()));
12
- return `<div class="cookbook-heading-wrapper level-h${level}">${heading}<a class="cookbook-anchor-link" href="#${escapeAttribute(id)}" aria-label="Permalink to “${title}”"><span class="cookbook-anchor-icon" aria-hidden="true">#</span></a></div>`;
12
+ return `<div class="cookbook-heading-wrapper" data-element="MarkdownHeading" data-heading="" data-level="h${level}">${heading}<a data-element="Anchor" href="#${escapeAttribute(id)}" aria-label="Permalink to “${title}”"><span data-element="AnchorIcon" aria-hidden="true">#</span></a></div>`;
13
13
  });
14
14
  }
15
15
  function decodeEntities(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"rendered-content.js","names":[],"sources":["../../src/markdown/rendered-content.ts"],"sourcesContent":["const headingPattern =\n /<div\\b[^>]*\\bclass=[\"'][^\"']*\\bcookbook-heading-wrapper\\b[^\"']*[\"'][^>]*>[\\s\\S]*?<\\/div>|<h([1-6])\\b([^>]*)>([\\s\\S]*?)<\\/h\\1>/gi;\nconst idPattern = /\\sid=(['\"])(.*?)\\1/i;\nconst tags = /<[^>]*>/g;\n\n/** Wrap rendered headings with a visible, accessible permalink. */\nexport function addHeadingPermalinks(html: string): string {\n return html.replace(\n headingPattern,\n (\n heading,\n level: string | undefined,\n attributes: string | undefined,\n content: string | undefined,\n ) => {\n // Consume an existing heading wrapper unchanged so its inner heading\n // is not matched and wrapped a second time.\n if (!level || attributes === undefined || content === undefined) {\n return heading;\n }\n const id = idPattern.exec(attributes)?.[2];\n if (!id) return heading;\n const title = escapeAttribute(\n decodeEntities(content.replace(tags, \"\").trim()),\n );\n return `<div class=\"cookbook-heading-wrapper level-h${level}\">${heading}<a class=\"cookbook-anchor-link\" href=\"#${escapeAttribute(id)}\" aria-label=\"Permalink to “${title}”\"><span class=\"cookbook-anchor-icon\" aria-hidden=\"true\">#</span></a></div>`;\n },\n );\n}\n\nfunction decodeEntities(value: string): string {\n const named: Record<string, string> = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n quot: '\"',\n };\n return value.replace(\n /&(?:#(\\d+)|#x([\\da-f]+)|(amp|apos|gt|lt|quot));/gi,\n (entity, decimal: string, hexadecimal: string, name: string) => {\n const point = decimal\n ? Number.parseInt(decimal, 10)\n : hexadecimal\n ? Number.parseInt(hexadecimal, 16)\n : undefined;\n return point === undefined\n ? (named[name.toLowerCase()] ?? entity)\n : String.fromCodePoint(point);\n },\n );\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&#39;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\");\n}\n"],"mappings":";AAAA,MAAM,iBACJ;AACF,MAAM,YAAY;AAClB,MAAM,OAAO;;AAGb,SAAgB,qBAAqB,MAAsB;CACzD,OAAO,KAAK,QACV,iBAEE,SACA,OACA,YACA,YACG;EAGH,IAAI,CAAC,SAAS,eAAe,KAAA,KAAa,YAAY,KAAA,GACpD,OAAO;EAET,MAAM,KAAK,UAAU,KAAK,UAAU,CAAC,GAAG;EACxC,IAAI,CAAC,IAAI,OAAO;EAChB,MAAM,QAAQ,gBACZ,eAAe,QAAQ,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CACjD;EACA,OAAO,+CAA+C,MAAM,IAAI,QAAQ,yCAAyC,gBAAgB,EAAE,EAAE,8BAA8B,MAAM;CAC3K,CACF;AACF;AAEA,SAAS,eAAe,OAAuB;CAC7C,MAAM,QAAgC;EACpC,KAAK;EACL,MAAM;EACN,IAAI;EACJ,IAAI;EACJ,MAAM;CACR;CACA,OAAO,MAAM,QACX,sDACC,QAAQ,SAAiB,aAAqB,SAAiB;EAC9D,MAAM,QAAQ,UACV,OAAO,SAAS,SAAS,EAAE,IAC3B,cACE,OAAO,SAAS,aAAa,EAAE,IAC/B,KAAA;EACN,OAAO,UAAU,KAAA,IACZ,MAAM,KAAK,YAAY,MAAM,SAC9B,OAAO,cAAc,KAAK;CAChC,CACF;AACF;AAEA,SAAS,gBAAgB,OAAuB;CAC9C,OAAO,MACJ,WAAW,KAAK,OAAO,CAAC,CACxB,WAAW,MAAK,QAAQ,CAAC,CACzB,WAAW,KAAK,OAAO,CAAC,CACxB,WAAW,KAAK,MAAM,CAAC,CACvB,WAAW,KAAK,MAAM;AAC3B"}
1
+ {"version":3,"file":"rendered-content.js","names":[],"sources":["../../src/markdown/rendered-content.ts"],"sourcesContent":["const headingPattern =\n /<div\\b[^>]*\\bdata-element=[\"']MarkdownHeading[\"'][^>]*>[\\s\\S]*?<\\/div>|<h([1-6])\\b([^>]*)>([\\s\\S]*?)<\\/h\\1>/gi;\nconst idPattern = /\\sid=(['\"])(.*?)\\1/i;\nconst tags = /<[^>]*>/g;\n\n/** Wrap rendered headings with a visible, accessible permalink. */\nexport function addHeadingPermalinks(html: string): string {\n return html.replace(\n headingPattern,\n (\n heading,\n level: string | undefined,\n attributes: string | undefined,\n content: string | undefined,\n ) => {\n // Consume an existing heading wrapper unchanged so its inner heading\n // is not matched and wrapped a second time.\n if (!level || attributes === undefined || content === undefined) {\n return heading;\n }\n const id = idPattern.exec(attributes)?.[2];\n if (!id) return heading;\n const title = escapeAttribute(\n decodeEntities(content.replace(tags, \"\").trim()),\n );\n return `<div class=\"cookbook-heading-wrapper\" data-element=\"MarkdownHeading\" data-heading=\"\" data-level=\"h${level}\">${heading}<a data-element=\"Anchor\" href=\"#${escapeAttribute(id)}\" aria-label=\"Permalink to “${title}”\"><span data-element=\"AnchorIcon\" aria-hidden=\"true\">#</span></a></div>`;\n },\n );\n}\n\nfunction decodeEntities(value: string): string {\n const named: Record<string, string> = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n quot: '\"',\n };\n return value.replace(\n /&(?:#(\\d+)|#x([\\da-f]+)|(amp|apos|gt|lt|quot));/gi,\n (entity, decimal: string, hexadecimal: string, name: string) => {\n const point = decimal\n ? Number.parseInt(decimal, 10)\n : hexadecimal\n ? Number.parseInt(hexadecimal, 16)\n : undefined;\n return point === undefined\n ? (named[name.toLowerCase()] ?? entity)\n : String.fromCodePoint(point);\n },\n );\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&#39;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\");\n}\n"],"mappings":";AAAA,MAAM,iBACJ;AACF,MAAM,YAAY;AAClB,MAAM,OAAO;;AAGb,SAAgB,qBAAqB,MAAsB;CACzD,OAAO,KAAK,QACV,iBAEE,SACA,OACA,YACA,YACG;EAGH,IAAI,CAAC,SAAS,eAAe,KAAA,KAAa,YAAY,KAAA,GACpD,OAAO;EAET,MAAM,KAAK,UAAU,KAAK,UAAU,CAAC,GAAG;EACxC,IAAI,CAAC,IAAI,OAAO;EAChB,MAAM,QAAQ,gBACZ,eAAe,QAAQ,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CACjD;EACA,OAAO,qGAAqG,MAAM,IAAI,QAAQ,kCAAkC,gBAAgB,EAAE,EAAE,8BAA8B,MAAM;CAC1N,CACF;AACF;AAEA,SAAS,eAAe,OAAuB;CAC7C,MAAM,QAAgC;EACpC,KAAK;EACL,MAAM;EACN,IAAI;EACJ,IAAI;EACJ,MAAM;CACR;CACA,OAAO,MAAM,QACX,sDACC,QAAQ,SAAiB,aAAqB,SAAiB;EAC9D,MAAM,QAAQ,UACV,OAAO,SAAS,SAAS,EAAE,IAC3B,cACE,OAAO,SAAS,aAAa,EAAE,IAC/B,KAAA;EACN,OAAO,UAAU,KAAA,IACZ,MAAM,KAAK,YAAY,MAAM,SAC9B,OAAO,cAAc,KAAK;CAChC,CACF;AACF;AAEA,SAAS,gBAAgB,OAAuB;CAC9C,OAAO,MACJ,WAAW,KAAK,OAAO,CAAC,CACxB,WAAW,MAAK,QAAQ,CAAC,CACzB,WAAW,KAAK,OAAO,CAAC,CACxB,WAAW,KAAK,MAAM,CAAC,CACvB,WAAW,KAAK,MAAM;AAC3B"}
@@ -50,7 +50,8 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
50
50
  ---
51
51
 
52
52
  <HeaderRoot
53
- className={`td-header${layout.tabs.length ? " td-header--with-tabs" : ""}`}
53
+ className="td-header"
54
+ data-with-tabs={layout.tabs.length ? "" : undefined}
54
55
  data-has-sidebar={Astro.locals.cookbookRoute.hasSidebar ? "" : undefined}
55
56
  >
56
57
  <div data-element="Primary">
@@ -93,28 +94,22 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
93
94
  />
94
95
  )
95
96
  }
96
- <div data-element="Search" class="cookbook-print-hidden">
97
+ <div data-element="Search" data-print-hidden="">
97
98
  {shouldRenderSearch && <Search />}
98
99
  </div>
99
100
  <HeaderLinks />
100
- <div
101
- data-element="MobileTheme"
102
- class="md:cookbook-hidden cookbook-print-hidden"
103
- >
101
+ <div data-element="MobileTheme" data-print-hidden="">
104
102
  <ThemeSelect />
105
103
  </div>
106
104
  {
107
105
  !Astro.locals.cookbookRoute.hasSidebar &&
108
106
  Object.keys(content.locales ?? {}).length > 1 && (
109
- <div data-element="MobileLanguage" class="cookbook-print-hidden">
107
+ <div data-element="MobileLanguage" data-print-hidden="">
110
108
  <LanguageSelect compact />
111
109
  </div>
112
110
  )
113
111
  }
114
- <div
115
- data-element="Tools"
116
- class="cookbook-hidden md:cookbook-flex cookbook-print-hidden"
117
- >
112
+ <div data-element="Tools" data-print-hidden="">
118
113
  <div data-element="Social"><SocialIcons /></div>
119
114
  <ThemeSelect />
120
115
  <LanguageSelect />
@@ -123,7 +118,8 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
123
118
  {
124
119
  layout.tabs.length > 0 && (
125
120
  <TopNavigationRoot
126
- className="td-top-tabs cookbook-print-hidden"
121
+ className="td-top-tabs"
122
+ data-print-hidden=""
127
123
  aria-label={ui.primary}
128
124
  >
129
125
  {layout.tabs.map((tab, index) => (
@@ -49,20 +49,25 @@ if (image) {
49
49
  />
50
50
  )
51
51
  }
52
- {rawHtml && <div class="hero-html" set:html={rawHtml} />}
53
- <div class="stack">
54
- <div class="copy">
52
+ {rawHtml && <div data-element="Visual" set:html={rawHtml} />}
53
+ <div data-element="Stack">
54
+ <div data-element="Copy">
55
55
  <h1 id="_top" data-page-title set:html={title} />
56
56
  {data.draft && <DraftContentNotice />}
57
- {tagline && <div class="tagline" set:html={tagline} />}
57
+ {tagline && <div data-element="Tagline" set:html={tagline} />}
58
58
  </div>
59
59
  {
60
60
  actions.length > 0 && (
61
- <div class="actions">
61
+ <div data-element="Actions">
62
62
  {actions.map(({ link: href, text, variant }) => (
63
63
  <a
64
64
  {href}
65
- class:list={["cookbook-link-button", variant ?? "secondary"]}
65
+ data-element="Action"
66
+ data-primary={variant === "primary" ? "" : undefined}
67
+ data-secondary={
68
+ !variant || variant === "secondary" ? "" : undefined
69
+ }
70
+ data-minimal={variant === "minimal" ? "" : undefined}
66
71
  >
67
72
  {text}
68
73
  </a>
@@ -5,7 +5,7 @@ import { MobileMenuFooterRoot } from "../components/MobileMenuFooter.styles.js";
5
5
  ---
6
6
 
7
7
  <MobileMenuFooterRoot className="td-mobile-preferences">
8
- <div class="td-mobile-preferences__social">
8
+ <div data-element="Social">
9
9
  <SocialIcons />
10
10
  </div>
11
11
  <LanguageSelect sidebar />
@@ -23,15 +23,16 @@ const section = layout.tabs[active]?.label;
23
23
  ---
24
24
 
25
25
  <MobileMenuToggleRoot
26
+ className="td-menu-button cookbook-menu-button"
26
27
  type="button"
27
28
  popovertarget="cookbook__sidebar"
28
29
  aria-controls="cookbook__sidebar"
29
30
  aria-expanded="false"
30
- className="td-menu-button cookbook-menu-button cookbook-print-hidden"
31
+ data-print-hidden=""
31
32
  >
32
- <Icon name="bars" class="open-menu" />
33
- <span class="sr-only">{Astro.locals.t("menuButton.accessibleLabel")}</span>
34
- {section && <span class="td-menu-button__section">{section}</span>}
33
+ <Icon name="bars" data-element="Icon" />
34
+ <span data-sr-only="">{Astro.locals.t("menuButton.accessibleLabel")}</span>
35
+ {section && <span data-element="Section">{section}</span>}
35
36
  {section && <Icon name="right-caret" />}
36
- <span class="td-menu-button__page">{route.entry.data.title}</span>
37
+ <span data-element="Page">{route.entry.data.title}</span>
37
38
  </MobileMenuToggleRoot>
@@ -10,14 +10,15 @@ const { hasSidebar } = Astro.locals.cookbookRoute;
10
10
  {
11
11
  hasSidebar && (
12
12
  <SidebarRoot
13
+ className="sidebar-pane"
13
14
  id="cookbook__sidebar"
14
- className="sidebar-pane cookbook-print-hidden"
15
+ data-print-hidden=""
15
16
  popover="auto"
16
17
  aria-label={Astro.locals.t("sidebarNav.accessibleLabel")}
17
18
  tabIndex={-1}
18
19
  >
19
20
  <nav
20
- class="sidebar-content"
21
+ data-element="Content"
21
22
  aria-label={Astro.locals.t("sidebarNav.accessibleLabel")}
22
23
  >
23
24
  <slot name="sidebar" />
@@ -25,7 +26,7 @@ const { hasSidebar } = Astro.locals.cookbookRoute;
25
26
  </SidebarRoot>
26
27
  )
27
28
  }
28
- <div class="main-frame"><slot /></div>
29
+ <div data-element="MainFrame"><slot /></div>
29
30
  </PageFrameRoot>
30
31
 
31
32
  <script>
@@ -35,7 +35,7 @@ const translations = {
35
35
  >
36
36
  </SearchButtonRoot>
37
37
  <dialog aria-label={label}>
38
- <div class="dialog-frame">
38
+ <div data-element="Frame">
39
39
  <button
40
40
  type="button"
41
41
  data-element="Close"
@@ -47,13 +47,13 @@ const translations = {
47
47
  {Astro.locals.t("search.devWarning")}
48
48
  </p>
49
49
  ) : (
50
- <div class="search-container">
50
+ <div data-element="Container">
51
51
  <p data-element="Status" data-search-status role="status" hidden />
52
52
  <SearchResultsRoot id="cookbook__search">
53
- <div class="pagefind-ui" role="search" aria-label={label}>
54
- <div class="cookbook-search-field">
53
+ <div data-element="UI" role="search" aria-label={label}>
54
+ <div data-element="Field">
55
55
  <input
56
- class="cookbook-search-input"
56
+ data-element="Input"
57
57
  data-search-input
58
58
  type="text"
59
59
  aria-label={label}
@@ -64,14 +64,14 @@ const translations = {
64
64
  autofocus
65
65
  />
66
66
  <button
67
- class="cookbook-search-clear"
67
+ data-element="Clear"
68
68
  data-clear-search
69
69
  type="button"
70
70
  aria-label={Astro.locals.t("pagefind.clear_search")}
71
71
  hidden
72
72
  />
73
73
  </div>
74
- <div data-search-results />
74
+ <div data-element="EngineUI" data-search-results />
75
75
  </div>
76
76
  </SearchResultsRoot>
77
77
  </div>
@@ -46,10 +46,9 @@ const sidebar =
46
46
  const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
47
47
  ---
48
48
 
49
- <div class="td-sidebar-heading">
49
+ <div data-element="MobileHeading">
50
50
  <a
51
51
  data-element="HomeLink"
52
- class="td-sidebar-heading__home"
53
52
  href={localeHref(
54
53
  (content.logo && content.logo.href) || "/",
55
54
  currentPath,
@@ -83,7 +82,7 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
83
82
  <SidebarList entries={sidebar} />
84
83
  </cookbook-sidebar>
85
84
 
86
- <div class="md:cookbook-hidden">
85
+ <div data-mobile="">
87
86
  <MobileMenuFooter />
88
87
  </div>
89
88
 
@@ -50,7 +50,7 @@ const contrasts = [
50
50
  />
51
51
  <Icon name={icon} />
52
52
  <span>{label}</span>
53
- <Icon name="approve-check" class="checkmark" />
53
+ <Icon name="approve-check" data-element="Checkmark" />
54
54
  </label>
55
55
  ))
56
56
  }
@@ -73,7 +73,7 @@ const contrasts = [
73
73
  <ContrastIcon level={icon} />
74
74
  )}
75
75
  <span>{label}</span>
76
- <Icon name="approve-check" class="checkmark" />
76
+ <Icon name="approve-check" data-element="Checkmark" />
77
77
  </label>
78
78
  ))
79
79
  }
@@ -64,8 +64,11 @@ const indexed = route.id !== "/404" && data.pagefind !== false && !data.draft;
64
64
  <div>
65
65
  {
66
66
  route.toc && (
67
- <TableOfContentsLayoutRoot className="right-sidebar-container cookbook-print-hidden">
68
- <div class="right-sidebar">
67
+ <TableOfContentsLayoutRoot
68
+ className="right-sidebar-container"
69
+ data-print-hidden=""
70
+ >
71
+ <div data-element="Content">
69
72
  <MobileTableOfContents />
70
73
  <TableOfContentsRoot className="right-sidebar-panel">
71
74
  <h2>{Astro.locals.t("tableOfContents.onThisPage")}</h2>
@@ -96,8 +99,8 @@ const indexed = route.id !== "/404" && data.pagefind !== false && !data.draft;
96
99
  }
97
100
  {
98
101
  data.hero ? (
99
- <div class="content-panel">
100
- <div class="cookbook-container">
102
+ <div data-element="Panel">
103
+ <div data-element="Container">
101
104
  <Hero />
102
105
  <MarkdownContent>
103
106
  <slot />
@@ -107,14 +110,14 @@ const indexed = route.id !== "/404" && data.pagefind !== false && !data.draft;
107
110
  </div>
108
111
  ) : (
109
112
  <>
110
- <div class="content-panel">
111
- <div class="cookbook-container">
113
+ <div data-element="Panel">
114
+ <div data-element="Container">
112
115
  <h1 id="_top" data-page-title set:html={data.title} />
113
116
  {data.draft && <DraftContentNotice />}
114
117
  </div>
115
118
  </div>
116
- <div class="content-panel">
117
- <div class="cookbook-container">
119
+ <div data-element="Panel">
120
+ <div data-element="Container">
118
121
  <MarkdownContent>
119
122
  <slot />
120
123
  </MarkdownContent>
package/dist/styling.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as resolveComponentStyles } from "./component-styles-DstqPFf3.js";
2
- import { t as configureCookbookStates } from "./tasty-states-_JhxFdK1.js";
2
+ import { t as configureCookbookStates } from "./tasty-states-BIgiJQ3N.js";
3
3
  import { n as extendComponent, t as defineComponent } from "./define-component-BP4YwMak.js";
4
4
  import { mergeStyles, tasty, useGlobalStyles } from "@tenphi/tasty";
5
5
  //#region src/components/Button.styles.js
@@ -9,16 +9,13 @@ const cookbookStates = {
9
9
  "@system-dark": systemDark,
10
10
  "@light": `@root(theme=light) | (!@root(theme) & ${systemLight})`,
11
11
  "@dark": `@root(theme=dark) | (!@root(theme) & ${systemDark})`,
12
- "@mobile": "@media(w < 50rem)",
13
- "@desktop": "@media(w >= 50rem)",
14
- "@small": "@media(w <= 40rem)",
15
- "@compact": "@media(w <= 23rem)",
16
- "@shell-mobile": "@media(w <= 48rem)",
17
- "@shell-desktop": "@media(w > 48rem)",
18
- "@narrow-layout": "@media(w < 72rem)",
19
- "@medium-layout": "@media(w >= 50rem) & @media(w < 72rem)",
12
+ "@sm": "@media(w > 40rem)",
13
+ "@md": "@media(w >= 50rem)",
14
+ "@lg": "@media(w >= 72rem)",
20
15
  "@reduced-motion": "@media(prefers-reduced-motion: reduce)",
21
- "@popover-open": ":is(:popover-open)"
16
+ "@prose": "@own(!:is([data-not-content] *))",
17
+ "@prose-block": "@own(!:is([data-not-content] *)) & (@own(block) | @own(!:is(a,strong,em,del,span,input,code,br,li,dt,dd))) & (@own(:is(:not(a,strong,em,del,span,input,code,br) + *)) | @own(:is([data-block] + *)))",
18
+ "@prose-heading": "@own(!:is([data-not-content] *)) & @own(!:is(h1 + *,h2 + *,h3 + *,h4 + *,h5 + *,h6 + *,[data-heading] + *))"
22
19
  };
23
20
  let configured = false;
24
21
  let configuredRuntime;
@@ -44,4 +41,4 @@ function configureCookbookStates() {
44
41
  //#endregion
45
42
  export { cookbookStates as n, configureCookbookStates as t };
46
43
 
47
- //# sourceMappingURL=tasty-states-_JhxFdK1.js.map
44
+ //# sourceMappingURL=tasty-states-BIgiJQ3N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasty-states-BIgiJQ3N.js","names":[],"sources":["../src/components/tasty-states.js"],"sourcesContent":["import { configure, getGlobalPredefinedStates } from \"@tenphi/tasty\";\nimport { resolveTypographyPresets } from \"../theme/defaults.js\";\nimport {\n TASTY_UNITS,\n TASTY_SPACING_PROPERTIES,\n} from \"../theme/tasty-config.js\";\n\nconst systemLight = \"@media(prefers-color-scheme: light)\";\nconst systemDark = \"@media(prefers-color-scheme: dark)\";\n\nexport const cookbookStates = {\n \"@system-light\": systemLight,\n \"@system-dark\": systemDark,\n \"@light\": `@root(theme=light) | (!@root(theme) & ${systemLight})`,\n \"@dark\": `@root(theme=dark) | (!@root(theme) & ${systemDark})`,\n \"@sm\": \"@media(w > 40rem)\",\n \"@md\": \"@media(w >= 50rem)\",\n \"@lg\": \"@media(w >= 72rem)\",\n \"@reduced-motion\": \"@media(prefers-reduced-motion: reduce)\",\n // Check each selected element's ancestry so isolated sections do not affect\n // surrounding prose in the same Markdown root.\n \"@prose\": \"@own(!:is([data-not-content] *))\",\n \"@prose-block\":\n \"@own(!:is([data-not-content] *)) & (@own(block) | @own(!:is(a,strong,em,del,span,input,code,br,li,dt,dd))) & (@own(:is(:not(a,strong,em,del,span,input,code,br) + *)) | @own(:is([data-block] + *)))\",\n \"@prose-heading\":\n \"@own(!:is([data-not-content] *)) & @own(!:is(h1 + *,h2 + *,h3 + *,h4 + *,h5 + *,h6 + *,[data-heading] + *))\",\n};\n\nlet configured = false;\nlet configuredRuntime;\n\n/** Configure aliases in the renderer's Tasty module before styles are parsed. */\nexport function configureCookbookStates() {\n // Process-local server configuration shared across Astro/Vite module graphs.\n // The integration prevents this module from entering browser bundles.\n const runtime = globalThis.__tenphiCookbookTastyRuntime;\n if (configured && configuredRuntime === runtime) return;\n configure({\n presets: resolveTypographyPresets(),\n properties: TASTY_SPACING_PROPERTIES,\n ...runtime,\n units: { ...TASTY_UNITS, ...runtime?.units },\n });\n configuredRuntime = runtime;\n // The integration may have configured this runtime already, including\n // consumer overrides of built-in breakpoints. Only supply missing aliases.\n const existingStates = getGlobalPredefinedStates();\n const missingStates = Object.fromEntries(\n Object.entries(cookbookStates).filter(\n ([name]) => existingStates[name] === undefined,\n ),\n );\n if (Object.keys(missingStates).length) configure({ states: missingStates });\n configured = true;\n}\n"],"mappings":";;;;AAOA,MAAM,cAAc;AACpB,MAAM,aAAa;AAEnB,MAAa,iBAAiB;CAC5B,iBAAiB;CACjB,gBAAgB;CAChB,UAAU,yCAAyC,YAAY;CAC/D,SAAS,wCAAwC,WAAW;CAC5D,OAAO;CACP,OAAO;CACP,OAAO;CACP,mBAAmB;CAGnB,UAAU;CACV,gBACE;CACF,kBACE;AACJ;AAEA,IAAI,aAAa;AACjB,IAAI;;AAGJ,SAAgB,0BAA0B;CAGxC,MAAM,UAAU,WAAW;CAC3B,IAAI,cAAc,sBAAsB,SAAS;CACjD,UAAU;EACR,SAAS,yBAAyB;EAClC,YAAY;EACZ,GAAG;EACH,OAAO;GAAE,GAAG;GAAa,GAAG,SAAS;EAAM;CAC7C,CAAC;CACD,oBAAoB;CAGpB,MAAM,iBAAiB,0BAA0B;CACjD,MAAM,gBAAgB,OAAO,YAC3B,OAAO,QAAQ,cAAc,CAAC,CAAC,QAC5B,CAAC,UAAU,eAAe,UAAU,KAAA,CACvC,CACF;CACA,IAAI,OAAO,KAAK,aAAa,CAAC,CAAC,QAAQ,UAAU,EAAE,QAAQ,cAAc,CAAC;CAC1E,aAAa;AACf"}
@@ -1 +1 @@
1
- {"version":3,"file":"shiki-theme.d.ts","names":[],"sources":["../../src/theme/shiki-theme.ts"],"mappings":";;;;;;;iBA2KgB,oBACd,QAAQ,sCACP;iBAqNa,0BAA0B,QAAQ;iBAGlC,yBAAqB"}
1
+ {"version":3,"file":"shiki-theme.d.ts","names":[],"sources":["../../src/theme/shiki-theme.ts"],"mappings":";;;;;;;iBAmOgB,oBACd,QAAQ,sCACP;iBAqNa,0BAA0B,QAAQ;iBAGlC,yBAAqB"}
@@ -60,10 +60,10 @@ const syntaxColors = new Map([
60
60
  background,
61
61
  inserted,
62
62
  deleted
63
- ].map((color) => [color, `td-${color.slice(6, -7)}`]));
63
+ ].map((color) => [color, color.slice(6, -7)]));
64
64
  /** Keep grammar classification in Shiki and all presentation in Tasty. */
65
- const tastyClassesTransformer = {
66
- name: "cookbook:tasty-classes",
65
+ const tastyModifiersTransformer = {
66
+ name: "cookbook:tasty-modifiers",
67
67
  enforce: "post",
68
68
  root(root) {
69
69
  const visit = (node) => {
@@ -74,41 +74,59 @@ const tastyClassesTransformer = {
74
74
  const separator = declaration.indexOf(":");
75
75
  const key = declaration.slice(0, separator).trim();
76
76
  const value = declaration.slice(separator + 1).trim();
77
- let className;
78
- if (key === "color") className = syntaxColors.get(value);
79
- else if (key === "background-color" && value === background) className = "td-syntax-bg";
80
- else if (key === "font-style" && value === "italic") className = "td-syntax-italic";
81
- else if (key === "font-weight" && value === "bold") className = "td-syntax-strong";
82
- else if (key === "text-decoration" && value === "underline") className = "td-syntax-underline";
83
- else if (key === "overflow-x" && value === "auto") className = "td-syntax-scroll";
84
- else if (key === "white-space" && value === "pre-wrap" || key === "word-wrap" && value === "break-word") className = "td-syntax-wrap";
85
- else if (key === "user-select" && value === "none") className = "td-syntax-marker";
86
- if (!className) throw new Error(`Unsupported Shiki style ${JSON.stringify(declaration)}. Use semantic classes and theme.styles.SyntaxHighlight for custom transformers.`);
87
- this.addClassToHast(node, className);
77
+ let modifier;
78
+ if (key === "color") modifier = syntaxColors.get(value);
79
+ else if (key === "background-color" && value === background) modifier = "syntax-bg";
80
+ else if (key === "font-style" && value === "italic") modifier = "syntax-italic";
81
+ else if (key === "font-weight" && value === "bold") modifier = "syntax-strong";
82
+ else if (key === "text-decoration" && value === "underline") modifier = "syntax-underline";
83
+ else if (key === "overflow-x" && value === "auto") modifier = "syntax-scroll";
84
+ else if (key === "white-space" && value === "pre-wrap" || key === "word-wrap" && value === "break-word") modifier = "syntax-wrap";
85
+ else if (key === "user-select" && value === "none") modifier = "syntax-marker";
86
+ if (!modifier) throw new Error(`Unsupported Shiki style ${JSON.stringify(declaration)}. Use semantic data modifiers and theme.styles.SyntaxHighlight for custom transformers.`);
87
+ node.properties[`data-${modifier}`] = "";
88
88
  }
89
89
  delete node.properties.style;
90
90
  }
91
+ const classValues = [node.properties?.class, node.properties?.className];
92
+ const classes = classValues.flatMap((value) => typeof value === "string" ? value.split(/\s+/).filter(Boolean) : Array.isArray(value) ? value : []);
93
+ if (classValues.some((value) => typeof value === "string" || Array.isArray(value))) {
94
+ for (const name of classes) if (name === "astro-code" || name === "tasty-code" || name === "shiki") node.properties["data-syntax"] = "";
95
+ else if (name === "line") node.properties.dataElement = "Line";
96
+ else if (node.tagName !== "pre") throw new Error(`Unsupported Shiki class ${JSON.stringify(name)}. Use semantic data modifiers and theme.styles.SyntaxHighlight for custom transformers.`);
97
+ delete node.properties.className;
98
+ if (node.tagName === "pre") node.properties.class = ["tasty-code", ...classes.filter((name) => ![
99
+ "astro-code",
100
+ "tasty-code",
101
+ "shiki"
102
+ ].includes(name))].join(" ");
103
+ else delete node.properties.class;
104
+ }
91
105
  node.children?.forEach(visit);
106
+ if (node.properties?.dataElement === "Line" && node.children?.every(emptyToken)) node.children = [];
92
107
  };
93
108
  visit(root);
94
109
  }
95
110
  };
111
+ function emptyToken(node) {
112
+ return node.type === "text" ? node.value === "" : node.tagName === "span" && (node.children ?? []).every(emptyToken);
113
+ }
96
114
  const diffLanguages = /* @__PURE__ */ new Set(["diff", "patch"]);
97
115
  /**
98
116
  * The diff grammar colors individual tokens, but it does not expose a stable
99
- * whole-line selector. Add semantic classes so insertions and deletions can
117
+ * whole-line selector. Add semantic modifiers so insertions and deletions can
100
118
  * receive subtle, full-width surfaces without hiding their +/- markers.
101
119
  */
102
120
  const diffLineTransformer = {
103
121
  name: "cookbook:diff-lines",
104
122
  pre(element) {
105
- if (this.options.lang && diffLanguages.has(this.options.lang)) this.addClassToHast(element, "td-diff");
123
+ if (this.options.lang && diffLanguages.has(this.options.lang)) element.properties["data-diff"] = "";
106
124
  },
107
125
  line(element, lineNumber) {
108
126
  if (!this.options.lang || !diffLanguages.has(this.options.lang)) return;
109
127
  const line = this.source.split(/\r?\n/)[lineNumber - 1] ?? "";
110
- if (line.startsWith("+") && !line.startsWith("+++")) this.addClassToHast(element, "td-diff-line--inserted");
111
- else if (line.startsWith("-") && !line.startsWith("---")) this.addClassToHast(element, "td-diff-line--deleted");
128
+ if (line.startsWith("+") && !line.startsWith("+++")) element.properties["data-inserted"] = "";
129
+ else if (line.startsWith("-") && !line.startsWith("---")) element.properties["data-deleted"] = "";
112
130
  }
113
131
  };
114
132
  /**
@@ -123,7 +141,7 @@ function cookbookShikiConfig(config) {
123
141
  const hasTsx = languages.some((language) => language === "tsx" || typeof language === "object" && language !== null && "name" in language && language.name === "tsx");
124
142
  if (!transformers.includes(bashPlaceholderTransformer)) transformers.push(bashPlaceholderTransformer);
125
143
  if (!transformers.includes(diffLineTransformer)) transformers.push(diffLineTransformer);
126
- if (!transformers.includes(tastyClassesTransformer)) transformers.push(tastyClassesTransformer);
144
+ if (!transformers.includes(tastyModifiersTransformer)) transformers.push(tastyModifiersTransformer);
127
145
  return {
128
146
  ...config,
129
147
  langs: hasTsx ? languages : [...languages, "tsx"],
@@ -1 +1 @@
1
- {"version":3,"file":"shiki-theme.js","names":[],"sources":["../../src/theme/shiki-theme.ts"],"sourcesContent":["const comment = \"var(--syntax-comment-color)\";\nconst punctuation = \"var(--syntax-punctuation-color)\";\nconst keyword = \"var(--syntax-keyword-color)\";\nconst string = \"var(--syntax-string-color)\";\nconst token = \"var(--syntax-token-color)\";\nconst property = \"var(--syntax-property-color)\";\nconst number = \"var(--syntax-number-color)\";\nconst func = \"var(--syntax-function-color)\";\nconst value = \"var(--syntax-value-color)\";\nconst operator = \"var(--syntax-operator-color)\";\nconst foreground = \"var(--syntax-text-color)\";\nconst background = \"var(--syntax-bg-color)\";\nconst inserted = \"var(--green-text-color)\";\nconst deleted = \"var(--red-text-color)\";\n\ntype HighlightToken = {\n content: string;\n offset: number;\n color?: string;\n};\n\nconst shellLanguages = new Set([\"bash\", \"sh\", \"shell\", \"shellscript\", \"zsh\"]);\nconst shellPlaceholder = /<[A-Za-z][A-Za-z0-9_-]*>/g;\n\n/**\n * Shell grammars interpret documentation placeholders such as `<plan-id>` as\n * redirections and can split the final character into an unscoped token. Keep\n * the placeholder name visually coherent while retaining the operator color\n * on the angle brackets.\n */\nconst bashPlaceholderTransformer = {\n name: \"cookbook:bash-placeholders\",\n enforce: \"post\" as const,\n tokens(\n this: { source: string; options: { lang?: string } },\n lines: HighlightToken[][],\n ): HighlightToken[][] | undefined {\n if (!this.options.lang || !shellLanguages.has(this.options.lang)) return;\n const ranges = [...this.source.matchAll(shellPlaceholder)].map((match) => ({\n start: (match.index ?? 0) + 1,\n end: (match.index ?? 0) + match[0].length - 1,\n }));\n if (ranges.length === 0) return;\n\n for (const line of lines) {\n for (const highlighted of line) {\n const start = highlighted.offset;\n const end = start + highlighted.content.length;\n if (ranges.some((range) => start < range.end && end > range.start)) {\n highlighted.color = string;\n }\n }\n }\n return lines;\n },\n};\n\ntype HastElement = {\n type?: string;\n tagName?: string;\n properties: Record<string, unknown>;\n children?: HastElement[];\n};\n\nconst syntaxColors = new Map(\n [\n comment,\n punctuation,\n keyword,\n string,\n token,\n property,\n number,\n func,\n value,\n operator,\n foreground,\n background,\n inserted,\n deleted,\n ].map((color) => [color, `td-${color.slice(6, -7)}`]),\n);\n\n/** Keep grammar classification in Shiki and all presentation in Tasty. */\nconst tastyClassesTransformer = {\n name: \"cookbook:tasty-classes\",\n enforce: \"post\" as const,\n root(this: DiffTransformerContext, root: HastElement): void {\n const visit = (node: HastElement) => {\n const style = node.properties?.style;\n if (typeof style === \"string\") {\n for (const declaration of style.split(\";\")) {\n if (!declaration.trim()) continue;\n const separator = declaration.indexOf(\":\");\n const key = declaration.slice(0, separator).trim();\n const value = declaration.slice(separator + 1).trim();\n let className: string | undefined;\n if (key === \"color\") className = syntaxColors.get(value);\n else if (key === \"background-color\" && value === background)\n className = \"td-syntax-bg\";\n else if (key === \"font-style\" && value === \"italic\")\n className = \"td-syntax-italic\";\n else if (key === \"font-weight\" && value === \"bold\")\n className = \"td-syntax-strong\";\n else if (key === \"text-decoration\" && value === \"underline\")\n className = \"td-syntax-underline\";\n else if (key === \"overflow-x\" && value === \"auto\")\n className = \"td-syntax-scroll\";\n else if (\n (key === \"white-space\" && value === \"pre-wrap\") ||\n (key === \"word-wrap\" && value === \"break-word\")\n )\n className = \"td-syntax-wrap\";\n else if (key === \"user-select\" && value === \"none\")\n className = \"td-syntax-marker\";\n if (!className)\n throw new Error(\n `Unsupported Shiki style ${JSON.stringify(declaration)}. Use semantic classes and theme.styles.SyntaxHighlight for custom transformers.`,\n );\n this.addClassToHast(node, className);\n }\n delete node.properties.style;\n }\n node.children?.forEach(visit);\n };\n visit(root);\n },\n};\n\ntype DiffTransformerContext = {\n source: string;\n options: { lang?: string };\n addClassToHast(element: HastElement, className: string): HastElement;\n};\n\nconst diffLanguages = new Set([\"diff\", \"patch\"]);\n\n/**\n * The diff grammar colors individual tokens, but it does not expose a stable\n * whole-line selector. Add semantic classes so insertions and deletions can\n * receive subtle, full-width surfaces without hiding their +/- markers.\n */\nconst diffLineTransformer = {\n name: \"cookbook:diff-lines\",\n pre(this: DiffTransformerContext, element: HastElement): void {\n if (this.options.lang && diffLanguages.has(this.options.lang)) {\n this.addClassToHast(element, \"td-diff\");\n }\n },\n line(\n this: DiffTransformerContext,\n element: HastElement,\n lineNumber: number,\n ): void {\n if (!this.options.lang || !diffLanguages.has(this.options.lang)) return;\n\n const line = this.source.split(/\\r?\\n/)[lineNumber - 1] ?? \"\";\n if (line.startsWith(\"+\") && !line.startsWith(\"+++\")) {\n this.addClassToHast(element, \"td-diff-line--inserted\");\n } else if (line.startsWith(\"-\") && !line.startsWith(\"---\")) {\n this.addClassToHast(element, \"td-diff-line--deleted\");\n }\n },\n};\n\n/**\n * Astro loads fenced-code grammars lazily. MDX embeds TSX, but loading MDX by\n * itself leaves that embedded grammar unavailable and produces partially\n * highlighted imports and JSX. Preload TSX while preserving consumer-supplied\n * languages and transformers.\n */\nexport function cookbookShikiConfig(\n config: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const languages = Array.isArray(config?.langs) ? [...config.langs] : [];\n const transformers = Array.isArray(config?.transformers)\n ? [...config.transformers]\n : [];\n const hasTsx = languages.some(\n (language) =>\n language === \"tsx\" ||\n (typeof language === \"object\" &&\n language !== null &&\n \"name\" in language &&\n language.name === \"tsx\"),\n );\n\n if (!transformers.includes(bashPlaceholderTransformer)) {\n transformers.push(bashPlaceholderTransformer);\n }\n if (!transformers.includes(diffLineTransformer)) {\n transformers.push(diffLineTransformer);\n }\n if (!transformers.includes(tastyClassesTransformer)) {\n transformers.push(tastyClassesTransformer);\n }\n\n return {\n ...config,\n langs: hasTsx ? languages : [...languages, \"tsx\"],\n theme: tastyCodeTheme,\n transformers,\n };\n}\n\n/**\n * Shiki performs the grammatical classification, while every emitted color\n * remains a reference to a Glaze-generated token owned by Tasty.\n */\nconst tastyCodeTheme = {\n name: \"tasty-code\",\n type: \"light\" as const,\n fg: foreground,\n bg: background,\n colors: {\n \"editor.background\": background,\n \"editor.foreground\": foreground,\n },\n settings: [\n {\n scope: [\n \"comment\",\n \"comment.line\",\n \"comment.block\",\n \"punctuation.definition.comment\",\n ],\n settings: { foreground: comment, fontStyle: \"italic\" },\n },\n {\n scope: [\n \"keyword\",\n \"keyword.control\",\n \"keyword.other\",\n \"storage.type\",\n \"storage.modifier\",\n \"keyword.control.at-rule.tasty\",\n \"keyword.control.at-rule.media.tasty\",\n \"keyword.control.at-rule.media-type.tasty\",\n \"keyword.control.at-rule.starting.tasty\",\n \"keyword.control.state-alias.tasty\",\n ],\n settings: { foreground: keyword },\n },\n {\n scope: [\n \"string\",\n \"string.quoted\",\n \"string.template\",\n \"string.quoted.attribute-value.tasty\",\n \"string.unquoted.attribute-value.tasty\",\n ],\n settings: { foreground: string },\n },\n {\n scope: [\n \"support.constant.color.tasty-token\",\n \"support.constant.color.tasty-token.builtin\",\n \"constant.other.color.tasty-token\",\n \"constant.other.color.tasty\",\n \"constant.other.color.hex\",\n \"constant.other.color.rgb-value\",\n ],\n settings: { foreground: token },\n },\n {\n scope: [\n \"constant.numeric\",\n \"constant.numeric.tasty\",\n \"constant.numeric.custom-unit.tasty\",\n \"constant.numeric.css-with-unit\",\n \"constant.numeric.bare.tasty\",\n \"constant.numeric.css\",\n \"constant.numeric.keyframe-step.tasty\",\n \"constant.language.boolean.tasty\",\n ],\n settings: { foreground: number },\n },\n {\n scope: [\n \"support.type.property-name.tasty\",\n \"variable.other.constant.tasty\",\n \"entity.other.attribute-name.tsx\",\n \"entity.other.attribute-name.jsx\",\n ],\n settings: { foreground: property },\n },\n {\n scope: [\"variable\", \"variable.other\"],\n settings: { foreground },\n },\n {\n scope: [\n \"entity.name.function\",\n \"support.function\",\n \"support.function.misc.css\",\n \"entity.name.tag\",\n \"entity.name.tag.tsx\",\n \"support.class.component\",\n \"entity.name.type.tasty\",\n \"entity.name.tag.tasty\",\n ],\n settings: { foreground: func },\n },\n {\n scope: [\n \"support.constant.property-value.tasty\",\n \"support.constant.property-value.tasty-display\",\n \"support.constant.property-value.tasty-directional\",\n \"support.constant.property-value.tasty-preset\",\n \"support.constant.property-value.tasty-shape\",\n \"support.constant.property-value.tasty-scrollbar\",\n \"support.constant.property-value.tasty-state\",\n \"support.constant.property-value.tasty-cursor\",\n \"support.constant.property-value.tasty-overflow\",\n \"support.constant.property-value.tasty-position\",\n \"support.constant.property-value.tasty-flex\",\n \"support.constant.property-value.tasty-font\",\n \"support.constant.property-value.tasty-text\",\n \"support.constant.property-value.tasty-alignment\",\n \"support.constant.property-value.tasty-border-style\",\n \"support.constant.property-value.tasty-whitespace\",\n \"support.constant.property-value.tasty-global\",\n \"support.constant.property-value.tasty-transition\",\n \"support.constant.property-value.css-syntax\",\n \"entity.other.attribute-name\",\n \"entity.other.attribute-name.tasty\",\n \"entity.other.attribute-name.pseudo-class.tasty\",\n \"entity.other.attribute-name.pseudo-class.css\",\n \"entity.other.attribute-name.class.tasty\",\n \"entity.other.attribute-name.pseudo-element.css\",\n \"punctuation.definition.entity.css\",\n ],\n settings: { foreground: value },\n },\n {\n scope: [\n \"keyword.operator\",\n \"keyword.operator.logical.tasty\",\n \"keyword.operator.arithmetic.css\",\n \"keyword.operator.assignment\",\n \"keyword.operator.selector-affix.tasty\",\n \"keyword.operator.attribute-selector.tasty\",\n \"keyword.operator.comparison.tasty\",\n ],\n settings: { foreground: operator },\n },\n {\n scope: [\n \"punctuation.definition.string\",\n \"punctuation.separator\",\n \"punctuation.definition.block\",\n \"punctuation.definition.array\",\n \"punctuation.section\",\n \"punctuation.definition.auto-calc\",\n \"punctuation.definition.attribute-selector\",\n \"punctuation.definition.tag\",\n \"punctuation.definition.pseudo-class\",\n \"punctuation.definition.fallback\",\n \"meta.brace\",\n ],\n settings: { foreground: punctuation },\n },\n {\n scope: [\"keyword.control.at-rule\", \"entity.name.tag.class.css\"],\n settings: { foreground: keyword },\n },\n {\n scope: [\"support.type.property-name.css\", \"meta.property-name.css\"],\n settings: { foreground: property },\n },\n {\n scope: [\"punctuation.definition.inserted.diff\"],\n settings: { foreground: inserted, fontStyle: \"bold\" },\n },\n {\n scope: [\"punctuation.definition.deleted.diff\"],\n settings: { foreground: deleted, fontStyle: \"bold\" },\n },\n ],\n};\n\n// Astro executes integrations and page modules in separate module graphs.\n// Share server-only transformer functions without serializing them into pages.\nconst sharedShiki = globalThis as typeof globalThis & {\n __tenphiCookbookShiki?: Record<string, unknown>;\n};\nexport function configureCodeHighlighting(config: Record<string, unknown>) {\n sharedShiki.__tenphiCookbookShiki = config;\n}\nexport function codeGroupHighlighting() {\n return sharedShiki.__tenphiCookbookShiki ?? cookbookShikiConfig(undefined);\n}\n"],"mappings":"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K;EAC/B;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,MAAM;EAChC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,SAAS;EACnC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,YAAY;EACtC;EACA;GACE,OAAO,CAAC,2BAA2B,2BAA2B;GAC9D,UAAU,EAAE,YAAY,QAAQ;EAClC;EACA;GACE,OAAO,CAAC,kCAAkC,wBAAwB;GAClE,UAAU,EAAE,YAAY,SAAS;EACnC;EACA;GACE,OAAO,CAAC,sCAAsC;GAC9C,UAAU;IAAE,YAAY;IAAU,WAAW;GAAO;EACtD;EACA;GACE,OAAO,CAAC,qCAAqC;GAC7C,UAAU;IAAE,YAAY;IAAS,WAAW;GAAO;EACrD;CACF;AACF;AAIA,MAAM,cAAc;AAGpB,SAAgB,0BAA0B,QAAiC;CACzE,YAAY,wBAAwB;AACtC;AACA,SAAgB,wBAAwB;CACtC,OAAO,YAAY,yBAAyB,oBAAoB,KAAA,CAAS;AAC3E"}
1
+ {"version":3,"file":"shiki-theme.js","names":[],"sources":["../../src/theme/shiki-theme.ts"],"sourcesContent":["const comment = \"var(--syntax-comment-color)\";\nconst punctuation = \"var(--syntax-punctuation-color)\";\nconst keyword = \"var(--syntax-keyword-color)\";\nconst string = \"var(--syntax-string-color)\";\nconst token = \"var(--syntax-token-color)\";\nconst property = \"var(--syntax-property-color)\";\nconst number = \"var(--syntax-number-color)\";\nconst func = \"var(--syntax-function-color)\";\nconst value = \"var(--syntax-value-color)\";\nconst operator = \"var(--syntax-operator-color)\";\nconst foreground = \"var(--syntax-text-color)\";\nconst background = \"var(--syntax-bg-color)\";\nconst inserted = \"var(--green-text-color)\";\nconst deleted = \"var(--red-text-color)\";\n\ntype HighlightToken = {\n content: string;\n offset: number;\n color?: string;\n};\n\nconst shellLanguages = new Set([\"bash\", \"sh\", \"shell\", \"shellscript\", \"zsh\"]);\nconst shellPlaceholder = /<[A-Za-z][A-Za-z0-9_-]*>/g;\n\n/**\n * Shell grammars interpret documentation placeholders such as `<plan-id>` as\n * redirections and can split the final character into an unscoped token. Keep\n * the placeholder name visually coherent while retaining the operator color\n * on the angle brackets.\n */\nconst bashPlaceholderTransformer = {\n name: \"cookbook:bash-placeholders\",\n enforce: \"post\" as const,\n tokens(\n this: { source: string; options: { lang?: string } },\n lines: HighlightToken[][],\n ): HighlightToken[][] | undefined {\n if (!this.options.lang || !shellLanguages.has(this.options.lang)) return;\n const ranges = [...this.source.matchAll(shellPlaceholder)].map((match) => ({\n start: (match.index ?? 0) + 1,\n end: (match.index ?? 0) + match[0].length - 1,\n }));\n if (ranges.length === 0) return;\n\n for (const line of lines) {\n for (const highlighted of line) {\n const start = highlighted.offset;\n const end = start + highlighted.content.length;\n if (ranges.some((range) => start < range.end && end > range.start)) {\n highlighted.color = string;\n }\n }\n }\n return lines;\n },\n};\n\ntype HastElement = {\n type?: string;\n tagName?: string;\n value?: string;\n properties: Record<string, unknown>;\n children?: HastElement[];\n};\n\nconst syntaxColors = new Map(\n [\n comment,\n punctuation,\n keyword,\n string,\n token,\n property,\n number,\n func,\n value,\n operator,\n foreground,\n background,\n inserted,\n deleted,\n ].map((color) => [color, color.slice(6, -7)]),\n);\n\n/** Keep grammar classification in Shiki and all presentation in Tasty. */\nconst tastyModifiersTransformer = {\n name: \"cookbook:tasty-modifiers\",\n enforce: \"post\" as const,\n root(root: HastElement): void {\n const visit = (node: HastElement) => {\n const style = node.properties?.style;\n if (typeof style === \"string\") {\n for (const declaration of style.split(\";\")) {\n if (!declaration.trim()) continue;\n const separator = declaration.indexOf(\":\");\n const key = declaration.slice(0, separator).trim();\n const value = declaration.slice(separator + 1).trim();\n let modifier: string | undefined;\n if (key === \"color\") modifier = syntaxColors.get(value);\n else if (key === \"background-color\" && value === background)\n modifier = \"syntax-bg\";\n else if (key === \"font-style\" && value === \"italic\")\n modifier = \"syntax-italic\";\n else if (key === \"font-weight\" && value === \"bold\")\n modifier = \"syntax-strong\";\n else if (key === \"text-decoration\" && value === \"underline\")\n modifier = \"syntax-underline\";\n else if (key === \"overflow-x\" && value === \"auto\")\n modifier = \"syntax-scroll\";\n else if (\n (key === \"white-space\" && value === \"pre-wrap\") ||\n (key === \"word-wrap\" && value === \"break-word\")\n )\n modifier = \"syntax-wrap\";\n else if (key === \"user-select\" && value === \"none\")\n modifier = \"syntax-marker\";\n if (!modifier)\n throw new Error(\n `Unsupported Shiki style ${JSON.stringify(declaration)}. Use semantic data modifiers and theme.styles.SyntaxHighlight for custom transformers.`,\n );\n node.properties[`data-${modifier}`] = \"\";\n }\n delete node.properties.style;\n }\n // Keep the stable syntax root class; normalize line anatomy and reject\n // authored token/modifier classes before serialization.\n const classValues = [node.properties?.class, node.properties?.className];\n const classes = classValues.flatMap((value) =>\n typeof value === \"string\"\n ? value.split(/\\s+/).filter(Boolean)\n : Array.isArray(value)\n ? value\n : [],\n );\n if (\n classValues.some(\n (value) => typeof value === \"string\" || Array.isArray(value),\n )\n ) {\n for (const name of classes) {\n if (\n name === \"astro-code\" ||\n name === \"tasty-code\" ||\n name === \"shiki\"\n ) {\n node.properties[\"data-syntax\"] = \"\";\n } else if (name === \"line\") {\n node.properties.dataElement = \"Line\";\n } else if (node.tagName !== \"pre\") {\n throw new Error(\n `Unsupported Shiki class ${JSON.stringify(name)}. Use semantic data modifiers and theme.styles.SyntaxHighlight for custom transformers.`,\n );\n }\n }\n delete node.properties.className;\n if (node.tagName === \"pre\") {\n node.properties.class = [\n \"tasty-code\",\n ...classes.filter(\n (name) => ![\"astro-code\", \"tasty-code\", \"shiki\"].includes(name),\n ),\n ].join(\" \");\n } else {\n delete node.properties.class;\n }\n }\n node.children?.forEach(visit);\n // Some grammars wrap empty lines in an empty token span. Canonicalize\n // those lines so :empty works consistently in fences and CodeGroup.\n if (\n node.properties?.dataElement === \"Line\" &&\n node.children?.every(emptyToken)\n ) {\n node.children = [];\n }\n };\n visit(root);\n },\n};\n\nfunction emptyToken(node: HastElement): boolean {\n return node.type === \"text\"\n ? node.value === \"\"\n : node.tagName === \"span\" && (node.children ?? []).every(emptyToken);\n}\n\ntype DiffTransformerContext = {\n source: string;\n options: { lang?: string };\n};\n\nconst diffLanguages = new Set([\"diff\", \"patch\"]);\n\n/**\n * The diff grammar colors individual tokens, but it does not expose a stable\n * whole-line selector. Add semantic modifiers so insertions and deletions can\n * receive subtle, full-width surfaces without hiding their +/- markers.\n */\nconst diffLineTransformer = {\n name: \"cookbook:diff-lines\",\n pre(this: DiffTransformerContext, element: HastElement): void {\n if (this.options.lang && diffLanguages.has(this.options.lang)) {\n element.properties[\"data-diff\"] = \"\";\n }\n },\n line(\n this: DiffTransformerContext,\n element: HastElement,\n lineNumber: number,\n ): void {\n if (!this.options.lang || !diffLanguages.has(this.options.lang)) return;\n\n const line = this.source.split(/\\r?\\n/)[lineNumber - 1] ?? \"\";\n if (line.startsWith(\"+\") && !line.startsWith(\"+++\")) {\n element.properties[\"data-inserted\"] = \"\";\n } else if (line.startsWith(\"-\") && !line.startsWith(\"---\")) {\n element.properties[\"data-deleted\"] = \"\";\n }\n },\n};\n\n/**\n * Astro loads fenced-code grammars lazily. MDX embeds TSX, but loading MDX by\n * itself leaves that embedded grammar unavailable and produces partially\n * highlighted imports and JSX. Preload TSX while preserving consumer-supplied\n * languages and transformers.\n */\nexport function cookbookShikiConfig(\n config: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const languages = Array.isArray(config?.langs) ? [...config.langs] : [];\n const transformers = Array.isArray(config?.transformers)\n ? [...config.transformers]\n : [];\n const hasTsx = languages.some(\n (language) =>\n language === \"tsx\" ||\n (typeof language === \"object\" &&\n language !== null &&\n \"name\" in language &&\n language.name === \"tsx\"),\n );\n\n if (!transformers.includes(bashPlaceholderTransformer)) {\n transformers.push(bashPlaceholderTransformer);\n }\n if (!transformers.includes(diffLineTransformer)) {\n transformers.push(diffLineTransformer);\n }\n if (!transformers.includes(tastyModifiersTransformer)) {\n transformers.push(tastyModifiersTransformer);\n }\n\n return {\n ...config,\n langs: hasTsx ? languages : [...languages, \"tsx\"],\n theme: tastyCodeTheme,\n transformers,\n };\n}\n\n/**\n * Shiki performs the grammatical classification, while every emitted color\n * remains a reference to a Glaze-generated token owned by Tasty.\n */\nconst tastyCodeTheme = {\n name: \"tasty-code\",\n type: \"light\" as const,\n fg: foreground,\n bg: background,\n colors: {\n \"editor.background\": background,\n \"editor.foreground\": foreground,\n },\n settings: [\n {\n scope: [\n \"comment\",\n \"comment.line\",\n \"comment.block\",\n \"punctuation.definition.comment\",\n ],\n settings: { foreground: comment, fontStyle: \"italic\" },\n },\n {\n scope: [\n \"keyword\",\n \"keyword.control\",\n \"keyword.other\",\n \"storage.type\",\n \"storage.modifier\",\n \"keyword.control.at-rule.tasty\",\n \"keyword.control.at-rule.media.tasty\",\n \"keyword.control.at-rule.media-type.tasty\",\n \"keyword.control.at-rule.starting.tasty\",\n \"keyword.control.state-alias.tasty\",\n ],\n settings: { foreground: keyword },\n },\n {\n scope: [\n \"string\",\n \"string.quoted\",\n \"string.template\",\n \"string.quoted.attribute-value.tasty\",\n \"string.unquoted.attribute-value.tasty\",\n ],\n settings: { foreground: string },\n },\n {\n scope: [\n \"support.constant.color.tasty-token\",\n \"support.constant.color.tasty-token.builtin\",\n \"constant.other.color.tasty-token\",\n \"constant.other.color.tasty\",\n \"constant.other.color.hex\",\n \"constant.other.color.rgb-value\",\n ],\n settings: { foreground: token },\n },\n {\n scope: [\n \"constant.numeric\",\n \"constant.numeric.tasty\",\n \"constant.numeric.custom-unit.tasty\",\n \"constant.numeric.css-with-unit\",\n \"constant.numeric.bare.tasty\",\n \"constant.numeric.css\",\n \"constant.numeric.keyframe-step.tasty\",\n \"constant.language.boolean.tasty\",\n ],\n settings: { foreground: number },\n },\n {\n scope: [\n \"support.type.property-name.tasty\",\n \"variable.other.constant.tasty\",\n \"entity.other.attribute-name.tsx\",\n \"entity.other.attribute-name.jsx\",\n ],\n settings: { foreground: property },\n },\n {\n scope: [\"variable\", \"variable.other\"],\n settings: { foreground },\n },\n {\n scope: [\n \"entity.name.function\",\n \"support.function\",\n \"support.function.misc.css\",\n \"entity.name.tag\",\n \"entity.name.tag.tsx\",\n \"support.class.component\",\n \"entity.name.type.tasty\",\n \"entity.name.tag.tasty\",\n ],\n settings: { foreground: func },\n },\n {\n scope: [\n \"support.constant.property-value.tasty\",\n \"support.constant.property-value.tasty-display\",\n \"support.constant.property-value.tasty-directional\",\n \"support.constant.property-value.tasty-preset\",\n \"support.constant.property-value.tasty-shape\",\n \"support.constant.property-value.tasty-scrollbar\",\n \"support.constant.property-value.tasty-state\",\n \"support.constant.property-value.tasty-cursor\",\n \"support.constant.property-value.tasty-overflow\",\n \"support.constant.property-value.tasty-position\",\n \"support.constant.property-value.tasty-flex\",\n \"support.constant.property-value.tasty-font\",\n \"support.constant.property-value.tasty-text\",\n \"support.constant.property-value.tasty-alignment\",\n \"support.constant.property-value.tasty-border-style\",\n \"support.constant.property-value.tasty-whitespace\",\n \"support.constant.property-value.tasty-global\",\n \"support.constant.property-value.tasty-transition\",\n \"support.constant.property-value.css-syntax\",\n \"entity.other.attribute-name\",\n \"entity.other.attribute-name.tasty\",\n \"entity.other.attribute-name.pseudo-class.tasty\",\n \"entity.other.attribute-name.pseudo-class.css\",\n \"entity.other.attribute-name.class.tasty\",\n \"entity.other.attribute-name.pseudo-element.css\",\n \"punctuation.definition.entity.css\",\n ],\n settings: { foreground: value },\n },\n {\n scope: [\n \"keyword.operator\",\n \"keyword.operator.logical.tasty\",\n \"keyword.operator.arithmetic.css\",\n \"keyword.operator.assignment\",\n \"keyword.operator.selector-affix.tasty\",\n \"keyword.operator.attribute-selector.tasty\",\n \"keyword.operator.comparison.tasty\",\n ],\n settings: { foreground: operator },\n },\n {\n scope: [\n \"punctuation.definition.string\",\n \"punctuation.separator\",\n \"punctuation.definition.block\",\n \"punctuation.definition.array\",\n \"punctuation.section\",\n \"punctuation.definition.auto-calc\",\n \"punctuation.definition.attribute-selector\",\n \"punctuation.definition.tag\",\n \"punctuation.definition.pseudo-class\",\n \"punctuation.definition.fallback\",\n \"meta.brace\",\n ],\n settings: { foreground: punctuation },\n },\n {\n scope: [\"keyword.control.at-rule\", \"entity.name.tag.class.css\"],\n settings: { foreground: keyword },\n },\n {\n scope: [\"support.type.property-name.css\", \"meta.property-name.css\"],\n settings: { foreground: property },\n },\n {\n scope: [\"punctuation.definition.inserted.diff\"],\n settings: { foreground: inserted, fontStyle: \"bold\" },\n },\n {\n scope: [\"punctuation.definition.deleted.diff\"],\n settings: { foreground: deleted, fontStyle: \"bold\" },\n },\n ],\n};\n\n// Astro executes integrations and page modules in separate module graphs.\n// Share server-only transformer functions without serializing them into pages.\nconst sharedShiki = globalThis as typeof globalThis & {\n __tenphiCookbookShiki?: Record<string, unknown>;\n};\nexport function configureCodeHighlighting(config: Record<string, unknown>) {\n sharedShiki.__tenphiCookbookShiki = config;\n}\nexport function codeGroupHighlighting() {\n return sharedShiki.__tenphiCookbookShiki ?? cookbookShikiConfig(undefined);\n}\n"],"mappings":"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AAC,GAAG,WAAW,KAAK;EAChD,OAAO;EACP;CACF;AACF;;;;;AAMA,MAAM,iBAAiB;CACrB,MAAM;CACN,MAAM;CACN,IAAI;CACJ,IAAI;CACJ,QAAQ;EACN,qBAAqB;EACrB,qBAAqB;CACvB;CACA,UAAU;EACR;GACE,OAAO;IACL;IACA;IACA;IACA;GACF;GACA,UAAU;IAAE,YAAY;IAAS,WAAW;GAAS;EACvD;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,QAAQ;EAClC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,OAAO;EACjC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,MAAM;EAChC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,OAAO;EACjC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,SAAS;EACnC;EACA;GACE,OAAO,CAAC,YAAY,gBAAgB;GACpC,UAAU,EAAE,WAAW;EACzB;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,KAAK;EAC/B;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,MAAM;EAChC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,SAAS;EACnC;EACA;GACE,OAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,UAAU,EAAE,YAAY,YAAY;EACtC;EACA;GACE,OAAO,CAAC,2BAA2B,2BAA2B;GAC9D,UAAU,EAAE,YAAY,QAAQ;EAClC;EACA;GACE,OAAO,CAAC,kCAAkC,wBAAwB;GAClE,UAAU,EAAE,YAAY,SAAS;EACnC;EACA;GACE,OAAO,CAAC,sCAAsC;GAC9C,UAAU;IAAE,YAAY;IAAU,WAAW;GAAO;EACtD;EACA;GACE,OAAO,CAAC,qCAAqC;GAC7C,UAAU;IAAE,YAAY;IAAS,WAAW;GAAO;EACrD;CACF;AACF;AAIA,MAAM,cAAc;AAGpB,SAAgB,0BAA0B,QAAiC;CACzE,YAAY,wBAAwB;AACtC;AACA,SAAgB,wBAAwB;CACtC,OAAO,YAAY,yBAAyB,oBAAoB,KAAA,CAAS;AAC3E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/renderer",
3
- "version": "0.22.1",
3
+ "version": "0.23.0",
4
4
  "description": "Astro renderer and Tasty theme for Cookbook",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -61,10 +61,10 @@
61
61
  "@fontsource-variable/jetbrains-mono": "^5.3.0",
62
62
  "@fontsource-variable/onest": "^5.3.0",
63
63
  "@pagefind/default-ui": "1.5.2",
64
- "@tenphi/docs": "0.22.1",
64
+ "@tenphi/docs": "0.23.0",
65
65
  "@tenphi/eslint-plugin-tasty": "1.6.0",
66
66
  "@tenphi/glaze": "2.0.1",
67
- "@tenphi/tasty": "3.9.9",
67
+ "@tenphi/tasty": "3.9.10",
68
68
  "beautiful-mermaid": "^1.1.3",
69
69
  "hast-util-from-html": "^2.0.3",
70
70
  "pagefind": "1.5.2",
@@ -1 +0,0 @@
1
- {"version":3,"file":"tasty-states-_JhxFdK1.js","names":[],"sources":["../src/components/tasty-states.js"],"sourcesContent":["import { configure, getGlobalPredefinedStates } from \"@tenphi/tasty\";\nimport { resolveTypographyPresets } from \"../theme/defaults.js\";\nimport {\n TASTY_UNITS,\n TASTY_SPACING_PROPERTIES,\n} from \"../theme/tasty-config.js\";\n\nconst systemLight = \"@media(prefers-color-scheme: light)\";\nconst systemDark = \"@media(prefers-color-scheme: dark)\";\n\nexport const cookbookStates = {\n \"@system-light\": systemLight,\n \"@system-dark\": systemDark,\n \"@light\": `@root(theme=light) | (!@root(theme) & ${systemLight})`,\n \"@dark\": `@root(theme=dark) | (!@root(theme) & ${systemDark})`,\n \"@mobile\": \"@media(w < 50rem)\",\n \"@desktop\": \"@media(w >= 50rem)\",\n \"@small\": \"@media(w <= 40rem)\",\n \"@compact\": \"@media(w <= 23rem)\",\n \"@shell-mobile\": \"@media(w <= 48rem)\",\n \"@shell-desktop\": \"@media(w > 48rem)\",\n \"@narrow-layout\": \"@media(w < 72rem)\",\n \"@medium-layout\": \"@media(w >= 50rem) & @media(w < 72rem)\",\n \"@reduced-motion\": \"@media(prefers-reduced-motion: reduce)\",\n \"@popover-open\": \":is(:popover-open)\",\n};\n\nlet configured = false;\nlet configuredRuntime;\n\n/** Configure aliases in the renderer's Tasty module before styles are parsed. */\nexport function configureCookbookStates() {\n // Process-local server configuration shared across Astro/Vite module graphs.\n // The integration prevents this module from entering browser bundles.\n const runtime = globalThis.__tenphiCookbookTastyRuntime;\n if (configured && configuredRuntime === runtime) return;\n configure({\n presets: resolveTypographyPresets(),\n properties: TASTY_SPACING_PROPERTIES,\n ...runtime,\n units: { ...TASTY_UNITS, ...runtime?.units },\n });\n configuredRuntime = runtime;\n // The integration may have configured this runtime already, including\n // consumer overrides of built-in breakpoints. Only supply missing aliases.\n const existingStates = getGlobalPredefinedStates();\n const missingStates = Object.fromEntries(\n Object.entries(cookbookStates).filter(\n ([name]) => existingStates[name] === undefined,\n ),\n );\n if (Object.keys(missingStates).length) configure({ states: missingStates });\n configured = true;\n}\n"],"mappings":";;;;AAOA,MAAM,cAAc;AACpB,MAAM,aAAa;AAEnB,MAAa,iBAAiB;CAC5B,iBAAiB;CACjB,gBAAgB;CAChB,UAAU,yCAAyC,YAAY;CAC/D,SAAS,wCAAwC,WAAW;CAC5D,WAAW;CACX,YAAY;CACZ,UAAU;CACV,YAAY;CACZ,iBAAiB;CACjB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;AACnB;AAEA,IAAI,aAAa;AACjB,IAAI;;AAGJ,SAAgB,0BAA0B;CAGxC,MAAM,UAAU,WAAW;CAC3B,IAAI,cAAc,sBAAsB,SAAS;CACjD,UAAU;EACR,SAAS,yBAAyB;EAClC,YAAY;EACZ,GAAG;EACH,OAAO;GAAE,GAAG;GAAa,GAAG,SAAS;EAAM;CAC7C,CAAC;CACD,oBAAoB;CAGpB,MAAM,iBAAiB,0BAA0B;CACjD,MAAM,gBAAgB,OAAO,YAC3B,OAAO,QAAQ,cAAc,CAAC,CAAC,QAC5B,CAAC,UAAU,eAAe,UAAU,KAAA,CACvC,CACF;CACA,IAAI,OAAO,KAAK,aAAa,CAAC,CAAC,QAAQ,UAAU,EAAE,QAAQ,cAAc,CAAC;CAC1E,aAAa;AACf"}