@specglass/theme-default 0.0.2 → 0.0.3

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 (111) hide show
  1. package/dist/__tests__/code-tabs.test.d.ts +0 -1
  2. package/dist/__tests__/code-tabs.test.js +0 -1
  3. package/dist/__tests__/copy-button.test.d.ts +0 -1
  4. package/dist/__tests__/copy-button.test.js +0 -1
  5. package/dist/__tests__/search-palette.test.d.ts +0 -1
  6. package/dist/__tests__/search-palette.test.js +0 -1
  7. package/dist/__tests__/shiki.test.d.ts +0 -1
  8. package/dist/__tests__/shiki.test.js +0 -1
  9. package/dist/__tests__/theme-css.test.d.ts +0 -1
  10. package/dist/__tests__/theme-css.test.js +0 -1
  11. package/dist/__tests__/theme-helpers.test.d.ts +0 -1
  12. package/dist/__tests__/theme-helpers.test.js +0 -1
  13. package/dist/index.d.ts +0 -1
  14. package/dist/index.js +0 -1
  15. package/dist/islands/CodeTabs.d.ts +0 -1
  16. package/dist/islands/CodeTabs.js +0 -1
  17. package/dist/islands/CopyButton.d.ts +0 -1
  18. package/dist/islands/CopyButton.js +0 -1
  19. package/dist/islands/SearchPalette.d.ts +0 -1
  20. package/dist/islands/SearchPalette.js +0 -1
  21. package/dist/islands/SearchResults.d.ts +0 -1
  22. package/dist/islands/SearchResults.js +0 -1
  23. package/dist/islands/ThemeToggle.d.ts +0 -1
  24. package/dist/islands/ThemeToggle.js +0 -1
  25. package/dist/layouts/DocPage.test.d.ts +0 -1
  26. package/dist/layouts/DocPage.test.js +0 -1
  27. package/dist/lib/utils.d.ts +0 -1
  28. package/dist/lib/utils.js +0 -1
  29. package/dist/scripts/code-block-enhancer.d.ts +0 -1
  30. package/dist/scripts/code-block-enhancer.js +0 -1
  31. package/dist/ui/command.d.ts +0 -1
  32. package/dist/ui/command.js +0 -1
  33. package/dist/ui/dialog.d.ts +0 -1
  34. package/dist/ui/dialog.js +0 -1
  35. package/dist/utils/parse-highlight-range.d.ts +0 -1
  36. package/dist/utils/parse-highlight-range.js +0 -1
  37. package/dist/utils/parse-highlight-range.test.d.ts +0 -1
  38. package/dist/utils/parse-highlight-range.test.js +0 -1
  39. package/dist/utils/schema-renderer.d.ts +0 -1
  40. package/dist/utils/schema-renderer.js +0 -1
  41. package/dist/utils/schema-renderer.test.d.ts +0 -1
  42. package/dist/utils/schema-renderer.test.js +0 -1
  43. package/dist/utils/shiki.d.ts +0 -1
  44. package/dist/utils/shiki.js +0 -1
  45. package/dist/utils/sidebar-helpers.d.ts +0 -1
  46. package/dist/utils/sidebar-helpers.js +0 -1
  47. package/dist/utils/theme-css.d.ts +0 -1
  48. package/dist/utils/theme-css.js +0 -1
  49. package/dist/utils/theme-helpers.d.ts +0 -1
  50. package/dist/utils/theme-helpers.js +0 -1
  51. package/dist/utils/toc-helpers.d.ts +0 -1
  52. package/dist/utils/toc-helpers.js +0 -1
  53. package/package.json +7 -3
  54. package/src/components/ApiExampleRequest.astro +179 -0
  55. package/src/components/ApiExampleResponse.astro +134 -0
  56. package/src/layouts/ApiReferencePage.astro +8 -0
  57. package/src/scripts/code-block-enhancer.ts +59 -0
  58. package/src/ui/command.tsx +183 -0
  59. package/src/ui/dialog.tsx +133 -0
  60. package/dist/__tests__/code-tabs.test.d.ts.map +0 -1
  61. package/dist/__tests__/code-tabs.test.js.map +0 -1
  62. package/dist/__tests__/copy-button.test.d.ts.map +0 -1
  63. package/dist/__tests__/copy-button.test.js.map +0 -1
  64. package/dist/__tests__/search-palette.test.d.ts.map +0 -1
  65. package/dist/__tests__/search-palette.test.js.map +0 -1
  66. package/dist/__tests__/shiki.test.d.ts.map +0 -1
  67. package/dist/__tests__/shiki.test.js.map +0 -1
  68. package/dist/__tests__/theme-css.test.d.ts.map +0 -1
  69. package/dist/__tests__/theme-css.test.js.map +0 -1
  70. package/dist/__tests__/theme-helpers.test.d.ts.map +0 -1
  71. package/dist/__tests__/theme-helpers.test.js.map +0 -1
  72. package/dist/index.d.ts.map +0 -1
  73. package/dist/index.js.map +0 -1
  74. package/dist/islands/CodeTabs.d.ts.map +0 -1
  75. package/dist/islands/CodeTabs.js.map +0 -1
  76. package/dist/islands/CopyButton.d.ts.map +0 -1
  77. package/dist/islands/CopyButton.js.map +0 -1
  78. package/dist/islands/SearchPalette.d.ts.map +0 -1
  79. package/dist/islands/SearchPalette.js.map +0 -1
  80. package/dist/islands/SearchResults.d.ts.map +0 -1
  81. package/dist/islands/SearchResults.js.map +0 -1
  82. package/dist/islands/ThemeToggle.d.ts.map +0 -1
  83. package/dist/islands/ThemeToggle.js.map +0 -1
  84. package/dist/layouts/DocPage.test.d.ts.map +0 -1
  85. package/dist/layouts/DocPage.test.js.map +0 -1
  86. package/dist/lib/utils.d.ts.map +0 -1
  87. package/dist/lib/utils.js.map +0 -1
  88. package/dist/scripts/code-block-enhancer.d.ts.map +0 -1
  89. package/dist/scripts/code-block-enhancer.js.map +0 -1
  90. package/dist/ui/command.d.ts.map +0 -1
  91. package/dist/ui/command.js.map +0 -1
  92. package/dist/ui/dialog.d.ts.map +0 -1
  93. package/dist/ui/dialog.js.map +0 -1
  94. package/dist/utils/parse-highlight-range.d.ts.map +0 -1
  95. package/dist/utils/parse-highlight-range.js.map +0 -1
  96. package/dist/utils/parse-highlight-range.test.d.ts.map +0 -1
  97. package/dist/utils/parse-highlight-range.test.js.map +0 -1
  98. package/dist/utils/schema-renderer.d.ts.map +0 -1
  99. package/dist/utils/schema-renderer.js.map +0 -1
  100. package/dist/utils/schema-renderer.test.d.ts.map +0 -1
  101. package/dist/utils/schema-renderer.test.js.map +0 -1
  102. package/dist/utils/shiki.d.ts.map +0 -1
  103. package/dist/utils/shiki.js.map +0 -1
  104. package/dist/utils/sidebar-helpers.d.ts.map +0 -1
  105. package/dist/utils/sidebar-helpers.js.map +0 -1
  106. package/dist/utils/theme-css.d.ts.map +0 -1
  107. package/dist/utils/theme-css.js.map +0 -1
  108. package/dist/utils/theme-helpers.d.ts.map +0 -1
  109. package/dist/utils/theme-helpers.js.map +0 -1
  110. package/dist/utils/toc-helpers.d.ts.map +0 -1
  111. package/dist/utils/toc-helpers.js.map +0 -1
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=code-tabs.test.d.ts.map
@@ -216,4 +216,3 @@ describe("CodeTabs", () => {
216
216
  });
