@tenphi/renderer 0.30.0 → 0.30.2

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.
@@ -0,0 +1,11 @@
1
+ import { dialog } from "@uniaria/core/dialog";
2
+ import { popover } from "@uniaria/core/popover";
3
+ import { UniElement } from "@uniaria/elements";
4
+ //#region src/client/elements.d.ts
5
+ declare global {
6
+ interface HTMLElementTagNameMap {
7
+ "cb-popover": UniElement<typeof popover>;
8
+ "cb-dialog": UniElement<typeof dialog>;
9
+ }
10
+ }
11
+ //# sourceMappingURL=elements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements.d.ts","names":[],"sources":["../../src/client/elements.ts"],"mappings":";;;;QAiBQ;YACI;IACR,cAAc,kBAAkB;IAChC,aAAa,kBAAkB"}
@@ -0,0 +1,16 @@
1
+ import { dialog } from "@uniaria/core/dialog";
2
+ import { configure } from "@uniaria/core/dom";
3
+ import { popover } from "@uniaria/core/popover";
4
+ import { defineElement } from "@uniaria/elements";
5
+ //#region src/client/elements.ts
6
+ /**
7
+ * Register UniAria's behaviors as `cb-*` light-DOM elements on server-rendered
8
+ * markup. Cookbook's own elements keep the `cookbook-*` prefix.
9
+ */
10
+ configure({ positioning: "css" });
11
+ defineElement(popover, { prefix: "cb" });
12
+ defineElement(dialog, { prefix: "cb" });
13
+ //#endregion
14
+ export {};
15
+
16
+ //# sourceMappingURL=elements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements.js","names":[],"sources":["../../src/client/elements.ts"],"sourcesContent":["/**\n * Register UniAria's behaviors as `cb-*` light-DOM elements on server-rendered\n * markup. Cookbook's own elements keep the `cookbook-*` prefix.\n */\nimport { dialog } from \"@uniaria/core/dialog\";\nimport { configure } from \"@uniaria/core/dom\";\nimport { popover } from \"@uniaria/core/popover\";\nimport type { UniElement } from \"@uniaria/elements\";\nimport { defineElement } from \"@uniaria/elements\";\n\n// Panels keep the placement Cookbook's styles give them; UniAria only links\n// each one to its anchor and reads the side back.\nconfigure({ positioning: \"css\" });\n// Each returns undefined without `customElements` and skips a defined name.\ndefineElement(popover, { prefix: \"cb\" });\ndefineElement(dialog, { prefix: \"cb\" });\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"cb-popover\": UniElement<typeof popover>;\n \"cb-dialog\": UniElement<typeof dialog>;\n }\n}\n"],"mappings":";;;;;;;;;AAYA,UAAU,EAAE,aAAa,MAAM,CAAC;AAEhC,cAAc,SAAS,EAAE,QAAQ,KAAK,CAAC;AACvC,cAAc,QAAQ,EAAE,QAAQ,KAAK,CAAC"}
@@ -35,7 +35,7 @@ var CookbookSidebarPane = class extends HTMLElement {
35
35
  this.#inert.set(element, element.inert);
36
36
  element.inert = true;
37
37
  }
38
- this.querySelector("[autofocus]")?.focus({ preventScroll: true });
38
+ if (!this.contains(document.activeElement)) this.querySelector("[autofocus]")?.focus({ preventScroll: true });
39
39
  } else {
40
40
  const restoreFocus = this.contains(document.activeElement) || document.activeElement === document.body;
41
41
  this.#release();
@@ -44,13 +44,6 @@ var CookbookSidebarPane = class extends HTMLElement {
44
44
  }, { signal });
