veslx 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/App.js +17 -0
- package/dist/client/App.js.map +1 -0
- package/dist/client/components/front-matter.js +33 -0
- package/dist/client/components/front-matter.js.map +1 -0
- package/dist/client/components/gallery/components/figure-caption.js +14 -0
- package/dist/client/components/gallery/components/figure-caption.js.map +1 -0
- package/dist/client/components/gallery/components/figure-header.js +13 -0
- package/dist/client/components/gallery/components/figure-header.js.map +1 -0
- package/dist/client/components/gallery/components/lightbox.js +96 -0
- package/dist/client/components/gallery/components/lightbox.js.map +1 -0
- package/dist/client/components/gallery/components/loading-image.js +46 -0
- package/dist/client/components/gallery/components/loading-image.js.map +1 -0
- package/dist/client/components/gallery/hooks/use-gallery-images.js +84 -0
- package/dist/client/components/gallery/hooks/use-gallery-images.js.map +1 -0
- package/dist/client/components/gallery/hooks/use-lightbox.js +37 -0
- package/dist/client/components/gallery/hooks/use-lightbox.js.map +1 -0
- package/dist/client/components/gallery/index.js +96 -0
- package/dist/client/components/gallery/index.js.map +1 -0
- package/dist/client/components/gallery/lib/render-math-in-text.js +42 -0
- package/dist/client/components/gallery/lib/render-math-in-text.js.map +1 -0
- package/dist/client/components/header.js +60 -0
- package/dist/client/components/header.js.map +1 -0
- package/dist/client/components/loading.js +15 -0
- package/dist/client/components/loading.js.map +1 -0
- package/dist/client/components/mdx-components.js +134 -0
- package/dist/client/components/mdx-components.js.map +1 -0
- package/dist/client/components/mode-toggle.js +39 -0
- package/dist/client/components/mode-toggle.js.map +1 -0
- package/dist/client/components/page-error.js +39 -0
- package/dist/client/components/page-error.js.map +1 -0
- package/dist/client/components/parameter-badge.js +48 -0
- package/dist/client/components/parameter-badge.js.map +1 -0
- package/dist/client/components/parameter-table.js +301 -0
- package/dist/client/components/parameter-table.js.map +1 -0
- package/dist/client/components/post-list.js +119 -0
- package/dist/client/components/post-list.js.map +1 -0
- package/dist/client/components/running-bar.js +15 -0
- package/dist/client/components/running-bar.js.map +1 -0
- package/dist/client/components/slides-renderer.js +75 -0
- package/dist/client/components/slides-renderer.js.map +1 -0
- package/dist/client/components/theme-provider.js +9 -0
- package/dist/client/components/theme-provider.js.map +1 -0
- package/dist/client/components/ui/button.js +49 -0
- package/dist/client/components/ui/button.js.map +1 -0
- package/dist/client/components/ui/carousel.js +195 -0
- package/dist/client/components/ui/carousel.js.map +1 -0
- package/dist/client/components/ui/dropdown-menu.js +132 -0
- package/dist/client/components/ui/dropdown-menu.js.map +1 -0
- package/dist/client/hooks/use-key-bindings.js +40 -0
- package/dist/client/hooks/use-key-bindings.js.map +1 -0
- package/dist/client/hooks/use-mdx-content.js +78 -0
- package/dist/client/hooks/use-mdx-content.js.map +1 -0
- package/dist/client/lib/constants.js +5 -0
- package/dist/client/lib/constants.js.map +1 -0
- package/dist/client/lib/format-date.js +8 -0
- package/dist/client/lib/format-date.js.map +1 -0
- package/dist/client/lib/parameter-utils.js +110 -0
- package/dist/client/lib/parameter-utils.js.map +1 -0
- package/dist/client/lib/utils.js +9 -0
- package/dist/client/lib/utils.js.map +1 -0
- package/dist/client/logo_dark.png +0 -0
- package/dist/client/logo_light.png +0 -0
- package/dist/client/main.js +9 -0
- package/dist/client/main.js.map +1 -0
- package/dist/client/pages/home.js +30 -0
- package/dist/client/pages/home.js.map +1 -0
- package/dist/client/pages/post.js +53 -0
- package/dist/client/pages/post.js.map +1 -0
- package/dist/client/pages/slides.js +137 -0
- package/dist/client/pages/slides.js.map +1 -0
- package/dist/client/plugin/src/client.js +185 -0
- package/dist/client/plugin/src/client.js.map +1 -0
- package/package.json +8 -4
- package/src/main.tsx +1 -1
- package/vite.config.ts +22 -3
- package/vite.lib.config.ts +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header.js","sources":["../../../src/components/header.tsx"],"sourcesContent":["import { Link } from \"react-router-dom\";\nimport { ModeToggle } from \"./mode-toggle\";\nimport { SiGithub } from \"@icons-pack/react-simple-icons\";\nimport { ChevronUp, ChevronDown } from \"lucide-react\";\n\ninterface HeaderProps {\n slideControls?: {\n current: number;\n total: number;\n onPrevious: () => void;\n onNext: () => void;\n };\n}\n\nexport function Header({ slideControls }: HeaderProps = {}) {\n return (\n <header className=\"print:hidden fixed top-0 left-0 right-0 z-40\">\n <div className=\"mx-auto w-full px-[var(--page-padding)] flex items-center gap-8 py-4\">\n <nav className=\"flex items-center gap-1\">\n <Link\n to=\"/\"\n className=\"rounded-lg font-mono py-1.5 text-sm font-medium text-muted-foreground hover:underline\"\n >\n pl\n </Link>\n </nav>\n\n <div className=\"flex-1\" />\n\n {/* Slide navigation controls */}\n {slideControls && (\n <nav className=\"flex items-center gap-1\">\n <button\n onClick={slideControls.onPrevious}\n className=\"p-1.5 text-muted-foreground/70 hover:text-foreground transition-colors duration-200\"\n title=\"Previous slide (↑)\"\n >\n <ChevronUp className=\"h-4 w-4\" />\n </button>\n <span className=\"font-mono text-xs text-muted-foreground/70 tabular-nums min-w-[3ch] text-center\">\n {slideControls.current + 1}/{slideControls.total}\n </span>\n <button\n onClick={slideControls.onNext}\n className=\"p-1.5 text-muted-foreground/70 hover:text-foreground transition-colors duration-200\"\n title=\"Next slide (↓)\"\n >\n <ChevronDown className=\"h-4 w-4\" />\n </button>\n </nav>\n )}\n\n {/* Navigation */}\n <nav className=\"flex items-center gap-2\">\n <Link\n to=\"https://github.com/eoinmurray/pinglab\"\n target=\"_blank\"\n className=\"text-muted-foreground/70 hover:text-foreground transition-colors duration-300\"\n aria-label=\"GitHub\"\n >\n <SiGithub className=\"h-4 w-4\" />\n </Link>\n <ModeToggle />\n </nav>\n </div>\n </header>\n );\n}\n"],"names":[],"mappings":";;;;;AAcO,SAAS,OAAO,EAAE,cAAA,IAA+B,IAAI;AAC1D,6BACG,UAAA,EAAO,WAAU,gDAChB,UAAA,qBAAC,OAAA,EAAI,WAAU,wEACb,UAAA;AAAA,IAAA,oBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAG;AAAA,QACH,WAAU;AAAA,QACX,UAAA;AAAA,MAAA;AAAA,IAAA,GAGH;AAAA,IAEA,oBAAC,OAAA,EAAI,WAAU,SAAA,CAAS;AAAA,IAGvB,iBACC,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,cAAc;AAAA,UACvB,WAAU;AAAA,UACV,OAAM;AAAA,UAEN,UAAA,oBAAC,WAAA,EAAU,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAEjC,qBAAC,QAAA,EAAK,WAAU,mFACb,UAAA;AAAA,QAAA,cAAc,UAAU;AAAA,QAAE;AAAA,QAAE,cAAc;AAAA,MAAA,GAC7C;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS,cAAc;AAAA,UACvB,WAAU;AAAA,UACV,OAAM;AAAA,UAEN,UAAA,oBAAC,aAAA,EAAY,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACnC,GACF;AAAA,IAIF,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAG;AAAA,UACH,QAAO;AAAA,UACP,WAAU;AAAA,UACV,cAAW;AAAA,UAEX,UAAA,oBAAC,UAAA,EAAS,WAAU,UAAA,CAAU;AAAA,QAAA;AAAA,MAAA;AAAA,0BAE/B,YAAA,CAAA,CAAW;AAAA,IAAA,EAAA,CACd;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
function Loading() {
|
|
3
|
+
return /* @__PURE__ */ jsx("main", { className: "min-h-screen flex items-center justify-center bg-background", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-6 animate-fade-in", children: [
|
|
4
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
5
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-primary/60 rounded-full animate-pulse" }),
|
|
6
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-primary/40 rounded-full animate-pulse", style: { animationDelay: "150ms" } }),
|
|
7
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-primary/20 rounded-full animate-pulse", style: { animationDelay: "300ms" } })
|
|
8
|
+
] }),
|
|
9
|
+
/* @__PURE__ */ jsx("p", { className: "font-mono text-xs text-muted-foreground/50 tracking-widest uppercase", children: "loading" })
|
|
10
|
+
] }) });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
Loading as default
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=loading.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading.js","sources":["../../../src/components/loading.tsx"],"sourcesContent":["export default function Loading() {\n return (\n <main className=\"min-h-screen flex items-center justify-center bg-background\">\n <div className=\"flex flex-col items-center gap-6 animate-fade-in\">\n <div className=\"flex items-center gap-3\">\n <div className=\"w-1.5 h-1.5 bg-primary/60 rounded-full animate-pulse\" />\n <div className=\"w-1.5 h-1.5 bg-primary/40 rounded-full animate-pulse\" style={{ animationDelay: '150ms' }} />\n <div className=\"w-1.5 h-1.5 bg-primary/20 rounded-full animate-pulse\" style={{ animationDelay: '300ms' }} />\n </div>\n <p className=\"font-mono text-xs text-muted-foreground/50 tracking-widest uppercase\">\n loading\n </p>\n </div>\n </main>\n )\n}\n"],"names":[],"mappings":";AAAA,SAAwB,UAAU;AAChC,6BACG,QAAA,EAAK,WAAU,+DACd,UAAA,qBAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,MAAA,oBAAC,OAAA,EAAI,WAAU,uDAAA,CAAuD;AAAA,MACtE,oBAAC,SAAI,WAAU,wDAAuD,OAAO,EAAE,gBAAgB,WAAW;AAAA,MAC1G,oBAAC,SAAI,WAAU,wDAAuD,OAAO,EAAE,gBAAgB,UAAQ,CAAG;AAAA,IAAA,GAC5G;AAAA,IACA,oBAAC,KAAA,EAAE,WAAU,wEAAuE,UAAA,UAAA,CAEpF;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import Gallery from "./gallery/index.js";
|
|
3
|
+
import { ParameterTable } from "./parameter-table.js";
|
|
4
|
+
import { ParameterBadge } from "./parameter-badge.js";
|
|
5
|
+
function generateId(children) {
|
|
6
|
+
return (children == null ? void 0 : children.toString().toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-")) ?? "";
|
|
7
|
+
}
|
|
8
|
+
const mdxComponents = {
|
|
9
|
+
Gallery,
|
|
10
|
+
ParameterTable,
|
|
11
|
+
ParameterBadge,
|
|
12
|
+
// Headings - clean sans-serif
|
|
13
|
+
h1: (props) => {
|
|
14
|
+
const id = generateId(props.children);
|
|
15
|
+
return /* @__PURE__ */ jsx(
|
|
16
|
+
"h1",
|
|
17
|
+
{
|
|
18
|
+
id,
|
|
19
|
+
className: "text-2xl font-semibold tracking-tight mt-12 mb-4 first:mt-0",
|
|
20
|
+
...props
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
},
|
|
24
|
+
h2: (props) => {
|
|
25
|
+
const id = generateId(props.children);
|
|
26
|
+
return /* @__PURE__ */ jsx(
|
|
27
|
+
"h2",
|
|
28
|
+
{
|
|
29
|
+
id,
|
|
30
|
+
className: "text-xl font-semibold tracking-tight mt-10 mb-3 pb-2 border-b border-border",
|
|
31
|
+
...props
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
},
|
|
35
|
+
h3: (props) => {
|
|
36
|
+
const id = generateId(props.children);
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
"h3",
|
|
39
|
+
{
|
|
40
|
+
id,
|
|
41
|
+
className: "text-lg font-medium tracking-tight mt-8 mb-2",
|
|
42
|
+
...props
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
},
|
|
46
|
+
h4: (props) => {
|
|
47
|
+
const id = generateId(props.children);
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
49
|
+
"h4",
|
|
50
|
+
{
|
|
51
|
+
id,
|
|
52
|
+
className: "text-base font-medium mt-6 mb-2",
|
|
53
|
+
...props
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
},
|
|
57
|
+
h5: (props) => {
|
|
58
|
+
const id = generateId(props.children);
|
|
59
|
+
return /* @__PURE__ */ jsx(
|
|
60
|
+
"h5",
|
|
61
|
+
{
|
|
62
|
+
id,
|
|
63
|
+
className: "text-sm font-medium mt-4 mb-1",
|
|
64
|
+
...props
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
// Code blocks - IDE/terminal style
|
|
69
|
+
pre: (props) => /* @__PURE__ */ jsx(
|
|
70
|
+
"pre",
|
|
71
|
+
{
|
|
72
|
+
className: "not-prose w-full overflow-x-auto p-4 text-sm bg-muted/50 border border-border rounded-md font-mono my-6",
|
|
73
|
+
...props
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
code: (props) => {
|
|
77
|
+
var _a;
|
|
78
|
+
const isInline = !((_a = props.className) == null ? void 0 : _a.includes("language-"));
|
|
79
|
+
if (isInline) {
|
|
80
|
+
return /* @__PURE__ */ jsx(
|
|
81
|
+
"code",
|
|
82
|
+
{
|
|
83
|
+
className: "font-mono text-[0.85em] bg-muted px-1.5 py-0.5 rounded text-primary",
|
|
84
|
+
...props
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return /* @__PURE__ */ jsx("code", { ...props });
|
|
89
|
+
},
|
|
90
|
+
// Blockquote
|
|
91
|
+
blockquote: (props) => /* @__PURE__ */ jsx(
|
|
92
|
+
"blockquote",
|
|
93
|
+
{
|
|
94
|
+
className: "border-l-2 border-primary pl-4 my-6 text-muted-foreground",
|
|
95
|
+
...props
|
|
96
|
+
}
|
|
97
|
+
),
|
|
98
|
+
// Lists
|
|
99
|
+
ul: (props) => /* @__PURE__ */ jsx("ul", { className: "my-4 ml-6 list-disc marker:text-muted-foreground", ...props }),
|
|
100
|
+
ol: (props) => /* @__PURE__ */ jsx("ol", { className: "my-4 ml-6 list-decimal marker:text-muted-foreground", ...props }),
|
|
101
|
+
li: (props) => /* @__PURE__ */ jsx("li", { className: "mt-1.5", ...props }),
|
|
102
|
+
// Links
|
|
103
|
+
a: (props) => /* @__PURE__ */ jsx(
|
|
104
|
+
"a",
|
|
105
|
+
{
|
|
106
|
+
className: "text-primary hover:underline underline-offset-2",
|
|
107
|
+
...props
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
// Tables
|
|
111
|
+
table: (props) => /* @__PURE__ */ jsx("div", { className: "not-prose my-6 overflow-x-auto border border-border rounded-md", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm border-collapse", ...props }) }),
|
|
112
|
+
thead: (props) => /* @__PURE__ */ jsx("thead", { className: "bg-muted/50", ...props }),
|
|
113
|
+
tbody: (props) => /* @__PURE__ */ jsx("tbody", { ...props }),
|
|
114
|
+
tr: (props) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border last:border-b-0", ...props }),
|
|
115
|
+
th: (props) => /* @__PURE__ */ jsx(
|
|
116
|
+
"th",
|
|
117
|
+
{
|
|
118
|
+
className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider",
|
|
119
|
+
...props
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
td: (props) => /* @__PURE__ */ jsx("td", { className: "px-4 py-3 align-top", ...props }),
|
|
123
|
+
// Horizontal rule
|
|
124
|
+
hr: (props) => /* @__PURE__ */ jsx("hr", { className: "my-8 border-t border-border", ...props }),
|
|
125
|
+
// Paragraph
|
|
126
|
+
p: (props) => /* @__PURE__ */ jsx("p", { className: "leading-relaxed mb-4 last:mb-0", ...props }),
|
|
127
|
+
// Strong/emphasis
|
|
128
|
+
strong: (props) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", ...props }),
|
|
129
|
+
em: (props) => /* @__PURE__ */ jsx("em", { className: "italic", ...props })
|
|
130
|
+
};
|
|
131
|
+
export {
|
|
132
|
+
mdxComponents
|
|
133
|
+
};
|
|
134
|
+
//# sourceMappingURL=mdx-components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mdx-components.js","sources":["../../../src/components/mdx-components.tsx"],"sourcesContent":["\nimport Gallery from '@/components/gallery'\nimport { ParameterTable } from '@/components/parameter-table'\nimport { ParameterBadge } from '@/components/parameter-badge'\n\nfunction generateId(children: unknown): string {\n return children\n ?.toString()\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-') ?? ''\n}\n\n// Shared MDX components - lab notebook / coder aesthetic\nexport const mdxComponents = {\n Gallery,\n\n ParameterTable,\n\n ParameterBadge,\n\n // Headings - clean sans-serif\n h1: (props: React.HTMLAttributes<HTMLHeadingElement>) => {\n const id = generateId(props.children)\n return (\n <h1\n id={id}\n className=\"text-2xl font-semibold tracking-tight mt-12 mb-4 first:mt-0\"\n {...props}\n />\n )\n },\n h2: (props: React.HTMLAttributes<HTMLHeadingElement>) => {\n const id = generateId(props.children)\n return (\n <h2\n id={id}\n className=\"text-xl font-semibold tracking-tight mt-10 mb-3 pb-2 border-b border-border\"\n {...props}\n />\n )\n },\n h3: (props: React.HTMLAttributes<HTMLHeadingElement>) => {\n const id = generateId(props.children)\n return (\n <h3\n id={id}\n className=\"text-lg font-medium tracking-tight mt-8 mb-2\"\n {...props}\n />\n )\n },\n h4: (props: React.HTMLAttributes<HTMLHeadingElement>) => {\n const id = generateId(props.children)\n return (\n <h4\n id={id}\n className=\"text-base font-medium mt-6 mb-2\"\n {...props}\n />\n )\n },\n h5: (props: React.HTMLAttributes<HTMLHeadingElement>) => {\n const id = generateId(props.children)\n return (\n <h5\n id={id}\n className=\"text-sm font-medium mt-4 mb-1\"\n {...props}\n />\n )\n },\n\n // Code blocks - IDE/terminal style\n pre: (props: React.HTMLAttributes<HTMLPreElement>) => (\n <pre\n className=\"not-prose w-full overflow-x-auto p-4 text-sm bg-muted/50 border border-border rounded-md font-mono my-6\"\n {...props}\n />\n ),\n code: (props: React.HTMLAttributes<HTMLElement> & { className?: string }) => {\n const isInline = !props.className?.includes('language-')\n if (isInline) {\n return (\n <code\n className=\"font-mono text-[0.85em] bg-muted px-1.5 py-0.5 rounded text-primary\"\n {...props}\n />\n )\n }\n return <code {...props} />\n },\n\n // Blockquote\n blockquote: (props: React.HTMLAttributes<HTMLQuoteElement>) => (\n <blockquote\n className=\"border-l-2 border-primary pl-4 my-6 text-muted-foreground\"\n {...props}\n />\n ),\n\n // Lists\n ul: (props: React.HTMLAttributes<HTMLUListElement>) => (\n <ul className=\"my-4 ml-6 list-disc marker:text-muted-foreground\" {...props} />\n ),\n ol: (props: React.HTMLAttributes<HTMLOListElement>) => (\n <ol className=\"my-4 ml-6 list-decimal marker:text-muted-foreground\" {...props} />\n ),\n li: (props: React.HTMLAttributes<HTMLLIElement>) => (\n <li className=\"mt-1.5\" {...props} />\n ),\n\n // Links\n a: (props: React.AnchorHTMLAttributes<HTMLAnchorElement>) => (\n <a\n className=\"text-primary hover:underline underline-offset-2\"\n {...props}\n />\n ),\n\n // Tables\n table: (props: React.TableHTMLAttributes<HTMLTableElement>) => (\n <div className=\"not-prose my-6 overflow-x-auto border border-border rounded-md\">\n <table className=\"w-full text-sm border-collapse\" {...props} />\n </div>\n ),\n thead: (props: React.HTMLAttributes<HTMLTableSectionElement>) => (\n <thead className=\"bg-muted/50\" {...props} />\n ),\n tbody: (props: React.HTMLAttributes<HTMLTableSectionElement>) => (\n <tbody {...props} />\n ),\n tr: (props: React.HTMLAttributes<HTMLTableRowElement>) => (\n <tr className=\"border-b border-border last:border-b-0\" {...props} />\n ),\n th: (props: React.ThHTMLAttributes<HTMLTableCellElement>) => (\n <th\n className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground uppercase tracking-wider\"\n {...props}\n />\n ),\n td: (props: React.TdHTMLAttributes<HTMLTableCellElement>) => (\n <td className=\"px-4 py-3 align-top\" {...props} />\n ),\n\n // Horizontal rule\n hr: (props: React.HTMLAttributes<HTMLHRElement>) => (\n <hr className=\"my-8 border-t border-border\" {...props} />\n ),\n\n // Paragraph\n p: (props: React.HTMLAttributes<HTMLParagraphElement>) => (\n <p className=\"leading-relaxed mb-4 last:mb-0\" {...props} />\n ),\n\n // Strong/emphasis\n strong: (props: React.HTMLAttributes<HTMLElement>) => (\n <strong className=\"font-semibold\" {...props} />\n ),\n em: (props: React.HTMLAttributes<HTMLElement>) => (\n <em className=\"italic\" {...props} />\n ),\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Sun, Moon, Monitor } from "lucide-react";
|
|
3
|
+
import { useTheme } from "next-themes";
|
|
4
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem } from "./ui/dropdown-menu.js";
|
|
5
|
+
function ModeToggle() {
|
|
6
|
+
const { theme, setTheme } = useTheme();
|
|
7
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
8
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
9
|
+
"button",
|
|
10
|
+
{
|
|
11
|
+
className: "relative p-2 text-muted-foreground/70 hover:text-foreground transition-colors duration-300",
|
|
12
|
+
"aria-label": "Toggle theme",
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsx(Sun, { className: `h-4 w-4 transition-all duration-300 ${theme === "light" ? "scale-100 rotate-0" : "scale-0 -rotate-90 absolute top-2 left-2"}` }),
|
|
15
|
+
/* @__PURE__ */ jsx(Moon, { className: `h-4 w-4 transition-all duration-300 ${theme === "dark" ? "scale-100 rotate-0" : "scale-0 rotate-90 absolute top-2 left-2"}` }),
|
|
16
|
+
/* @__PURE__ */ jsx(Monitor, { className: `h-4 w-4 transition-all duration-300 ${theme === "system" || !theme ? "scale-100" : "scale-0 absolute top-2 left-2"}` })
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
) }),
|
|
20
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", children: /* @__PURE__ */ jsxs(DropdownMenuRadioGroup, { value: theme, onValueChange: setTheme, children: [
|
|
21
|
+
/* @__PURE__ */ jsxs(DropdownMenuRadioItem, { value: "light", children: [
|
|
22
|
+
/* @__PURE__ */ jsx(Sun, { className: "mr-2 h-4 w-4" }),
|
|
23
|
+
"Light"
|
|
24
|
+
] }),
|
|
25
|
+
/* @__PURE__ */ jsxs(DropdownMenuRadioItem, { value: "dark", children: [
|
|
26
|
+
/* @__PURE__ */ jsx(Moon, { className: "mr-2 h-4 w-4" }),
|
|
27
|
+
"Dark"
|
|
28
|
+
] }),
|
|
29
|
+
/* @__PURE__ */ jsxs(DropdownMenuRadioItem, { value: "system", children: [
|
|
30
|
+
/* @__PURE__ */ jsx(Monitor, { className: "mr-2 h-4 w-4" }),
|
|
31
|
+
"System"
|
|
32
|
+
] })
|
|
33
|
+
] }) })
|
|
34
|
+
] });
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
ModeToggle
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=mode-toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mode-toggle.js","sources":["../../../src/components/mode-toggle.tsx"],"sourcesContent":["import { Moon, Sun, Monitor } from \"lucide-react\"\nimport { useTheme } from \"next-themes\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\n\nexport function ModeToggle() {\n const { theme, setTheme } = useTheme()\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n className=\"relative p-2 text-muted-foreground/70 hover:text-foreground transition-colors duration-300\"\n aria-label=\"Toggle theme\"\n >\n <Sun className={`h-4 w-4 transition-all duration-300 ${theme === \"light\" ? \"scale-100 rotate-0\" : \"scale-0 -rotate-90 absolute top-2 left-2\"}`} />\n <Moon className={`h-4 w-4 transition-all duration-300 ${theme === \"dark\" ? \"scale-100 rotate-0\" : \"scale-0 rotate-90 absolute top-2 left-2\"}`} />\n <Monitor className={`h-4 w-4 transition-all duration-300 ${theme === \"system\" || !theme ? \"scale-100\" : \"scale-0 absolute top-2 left-2\"}`} />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>\n <DropdownMenuRadioItem value=\"light\">\n <Sun className=\"mr-2 h-4 w-4\" />\n Light\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"dark\">\n <Moon className=\"mr-2 h-4 w-4\" />\n Dark\n </DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"system\">\n <Monitor className=\"mr-2 h-4 w-4\" />\n System\n </DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n"],"names":[],"mappings":";;;;AAUO,SAAS,aAAa;AAC3B,QAAM,EAAE,OAAO,SAAA,IAAa,SAAA;AAE5B,8BACG,cAAA,EACC,UAAA;AAAA,IAAA,oBAAC,qBAAA,EAAoB,SAAO,MAC1B,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,cAAW;AAAA,QAEX,UAAA;AAAA,UAAA,oBAAC,OAAI,WAAW,uCAAuC,UAAU,UAAU,uBAAuB,0CAA0C,IAAI;AAAA,UAChJ,oBAAC,QAAK,WAAW,uCAAuC,UAAU,SAAS,uBAAuB,yCAAyC,IAAI;AAAA,UAC/I,oBAAC,SAAA,EAAQ,WAAW,uCAAuC,UAAU,YAAY,CAAC,QAAQ,cAAc,+BAA+B,GAAA,CAAI;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,GAE/I;AAAA,IACA,oBAAC,uBAAoB,OAAM,OACzB,+BAAC,wBAAA,EAAuB,OAAO,OAAO,eAAe,UACnD,UAAA;AAAA,MAAA,qBAAC,uBAAA,EAAsB,OAAM,SAC3B,UAAA;AAAA,QAAA,oBAAC,KAAA,EAAI,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,GAElC;AAAA,MACA,qBAAC,uBAAA,EAAsB,OAAM,QAC3B,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAK,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,GAEnC;AAAA,MACA,qBAAC,uBAAA,EAAsB,OAAM,UAC3B,UAAA;AAAA,QAAA,oBAAC,SAAA,EAAQ,WAAU,eAAA,CAAe;AAAA,QAAE;AAAA,MAAA,EAAA,CAEtC;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
function ErrorDisplay({ error, path }) {
|
|
3
|
+
const containerClass = "min-h-screen bg-background container mx-auto max-w-[var(--content-width)] py-24 px-[var(--page-padding)]";
|
|
4
|
+
switch (error.type) {
|
|
5
|
+
case "config_not_found":
|
|
6
|
+
return /* @__PURE__ */ jsx("main", { className: containerClass, children: /* @__PURE__ */ jsxs("div", { className: "text-center space-y-4", children: [
|
|
7
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: "Setup Required" }),
|
|
8
|
+
/* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
|
|
9
|
+
"Could not find ",
|
|
10
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-sm bg-muted px-2 py-1", children: ".veslx.json" })
|
|
11
|
+
] }),
|
|
12
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground/70 text-sm", children: "Run the veslx build script to generate the directory index." })
|
|
13
|
+
] }) });
|
|
14
|
+
case "path_not_found":
|
|
15
|
+
return /* @__PURE__ */ jsx("main", { className: containerClass, children: /* @__PURE__ */ jsxs("div", { className: "text-center space-y-4", children: [
|
|
16
|
+
/* @__PURE__ */ jsx("h1", { className: "font-mono text-6xl tracking-tighter text-muted-foreground/30", children: "404" }),
|
|
17
|
+
/* @__PURE__ */ jsx("p", { className: "text-lg text-foreground", children: "Page not found" }),
|
|
18
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: /* @__PURE__ */ jsx("code", { className: "font-mono bg-muted px-2 py-1", children: path }) })
|
|
19
|
+
] }) });
|
|
20
|
+
case "parse_error":
|
|
21
|
+
return /* @__PURE__ */ jsx("main", { className: containerClass, children: /* @__PURE__ */ jsxs("div", { className: "text-center space-y-4", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-destructive", children: "Configuration Error" }),
|
|
23
|
+
/* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
|
|
24
|
+
"Failed to parse ",
|
|
25
|
+
/* @__PURE__ */ jsx("code", { className: "font-mono text-sm bg-muted px-2 py-1", children: ".veslx.json" })
|
|
26
|
+
] })
|
|
27
|
+
] }) });
|
|
28
|
+
case "fetch_error":
|
|
29
|
+
default:
|
|
30
|
+
return /* @__PURE__ */ jsx("main", { className: containerClass, children: /* @__PURE__ */ jsxs("div", { className: "text-center space-y-4", children: [
|
|
31
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-destructive", children: "Error" }),
|
|
32
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: error.message })
|
|
33
|
+
] }) });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
ErrorDisplay
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=page-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-error.js","sources":["../../../src/components/page-error.tsx"],"sourcesContent":["\nimport { DirectoryError } from \"../../plugin/src/client\";\n\nexport function ErrorDisplay({ error, path }: { error: DirectoryError; path: string }) {\n const containerClass = \"min-h-screen bg-background container mx-auto max-w-[var(--content-width)] py-24 px-[var(--page-padding)]\";\n\n switch (error.type) {\n case 'config_not_found':\n return (\n <main className={containerClass}>\n <div className=\"text-center space-y-4\">\n <h1 className=\"text-2xl font-semibold tracking-tight\">Setup Required</h1>\n <p className=\"text-muted-foreground\">\n Could not find <code className=\"font-mono text-sm bg-muted px-2 py-1\">.veslx.json</code>\n </p>\n <p className=\"text-muted-foreground/70 text-sm\">\n Run the veslx build script to generate the directory index.\n </p>\n </div>\n </main>\n );\n\n case 'path_not_found':\n return (\n <main className={containerClass}>\n <div className=\"text-center space-y-4\">\n <h1 className=\"font-mono text-6xl tracking-tighter text-muted-foreground/30\">404</h1>\n <p className=\"text-lg text-foreground\">Page not found</p>\n <p className=\"text-muted-foreground text-sm\">\n <code className=\"font-mono bg-muted px-2 py-1\">{path}</code>\n </p>\n </div>\n </main>\n );\n\n case 'parse_error':\n return (\n <main className={containerClass}>\n <div className=\"text-center space-y-4\">\n <h1 className=\"text-2xl font-semibold text-destructive\">Configuration Error</h1>\n <p className=\"text-muted-foreground\">\n Failed to parse <code className=\"font-mono text-sm bg-muted px-2 py-1\">.veslx.json</code>\n </p>\n </div>\n </main>\n );\n\n case 'fetch_error':\n default:\n return (\n <main className={containerClass}>\n <div className=\"text-center space-y-4\">\n <h1 className=\"text-2xl font-semibold text-destructive\">Error</h1>\n <p className=\"text-muted-foreground\">{error.message}</p>\n </div>\n </main>\n );\n }\n}\n"],"names":[],"mappings":";AAGO,SAAS,aAAa,EAAE,OAAO,QAAiD;AACrF,QAAM,iBAAiB;AAEvB,UAAQ,MAAM,MAAA;AAAA,IACZ,KAAK;AACH,iCACG,QAAA,EAAK,WAAW,gBACf,UAAA,qBAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,yCAAwC,UAAA,kBAAc;AAAA,QACpE,qBAAC,KAAA,EAAE,WAAU,yBAAwB,UAAA;AAAA,UAAA;AAAA,UACpB,oBAAC,QAAA,EAAK,WAAU,wCAAuC,UAAA,cAAA,CAAW;AAAA,QAAA,GACnF;AAAA,QACA,oBAAC,KAAA,EAAE,WAAU,oCAAmC,UAAA,8DAAA,CAEhD;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAGJ,KAAK;AACH,iCACG,QAAA,EAAK,WAAW,gBACf,UAAA,qBAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,gEAA+D,UAAA,OAAG;AAAA,QAChF,oBAAC,KAAA,EAAE,WAAU,2BAA0B,UAAA,kBAAc;AAAA,QACrD,oBAAC,OAAE,WAAU,iCACX,8BAAC,QAAA,EAAK,WAAU,gCAAgC,UAAA,KAAA,CAAK,EAAA,CACvD;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAGJ,KAAK;AACH,iCACG,QAAA,EAAK,WAAW,gBACf,UAAA,qBAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,2CAA0C,UAAA,uBAAmB;AAAA,QAC3E,qBAAC,KAAA,EAAE,WAAU,yBAAwB,UAAA;AAAA,UAAA;AAAA,UACnB,oBAAC,QAAA,EAAK,WAAU,wCAAuC,UAAA,cAAA,CAAW;AAAA,QAAA,EAAA,CACpF;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAGJ,KAAK;AAAA,IACL;AACE,iCACG,QAAA,EAAK,WAAW,gBACf,UAAA,qBAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,2CAA0C,UAAA,SAAK;AAAA,QAC7D,oBAAC,KAAA,EAAE,WAAU,yBAAyB,gBAAM,QAAA,CAAQ;AAAA,MAAA,EAAA,CACtD,EAAA,CACF;AAAA,EAAA;AAGR;"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFileContent } from "../plugin/src/client.js";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { parseConfigFile, extractPath, deriveLabelFromPath, formatValue, getValueType } from "../lib/parameter-utils.js";
|
|
6
|
+
function ParameterBadge({ path, keyPath, label, unit }) {
|
|
7
|
+
const { content, loading, error } = useFileContent(path);
|
|
8
|
+
const { value, displayLabel } = useMemo(() => {
|
|
9
|
+
if (!content) return { value: void 0, displayLabel: "" };
|
|
10
|
+
const data = parseConfigFile(content, path);
|
|
11
|
+
if (!data) return { value: void 0, displayLabel: "" };
|
|
12
|
+
const extracted = extractPath(data, keyPath);
|
|
13
|
+
const derivedLabel = label || deriveLabelFromPath(keyPath);
|
|
14
|
+
return { value: extracted, displayLabel: derivedLabel };
|
|
15
|
+
}, [content, path, keyPath, label]);
|
|
16
|
+
if (loading) {
|
|
17
|
+
return /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md bg-muted/50 border border-border/50", children: /* @__PURE__ */ jsx("span", { className: "w-2 h-2 border border-muted-foreground/40 border-t-transparent rounded-full animate-spin" }) });
|
|
18
|
+
}
|
|
19
|
+
if (error || value === void 0) {
|
|
20
|
+
return /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md bg-destructive/10 border border-destructive/30", children: /* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono text-destructive", children: "—" }) });
|
|
21
|
+
}
|
|
22
|
+
const type = getValueType(value);
|
|
23
|
+
const formattedValue = formatValue(value);
|
|
24
|
+
return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md font-mono text-[11px]", children: [
|
|
25
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: displayLabel }),
|
|
26
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "=" }),
|
|
27
|
+
/* @__PURE__ */ jsx(
|
|
28
|
+
"span",
|
|
29
|
+
{
|
|
30
|
+
className: cn(
|
|
31
|
+
"font-medium tabular-nums",
|
|
32
|
+
type === "number" && "text-foreground",
|
|
33
|
+
type === "string" && "text-amber-600 dark:text-amber-500",
|
|
34
|
+
type === "boolean" && "text-cyan-600 dark:text-cyan-500",
|
|
35
|
+
type === "null" && "text-muted-foreground/50",
|
|
36
|
+
type === "array" && "text-purple-600 dark:text-purple-400",
|
|
37
|
+
type === "object" && "text-purple-600 dark:text-purple-400"
|
|
38
|
+
),
|
|
39
|
+
children: type === "string" ? `"${formattedValue}"` : formattedValue
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
unit && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/60", children: unit })
|
|
43
|
+
] });
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
ParameterBadge
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=parameter-badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parameter-badge.js","sources":["../../../src/components/parameter-badge.tsx"],"sourcesContent":["import { useFileContent } from \"../../plugin/src/client\";\nimport { useMemo } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n type ParameterValue,\n extractPath,\n getValueType,\n formatValue,\n parseConfigFile,\n deriveLabelFromPath,\n} from \"@/lib/parameter-utils\";\n\ninterface ParameterBadgeProps {\n /** Path to the YAML or JSON file */\n path: string;\n /** jq-like path to the value (e.g., \".base.N_E\") */\n keyPath: string;\n /** Optional label override (defaults to last segment of keyPath) */\n label?: string;\n /** Optional unit suffix (e.g., \"ms\", \"Hz\") */\n unit?: string;\n}\n\nexport function ParameterBadge({ path, keyPath, label, unit }: ParameterBadgeProps) {\n const { content, loading, error } = useFileContent(path);\n\n const { value, displayLabel } = useMemo(() => {\n if (!content) return { value: undefined, displayLabel: \"\" };\n\n const data = parseConfigFile(content, path);\n if (!data) return { value: undefined, displayLabel: \"\" };\n\n const extracted = extractPath(data, keyPath);\n const derivedLabel = label || deriveLabelFromPath(keyPath);\n\n return { value: extracted, displayLabel: derivedLabel };\n }, [content, path, keyPath, label]);\n\n if (loading) {\n return (\n <span className=\"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md bg-muted/50 border border-border/50\">\n <span className=\"w-2 h-2 border border-muted-foreground/40 border-t-transparent rounded-full animate-spin\" />\n </span>\n );\n }\n\n if (error || value === undefined) {\n return (\n <span className=\"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md bg-destructive/10 border border-destructive/30\">\n <span className=\"text-[10px] font-mono text-destructive\">—</span>\n </span>\n );\n }\n\n const type = getValueType(value);\n const formattedValue = formatValue(value);\n\n return (\n <span className=\"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-md font-mono text-[11px]\">\n <span className=\"text-muted-foreground\">{displayLabel}</span>\n <span className=\"text-muted-foreground/40\">=</span>\n <span\n className={cn(\n \"font-medium tabular-nums\",\n type === \"number\" && \"text-foreground\",\n type === \"string\" && \"text-amber-600 dark:text-amber-500\",\n type === \"boolean\" && \"text-cyan-600 dark:text-cyan-500\",\n type === \"null\" && \"text-muted-foreground/50\",\n type === \"array\" && \"text-purple-600 dark:text-purple-400\",\n type === \"object\" && \"text-purple-600 dark:text-purple-400\"\n )}\n >\n {type === \"string\" ? `\"${formattedValue}\"` : formattedValue}\n </span>\n {unit && <span className=\"text-muted-foreground/60\">{unit}</span>}\n </span>\n );\n}\n"],"names":[],"mappings":";;;;;AAuBO,SAAS,eAAe,EAAE,MAAM,SAAS,OAAO,QAA6B;AAClF,QAAM,EAAE,SAAS,SAAS,MAAA,IAAU,eAAe,IAAI;AAEvD,QAAM,EAAE,OAAO,aAAA,IAAiB,QAAQ,MAAM;AAC5C,QAAI,CAAC,QAAS,QAAO,EAAE,OAAO,QAAW,cAAc,GAAA;AAEvD,UAAM,OAAO,gBAAgB,SAAS,IAAI;AAC1C,QAAI,CAAC,KAAM,QAAO,EAAE,OAAO,QAAW,cAAc,GAAA;AAEpD,UAAM,YAAY,YAAY,MAAM,OAAO;AAC3C,UAAM,eAAe,SAAS,oBAAoB,OAAO;AAEzD,WAAO,EAAE,OAAO,WAAW,cAAc,aAAA;AAAA,EAC3C,GAAG,CAAC,SAAS,MAAM,SAAS,KAAK,CAAC;AAElC,MAAI,SAAS;AACX,WACE,oBAAC,UAAK,WAAU,+FACd,8BAAC,QAAA,EAAK,WAAU,4FAA2F,EAAA,CAC7G;AAAA,EAEJ;AAEA,MAAI,SAAS,UAAU,QAAW;AAChC,WACE,oBAAC,UAAK,WAAU,0GACd,8BAAC,QAAA,EAAK,WAAU,0CAAyC,UAAA,IAAA,CAAC,EAAA,CAC5D;AAAA,EAEJ;AAEA,QAAM,OAAO,aAAa,KAAK;AAC/B,QAAM,iBAAiB,YAAY,KAAK;AAExC,SACE,qBAAC,QAAA,EAAK,WAAU,iFACd,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAK,WAAU,yBAAyB,UAAA,cAAa;AAAA,IACtD,oBAAC,QAAA,EAAK,WAAU,4BAA2B,UAAA,KAAC;AAAA,IAC5C;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,SAAS,YAAY;AAAA,UACrB,SAAS,YAAY;AAAA,UACrB,SAAS,aAAa;AAAA,UACtB,SAAS,UAAU;AAAA,UACnB,SAAS,WAAW;AAAA,UACpB,SAAS,YAAY;AAAA,QAAA;AAAA,QAGtB,UAAA,SAAS,WAAW,IAAI,cAAc,MAAM;AAAA,MAAA;AAAA,IAAA;AAAA,IAE9C,QAAQ,oBAAC,QAAA,EAAK,WAAU,4BAA4B,UAAA,KAAA,CAAK;AAAA,EAAA,GAC5D;AAEJ;"}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFileContent } from "../plugin/src/client.js";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { parseConfigFile, extractPath, getValueType, formatValue } from "../lib/parameter-utils.js";
|
|
6
|
+
function filterData(data, keys) {
|
|
7
|
+
const result = {};
|
|
8
|
+
for (const keyPath of keys) {
|
|
9
|
+
const extracted = extractPath(data, keyPath);
|
|
10
|
+
if (extracted === void 0) continue;
|
|
11
|
+
const cleanPath = keyPath.startsWith(".") ? keyPath.slice(1) : keyPath;
|
|
12
|
+
let keyName;
|
|
13
|
+
if (cleanPath.includes("[")) {
|
|
14
|
+
keyName = cleanPath.replace(/\[\]/g, "").replace(/\[(\d+)\]/g, "_$1");
|
|
15
|
+
} else {
|
|
16
|
+
const parts = cleanPath.split(".");
|
|
17
|
+
keyName = parts[parts.length - 1];
|
|
18
|
+
}
|
|
19
|
+
result[keyName] = extracted;
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
function ParameterGrid({ entries }) {
|
|
24
|
+
if (entries.length === 0) return null;
|
|
25
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(180px,1fr))] gap-x-6 gap-y-px", children: entries.map(([key, value]) => {
|
|
26
|
+
const type = getValueType(value);
|
|
27
|
+
return /* @__PURE__ */ jsxs(
|
|
28
|
+
"div",
|
|
29
|
+
{
|
|
30
|
+
className: "flex items-baseline justify-between gap-2 py-1 group hover:bg-muted/30 -mx-1.5 px-1.5 rounded-sm transition-colors",
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground font-mono truncate", children: key }),
|
|
33
|
+
/* @__PURE__ */ jsx(
|
|
34
|
+
"span",
|
|
35
|
+
{
|
|
36
|
+
className: cn(
|
|
37
|
+
"text-[11px] font-mono tabular-nums font-medium shrink-0",
|
|
38
|
+
type === "number" && "text-foreground",
|
|
39
|
+
type === "string" && "text-amber-600 dark:text-amber-500",
|
|
40
|
+
type === "boolean" && "text-cyan-600 dark:text-cyan-500",
|
|
41
|
+
type === "null" && "text-muted-foreground/50"
|
|
42
|
+
),
|
|
43
|
+
children: type === "string" ? `"${formatValue(value)}"` : formatValue(value)
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
key
|
|
49
|
+
);
|
|
50
|
+
}) });
|
|
51
|
+
}
|
|
52
|
+
function ParameterSection({
|
|
53
|
+
name,
|
|
54
|
+
data,
|
|
55
|
+
depth = 0
|
|
56
|
+
}) {
|
|
57
|
+
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
58
|
+
const entries = Object.entries(data);
|
|
59
|
+
const leafEntries = entries.filter(([, v]) => {
|
|
60
|
+
const t = getValueType(v);
|
|
61
|
+
return t !== "object" && t !== "array";
|
|
62
|
+
});
|
|
63
|
+
const nestedEntries = entries.filter(([, v]) => {
|
|
64
|
+
const t = getValueType(v);
|
|
65
|
+
return t === "object" || t === "array";
|
|
66
|
+
});
|
|
67
|
+
return /* @__PURE__ */ jsxs("div", { className: cn(depth === 0 && "mb-4 last:mb-0"), children: [
|
|
68
|
+
/* @__PURE__ */ jsxs(
|
|
69
|
+
"button",
|
|
70
|
+
{
|
|
71
|
+
onClick: () => setIsCollapsed(!isCollapsed),
|
|
72
|
+
className: cn(
|
|
73
|
+
"flex items-center gap-2 w-full text-left group mb-1.5",
|
|
74
|
+
depth === 0 && "pb-1 border-b border-border/50"
|
|
75
|
+
),
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
78
|
+
"text-[10px] text-muted-foreground/60 transition-transform duration-150 select-none",
|
|
79
|
+
isCollapsed && "-rotate-90"
|
|
80
|
+
), children: isCollapsed ? "+" : "-" }),
|
|
81
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
82
|
+
"font-mono text-[11px] uppercase tracking-widest",
|
|
83
|
+
depth === 0 ? "text-foreground/80 font-semibold" : "text-muted-foreground/70"
|
|
84
|
+
), children: name.replace(/_/g, " ") }),
|
|
85
|
+
/* @__PURE__ */ jsx("span", { className: "text-[9px] font-mono text-muted-foreground/40 ml-auto", children: entries.length })
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
),
|
|
89
|
+
!isCollapsed && /* @__PURE__ */ jsxs("div", { className: cn(
|
|
90
|
+
depth > 0 && "pl-3 ml-1 border-l border-border/40"
|
|
91
|
+
), children: [
|
|
92
|
+
leafEntries.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(nestedEntries.length > 0 && "mb-3"), children: /* @__PURE__ */ jsx(ParameterGrid, { entries: leafEntries }) }),
|
|
93
|
+
nestedEntries.map(([key, value]) => {
|
|
94
|
+
const type = getValueType(value);
|
|
95
|
+
if (type === "array") {
|
|
96
|
+
const arr = value;
|
|
97
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-2 last:mb-0", children: [
|
|
98
|
+
/* @__PURE__ */ jsxs("div", { className: "text-[10px] font-mono text-muted-foreground/60 uppercase tracking-wider mb-1", children: [
|
|
99
|
+
key,
|
|
100
|
+
" [",
|
|
101
|
+
arr.length,
|
|
102
|
+
"]"
|
|
103
|
+
] }),
|
|
104
|
+
/* @__PURE__ */ jsx("div", { className: "pl-3 ml-1 border-l border-border/40", children: arr.map((item, i) => {
|
|
105
|
+
const itemType = getValueType(item);
|
|
106
|
+
if (itemType === "object") {
|
|
107
|
+
return /* @__PURE__ */ jsx(
|
|
108
|
+
ParameterSection,
|
|
109
|
+
{
|
|
110
|
+
name: `${i}`,
|
|
111
|
+
data: item,
|
|
112
|
+
depth: depth + 1
|
|
113
|
+
},
|
|
114
|
+
i
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return /* @__PURE__ */ jsxs("div", { className: "text-[11px] font-mono text-foreground py-0.5", children: [
|
|
118
|
+
"[",
|
|
119
|
+
i,
|
|
120
|
+
"] ",
|
|
121
|
+
formatValue(item)
|
|
122
|
+
] }, i);
|
|
123
|
+
}) })
|
|
124
|
+
] }, key);
|
|
125
|
+
}
|
|
126
|
+
return /* @__PURE__ */ jsx(
|
|
127
|
+
ParameterSection,
|
|
128
|
+
{
|
|
129
|
+
name: key,
|
|
130
|
+
data: value,
|
|
131
|
+
depth: depth + 1
|
|
132
|
+
},
|
|
133
|
+
key
|
|
134
|
+
);
|
|
135
|
+
})
|
|
136
|
+
] })
|
|
137
|
+
] });
|
|
138
|
+
}
|
|
139
|
+
function estimateHeight(data, depth = 0) {
|
|
140
|
+
const entries = Object.entries(data);
|
|
141
|
+
let height = 0;
|
|
142
|
+
for (const [, value] of entries) {
|
|
143
|
+
const type = getValueType(value);
|
|
144
|
+
if (type === "object") {
|
|
145
|
+
height += 28 + estimateHeight(value, depth + 1);
|
|
146
|
+
} else if (type === "array") {
|
|
147
|
+
const arr = value;
|
|
148
|
+
height += 28;
|
|
149
|
+
for (const item of arr) {
|
|
150
|
+
if (getValueType(item) === "object") {
|
|
151
|
+
height += 24 + estimateHeight(item, depth + 1);
|
|
152
|
+
} else {
|
|
153
|
+
height += 24;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
height += 24;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return height;
|
|
161
|
+
}
|
|
162
|
+
function splitIntoColumns(entries, numColumns) {
|
|
163
|
+
if (numColumns <= 1) return [entries];
|
|
164
|
+
const entryHeights = entries.map(([, value]) => {
|
|
165
|
+
const type = getValueType(value);
|
|
166
|
+
if (type === "object") {
|
|
167
|
+
return 28 + estimateHeight(value);
|
|
168
|
+
} else if (type === "array") {
|
|
169
|
+
const arr = value;
|
|
170
|
+
let h = 28;
|
|
171
|
+
for (const item of arr) {
|
|
172
|
+
if (getValueType(item) === "object") {
|
|
173
|
+
h += 24 + estimateHeight(item);
|
|
174
|
+
} else {
|
|
175
|
+
h += 24;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return h;
|
|
179
|
+
}
|
|
180
|
+
return 24;
|
|
181
|
+
});
|
|
182
|
+
const totalHeight = entryHeights.reduce((a, b) => a + b, 0);
|
|
183
|
+
const targetPerColumn = totalHeight / numColumns;
|
|
184
|
+
const columns = [];
|
|
185
|
+
let currentColumn = [];
|
|
186
|
+
let currentHeight = 0;
|
|
187
|
+
for (let i = 0; i < entries.length; i++) {
|
|
188
|
+
const entry = entries[i];
|
|
189
|
+
const entryHeight = entryHeights[i];
|
|
190
|
+
if (currentHeight >= targetPerColumn && columns.length < numColumns - 1 && currentColumn.length > 0) {
|
|
191
|
+
columns.push(currentColumn);
|
|
192
|
+
currentColumn = [];
|
|
193
|
+
currentHeight = 0;
|
|
194
|
+
}
|
|
195
|
+
currentColumn.push(entry);
|
|
196
|
+
currentHeight += entryHeight;
|
|
197
|
+
}
|
|
198
|
+
if (currentColumn.length > 0) {
|
|
199
|
+
columns.push(currentColumn);
|
|
200
|
+
}
|
|
201
|
+
return columns;
|
|
202
|
+
}
|
|
203
|
+
function ParameterTable({ path, keys }) {
|
|
204
|
+
const { content, loading, error } = useFileContent(path);
|
|
205
|
+
const parsed = useMemo(() => {
|
|
206
|
+
if (!content) return null;
|
|
207
|
+
const data = parseConfigFile(content, path);
|
|
208
|
+
if (!data) return null;
|
|
209
|
+
if (keys && keys.length > 0) {
|
|
210
|
+
return filterData(data, keys);
|
|
211
|
+
}
|
|
212
|
+
return data;
|
|
213
|
+
}, [content, path, keys]);
|
|
214
|
+
if (loading) {
|
|
215
|
+
return /* @__PURE__ */ jsx("div", { className: "my-6 p-4 rounded border border-border/50 bg-card/30", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground/60", children: [
|
|
216
|
+
/* @__PURE__ */ jsx("div", { className: "w-3 h-3 border border-current border-t-transparent rounded-full animate-spin" }),
|
|
217
|
+
/* @__PURE__ */ jsx("span", { className: "text-[11px] font-mono", children: "loading parameters..." })
|
|
218
|
+
] }) });
|
|
219
|
+
}
|
|
220
|
+
if (error) {
|
|
221
|
+
return /* @__PURE__ */ jsx("div", { className: "my-6 p-3 rounded border border-destructive/30 bg-destructive/5", children: /* @__PURE__ */ jsx("p", { className: "text-[11px] font-mono text-destructive", children: error }) });
|
|
222
|
+
}
|
|
223
|
+
if (!parsed) {
|
|
224
|
+
return /* @__PURE__ */ jsx("div", { className: "my-6 p-3 rounded border border-border/50 bg-card/30", children: /* @__PURE__ */ jsx("p", { className: "text-[11px] font-mono text-muted-foreground", children: "unable to parse config" }) });
|
|
225
|
+
}
|
|
226
|
+
const entries = Object.entries(parsed);
|
|
227
|
+
const topLeaves = entries.filter(([, v]) => {
|
|
228
|
+
const t = getValueType(v);
|
|
229
|
+
return t !== "object" && t !== "array";
|
|
230
|
+
});
|
|
231
|
+
const topNested = entries.filter(([, v]) => {
|
|
232
|
+
const t = getValueType(v);
|
|
233
|
+
return t === "object" || t === "array";
|
|
234
|
+
});
|
|
235
|
+
const estHeight = estimateHeight(parsed);
|
|
236
|
+
const HEIGHT_THRESHOLD = 500;
|
|
237
|
+
const numColumns = estHeight > HEIGHT_THRESHOLD ? Math.min(Math.ceil(estHeight / HEIGHT_THRESHOLD), 3) : 1;
|
|
238
|
+
const useColumns = numColumns > 1 && topNested.length > 1;
|
|
239
|
+
const columns = useColumns ? splitIntoColumns(topNested, numColumns) : [topNested];
|
|
240
|
+
path.split("/").pop() || path;
|
|
241
|
+
const renderNestedEntry = ([key, value]) => {
|
|
242
|
+
const type = getValueType(value);
|
|
243
|
+
if (type === "array") {
|
|
244
|
+
const arr = value;
|
|
245
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-4 last:mb-0", children: [
|
|
246
|
+
/* @__PURE__ */ jsxs("div", { className: "text-[11px] font-mono text-foreground/80 uppercase tracking-widest font-semibold mb-1.5 pb-1 border-b border-border/50", children: [
|
|
247
|
+
key.replace(/_/g, " "),
|
|
248
|
+
" [",
|
|
249
|
+
arr.length,
|
|
250
|
+
"]"
|
|
251
|
+
] }),
|
|
252
|
+
/* @__PURE__ */ jsx("div", { className: "pl-3 ml-1 border-l border-border/40", children: arr.map((item, i) => {
|
|
253
|
+
const itemType = getValueType(item);
|
|
254
|
+
if (itemType === "object") {
|
|
255
|
+
return /* @__PURE__ */ jsx(
|
|
256
|
+
ParameterSection,
|
|
257
|
+
{
|
|
258
|
+
name: `${i}`,
|
|
259
|
+
data: item,
|
|
260
|
+
depth: 1
|
|
261
|
+
},
|
|
262
|
+
i
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
return /* @__PURE__ */ jsxs("div", { className: "text-[11px] font-mono text-foreground py-0.5", children: [
|
|
266
|
+
"[",
|
|
267
|
+
i,
|
|
268
|
+
"] ",
|
|
269
|
+
formatValue(item)
|
|
270
|
+
] }, i);
|
|
271
|
+
}) })
|
|
272
|
+
] }, key);
|
|
273
|
+
}
|
|
274
|
+
return /* @__PURE__ */ jsx(
|
|
275
|
+
ParameterSection,
|
|
276
|
+
{
|
|
277
|
+
name: key,
|
|
278
|
+
data: value,
|
|
279
|
+
depth: 0
|
|
280
|
+
},
|
|
281
|
+
key
|
|
282
|
+
);
|
|
283
|
+
};
|
|
284
|
+
return /* @__PURE__ */ jsx("div", { className: "my-6 not-prose", children: /* @__PURE__ */ jsxs("div", { className: "rounded border border-border/60 bg-card/20 p-3 overflow-hidden", children: [
|
|
285
|
+
topLeaves.length > 0 && /* @__PURE__ */ jsx("div", { className: cn(topNested.length > 0 && "mb-4 pb-3 border-b border-border/30"), children: /* @__PURE__ */ jsx(ParameterGrid, { entries: topLeaves }) }),
|
|
286
|
+
useColumns ? /* @__PURE__ */ jsx(
|
|
287
|
+
"div",
|
|
288
|
+
{
|
|
289
|
+
className: "grid gap-6",
|
|
290
|
+
style: { gridTemplateColumns: `repeat(${columns.length}, 1fr)` },
|
|
291
|
+
children: columns.map((columnEntries, colIndex) => /* @__PURE__ */ jsx("div", { className: cn(
|
|
292
|
+
colIndex > 0 && "border-l border-border/30 pl-6"
|
|
293
|
+
), children: columnEntries.map(renderNestedEntry) }, colIndex))
|
|
294
|
+
}
|
|
295
|
+
) : topNested.map(renderNestedEntry)
|
|
296
|
+
] }) });
|
|
297
|
+
}
|
|
298
|
+
export {
|
|
299
|
+
ParameterTable
|
|
300
|
+
};
|
|
301
|
+
//# sourceMappingURL=parameter-table.js.map
|