217
217
  });
218
218
  });
219
- //# sourceMappingURL=code-tabs.test.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=copy-button.test.d.ts.map
@@ -113,4 +113,3 @@ describe("CopyButton logic", () => {
113
113
  expect(result.current.copied).toBe(false);
114
114
  });
115
115
  });
116
- //# sourceMappingURL=copy-button.test.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=search-palette.test.d.ts.map
@@ -68,4 +68,3 @@ describe("ui/dialog", () => {
68
68
  expect(mod.DialogDescription).toBeDefined();
69
69
  });
70
70
  });
71
- //# sourceMappingURL=search-palette.test.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=shiki.test.d.ts.map
@@ -34,4 +34,3 @@ describe("highlight utility", () => {
34
34
  expect(html2).toContain("--shiki-light");
35
35
  });
36
36
  });
37
- //# sourceMappingURL=shiki.test.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=theme-css.test.d.ts.map
@@ -121,4 +121,3 @@ describe("generateThemeCSS", () => {
121
121
  expect(css).not.toContain("--color-surface:");
122
122
  });
123
123
  });
124
- //# sourceMappingURL=theme-css.test.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=theme-helpers.test.d.ts.map
@@ -78,4 +78,3 @@ describe("theme-helpers", () => {
78
78
  });
79
79
  });