45
45
  this.addEventListener("keydown", (event) => {
46
46
  if (desktop.matches || !this.matches(":popover-open")) return;
47
- const sections = this.querySelector("[data-element=MobileNavigationTabs] details[open]");
48
- if (event.key === "Escape" && sections) {
49
- event.preventDefault();
50
- sections.open = false;
51
- sections.querySelector("summary")?.focus();
52
- return;
53
- }
54
47
  if (event.key !== "Tab") return;
55
48
  const focusable = Array.from(this.querySelectorAll("a[href], button:not([disabled]), select:not([disabled]), input:not([disabled]), summary, [tabindex=\"0\"]")).filter((element) => element.tabIndex >= 0 && element.getClientRects().length > 0);
56
49
  const first = focusable[0];
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.js","names":[],"sources":["../../src/client/navigation.ts"],"sourcesContent":["import { initializePopoverMotion } from \"./popover-motion.js\";\n\nclass CookbookSidebarPane extends HTMLElement {\n #listeners?: AbortController;\n #inert = new Map<HTMLElement, boolean>();\n #trigger: HTMLButtonElement | undefined;\n\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n const { signal } = this.#listeners;\n this.#trigger =\n document.querySelector<HTMLButtonElement>(\n '[data-element=MobileMenuToggle][popovertarget=\"cookbook__sidebar\"]',\n ) ?? undefined;\n const desktop = matchMedia(\"(min-width: 50rem)\");\n const syncViewport = () => {\n if (desktop.matches) {\n if (this.matches(\":popover-open\")) this.hidePopover();\n this.#release();\n this.popover = null;\n this.removeAttribute(\"role\");\n this.removeAttribute(\"aria-modal\");\n } else {\n this.popover = \"auto\";\n this.setAttribute(\"role\", \"dialog\");\n this.setAttribute(\"aria-modal\", \"true\");\n }\n };\n syncViewport();\n desktop.addEventListener(\"change\", syncViewport, { signal });\n this.addEventListener(\n \"toggle\",\n () => {\n const open = !desktop.matches && this.matches(\":popover-open\");\n this.#trigger?.setAttribute(\"aria-expanded\", String(open));\n if (open) {\n // Establish the closed position after the popover enters the top\n // layer so its attribute change transitions from an actual layout.\n // Tasty's global SSR renderer does not preserve @starting-style.\n this.getBoundingClientRect();\n this.setAttribute(\"data-open\", \"\");\n for (const element of document.querySelectorAll<HTMLElement>(\n \"[data-element=HeaderFrame], [data-element=MainFrame], [data-element=SkipLink]\",\n )) {\n this.#inert.set(element, element.inert);\n element.inert = true;\n }\n this.querySelector<HTMLElement>(\"[autofocus]\")?.focus({\n preventScroll: true,\n });\n } else {\n const restoreFocus =\n this.contains(document.activeElement) ||\n document.activeElement === document.body;\n this.#release();\n if (restoreFocus && !desktop.matches) this.#trigger?.focus();\n }\n },\n { signal },\n );\n this.addEventListener(\n \"keydown\",\n (event) => {\n if (desktop.matches || !this.matches(\":popover-open\")) return;\n const sections = this.querySelector<HTMLDetailsElement>(\n \"[data-element=MobileNavigationTabs] details[open]\",\n );\n if (event.key === \"Escape\" && sections) {\n event.preventDefault();\n sections.open = false;\n sections.querySelector(\"summary\")?.focus();\n return;\n }\n if (event.key !== \"Tab\") return;\n const focusable = Array.from(\n this.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), select:not([disabled]), input:not([disabled]), summary, [tabindex=\"0\"]',\n ),\n ).filter(\n (element) =>\n element.tabIndex >= 0 && element.getClientRects().length > 0,\n );\n const first = focusable[0];\n const last = focusable.at(-1);\n if (!first || !last) {\n event.preventDefault();\n this.focus();\n return;\n }\n if (\n event.shiftKey &&\n (document.activeElement === first || document.activeElement === this)\n ) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n },\n { signal },\n );\n this.addEventListener(\n \"click\",\n (event) => {\n if (\n !event.defaultPrevented &&\n event.target instanceof Element &&\n event.target.closest(\"a[href]\") &&\n this.matches(\":popover-open\")\n )\n this.hidePopover();\n },\n { signal },\n );\n }\n\n #release() {\n this.removeAttribute(\"data-open\");\n for (const [element, inert] of this.#inert) element.inert = inert;\n this.#inert.clear();\n this.#trigger?.setAttribute(\"aria-expanded\", \"false\");\n }\n\n disconnectedCallback() {\n this.#listeners?.abort();\n this.#release();\n }\n}\n\nclass CookbookHeaderLinks extends HTMLElement {\n #listeners?: AbortController;\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n const { signal } = this.#listeners;\n const panel = this.querySelector<HTMLElement>(\"[popover]\");\n const desktop = matchMedia(\"(min-width: 50rem)\");\n const close = () => {\n if (panel?.matches(\":popover-open\")) panel.hidePopover();\n };\n if (panel) initializePopoverMotion(panel, signal);\n desktop.addEventListener(\n \"change\",\n () => {\n if (desktop.matches) close();\n },\n { signal },\n );\n panel?.addEventListener(\n \"click\",\n (event) => {\n if (event.target instanceof Element && event.target.closest(\"a[href]\"))\n close();\n },\n { signal },\n );\n }\n disconnectedCallback() {\n this.#listeners?.abort();\n }\n}\n\nif (!customElements.get(\"cookbook-sidebar-pane\"))\n customElements.define(\"cookbook-sidebar-pane\", CookbookSidebarPane);\nif (!customElements.get(\"cookbook-header-links\"))\n customElements.define(\"cookbook-header-links\", CookbookHeaderLinks);\n"],"mappings":"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"}
1
+ {"version":3,"file":"navigation.js","names":[],"sources":["../../src/client/navigation.ts"],"sourcesContent":["import { initializePopoverMotion } from \"./popover-motion.js\";\n\nclass CookbookSidebarPane extends HTMLElement {\n #listeners?: AbortController;\n #inert = new Map<HTMLElement, boolean>();\n #trigger: HTMLButtonElement | undefined;\n\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n const { signal } = this.#listeners;\n this.#trigger =\n document.querySelector<HTMLButtonElement>(\n '[data-element=MobileMenuToggle][popovertarget=\"cookbook__sidebar\"]',\n ) ?? undefined;\n const desktop = matchMedia(\"(min-width: 50rem)\");\n const syncViewport = () => {\n if (desktop.matches) {\n if (this.matches(\":popover-open\")) this.hidePopover();\n this.#release();\n this.popover = null;\n this.removeAttribute(\"role\");\n this.removeAttribute(\"aria-modal\");\n } else {\n this.popover = \"auto\";\n this.setAttribute(\"role\", \"dialog\");\n this.setAttribute(\"aria-modal\", \"true\");\n }\n };\n syncViewport();\n desktop.addEventListener(\"change\", syncViewport, { signal });\n this.addEventListener(\n \"toggle\",\n () => {\n const open = !desktop.matches && this.matches(\":popover-open\");\n this.#trigger?.setAttribute(\"aria-expanded\", String(open));\n if (open) {\n // Establish the closed position after the popover enters the top\n // layer so its attribute change transitions from an actual layout.\n // Tasty's global SSR renderer does not preserve @starting-style.\n this.getBoundingClientRect();\n this.setAttribute(\"data-open\", \"\");\n for (const element of document.querySelectorAll<HTMLElement>(\n \"[data-element=HeaderFrame], [data-element=MainFrame], [data-element=SkipLink]\",\n )) {\n this.#inert.set(element, element.inert);\n element.inert = true;\n }\n // The browser focuses [autofocus] as the popover opens, but this\n // event arrives later; never pull back focus that moved on since.\n if (!this.contains(document.activeElement))\n this.querySelector<HTMLElement>(\"[autofocus]\")?.focus({\n preventScroll: true,\n });\n } else {\n const restoreFocus =\n this.contains(document.activeElement) ||\n document.activeElement === document.body;\n this.#release();\n if (restoreFocus && !desktop.matches) this.#trigger?.focus();\n }\n },\n { signal },\n );\n this.addEventListener(\n \"keydown\",\n (event) => {\n if (desktop.matches || !this.matches(\":popover-open\")) return;\n if (event.key !== \"Tab\") return;\n const focusable = Array.from(\n this.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), select:not([disabled]), input:not([disabled]), summary, [tabindex=\"0\"]',\n ),\n ).filter(\n (element) =>\n element.tabIndex >= 0 && element.getClientRects().length > 0,\n );\n const first = focusable[0];\n const last = focusable.at(-1);\n if (!first || !last) {\n event.preventDefault();\n this.focus();\n return;\n }\n if (\n event.shiftKey &&\n (document.activeElement === first || document.activeElement === this)\n ) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n },\n { signal },\n );\n this.addEventListener(\n \"click\",\n (event) => {\n if (\n !event.defaultPrevented &&\n event.target instanceof Element &&\n event.target.closest(\"a[href]\") &&\n this.matches(\":popover-open\")\n )\n this.hidePopover();\n },\n { signal },\n );\n }\n\n #release() {\n this.removeAttribute(\"data-open\");\n for (const [element, inert] of this.#inert) element.inert = inert;\n this.#inert.clear();\n this.#trigger?.setAttribute(\"aria-expanded\", \"false\");\n }\n\n disconnectedCallback() {\n this.#listeners?.abort();\n this.#release();\n }\n}\n\nclass CookbookHeaderLinks extends HTMLElement {\n #listeners?: AbortController;\n connectedCallback() {\n this.#listeners?.abort();\n this.#listeners = new AbortController();\n const { signal } = this.#listeners;\n const panel = this.querySelector<HTMLElement>(\"[popover]\");\n const desktop = matchMedia(\"(min-width: 50rem)\");\n const close = () => {\n if (panel?.matches(\":popover-open\")) panel.hidePopover();\n };\n if (panel) initializePopoverMotion(panel, signal);\n desktop.addEventListener(\n \"change\",\n () => {\n if (desktop.matches) close();\n },\n { signal },\n );\n panel?.addEventListener(\n \"click\",\n (event) => {\n if (event.target instanceof Element && event.target.closest(\"a[href]\"))\n close();\n },\n { signal },\n );\n }\n disconnectedCallback() {\n this.#listeners?.abort();\n }\n}\n\nif (!customElements.get(\"cookbook-sidebar-pane\"))\n customElements.define(\"cookbook-sidebar-pane\", CookbookSidebarPane);\nif (!customElements.get(\"cookbook-header-links\"))\n customElements.define(\"cookbook-header-links\", CookbookHeaderLinks);\n"],"mappings":"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"}
@@ -12,7 +12,7 @@ export const MobileMenuFooterRoot = defineComponent("MobileMenuFooter", {
12
12
  justifyContent: "space-between",
13
13
  flow: "row wrap",
14
14
  gap: "2x",
15
- blockPadding: "1x",
15
+ padding: "1x $docs-sidebar-pad-x",
16
16
  blockBorder: "1bw solid #border start",
17
17
  Social: {
18
18
  $: "Social",
@@ -21,7 +21,7 @@ export const MobileMenuFooterRoot = defineComponent("MobileMenuFooter", {
21
21
  alignItems: "center",
22
22
  gap: "2x",
23
23
  inlineMargin: "auto end",
24
- blockPadding: "2x",
24
+ blockPadding: "1x",
25
25
  },
26
26
  },
27
27
  });
@@ -9,6 +9,7 @@ import { content } from "virtual:cookbook/config";
9
9
  import { layout as configuredLayout } from "virtual:cookbook/layout";
10
10
  import { activeNavigationTab, navigationPath } from "../navigation.js";
11
11
  import { MobileNavigationTabsRoot } from "./MobileNavigationTabs.styles.js";
12
+ import SelectPopover from "./SelectPopover.astro";
12
13
 
13
14
  interface Props {
14
15
  base?: string;
@@ -45,35 +46,36 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
45
46
  <MobileNavigationTabsRoot
46
47
  className="td-mobile-tabs"
47
48
  data-print-hidden=""
48
- aria-label={ui.sections}
49
+ non-modal=""
50
+ focus-on-open="false"
49
51
  >
50
- <details>
51
- <summary aria-label={ui.chooseSection}>
52
- <span data-element="Label">
53
- {layout.tabs[activeTab]?.label ?? ui.sections}
54
- </span>
55
- <svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
56
- <path
57
- d="m4 6 4 4 4-4"
58
- fill="none"
59
- stroke="currentColor"
60
- stroke-width="1.5"
61
- />
62
- </svg>
63
- </summary>
64
- <ul>
65
- {layout.tabs.map((tab, index) => (
66
- <li>
67
- <a
68
- href={tabHref(tab.link)}
69
- aria-current={index === activeTab ? "page" : undefined}
70
- >
71
- {tab.label}
72
- </a>
73
- </li>
74
- ))}
75
- </ul>
76
- </details>
52
+ <SelectPopover
53
+ managed
54
+ triggerLabel={ui.chooseSection}
55
+ selectedLabel={layout.tabs[activeTab]?.label ?? ui.sections}
56
+ title={ui.sections}
57
+ options={layout.tabs.map((tab, index) => ({
58
+ href: tabHref(tab.link),
59
+ label: tab.label,
60
+ current: index === activeTab,
61
+ }))}
62
+ />
77
63
  </MobileNavigationTabsRoot>
78
64
  )
79
65
  }