80
80
  });
81
- //# sourceMappingURL=theme-helpers.test.js.map
package/dist/index.d.ts CHANGED
@@ -60,4 +60,3 @@ export interface TableOfContentsProps {
60
60
  text: string;
61
61
  }>;
62
62
  }
63
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -10,4 +10,3 @@ export { getStoredTheme, getEffectiveTheme, applyTheme, THEME_STORAGE_KEY, DEFAU
10
10
  export { ThemeToggle } from "./islands/ThemeToggle.js";
11
11
  export { CopyButton } from "./islands/CopyButton.js";
12
12
  export { CodeTabs } from "./islands/CodeTabs.js";
13
- //# sourceMappingURL=index.js.map
@@ -18,4 +18,3 @@ interface CodeTabsProps {
18
18
  declare function CodeTabs({ tabs, syncKey, ariaLabel }: CodeTabsProps): import("react/jsx-runtime").JSX.Element | null;
19
19
  export { CodeTabs };
20
20
  export type { CodeTab, CodeTabsProps };
21
- //# sourceMappingURL=CodeTabs.d.ts.map
@@ -122,4 +122,3 @@ function CodeTabs({ tabs, syncKey = "sdk-language", ariaLabel = "SDK language ta
122
122
  return (_jsxs("div", { className: "my-6 border border-border rounded-lg overflow-hidden", children: [_jsx("div", { role: "tablist", "aria-label": ariaLabel, className: "flex border-b border-border bg-surface-raised", onKeyDown: handleKeyDown, children: tabs.map((tab, i) => (_jsx("button", { id: `${groupId}-tab-${i}`, role: "tab", "aria-selected": i === activeIndex, "aria-controls": `${groupId}-panel-${i}`, tabIndex: i === activeIndex ? 0 : -1, className: cn("px-4 py-2 border-b-2 border-transparent text-[0.8125rem] font-medium font-mono", "text-text-muted cursor-pointer whitespace-nowrap bg-transparent", "transition-colors duration-150 hover:text-text", "focus-visible:outline-2 focus-visible:outline-primary focus-visible:-outline-offset-2", i === activeIndex && "text-text border-b-primary"), onClick: () => setTab(i), children: tab.label }, tab.language))) }), tabs.map((tab, i) => (_jsx("div", { id: `${groupId}-panel-${i}`, role: "tabpanel", "aria-labelledby": `${groupId}-tab-${i}`, tabIndex: 0, className: "code-tabs-panel", style: { display: i === activeIndex ? undefined : "none" }, dangerouslySetInnerHTML: { __html: tab.content } }, tab.language)))] }));
123
123
  }
124
124
  export { CodeTabs };
125
- //# sourceMappingURL=CodeTabs.js.map
@@ -13,4 +13,3 @@ export interface CopyButtonProps {
13
13
  code: string;
14
14
  }
15
15
  export declare function CopyButton({ code }: CopyButtonProps): import("react/jsx-runtime").JSX.Element;
16
- //# sourceMappingURL=CopyButton.d.ts.map
@@ -51,4 +51,3 @@ export function CopyButton({ code }) {
51
51
  /* Copy icon */
52
52
  _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }), _jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })] })) }));
53
53
  }
54
- //# sourceMappingURL=CopyButton.js.map
@@ -1,2 +1 @@
1
1
  export declare function SearchPalette(): import("react/jsx-runtime").JSX.Element;
2
- //# sourceMappingURL=SearchPalette.d.ts.map
@@ -106,4 +106,3 @@ export function SearchPalette() {
106
106
  __html: result.sub_results?.[0]?.excerpt ?? result.excerpt ?? "",
107
107
  } })] }, result.id)))] }), (results.length > 0 || query.trim().length > 0) && !isUnavailable && (_jsx("div", { className: "flex items-center justify-between border-t border-border px-3 py-2 text-xs text-text-muted", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border border-border bg-surface-raised px-1 py-0.5 font-mono text-[10px]", children: "\u2191\u2193" }), "navigate"] }), _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border border-border bg-surface-raised px-1 py-0.5 font-mono text-[10px]", children: "\u21B5" }), "open"] }), _jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("kbd", { className: "rounded border border-border bg-surface-raised px-1 py-0.5 font-mono text-[10px]", children: "esc" }), "close"] })] }) }))] })] }));
108
108
  }
109
- //# sourceMappingURL=SearchPalette.js.map
@@ -1,2 +1 @@
1
1
  export declare function SearchResults(): import("react/jsx-runtime").JSX.Element;
2
- //# sourceMappingURL=SearchResults.d.ts.map
@@ -127,4 +127,3 @@ export function SearchResults() {
127
127
  __html: result.sub_results?.[0]?.excerpt ?? result.excerpt ?? "",
128
128
  } })] }, result.id)))] }))] }));
129
129
  }
130
- //# sourceMappingURL=SearchResults.js.map
@@ -9,4 +9,3 @@
9
9
  * Imports shared utilities from theme-helpers.ts for consistency.
10
10
  */
11
11
  export declare function ThemeToggle(): import("react/jsx-runtime").JSX.Element;
12
- //# sourceMappingURL=ThemeToggle.d.ts.map
@@ -40,4 +40,3 @@ export function ThemeToggle() {
40
40
  }, []);
41
41
  return (_jsx("button", { type: "button", onClick: toggleTheme, "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode", className: "inline-flex items-center justify-center rounded-md p-2 text-text-muted hover:text-(--color-text) hover:bg-hover-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-primary transition-colors", children: _jsxs("span", { className: "relative inline-flex items-center justify-center w-5 h-5", children: [_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className: `absolute inset-0 transition-transform duration-300 ${isDark ? "rotate-0 scale-100" : "-rotate-90 scale-0"}`, children: [_jsx("circle", { cx: "12", cy: "12", r: "4" }), _jsx("path", { d: "M12 2v2" }), _jsx("path", { d: "M12 20v2" }), _jsx("path", { d: "m4.93 4.93 1.41 1.41" }), _jsx("path", { d: "m17.66 17.66 1.41 1.41" }), _jsx("path", { d: "M2 12h2" }), _jsx("path", { d: "M20 12h2" }), _jsx("path", { d: "m6.34 17.66-1.41 1.41" }), _jsx("path", { d: "m19.07 4.93-1.41 1.41" })] }), _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", className: `absolute inset-0 transition-transform duration-300 ${!isDark ? "rotate-0 scale-100" : "rotate-90 scale-0"}`, children: _jsx("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }) })] }) }));