66
+
67
+ <script>
68
+ // The section selector is mobile-only. Keep the behavior runtime out of
69
+ // desktop page loads, including when a reader later narrows the viewport.
70
+ const mobile = matchMedia("(width < 50rem)");
71
+ const initialize = () => {
72
+ if (
73
+ mobile.matches &&
74
+ document.querySelector("cb-popover[data-element=MobileNavigationTabs]")
75
+ )
76
+ void import("../client/elements.js");
77
+ };
78
+ mobile.addEventListener("change", initialize);
79
+ document.addEventListener("astro:page-load", initialize);
80
+ initialize();
81
+ </script>
@@ -1,86 +1,63 @@
1
+ import { selectPopoverStyles } from "./select-popover-styles.js";
1
2
  import { configureCookbookStates } from "./tasty-states.js";
2
3
  import { defineComponent } from "../define-component.js";
3
4
 
4
5
  configureCookbookStates();
5
6
 
7
+ const sectionSelectStyles = selectPopoverStyles({
8
+ option: "Link",
9
+ hoverOption: "HoverLink",
10
+ currentOption: "CurrentLink",
11
+ });
12
+
6
13
  export const MobileNavigationTabsRoot = defineComponent(
7
14
  "MobileNavigationTabs",
8
15
  {
9
- as: "nav",
16
+ as: "cb-popover",
10
17
  "data-element": "MobileNavigationTabs",
11
18
  styles: {
19
+ // Reuse the shared, server-only popover anatomy.
20
+ // eslint-disable-next-line tasty/no-style-spread
21
+ ...sectionSelectStyles,
12
22
  display: "grid",
13
23
  hide: { "": false, "@md": true },
14
- gap: "1x",
24
+ inlineSize: "min 0",
15
25
  blockMargin: "0",
16
- Label: {
17
- $: "Label",
18
- overflow: "hidden",
19
- textOverflow: "ellipsis",
20
- whiteSpace: "nowrap",
21
- },
22
26
  Trigger: {
23
- $: "summary",
24
- display: "flex",
25
- alignItems: "center",
27
+ // Reuse the shared, server-only popover anatomy.
28
+ // eslint-disable-next-line tasty/no-style-spread
29
+ ...sectionSelectStyles.Trigger,
26
30
  justifyContent: "space-between",
27
- gap: "1x",
31
+ inlineSize: "100%",
28
32
  blockSize: "min 2.75rem",
29
33
  padding: "1x 1.25x",
30
34
  border: true,
31
35
  radius: "1r",
32
- color: "#text-soft",
33
36
  fill: "#surface",
34
37
  preset: "navigation",
35
- listStyle: "none",
36
- },
37
- Marker: {
38
- $: "summary::marker, summary::-webkit-details-marker",
39
- hide: true,
40
- },
41
- Caret: { $: "summary > svg", flexShrink: "0" },
42
- ExpandedCaret: {
43
- $: "details > summary > svg",
44
- rotate: {
45
- "": null,
46
- "@own(:is([open] > summary >))": "180deg",
47
- },
48
- },
49
- List: {
50
- $: "ul",
51
- display: "grid",
52
- gap: "1bw",
53
- padding: "1x",
54
- margin: "1x top",
55
- listStyle: "none",
56
- border: true,
57
- radius: "1r",
58
- fill: "#surface",
38
+ anchorName: "--section-trigger",
59
39
  },
60
- Item: { $: "li", margin: "0" },
61
- Link: {
62
- $: "a",
63
- display: "flex",
64
- alignItems: "center",
65
- blockSize: "min 2.25rem",
66
- padding: "0.75x 1.25x",
67
- color: "#text-soft",
68
- preset: "navigation",
69
- textDecoration: "none",
70
- radius: "1r",
40
+ Panel: {
41
+ // Reuse the shared, server-only popover anatomy.
42
+ // eslint-disable-next-line tasty/no-style-spread
43
+ ...sectionSelectStyles.Panel,
44
+ positionAnchor: "--section-trigger",
45
+ blockInset: "(anchor(bottom) + 1x) start, auto end",
46
+ inlineInset: "anchor(start) start, auto end",
47
+ inlineSize: "anchor-size(width)",
48
+ blockSize: "max (100dvh - anchor(bottom) - 2x)",
71
49
  },
72
- HoverLink: {
73
- $: "a",
74
- color: { "": null, "@own(:hover)": "#text" },
75
- fill: { "": null, "@own(:hover)": "#surface-2-hover" },
50
+ // Keep the original disclosure's customization names on the Select anatomy.
51
+ Label: {
52
+ // eslint-disable-next-line tasty/no-style-spread -- shared label anatomy, retained under its original customization name.
53
+ ...sectionSelectStyles.TriggerLabel,
76
54
  },
77
- CurrentLink: {
78
- $: "a",
79
- color: { "": null, '@own([aria-current="page"])': "#accent-text" },
80
- fill: {
81
- "": null,
82
- '@own([aria-current="page"])': "#accent-surface-subtle",
83
- },
55
+ List: { $: "> Panel > nav" },
56
+ Item: { $: "> Panel > nav > a" },
57
+ Marker: { $: "> button::marker" },
58
+ ExpandedCaret: {
59
+ $: "> button > Caret",
60
+ rotate: { "": null, ":has([popover]:popover-open)": "180deg" },
84
61
  },
85
62
  },
86
63
  },
@@ -15,15 +15,25 @@ interface Props {
15
15
  title: string;
16
16
  options: Option[];
17
17
  icon?: string;
18
+ /** UniAria owns behavior when rendered inside a cb-popover host. */
19
+ managed?: boolean;
18
20
  }
19
21
 
20
- const { triggerLabel, selectedLabel, title, options, icon } = Astro.props;
22
+ const {
23
+ triggerLabel,
24
+ selectedLabel,
25
+ title,
26
+ options,
27
+ icon,
28
+ managed = false,
29
+ } = Astro.props;
21
30
  const id = `select-${crypto.randomUUID()}`;
22
31
  ---
23
32
 
24
33
  <button
25
34
  type="button"
26
- popovertarget={id}
35
+ popovertarget={managed ? undefined : id}
36
+ data-uni-part={managed ? "popover-trigger" : undefined}
27
37
  aria-label={triggerLabel}
28
38
  title={title}
29
39
  >
@@ -34,10 +44,11 @@ const id = `select-${crypto.randomUUID()}`;
34
44
  <div
35
45
  id={id}
36
46
  data-element="Panel"
37
- popover="auto"
47
+ popover={managed ? "manual" : "auto"}
48
+ data-uni={managed ? "popover" : undefined}
38
49
  role="group"
39
50
  aria-label={title}
40
- data-select-popover-panel
51
+ data-select-popover-panel={managed ? undefined : ""}
41
52
  >
42
53
  <div data-element="PanelTitle">{title}</div>
43
54
  <nav aria-label={title}>
@@ -31,7 +31,7 @@ export const SidebarRoot = defineComponent("Sidebar", {
31
31
  border: "0",
32
32
  color: "#text",
33
33
  overflowY: "auto",
34
- scrollbar: "auto stable",
34
+ scrollbar: { "": "auto stable", "!@md": "auto" },
35
35
  fill: "#surface",
36
36
  overscrollBehavior: "contain",
37
37
  shadow: { "": "none", "!@md": "0.25rem 0 1rem #shadow" },
@@ -59,6 +59,14 @@ export const SidebarRoot = defineComponent("Sidebar", {
59
59
  $: "&::backdrop",
60
60
  opacity: { "": null, ":popover-open & [data-open]": "1" },
61
61
  },
62
+ MobileHeader: {
63
+ display: "grid",
64
+ hide: { "": true, "!@md": false },
65
+ flexShrink: "0",
66
+ gap: "2x",
67
+ padding: "2x $docs-sidebar-pad-x",
68
+ blockBorder: "1bw solid #border end",
69
+ },
62
70
  MobileHeading: {
63
71
  $: "MobileHeading",
64
72
  display: "flex",
@@ -135,15 +143,29 @@ export const SidebarRoot = defineComponent("Sidebar", {
135
143
  $: "Content",
136
144
  display: "flex",
137
145
  flow: "column",
138
- blockSize: "min 100%",
139
- inlinePadding: "$docs-sidebar-pad-x",
140
- gap: "2x",
146
+ blockSize: { "": "min 100%", "!@md": "100%" },
147
+ inlinePadding: { "": "$docs-sidebar-pad-x", "!@md": "0" },
148
+ gap: { "": "2x", "!@md": "0" },
141
149
  blockPadding: {
142
150
  "": "3x start, 6x end",
143
- "!@md": "2x start, 6x end",
151
+ "!@md": "0",
144
152
  },
145
153
  },
146
- Tree: { $: "cookbook-sidebar", display: "block" },
154
+ Tree: {
155
+ $: "cookbook-sidebar",
156
+ display: "block",
157
+ flexGrow: { "": null, "!@md": "1" },
158
+ flexBasis: { "": null, "!@md": "0" },
159
+ blockSize: { "": null, "!@md": "min 0" },
160
+ padding: { "": null, "!@md": "2x $docs-sidebar-pad-x" },
161
+ overflowY: { "": null, "!@md": "auto" },
162
+ scrollbar: { "": null, "!@md": "auto stable" },
163
+ overscrollBehavior: { "": null, "!@md": "contain" },
164
+ },
165
+ MobileFooter: {
166
+ hide: { "": true, "!@md": false },
167
+ flexShrink: "0",
168
+ },
147
169
  List: {
148
170
  $: "cookbook-sidebar ul",
149
171
  display: "grid",
@@ -104,7 +104,7 @@ export const ThemeSelectRoot = defineComponent("ThemeSelect", {
104
104
  inlineSize: "100%",
105
105
  padding: "0.75x 1x",
106
106
  color: "#text-muted",
107
- preset: "small / strong",
107
+ preset: "control-label / strong",
108
108
  },
109
109
  Option: {
110
110
  $: "label",
@@ -1,4 +1,4 @@
1
- /** Shared server-side styles for the language and version selectors. */
1
+ /** Shared server-side styles for the language, version, and section selectors. */
2
2
  export function selectPopoverStyles({
3
3
  option = "Option",
4
4
  hoverOption = "HoverOption",
@@ -65,17 +65,22 @@ export function selectPopoverStyles({
65
65
  },
66
66
  OpenPanel: {
67
67
  $: '> [data-element="Panel"]',
68
+ // UniAria clears data-entering after two frames in the top layer,
69
+ // giving the closed opacity and scale a painted starting point.
68
70
  opacity: {
69
71
  "": null,
70
- "@own(:popover-open & [data-open])": "1",
72
+ "@own(:popover-open & [data-open] & ![data-entering])": "1",
73
+ },
74
+ scale: {
75
+ "": null,
76
+ "@own(:popover-open & [data-open] & ![data-entering])": "1",
71
77
  },
72
- scale: { "": null, "@own(:popover-open & [data-open])": "1" },
73
78
  },
74
79
  PanelTitle: {
75
80
  $: "PanelTitle",
76
81
  padding: "0.75x 1x",
77
82
  color: "#text-muted",
78
- preset: "small / strong",
83
+ preset: "control-label / strong",
79
84
  },
80
85
  Options: { $: "nav", display: "grid", gap: "0.25x" },
81
86
  [option]: {
@@ -144,7 +144,8 @@ var tasty_config_default = {
144
144
  "hero-title",
145
145
  "hero-tagline",
146
146
  "prose",
147
- "inline-code"
147
+ "inline-code",
148
+ "control-label"
148
149
  ]
149
150
  };
150
151
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-plugin.js","names":["validationConfig"],"sources":["../src/tasty.config.ts","../src/eslint-plugin.ts"],"sourcesContent":["import type { TastyValidationConfig } from \"@tenphi/eslint-plugin-tasty\";\n\nexport default {\n importSources: [\n \"@tenphi/cookbook/styling\",\n \"@tenphi/renderer/styling\",\n \"./component-styles.js\",\n \"../define-component.js\",\n ],\n styleFunctions: {\n defineComponent: { argument: 1, kind: \"options\" },\n extendComponent: { argument: 2, kind: \"options\", partial: true },\n resolveComponentStyles: { argument: 1, kind: \"styles\" },\n },\n tokens: [\n \"$gap\",\n \"$margin-block-start\",\n \"$margin-block-end\",\n \"$padding-block-start\",\n \"$padding-block-end\",\n \"$radius\",\n \"$header-control-radius\",\n \"$card-radius\",\n \"$border-width\",\n \"$outline-width\",\n \"$outline-offset\",\n \"$layout-width\",\n \"$content-width\",\n \"$sidebar-width\",\n \"$control-height\",\n \"$transition\",\n \"$sharp-radius\",\n \"$bold-font-weight\",\n \"#white\",\n \"#black\",\n \"#clear\",\n \"#current\",\n \"#surface\",\n \"#header\",\n \"#heading\",\n \"#surface-2\",\n \"#surface-3\",\n \"#surface-2-hover\",\n \"#surface-2-pressed\",\n \"#surface-3-hover\",\n \"#surface-3-pressed\",\n \"#text\",\n \"#text-soft\",\n \"#text-muted\",\n \"#sidebar-text\",\n \"#border\",\n \"#border-strong\",\n \"#accent-text\",\n \"#accent-surface\",\n \"#accent-surface-text\",\n \"#logo-surface\",\n \"#logo-mark\",\n \"#accent-surface-subtle\",\n \"#accent-surface-2-subtle\",\n \"#focus\",\n \"#shadow\",\n \"#overlay\",\n \"#syntax-bg\",\n \"#syntax-text\",\n \"#syntax-comment\",\n \"#syntax-punctuation\",\n \"#syntax-keyword\",\n \"#syntax-string\",\n \"#syntax-token\",\n \"#syntax-property\",\n \"#syntax-number\",\n \"#syntax-function\",\n \"#syntax-value\",\n \"#syntax-operator\",\n \"#info\",\n \"#info-surface\",\n \"#info-text\",\n \"#success\",\n \"#success-surface\",\n \"#success-text\",\n \"#warning\",\n \"#warning-surface\",\n \"#warning-text\",\n \"#danger\",\n \"#danger-surface\",\n \"#danger-text\",\n \"#orange-surface\",\n \"#orange\",\n \"#orange-text\",\n \"#green-surface\",\n \"#green\",\n \"#green-text\",\n \"#blue-surface\",\n \"#blue\",\n \"#blue-text\",\n \"#purple-surface\",\n \"#purple\",\n \"#purple-text\",\n \"#red-surface\",\n \"#red\",\n \"#red-text\",\n ],\n units: [\"x\", \"r\", \"cr\", \"bw\"],\n states: [\n \"@system-light\",\n \"@system-dark\",\n \"@light\",\n \"@dark\",\n \"@sm\",\n \"@md\",\n \"@lg\",\n \"@reduced-motion\",\n \"@prose\",\n \"@prose-block\",\n \"@prose-heading\",\n ],\n presets: [\n \"body\",\n \"heading\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"navigation\",\n \"small\",\n \"code\",\n \"hero-title\",\n \"hero-tagline\",\n \"prose\",\n \"inline-code\",\n ],\n} satisfies TastyValidationConfig;\n","export { default, recommended, strict } from \"@tenphi/eslint-plugin-tasty\";\nexport type {\n ResolvedConfig,\n StyleFunctionConfig,\n TastyValidationConfig,\n} from \"@tenphi/eslint-plugin-tasty\";\nexport { default as validationConfig } from \"./tasty.config.js\";\n\nimport type { ThemeConfig } from \"@tenphi/docs\";\nimport type { TastyValidationConfig } from \"@tenphi/eslint-plugin-tasty\";\nimport validationConfig from \"./tasty.config.js\";\n\n/** Keep editor/linter names aligned with a Cookbook theme. */\nexport function createValidationConfig(\n theme: ThemeConfig = {},\n): TastyValidationConfig {\n return {\n ...validationConfig,\n tokens: [\n ...validationConfig.tokens,\n ...Object.keys(theme.tokens ?? {}),\n ...Object.keys(theme.palette ?? {}).map((name) => `#${name}`),\n ],\n units: [...validationConfig.units, ...Object.keys(theme.units ?? {})],\n states: [...validationConfig.states, ...Object.keys(theme.states ?? {})],\n presets: [...validationConfig.presets, ...Object.keys(theme.presets ?? {})],\n recipes: Object.keys(theme.recipes ?? {}),\n };\n}\n"],"mappings":";;AAEA,IAAA,uBAAe;CACb,eAAe;EACb;EACA;EACA;EACA;CACF;CACA,gBAAgB;EACd,iBAAiB;GAAE,UAAU;GAAG,MAAM;EAAU;EAChD,iBAAiB;GAAE,UAAU;GAAG,MAAM;GAAW,SAAS;EAAK;EAC/D,wBAAwB;GAAE,UAAU;GAAG,MAAM;EAAS;CACxD;CACA,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO;EAAC;EAAK;EAAK;EAAM;CAAI;CAC5B,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;ACxHA,SAAgB,uBACd,QAAqB,CAAC,GACC;CACvB,OAAO;EACL,GAAGA;EACH,QAAQ;GACN,GAAGA,qBAAiB;GACpB,GAAG,OAAO,KAAK,MAAM,UAAU,CAAC,CAAC;GACjC,GAAG,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM;EAC9D;EACA,OAAO,CAAC,GAAGA,qBAAiB,OAAO,GAAG,OAAO,KAAK,MAAM,SAAS,CAAC,CAAC,CAAC;EACpE,QAAQ,CAAC,GAAGA,qBAAiB,QAAQ,GAAG,OAAO,KAAK,MAAM,UAAU,CAAC,CAAC,CAAC;EACvE,SAAS,CAAC,GAAGA,qBAAiB,SAAS,GAAG,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC;EAC1E,SAAS,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC;CAC1C;AACF"}
1
+ {"version":3,"file":"eslint-plugin.js","names":["validationConfig"],"sources":["../src/tasty.config.ts","../src/eslint-plugin.ts"],"sourcesContent":["import type { TastyValidationConfig } from \"@tenphi/eslint-plugin-tasty\";\n\nexport default {\n importSources: [\n \"@tenphi/cookbook/styling\",\n \"@tenphi/renderer/styling\",\n \"./component-styles.js\",\n \"../define-component.js\",\n ],\n styleFunctions: {\n defineComponent: { argument: 1, kind: \"options\" },\n extendComponent: { argument: 2, kind: \"options\", partial: true },\n resolveComponentStyles: { argument: 1, kind: \"styles\" },\n },\n tokens: [\n \"$gap\",\n \"$margin-block-start\",\n \"$margin-block-end\",\n \"$padding-block-start\",\n \"$padding-block-end\",\n \"$radius\",\n \"$header-control-radius\",\n \"$card-radius\",\n \"$border-width\",\n \"$outline-width\",\n \"$outline-offset\",\n \"$layout-width\",\n \"$content-width\",\n \"$sidebar-width\",\n \"$control-height\",\n \"$transition\",\n \"$sharp-radius\",\n \"$bold-font-weight\",\n \"#white\",\n \"#black\",\n \"#clear\",\n \"#current\",\n \"#surface\",\n \"#header\",\n \"#heading\",\n \"#surface-2\",\n \"#surface-3\",\n \"#surface-2-hover\",\n \"#surface-2-pressed\",\n \"#surface-3-hover\",\n \"#surface-3-pressed\",\n \"#text\",\n \"#text-soft\",\n \"#text-muted\",\n \"#sidebar-text\",\n \"#border\",\n \"#border-strong\",\n \"#accent-text\",\n \"#accent-surface\",\n \"#accent-surface-text\",\n \"#logo-surface\",\n \"#logo-mark\",\n \"#accent-surface-subtle\",\n \"#accent-surface-2-subtle\",\n \"#focus\",\n \"#shadow\",\n \"#overlay\",\n \"#syntax-bg\",\n \"#syntax-text\",\n \"#syntax-comment\",\n \"#syntax-punctuation\",\n \"#syntax-keyword\",\n \"#syntax-string\",\n \"#syntax-token\",\n \"#syntax-property\",\n \"#syntax-number\",\n \"#syntax-function\",\n \"#syntax-value\",\n \"#syntax-operator\",\n \"#info\",\n \"#info-surface\",\n \"#info-text\",\n \"#success\",\n \"#success-surface\",\n \"#success-text\",\n \"#warning\",\n \"#warning-surface\",\n \"#warning-text\",\n \"#danger\",\n \"#danger-surface\",\n \"#danger-text\",\n \"#orange-surface\",\n \"#orange\",\n \"#orange-text\",\n \"#green-surface\",\n \"#green\",\n \"#green-text\",\n \"#blue-surface\",\n \"#blue\",\n \"#blue-text\",\n \"#purple-surface\",\n \"#purple\",\n \"#purple-text\",\n \"#red-surface\",\n \"#red\",\n \"#red-text\",\n ],\n units: [\"x\", \"r\", \"cr\", \"bw\"],\n states: [\n \"@system-light\",\n \"@system-dark\",\n \"@light\",\n \"@dark\",\n \"@sm\",\n \"@md\",\n \"@lg\",\n \"@reduced-motion\",\n \"@prose\",\n \"@prose-block\",\n \"@prose-heading\",\n ],\n presets: [\n \"body\",\n \"heading\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"navigation\",\n \"small\",\n \"code\",\n \"hero-title\",\n \"hero-tagline\",\n \"prose\",\n \"inline-code\",\n \"control-label\",\n ],\n} satisfies TastyValidationConfig;\n","export { default, recommended, strict } from \"@tenphi/eslint-plugin-tasty\";\nexport type {\n ResolvedConfig,\n StyleFunctionConfig,\n TastyValidationConfig,\n} from \"@tenphi/eslint-plugin-tasty\";\nexport { default as validationConfig } from \"./tasty.config.js\";\n\nimport type { ThemeConfig } from \"@tenphi/docs\";\nimport type { TastyValidationConfig } from \"@tenphi/eslint-plugin-tasty\";\nimport validationConfig from \"./tasty.config.js\";\n\n/** Keep editor/linter names aligned with a Cookbook theme. */\nexport function createValidationConfig(\n theme: ThemeConfig = {},\n): TastyValidationConfig {\n return {\n ...validationConfig,\n tokens: [\n ...validationConfig.tokens,\n ...Object.keys(theme.tokens ?? {}),\n ...Object.keys(theme.palette ?? {}).map((name) => `#${name}`),\n ],\n units: [...validationConfig.units, ...Object.keys(theme.units ?? {})],\n states: [...validationConfig.states, ...Object.keys(theme.states ?? {})],\n presets: [...validationConfig.presets, ...Object.keys(theme.presets ?? {})],\n recipes: Object.keys(theme.recipes ?? {}),\n };\n}\n"],"mappings":";;AAEA,IAAA,uBAAe;CACb,eAAe;EACb;EACA;EACA;EACA;CACF;CACA,gBAAgB;EACd,iBAAiB;GAAE,UAAU;GAAG,MAAM;EAAU;EAChD,iBAAiB;GAAE,UAAU;GAAG,MAAM;GAAW,SAAS;EAAK;EAC/D,wBAAwB;GAAE,UAAU;GAAG,MAAM;EAAS;CACxD;CACA,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,OAAO;EAAC;EAAK;EAAK;EAAM;CAAI;CAC5B,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,SAAS;EACP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF;;;;ACzHA,SAAgB,uBACd,QAAqB,CAAC,GACC;CACvB,OAAO;EACL,GAAGA;EACH,QAAQ;GACN,GAAGA,qBAAiB;GACpB,GAAG,OAAO,KAAK,MAAM,UAAU,CAAC,CAAC;GACjC,GAAG,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM;EAC9D;EACA,OAAO,CAAC,GAAGA,qBAAiB,OAAO,GAAG,OAAO,KAAK,MAAM,SAAS,CAAC,CAAC,CAAC;EACpE,QAAQ,CAAC,GAAGA,qBAAiB,QAAQ,GAAG,OAAO,KAAK,MAAM,UAAU,CAAC,CAAC,CAAC;EACvE,SAAS,CAAC,GAAGA,qBAAiB,SAAS,GAAG,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC;EAC1E,SAAS,OAAO,KAAK,MAAM,WAAW,CAAC,CAAC;CAC1C;AACF"}
@@ -46,35 +46,37 @@ const sidebar =
46
46
  const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
47
47
  ---
48
48
 
49
- <div data-element="MobileHeading">
50
- <a
51
- data-element="HomeLink"
52
- href={localeHref(
53
- (content.logo && content.logo.href) || "/",
54
- currentPath,
55
- content.routes,
56
- content,
57
- content.base,
58
- )}
59
- >
60
- <Logo />
61
- <span data-element="HomeLabel" data-site-title
62
- >{Astro.locals.cookbookRoute.siteTitle}</span
49
+ <div data-element="MobileHeader">
50
+ <div data-element="MobileHeading">
51
+ <a
52
+ data-element="HomeLink"
53
+ href={localeHref(
54
+ (content.logo && content.logo.href) || "/",
55
+ currentPath,
56
+ content.routes,
57
+ content,
58
+ content.base,
59
+ )}
63
60
  >
64
- </a>
65
- <button
66
- type="button"
67
- popovertarget="cookbook__sidebar"
68
- popovertargetaction="hide"
69
- aria-label={ui.closeNavigation}
70
- autofocus><Icon name="close" /></button
71
- >
72
- </div>
61
+ <Logo />
62
+ <span data-element="HomeLabel" data-site-title
63
+ >{Astro.locals.cookbookRoute.siteTitle}</span
64
+ >
65
+ </a>
66
+ <button
67
+ type="button"
68
+ popovertarget="cookbook__sidebar"
69
+ popovertargetaction="hide"
70
+ aria-label={ui.closeNavigation}
71
+ autofocus><Icon name="close" /></button
72
+ >
73
+ </div>
73
74
 
74
- <MobileNavigationTabs
75
- base={import.meta.env.BASE_URL}
76
- currentPath={Astro.url.pathname}
77
- />
75
+ <MobileNavigationTabs
76
+ base={import.meta.env.BASE_URL}
77
+ currentPath={Astro.url.pathname}
78
+ />
79
+ </div>
78
80
 
79
81
  <cookbook-sidebar
80
82
  data-storage-key={`cookbook-sidebar:${import.meta.env.BASE_URL}:${groupIndex ?? "all"}`}
@@ -82,7 +84,7 @@ const ui = messages(Astro.locals.cookbookRoute?.lang ?? "en", content);
82
84
  <SidebarList entries={sidebar} />
83
85
  </cookbook-sidebar>
84
86
 
85
- <div data-mobile="">
87
+ <div data-element="MobileFooter" data-mobile="">
86
88
  <MobileMenuFooter />
87
89
  </div>
88
90
 
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","names":[],"sources":["../../src/theme/defaults.ts"],"mappings":";;cAMa;;;;;;;;;;;;;cAmBA,4BAA4B,eAAe;iBA4ExC,mBAAmB,SAAQ,cAAmB;iBAI9C,yBACd,UAAS,mBACT,eAAc,QAAQ,+CACrB,eAAe"}
1
+ {"version":3,"file":"defaults.d.ts","names":[],"sources":["../../src/theme/defaults.ts"],"mappings":";;cAMa;;;;;;;;;;;;;cAmBA,4BAA4B,eAAe;iBAkFxC,mBAAmB,SAAQ,cAAmB;iBAI9C,yBACd,UAAS,mBACT,eAAc,QAAQ,+CACrB,eAAe"}
@@ -66,7 +66,13 @@ const DEFAULT_TYPOGRAPHY_PRESETS = {
66
66
  lineHeight: 1.55
67
67
  }),
68
68
  prose: derivedPreset("body", { fontSize: "1.025rem" }),
69
- "inline-code": derivedPreset("code", { fontSize: "0.875em" })
69
+ "inline-code": derivedPreset("code", { fontSize: "0.875em" }),
70
+ "control-label": derivedPreset("small", {
71
+ fontSize: "0.75rem",
72
+ lineHeight: 1.4,
73
+ letterSpacing: "0.06em",
74
+ textTransform: "uppercase"
75
+ })
70
76
  };
71
77
  /** Keep specialized typography linked to user-configured base presets. */
72
78
  function derivedPreset(base, overrides) {
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","names":[],"sources":["../../src/theme/defaults.ts"],"sourcesContent":["import type {\n ThemeTokens,\n TypographyPreset,\n TypographyPresets,\n} from \"@tenphi/docs\";\n\nexport const DEFAULT_THEME_TOKENS = {\n $gap: \"0.5rem\",\n $radius: \"8px\",\n \"$header-control-radius\": \"999px\",\n \"$card-radius\": \"16px\",\n \"$border-width\": \"1px\",\n \"$outline-width\": \"2px\",\n \"$outline-offset\": \"2px\",\n \"$layout-width\": \"87.5rem\",\n \"$content-width\": \"58rem\",\n \"$sidebar-width\": \"17.5rem\",\n \"$control-height\": \"2.5rem\",\n} satisfies ThemeTokens;\n\nconst BODY_FONT =\n \"'Onest Variable', Onest, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\";\nconst MONO_FONT =\n \"'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace\";\n\nexport const DEFAULT_TYPOGRAPHY_PRESETS: Record<string, TypographyPreset> = {\n body: {\n fontFamily: BODY_FONT,\n fontSize: \"1rem\",\n lineHeight: 1.65,\n letterSpacing: \"0\",\n fontWeight: 400,\n boldFontWeight: 640,\n },\n heading: {\n fontFamily: BODY_FONT,\n fontSize: \"1rem\",\n lineHeight: 1.15,\n letterSpacing: \"-0.006em\",\n fontWeight: 610,\n boldFontWeight: 720,\n },\n h1: heading(\"clamp(2.5rem, 5vw, 3.25rem)\", 1.05, \"-0.015em\"),\n h2: heading(\"clamp(1.75rem, 3vw, 2.125rem)\", 1.1, \"-0.01em\"),\n h3: heading(\"1.5rem\", 1.15, \"-0.006em\"),\n h4: heading(\"1.25rem\", 1.2, \"-0.003em\"),\n h5: heading(\"1.125rem\", 1.25, \"0\"),\n h6: heading(\"1rem\", 1.3, \"0\"),\n navigation: {\n fontFamily: \"var(--body-font-family)\",\n fontSize: \"0.9375rem\",\n lineHeight: 1.4,\n letterSpacing: \"0\",\n fontWeight: 450,\n boldFontWeight: 580,\n },\n small: {\n fontFamily: \"var(--body-font-family)\",\n fontSize: \"0.875rem\",\n lineHeight: 1.45,\n letterSpacing: \"-0.002em\",\n fontWeight: 420,\n boldFontWeight: 600,\n },\n code: {\n fontFamily: MONO_FONT,\n fontSize: \"0.875rem\",\n lineHeight: 1.65,\n letterSpacing: \"0\",\n fontWeight: 400,\n boldFontWeight: 650,\n },\n \"hero-title\": derivedPreset(\"h1\", {\n fontSize: \"clamp(2.75rem, 7vw, 4.75rem)\",\n }),\n \"hero-tagline\": derivedPreset(\"body\", {\n fontSize: \"clamp(1.05rem, 2.5vw, 1.35rem)\",\n lineHeight: 1.55,\n }),\n prose: derivedPreset(\"body\", { fontSize: \"1.025rem\" }),\n \"inline-code\": derivedPreset(\"code\", { fontSize: \"0.875em\" }),\n};\n\n/** Keep specialized typography linked to user-configured base presets. */\nfunction derivedPreset(\n base: string,\n overrides: TypographyPreset,\n): TypographyPreset {\n return {\n fontFamily: `var(--${base}-font-family)`,\n fontSize: `var(--${base}-font-size)`,\n lineHeight: `var(--${base}-line-height)`,\n letterSpacing: `var(--${base}-letter-spacing)`,\n fontWeight: `var(--${base}-font-weight)`,\n boldFontWeight: `var(--${base}-bold-font-weight)`,\n fontStyle: `var(--${base}-font-style, var(--default-font-style))`,\n textTransform: `var(--${base}-text-transform, var(--default-text-transform))`,\n ...overrides,\n };\n}\n\nexport function resolveThemeTokens(tokens: ThemeTokens = {}): ThemeTokens {\n return { ...DEFAULT_THEME_TOKENS, ...tokens };\n}\n\nexport function resolveTypographyPresets(\n presets: TypographyPresets = {},\n fontFamilies: Partial<Record<\"body\" | \"heading\" | \"code\", string>> = {},\n): Record<string, TypographyPreset> {\n const body = DEFAULT_TYPOGRAPHY_PRESETS.body;\n if (!body) throw new Error(\"The body typography preset is required.\");\n const names = new Set([\n ...Object.keys(DEFAULT_TYPOGRAPHY_PRESETS),\n ...Object.keys(presets),\n ]);\n return Object.fromEntries(\n [...names].map((name) => [\n name,\n {\n ...(DEFAULT_TYPOGRAPHY_PRESETS[name] ?? body),\n ...(name in fontFamilies\n ? { fontFamily: fontFamilies[name as keyof typeof fontFamilies] }\n : {}),\n ...(presets[name] ?? {}),\n },\n ]),\n );\n}\n\nfunction heading(\n fontSize: string,\n lineHeight: number,\n letterSpacing: string,\n): TypographyPreset {\n return {\n fontFamily: \"var(--heading-font-family)\",\n fontSize,\n lineHeight,\n letterSpacing,\n fontWeight: \"var(--heading-font-weight)\",\n boldFontWeight: \"var(--heading-bold-font-weight)\",\n };\n}\n"],"mappings":";AAMA,MAAa,uBAAuB;CAClC,MAAM;CACN,SAAS;CACT,0BAA0B;CAC1B,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;CACjB,kBAAkB;CAClB,kBAAkB;CAClB,mBAAmB;AACrB;AAEA,MAAM,YACJ;AAIF,MAAa,6BAA+D;CAC1E,MAAM;EACJ,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,SAAS;EACP,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,IAAI,QAAQ,+BAA+B,MAAM,UAAU;CAC3D,IAAI,QAAQ,iCAAiC,KAAK,SAAS;CAC3D,IAAI,QAAQ,UAAU,MAAM,UAAU;CACtC,IAAI,QAAQ,WAAW,KAAK,UAAU;CACtC,IAAI,QAAQ,YAAY,MAAM,GAAG;CACjC,IAAI,QAAQ,QAAQ,KAAK,GAAG;CAC5B,YAAY;EACV,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,OAAO;EACL,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,MAAM;EACJ,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,cAAc,cAAc,MAAM,EAChC,UAAU,+BACZ,CAAC;CACD,gBAAgB,cAAc,QAAQ;EACpC,UAAU;EACV,YAAY;CACd,CAAC;CACD,OAAO,cAAc,QAAQ,EAAE,UAAU,WAAW,CAAC;CACrD,eAAe,cAAc,QAAQ,EAAE,UAAU,UAAU,CAAC;AAC9D;;AAGA,SAAS,cACP,MACA,WACkB;CAClB,OAAO;EACL,YAAY,SAAS,KAAK;EAC1B,UAAU,SAAS,KAAK;EACxB,YAAY,SAAS,KAAK;EAC1B,eAAe,SAAS,KAAK;EAC7B,YAAY,SAAS,KAAK;EAC1B,gBAAgB,SAAS,KAAK;EAC9B,WAAW,SAAS,KAAK;EACzB,eAAe,SAAS,KAAK;EAC7B,GAAG;CACL;AACF;AAEA,SAAgB,mBAAmB,SAAsB,CAAC,GAAgB;CACxE,OAAO;EAAE,GAAG;EAAsB,GAAG;CAAO;AAC9C;AAEA,SAAgB,yBACd,UAA6B,CAAC,GAC9B,eAAqE,CAAC,GACpC;CAClC,MAAM,OAAO,2BAA2B;CACxC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,yCAAyC;CACpE,MAAM,wBAAQ,IAAI,IAAI,CACpB,GAAG,OAAO,KAAK,0BAA0B,GACzC,GAAG,OAAO,KAAK,OAAO,CACxB,CAAC;CACD,OAAO,OAAO,YACZ,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,SAAS,CACvB,MACA;EACE,GAAI,2BAA2B,SAAS;EACxC,GAAI,QAAQ,eACR,EAAE,YAAY,aAAa,MAAmC,IAC9D,CAAC;EACL,GAAI,QAAQ,SAAS,CAAC;CACxB,CACF,CAAC,CACH;AACF;AAEA,SAAS,QACP,UACA,YACA,eACkB;CAClB,OAAO;EACL,YAAY;EACZ;EACA;EACA;EACA,YAAY;EACZ,gBAAgB;CAClB;AACF"}
1
+ {"version":3,"file":"defaults.js","names":[],"sources":["../../src/theme/defaults.ts"],"sourcesContent":["import type {\n ThemeTokens,\n TypographyPreset,\n TypographyPresets,\n} from \"@tenphi/docs\";\n\nexport const DEFAULT_THEME_TOKENS = {\n $gap: \"0.5rem\",\n $radius: \"8px\",\n \"$header-control-radius\": \"999px\",\n \"$card-radius\": \"16px\",\n \"$border-width\": \"1px\",\n \"$outline-width\": \"2px\",\n \"$outline-offset\": \"2px\",\n \"$layout-width\": \"87.5rem\",\n \"$content-width\": \"58rem\",\n \"$sidebar-width\": \"17.5rem\",\n \"$control-height\": \"2.5rem\",\n} satisfies ThemeTokens;\n\nconst BODY_FONT =\n \"'Onest Variable', Onest, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\";\nconst MONO_FONT =\n \"'JetBrains Mono Variable', 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace\";\n\nexport const DEFAULT_TYPOGRAPHY_PRESETS: Record<string, TypographyPreset> = {\n body: {\n fontFamily: BODY_FONT,\n fontSize: \"1rem\",\n lineHeight: 1.65,\n letterSpacing: \"0\",\n fontWeight: 400,\n boldFontWeight: 640,\n },\n heading: {\n fontFamily: BODY_FONT,\n fontSize: \"1rem\",\n lineHeight: 1.15,\n letterSpacing: \"-0.006em\",\n fontWeight: 610,\n boldFontWeight: 720,\n },\n h1: heading(\"clamp(2.5rem, 5vw, 3.25rem)\", 1.05, \"-0.015em\"),\n h2: heading(\"clamp(1.75rem, 3vw, 2.125rem)\", 1.1, \"-0.01em\"),\n h3: heading(\"1.5rem\", 1.15, \"-0.006em\"),\n h4: heading(\"1.25rem\", 1.2, \"-0.003em\"),\n h5: heading(\"1.125rem\", 1.25, \"0\"),\n h6: heading(\"1rem\", 1.3, \"0\"),\n navigation: {\n fontFamily: \"var(--body-font-family)\",\n fontSize: \"0.9375rem\",\n lineHeight: 1.4,\n letterSpacing: \"0\",\n fontWeight: 450,\n boldFontWeight: 580,\n },\n small: {\n fontFamily: \"var(--body-font-family)\",\n fontSize: \"0.875rem\",\n lineHeight: 1.45,\n letterSpacing: \"-0.002em\",\n fontWeight: 420,\n boldFontWeight: 600,\n },\n code: {\n fontFamily: MONO_FONT,\n fontSize: \"0.875rem\",\n lineHeight: 1.65,\n letterSpacing: \"0\",\n fontWeight: 400,\n boldFontWeight: 650,\n },\n \"hero-title\": derivedPreset(\"h1\", {\n fontSize: \"clamp(2.75rem, 7vw, 4.75rem)\",\n }),\n \"hero-tagline\": derivedPreset(\"body\", {\n fontSize: \"clamp(1.05rem, 2.5vw, 1.35rem)\",\n lineHeight: 1.55,\n }),\n prose: derivedPreset(\"body\", { fontSize: \"1.025rem\" }),\n \"inline-code\": derivedPreset(\"code\", { fontSize: \"0.875em\" }),\n \"control-label\": derivedPreset(\"small\", {\n fontSize: \"0.75rem\",\n lineHeight: 1.4,\n letterSpacing: \"0.06em\",\n textTransform: \"uppercase\",\n }),\n};\n\n/** Keep specialized typography linked to user-configured base presets. */\nfunction derivedPreset(\n base: string,\n overrides: TypographyPreset,\n): TypographyPreset {\n return {\n fontFamily: `var(--${base}-font-family)`,\n fontSize: `var(--${base}-font-size)`,\n lineHeight: `var(--${base}-line-height)`,\n letterSpacing: `var(--${base}-letter-spacing)`,\n fontWeight: `var(--${base}-font-weight)`,\n boldFontWeight: `var(--${base}-bold-font-weight)`,\n fontStyle: `var(--${base}-font-style, var(--default-font-style))`,\n textTransform: `var(--${base}-text-transform, var(--default-text-transform))`,\n ...overrides,\n };\n}\n\nexport function resolveThemeTokens(tokens: ThemeTokens = {}): ThemeTokens {\n return { ...DEFAULT_THEME_TOKENS, ...tokens };\n}\n\nexport function resolveTypographyPresets(\n presets: TypographyPresets = {},\n fontFamilies: Partial<Record<\"body\" | \"heading\" | \"code\", string>> = {},\n): Record<string, TypographyPreset> {\n const body = DEFAULT_TYPOGRAPHY_PRESETS.body;\n if (!body) throw new Error(\"The body typography preset is required.\");\n const names = new Set([\n ...Object.keys(DEFAULT_TYPOGRAPHY_PRESETS),\n ...Object.keys(presets),\n ]);\n return Object.fromEntries(\n [...names].map((name) => [\n name,\n {\n ...(DEFAULT_TYPOGRAPHY_PRESETS[name] ?? body),\n ...(name in fontFamilies\n ? { fontFamily: fontFamilies[name as keyof typeof fontFamilies] }\n : {}),\n ...(presets[name] ?? {}),\n },\n ]),\n );\n}\n\nfunction heading(\n fontSize: string,\n lineHeight: number,\n letterSpacing: string,\n): TypographyPreset {\n return {\n fontFamily: \"var(--heading-font-family)\",\n fontSize,\n lineHeight,\n letterSpacing,\n fontWeight: \"var(--heading-font-weight)\",\n boldFontWeight: \"var(--heading-bold-font-weight)\",\n };\n}\n"],"mappings":";AAMA,MAAa,uBAAuB;CAClC,MAAM;CACN,SAAS;CACT,0BAA0B;CAC1B,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;CACjB,kBAAkB;CAClB,kBAAkB;CAClB,mBAAmB;AACrB;AAEA,MAAM,YACJ;AAIF,MAAa,6BAA+D;CAC1E,MAAM;EACJ,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,SAAS;EACP,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,IAAI,QAAQ,+BAA+B,MAAM,UAAU;CAC3D,IAAI,QAAQ,iCAAiC,KAAK,SAAS;CAC3D,IAAI,QAAQ,UAAU,MAAM,UAAU;CACtC,IAAI,QAAQ,WAAW,KAAK,UAAU;CACtC,IAAI,QAAQ,YAAY,MAAM,GAAG;CACjC,IAAI,QAAQ,QAAQ,KAAK,GAAG;CAC5B,YAAY;EACV,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,OAAO;EACL,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,MAAM;EACJ,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,eAAe;EACf,YAAY;EACZ,gBAAgB;CAClB;CACA,cAAc,cAAc,MAAM,EAChC,UAAU,+BACZ,CAAC;CACD,gBAAgB,cAAc,QAAQ;EACpC,UAAU;EACV,YAAY;CACd,CAAC;CACD,OAAO,cAAc,QAAQ,EAAE,UAAU,WAAW,CAAC;CACrD,eAAe,cAAc,QAAQ,EAAE,UAAU,UAAU,CAAC;CAC5D,iBAAiB,cAAc,SAAS;EACtC,UAAU;EACV,YAAY;EACZ,eAAe;EACf,eAAe;CACjB,CAAC;AACH;;AAGA,SAAS,cACP,MACA,WACkB;CAClB,OAAO;EACL,YAAY,SAAS,KAAK;EAC1B,UAAU,SAAS,KAAK;EACxB,YAAY,SAAS,KAAK;EAC1B,eAAe,SAAS,KAAK;EAC7B,YAAY,SAAS,KAAK;EAC1B,gBAAgB,SAAS,KAAK;EAC9B,WAAW,SAAS,KAAK;EACzB,eAAe,SAAS,KAAK;EAC7B,GAAG;CACL;AACF;AAEA,SAAgB,mBAAmB,SAAsB,CAAC,GAAgB;CACxE,OAAO;EAAE,GAAG;EAAsB,GAAG;CAAO;AAC9C;AAEA,SAAgB,yBACd,UAA6B,CAAC,GAC9B,eAAqE,CAAC,GACpC;CAClC,MAAM,OAAO,2BAA2B;CACxC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,yCAAyC;CACpE,MAAM,wBAAQ,IAAI,IAAI,CACpB,GAAG,OAAO,KAAK,0BAA0B,GACzC,GAAG,OAAO,KAAK,OAAO,CACxB,CAAC;CACD,OAAO,OAAO,YACZ,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,SAAS,CACvB,MACA;EACE,GAAI,2BAA2B,SAAS;EACxC,GAAI,QAAQ,eACR,EAAE,YAAY,aAAa,MAAmC,IAC9D,CAAC;EACL,GAAI,QAAQ,SAAS,CAAC;CACxB,CACF,CAAC,CACH;AACF;AAEA,SAAS,QACP,UACA,YACA,eACkB;CAClB,OAAO;EACL,YAAY;EACZ;EACA;EACA;EACA,YAAY;EACZ,gBAAgB;CAClB;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/renderer",
3
- "version": "0.30.0",
3
+ "version": "0.30.2",
4
4
  "description": "Astro renderer and Tasty theme for Cookbook",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -61,10 +61,12 @@
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.30.0",
64
+ "@tenphi/docs": "0.30.2",
65
65
  "@tenphi/eslint-plugin-tasty": "1.12.0",
66
66
  "@tenphi/glaze": "2.0.1",
67
67
  "@tenphi/tasty": "3.14.0",
68
+ "@uniaria/core": "0.3.0",
69
+ "@uniaria/elements": "0.3.0",
68
70
  "beautiful-mermaid": "^1.1.3",
69
71
  "hast-util-from-html": "^2.0.3",
70
72
  "pagefind": "1.5.2",