42
42
  }
43
- //# sourceMappingURL=ThemeToggle.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=DocPage.test.d.ts.map
@@ -162,4 +162,3 @@ describe("DocPage props contract", () => {
162
162
  });
163
163
  });
164
164
  });
165
- //# sourceMappingURL=DocPage.test.js.map
@@ -7,4 +7,3 @@ import { type ClassValue } from "clsx";
7
7
  * Will be used by UI primitives in upcoming stories (e.g., search, dialogs).
8
8
  */
9
9
  export declare function cn(...inputs: ClassValue[]): string;
10
- //# sourceMappingURL=utils.d.ts.map
package/dist/lib/utils.js CHANGED
@@ -10,4 +10,3 @@ import { twMerge } from "tailwind-merge";
10
10
  export function cn(...inputs) {
11
11
  return twMerge(clsx(inputs));
12
12
  }
13
- //# sourceMappingURL=utils.js.map
@@ -13,4 +13,3 @@
13
13
  * until the user actually clicks copy.
14
14
  */
15
15
  declare function initCopyButtons(): void;
16
- //# sourceMappingURL=code-block-enhancer.d.ts.map
@@ -52,4 +52,3 @@ function initCopyButtons() {
52
52
  document.addEventListener("DOMContentLoaded", initCopyButtons);
53
53
  // Re-run after Astro ViewTransitions page swaps
54
54
  document.addEventListener("astro:after-swap", initCopyButtons);
55
- //# sourceMappingURL=code-block-enhancer.js.map
@@ -84,4 +84,3 @@ declare const CommandShortcut: {
84
84
  displayName: string;
85
85
  };
86
86
  export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, };
87
- //# sourceMappingURL=command.d.ts.map
@@ -25,4 +25,3 @@ const CommandShortcut = ({ className, ...props }) => {
25
25
  };
26
26
  CommandShortcut.displayName = "CommandShortcut";
27
27
  export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator, };
28
- //# sourceMappingURL=command.js.map
@@ -17,4 +17,3 @@ declare const DialogFooter: {
17
17
  declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
18
18
  declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
19
19
  export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };
20
- //# sourceMappingURL=dialog.d.ts.map
package/dist/ui/dialog.js CHANGED
@@ -19,4 +19,3 @@ DialogTitle.displayName = DialogPrimitive.Title.displayName;
19
19
  const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Description, { ref: ref, className: cn("text-sm text-text-muted", className), ...props })));
20
20
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
21
21
  export { Dialog, DialogPortal, DialogOverlay, DialogClose, DialogTrigger, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };
22
- //# sourceMappingURL=dialog.js.map
@@ -9,4 +9,3 @@
9
9
  * parseHighlightRange("") // → []
10
10
  */
11
11
  export declare function parseHighlightRange(range: string): number[];
12
- //# sourceMappingURL=parse-highlight-range.d.ts.map
@@ -37,4 +37,3 @@ export function parseHighlightRange(range) {
37
37
  }
38
38
  return result;
39
39
  }
40
- //# sourceMappingURL=parse-highlight-range.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=parse-highlight-range.test.d.ts.map
@@ -29,4 +29,3 @@ describe("parseHighlightRange", () => {
29
29
  expect(parseHighlightRange("1,abc,3")).toEqual([1, 3]);
30
30
  });
31
31
  });
32
- //# sourceMappingURL=parse-highlight-range.test.js.map
@@ -35,4 +35,3 @@ export declare function renderTypeString(schema: ApiSchema | undefined): string;
35
35
  * suitable for rendering in a table. Only expands 1 level deep for MVP.
36
36
  */
37
37
  export declare function flattenSchemaProperties(schema: ApiSchema | undefined, requiredFields?: string[], maxDepth?: number): SchemaProperty[];
38
- //# sourceMappingURL=schema-renderer.d.ts.map
@@ -112,4 +112,3 @@ export function flattenSchemaProperties(schema, requiredFields, maxDepth = 1) {
112
112
  }
113
113
  return properties;
114
114
  }
115
- //# sourceMappingURL=schema-renderer.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=schema-renderer.test.d.ts.map
@@ -216,4 +216,3 @@ describe("flattenSchemaProperties", () => {
216
216
  expect(props[0].name).toBe("nested");
217
217
  });
218
218
  });
219
- //# sourceMappingURL=schema-renderer.test.js.map
@@ -17,4 +17,3 @@ export interface HighlightOptions {
17
17
  * Returns raw HTML string with CSS variable tokens — ready for `set:html`.
18
18
  */
19
19
  export declare function highlight(code: string, lang: string, options?: HighlightOptions): Promise<string>;
20
- //# sourceMappingURL=shiki.d.ts.map
@@ -81,4 +81,3 @@ export async function highlight(code, lang, options) {
81
81
  ...(decorations?.length ? { decorations } : {}),
82
82
  });
83
83
  }
84
- //# sourceMappingURL=shiki.js.map
@@ -7,4 +7,3 @@ import type { NavItem } from "@specglass/core";
7
7
  export declare function filterVisibleItems(items: NavItem[]): NavItem[];
8
8
  /** Check if this item or any descendant is the current page. */
9
9
  export declare function isActiveOrAncestor(item: NavItem, currentSlug: string): boolean;
10
- //# sourceMappingURL=sidebar-helpers.d.ts.map
@@ -11,4 +11,3 @@ export function isActiveOrAncestor(item, currentSlug) {
11
11
  }
12
12
  return false;
13
13
  }
14
- //# sourceMappingURL=sidebar-helpers.js.map
@@ -18,4 +18,3 @@ import type { SpecglassConfig } from "@specglass/core";
18
18
  * ```
19
19
  */
20
20
  export declare function generateThemeCSS(config: SpecglassConfig): string;
21
- //# sourceMappingURL=theme-css.d.ts.map
@@ -74,4 +74,3 @@ export function generateThemeCSS(config) {
74
74
  return "";
75
75
  return `:root {\n${overrides.join("\n")}\n}`;
76
76
  }
77
- //# sourceMappingURL=theme-css.js.map
@@ -25,4 +25,3 @@ export declare function getEffectiveTheme(stored: Theme | null): Theme;
25
25
  * Also persists the preference to localStorage.
26
26
  */
27
27
  export declare function applyTheme(theme: Theme): void;
28
- //# sourceMappingURL=theme-helpers.d.ts.map
@@ -52,4 +52,3 @@ export function applyTheme(theme) {
52
52
  // localStorage unavailable — graceful degradation
53
53
  }
54
54
  }
55
- //# sourceMappingURL=theme-helpers.js.map
@@ -9,4 +9,3 @@ export type Heading = {
9
9
  };
10
10
  /** Filter headings to include only h2 and h3 for ToC display. */
11
11
  export declare function filterTocHeadings(headings: Heading[]): Heading[];
12
- //# sourceMappingURL=toc-helpers.d.ts.map
@@ -6,4 +6,3 @@
6
6
  export function filterTocHeadings(headings) {
7
7
  return headings.filter((h) => h.depth >= 2 && h.depth <= 3);
8
8
  }
9
- //# sourceMappingURL=toc-helpers.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specglass/theme-default",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Default theme for Specglass — layouts, components, React islands, and styles",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,7 +23,9 @@
23
23
  "./layouts/*": "./src/layouts/*",
24
24
  "./lib/*": "./src/lib/*",
25
25
  "./styles/*": "./src/styles/*",
26
- "./utils/*": "./src/utils/*"
26
+ "./utils/*": "./src/utils/*",
27
+ "./ui/*": "./src/ui/*",
28
+ "./scripts/*": "./src/scripts/*"
27
29
  },
28
30
  "files": [
29
31
  "dist",
@@ -32,7 +34,9 @@
32
34
  "src/layouts",
33
35
  "src/lib",
34
36
  "src/styles",
35
- "src/utils"
37
+ "src/utils",
38
+ "src/ui",
39
+ "src/scripts"
36
40
  ],
37
41
  "scripts": {
38
42
  "build": "tsc",
@@ -0,0 +1,179 @@
1
+ ---
2
+ /**
3
+ * ApiExampleRequest.astro — Renders multi-language request code examples.
4
+ *
5
+ * Generates cURL, Python, and Node.js request examples from endpoint data.
6
+ * Uses a tab interface with localStorage persistence for language preference.
7
+ * Each tab includes a copy button for the code snippet.
8
+ */
9
+ import type { ApiEndpoint } from "@specglass/core";
10
+ import { generateCurlExample, generatePythonExample, generateNodeExample } from "@specglass/core";
11
+ import { CopyButton } from "../islands/CopyButton";
12
+
13
+ export interface Props {
14
+ endpoint: ApiEndpoint;
15
+ baseUrl?: string;
16
+ }
17
+
18
+ const { endpoint, baseUrl = "https://api.example.com" } = Astro.props;
19
+
20
+ const options = { baseUrl };
21
+
22
+ const languages = [
23
+ { id: "curl", label: "cURL", code: generateCurlExample(endpoint, options), lang: "bash" },
24
+ { id: "python", label: "Python", code: generatePythonExample(endpoint, options), lang: "python" },
25
+ {
26
+ id: "node",
27
+ label: "Node.js",
28
+ code: generateNodeExample(endpoint, options),
29
+ lang: "javascript",
30
+ },
31
+ ];
32
+
33
+ const tabGroupId = `api-req-${endpoint.method}-${endpoint.path.replace(/[{}/]/g, "-")}`;
34
+ ---
35
+
36
+ <div class="mt-6">
37
+ <h2 class="text-lg font-semibold text-text mb-4">Request Example</h2>
38
+
39
+ <div
40
+ class="api-code-tabs rounded-lg border border-border overflow-hidden"
41
+ data-tab-group={tabGroupId}
42
+ data-sync-key="api-lang"
43
+ >
44
+ {/* Tab buttons */}
45
+ <div
46
+ class="flex border-b border-border bg-surface-raised"
47
+ role="tablist"
48
+ aria-label="Request language"
49
+ >
50
+ {
51
+ languages.map((lang, i) => (
52
+ <button
53
+ type="button"
54
+ role="tab"
55
+ id={`${tabGroupId}-tab-${lang.id}`}
56
+ aria-controls={`${tabGroupId}-panel-${lang.id}`}
57
+ aria-selected={i === 0 ? "true" : "false"}
58
+ tabindex={i === 0 ? 0 : -1}
59
+ data-lang={lang.id}
60
+ class:list={[
61
+ "px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
62
+ i === 0
63
+ ? "text-text border-b-2 border-primary bg-surface"
64
+ : "text-text-muted hover:text-text",
65
+ ]}
66
+ >
67
+ {lang.label}
68
+ </button>
69
+ ))
70
+ }
71
+ </div>
72
+
73
+ {/* Tab panels */}
74
+ {
75
+ languages.map((lang, i) => (
76
+ <div
77
+ role="tabpanel"
78
+ id={`${tabGroupId}-panel-${lang.id}`}
79
+ aria-labelledby={`${tabGroupId}-tab-${lang.id}`}
80
+ data-lang={lang.id}
81
+ class={i === 0 ? "" : "hidden"}
82
+ >
83
+ <div class="relative group">
84
+ <pre class="overflow-x-auto p-4 bg-[#0d1117] dark:bg-[#0d1117] text-gray-300 text-sm font-mono leading-relaxed m-0">
85
+ <code>{lang.code}</code>
86
+ </pre>
87
+ <div class="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity">
88
+ <CopyButton client:idle code={lang.code} />
89
+ </div>
90
+ </div>
91
+ </div>
92
+ ))
93
+ }
94
+ </div>
95
+ </div>
96
+
97
+ <script>
98
+ function initApiCodeTabs() {
99
+ const SYNC_KEY = "api-lang";
100
+ const STORAGE_KEY = `specglass-preferred-${SYNC_KEY}`;
101
+
102
+ document.querySelectorAll<HTMLElement>(".api-code-tabs").forEach((container) => {
103
+ const tabs = container.querySelectorAll<HTMLButtonElement>('[role="tab"]');
104
+ const panels = container.querySelectorAll<HTMLElement>('[role="tabpanel"]');
105
+
106
+ // Restore saved preference
107
+ try {
108
+ const saved = localStorage.getItem(STORAGE_KEY);
109
+ if (saved) {
110
+ activateTab(saved);
111
+ }
112
+ } catch {
113
+ // localStorage unavailable
114
+ }
115
+
116
+ function activateTab(langId: string) {
117
+ let found = false;
118
+ tabs.forEach((tab) => {
119
+ const isActive = tab.dataset.lang === langId;
120
+ tab.setAttribute("aria-selected", isActive ? "true" : "false");
121
+ tab.tabIndex = isActive ? 0 : -1;
122
+ if (isActive) {
123
+ tab.classList.add("text-text", "border-b-2", "border-primary", "bg-surface");
124
+ tab.classList.remove("text-text-muted");
125
+ found = true;
126
+ } else {
127
+ tab.classList.remove("text-text", "border-b-2", "border-primary", "bg-surface");
128
+ tab.classList.add("text-text-muted");
129
+ }
130
+ });
131
+ panels.forEach((panel) => {
132
+ panel.classList.toggle("hidden", panel.dataset.lang !== langId);
133
+ });
134
+ return found;
135
+ }
136
+
137
+ tabs.forEach((tab) => {
138
+ tab.addEventListener("click", () => {
139
+ const lang = tab.dataset.lang;
140
+ if (!lang) return;
141
+ activateTab(lang);
142
+ // Persist and sync
143
+ try {
144
+ localStorage.setItem(STORAGE_KEY, lang);
145
+ } catch {}
146
+ // Broadcast sync event for other tab groups on the page
147
+ document.dispatchEvent(
148
+ new CustomEvent("specglass-lang-sync", { detail: { syncKey: SYNC_KEY, lang } }),
149
+ );
150
+ });
151
+
152
+ // Keyboard navigation
153
+ tab.addEventListener("keydown", (e) => {
154
+ const tabList = Array.from(tabs);
155
+ const index = tabList.indexOf(tab);
156
+ let nextIndex = index;
157
+ if (e.key === "ArrowRight") nextIndex = (index + 1) % tabList.length;
158
+ else if (e.key === "ArrowLeft") nextIndex = (index - 1 + tabList.length) % tabList.length;
159
+ else if (e.key === "Home") nextIndex = 0;
160
+ else if (e.key === "End") nextIndex = tabList.length - 1;
161
+ else return;
162
+ e.preventDefault();
163
+ tabList[nextIndex].focus();
164
+ tabList[nextIndex].click();
165
+ });
166
+ });
167
+
168
+ // Listen for sync events from other tab groups
169
+ document.addEventListener("specglass-lang-sync", ((e: CustomEvent) => {
170
+ if (e.detail?.syncKey === SYNC_KEY) {
171
+ activateTab(e.detail.lang);
172
+ }
173
+ }) as EventListener);
174
+ });
175
+ }
176
+
177
+ initApiCodeTabs();
178
+ document.addEventListener("astro:after-swap", initApiCodeTabs);
179
+ </script>