@oaspect/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +14 -0
  3. package/dist/api-reference.js +476 -0
  4. package/dist/api-reference.js.map +1 -0
  5. package/dist/auth-panel.js +116 -0
  6. package/dist/auth-panel.js.map +1 -0
  7. package/dist/code-block.js +105 -0
  8. package/dist/code-block.js.map +1 -0
  9. package/dist/i18n/ar.js +89 -0
  10. package/dist/i18n/ar.js.map +1 -0
  11. package/dist/i18n/context.js +50 -0
  12. package/dist/i18n/context.js.map +1 -0
  13. package/dist/i18n/en.js +89 -0
  14. package/dist/i18n/en.js.map +1 -0
  15. package/dist/i18n/index.js +37 -0
  16. package/dist/i18n/index.js.map +1 -0
  17. package/dist/i18n/tr.js +89 -0
  18. package/dist/i18n/tr.js.map +1 -0
  19. package/dist/icons.js +55 -0
  20. package/dist/icons.js.map +1 -0
  21. package/dist/index.d.ts +78 -0
  22. package/dist/index.js +12 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/intro.js +132 -0
  25. package/dist/intro.js.map +1 -0
  26. package/dist/lazy.js +41 -0
  27. package/dist/lazy.js.map +1 -0
  28. package/dist/logo.js +12 -0
  29. package/dist/logo.js.map +1 -0
  30. package/dist/markdown.js +170 -0
  31. package/dist/markdown.js.map +1 -0
  32. package/dist/method-badge.js +37 -0
  33. package/dist/method-badge.js.map +1 -0
  34. package/dist/models.js +27 -0
  35. package/dist/models.js.map +1 -0
  36. package/dist/oaspect.css +1703 -0
  37. package/dist/operation.js +267 -0
  38. package/dist/operation.js.map +1 -0
  39. package/dist/samples.js +129 -0
  40. package/dist/samples.js.map +1 -0
  41. package/dist/schema-tree.js +160 -0
  42. package/dist/schema-tree.js.map +1 -0
  43. package/dist/send.js +58 -0
  44. package/dist/send.js.map +1 -0
  45. package/dist/sidebar.js +125 -0
  46. package/dist/sidebar.js.map +1 -0
  47. package/dist/spec-context.js +23 -0
  48. package/dist/spec-context.js.map +1 -0
  49. package/dist/storage.js +30 -0
  50. package/dist/storage.js.map +1 -0
  51. package/dist/try-it.js +277 -0
  52. package/dist/try-it.js.map +1 -0
  53. package/package.json +66 -0
  54. package/tailwind.css +21 -0
@@ -0,0 +1,170 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ import { useLocale } from "./i18n/context.js";
5
+ import { parseMarkdown, safeUrl, selectLocale } from "@oaspect/core";
6
+ import CodeBlock from "./code-block.js";
7
+ const CODE_LANGUAGES = {
8
+ json: "json",
9
+ sh: "shell",
10
+ bash: "shell",
11
+ shell: "shell",
12
+ zsh: "shell",
13
+ curl: "shell",
14
+ js: "javascript",
15
+ javascript: "javascript",
16
+ ts: "javascript",
17
+ typescript: "javascript",
18
+ php: "php",
19
+ py: "python",
20
+ python: "python",
21
+ go: "go",
22
+ java: "java",
23
+ kotlin: "kotlin",
24
+ kt: "kotlin",
25
+ cs: "csharp",
26
+ csharp: "csharp",
27
+ rb: "ruby",
28
+ ruby: "ruby",
29
+ swift: "swift",
30
+ dart: "dart",
31
+ rust: "rust",
32
+ rs: "rust",
33
+ c: "c",
34
+ powershell: "powershell",
35
+ ps1: "powershell",
36
+ http: "http"
37
+ };
38
+ const HEADING_STYLES = {
39
+ 1: "text-xl font-bold",
40
+ 2: "text-lg font-semibold",
41
+ 3: "text-base font-semibold",
42
+ 4: "text-sm font-semibold",
43
+ 5: "text-sm font-semibold",
44
+ 6: "text-xs font-semibold uppercase tracking-wide"
45
+ };
46
+ function Inline({ nodes }) {
47
+ return nodes.map((node, index) => {
48
+ switch (node.type) {
49
+ case "text":
50
+ return node.value;
51
+ case "br":
52
+ return /* @__PURE__ */ jsx("br", {}, index);
53
+ case "code":
54
+ return /* @__PURE__ */ jsx("code", { dir: "ltr", className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: node.value }, index);
55
+ case "strong":
56
+ return /* @__PURE__ */ jsx("strong", { className: "font-semibold text-foreground", children: /* @__PURE__ */ jsx(Inline, { nodes: node.children }) }, index);
57
+ case "em":
58
+ return /* @__PURE__ */ jsx("em", { children: /* @__PURE__ */ jsx(Inline, { nodes: node.children }) }, index);
59
+ case "del":
60
+ return /* @__PURE__ */ jsx("del", { children: /* @__PURE__ */ jsx(Inline, { nodes: node.children }) }, index);
61
+ case "link": {
62
+ const href = safeUrl(node.href);
63
+ if (!href) return /* @__PURE__ */ jsx(Inline, { nodes: node.children }, index);
64
+ const external = /^https?:/i.test(href);
65
+ return /* @__PURE__ */ jsx(
66
+ "a",
67
+ {
68
+ href,
69
+ title: node.title,
70
+ ...external ? { target: "_blank", rel: "noreferrer" } : {},
71
+ className: "text-primary underline underline-offset-2",
72
+ children: /* @__PURE__ */ jsx(Inline, { nodes: node.children })
73
+ },
74
+ index
75
+ );
76
+ }
77
+ case "image": {
78
+ const src = safeUrl(node.src, { image: true });
79
+ if (!src) return node.alt;
80
+ return /* @__PURE__ */ jsx("img", { src, alt: node.alt, title: node.title, loading: "lazy", className: "inline-block max-w-full rounded-lg" }, index);
81
+ }
82
+ default:
83
+ return null;
84
+ }
85
+ });
86
+ }
87
+ function Blocks({ blocks, tight = false }) {
88
+ return blocks.map((block, index) => {
89
+ switch (block.type) {
90
+ case "heading": {
91
+ const Tag = `h${Math.min(block.level + 2, 6)}`;
92
+ return /* @__PURE__ */ jsx(Tag, { dir: "auto", className: `${HEADING_STYLES[block.level]} pt-2 text-foreground`, children: /* @__PURE__ */ jsx(Inline, { nodes: block.children }) }, index);
93
+ }
94
+ case "paragraph":
95
+ return tight ? /* @__PURE__ */ jsx(Inline, { nodes: block.children }, index) : /* @__PURE__ */ jsx("p", { dir: "auto", children: /* @__PURE__ */ jsx(Inline, { nodes: block.children }) }, index);
96
+ case "code":
97
+ return /* @__PURE__ */ jsx(
98
+ CodeBlock,
99
+ {
100
+ code: block.text,
101
+ language: CODE_LANGUAGES[block.language] ?? "text",
102
+ toolbar: block.language && /* @__PURE__ */ jsx("span", { className: "px-1 font-mono text-[11px] text-white/50", children: block.language })
103
+ },
104
+ index
105
+ );
106
+ case "blockquote":
107
+ return /* @__PURE__ */ jsx("blockquote", { className: "space-y-3 border-s-4 border-border ps-4 italic", children: /* @__PURE__ */ jsx(Blocks, { blocks: block.children }) }, index);
108
+ case "hr":
109
+ return /* @__PURE__ */ jsx("hr", { className: "border-border" }, index);
110
+ case "lang-selected":
111
+ return /* @__PURE__ */ jsx("div", { lang: block.locale, className: "space-y-3", children: /* @__PURE__ */ jsx(Blocks, { blocks: block.children, tight }) }, index);
112
+ case "list": {
113
+ const List = block.ordered ? "ol" : "ul";
114
+ const task = block.items.some((item) => item.checked !== null);
115
+ return /* @__PURE__ */ jsx(
116
+ List,
117
+ {
118
+ dir: "auto",
119
+ start: block.ordered && block.start !== 1 ? block.start : void 0,
120
+ className: `space-y-1.5 ${task ? "ps-1" : `ps-5 ${block.ordered ? "list-decimal" : "list-disc"}`} marker:text-muted-foreground`,
121
+ children: block.items.map((item, itemIndex) => /* @__PURE__ */ jsxs("li", { className: `${block.loose ? "space-y-2" : "space-y-1"} ${item.checked !== null ? "flex list-none items-start gap-2" : ""}`, children: [
122
+ item.checked !== null && /* @__PURE__ */ jsx("input", { type: "checkbox", checked: item.checked, readOnly: true, disabled: true, className: "mt-1 accent-primary" }),
123
+ /* @__PURE__ */ jsx("div", { className: item.checked !== null ? "min-w-0 flex-1 space-y-1" : "contents", children: /* @__PURE__ */ jsx(Blocks, { blocks: item.children, tight: !block.loose && item.children.length === 1 }) })
124
+ ] }, itemIndex))
125
+ },
126
+ index
127
+ );
128
+ }
129
+ case "table":
130
+ return (
131
+ // dir="auto": an English table keeps its column order inside an RTL UI.
132
+ // Code tokens (parameter names, values) never wrap mid-token.
133
+ /* @__PURE__ */ jsx("div", { dir: "auto", className: "overflow-x-auto rounded-lg border border-border", children: /* @__PURE__ */ jsxs("table", { dir: "auto", className: "w-full border-collapse text-start text-sm [&_code]:whitespace-nowrap", children: [
134
+ /* @__PURE__ */ jsx("thead", { className: "bg-muted/60", children: /* @__PURE__ */ jsx("tr", { children: block.header.map((cell, column) => /* @__PURE__ */ jsx(
135
+ "th",
136
+ {
137
+ dir: "auto",
138
+ style: block.align[column] ? { textAlign: block.align[column] } : void 0,
139
+ className: "border-b border-border px-3 py-2 text-start font-semibold text-foreground",
140
+ children: /* @__PURE__ */ jsx(Inline, { nodes: cell })
141
+ },
142
+ column
143
+ )) }) }),
144
+ /* @__PURE__ */ jsx("tbody", { children: block.rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border last:border-b-0", children: row.map((cell, column) => /* @__PURE__ */ jsx(
145
+ "td",
146
+ {
147
+ dir: "auto",
148
+ style: block.align[column] ? { textAlign: block.align[column] } : void 0,
149
+ className: "px-3 py-2 align-top",
150
+ children: /* @__PURE__ */ jsx(Inline, { nodes: cell })
151
+ },
152
+ column
153
+ )) }, rowIndex)) })
154
+ ] }) }, index)
155
+ );
156
+ default:
157
+ return null;
158
+ }
159
+ });
160
+ }
161
+ function Markdown({ source, className = "" }) {
162
+ const locale = useLocale();
163
+ const blocks = useMemo(() => selectLocale(parseMarkdown(source), locale), [source, locale]);
164
+ if (blocks.length === 0) return null;
165
+ return /* @__PURE__ */ jsx("div", { className: `space-y-3 text-sm leading-relaxed ${className}`, children: /* @__PURE__ */ jsx(Blocks, { blocks }) });
166
+ }
167
+ export {
168
+ Markdown as default
169
+ };
170
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/markdown.jsx"],"sourcesContent":["\"use client\";\n\n// Renders OpenAPI descriptions (GFM subset, see src/lib/markdown.js) as React\n// elements; raw HTML in the source is never interpreted. Blocks use\n// dir=\"auto\" so English spec text stays readable inside an RTL interface.\n// \":::lang xx\" blocks are resolved for the current UI language.\n\nimport { useMemo } from \"react\";\nimport { useLocale } from \"./i18n/context\";\nimport { parseMarkdown, safeUrl, selectLocale } from \"@oaspect/core\";\nimport CodeBlock from \"./code-block\";\n\n// Fence info strings → tokenizer languages in src/lib/highlight.js.\nconst CODE_LANGUAGES = {\n json: \"json\",\n sh: \"shell\",\n bash: \"shell\",\n shell: \"shell\",\n zsh: \"shell\",\n curl: \"shell\",\n js: \"javascript\",\n javascript: \"javascript\",\n ts: \"javascript\",\n typescript: \"javascript\",\n php: \"php\",\n py: \"python\",\n python: \"python\",\n go: \"go\",\n java: \"java\",\n kotlin: \"kotlin\",\n kt: \"kotlin\",\n cs: \"csharp\",\n csharp: \"csharp\",\n rb: \"ruby\",\n ruby: \"ruby\",\n swift: \"swift\",\n dart: \"dart\",\n rust: \"rust\",\n rs: \"rust\",\n c: \"c\",\n powershell: \"powershell\",\n ps1: \"powershell\",\n http: \"http\",\n};\n\nconst HEADING_STYLES = {\n 1: \"text-xl font-bold\",\n 2: \"text-lg font-semibold\",\n 3: \"text-base font-semibold\",\n 4: \"text-sm font-semibold\",\n 5: \"text-sm font-semibold\",\n 6: \"text-xs font-semibold uppercase tracking-wide\",\n};\n\nfunction Inline({ nodes }) {\n return nodes.map((node, index) => {\n switch (node.type) {\n case \"text\":\n return node.value;\n case \"br\":\n return <br key={index} />;\n case \"code\":\n return (\n <code key={index} dir=\"ltr\" className=\"rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]\">\n {node.value}\n </code>\n );\n case \"strong\":\n return (\n <strong key={index} className=\"font-semibold text-foreground\">\n <Inline nodes={node.children} />\n </strong>\n );\n case \"em\":\n return (\n <em key={index}>\n <Inline nodes={node.children} />\n </em>\n );\n case \"del\":\n return (\n <del key={index}>\n <Inline nodes={node.children} />\n </del>\n );\n case \"link\": {\n const href = safeUrl(node.href);\n if (!href) return <Inline key={index} nodes={node.children} />;\n const external = /^https?:/i.test(href);\n return (\n <a\n key={index}\n href={href}\n title={node.title}\n {...(external ? { target: \"_blank\", rel: \"noreferrer\" } : {})}\n className=\"text-primary underline underline-offset-2\"\n >\n <Inline nodes={node.children} />\n </a>\n );\n }\n case \"image\": {\n const src = safeUrl(node.src, { image: true });\n if (!src) return node.alt;\n // Plain <img>: description images can come from any host.\n return <img key={index} src={src} alt={node.alt} title={node.title} loading=\"lazy\" className=\"inline-block max-w-full rounded-lg\" />;\n }\n default:\n return null;\n }\n });\n}\n\nfunction Blocks({ blocks, tight = false }) {\n return blocks.map((block, index) => {\n switch (block.type) {\n case \"heading\": {\n // Descriptions sit under the page's own h1/h2, so levels shift down.\n const Tag = `h${Math.min(block.level + 2, 6)}`;\n return (\n <Tag key={index} dir=\"auto\" className={`${HEADING_STYLES[block.level]} pt-2 text-foreground`}>\n <Inline nodes={block.children} />\n </Tag>\n );\n }\n case \"paragraph\":\n return tight ? (\n <Inline key={index} nodes={block.children} />\n ) : (\n <p key={index} dir=\"auto\">\n <Inline nodes={block.children} />\n </p>\n );\n case \"code\":\n return (\n <CodeBlock\n key={index}\n code={block.text}\n language={CODE_LANGUAGES[block.language] ?? \"text\"}\n toolbar={block.language && <span className=\"px-1 font-mono text-[11px] text-white/50\">{block.language}</span>}\n />\n );\n case \"blockquote\":\n return (\n <blockquote key={index} className=\"space-y-3 border-s-4 border-border ps-4 italic\">\n <Blocks blocks={block.children} />\n </blockquote>\n );\n case \"hr\":\n return <hr key={index} className=\"border-border\" />;\n case \"lang-selected\":\n return (\n <div key={index} lang={block.locale} className=\"space-y-3\">\n <Blocks blocks={block.children} tight={tight} />\n </div>\n );\n case \"list\": {\n const List = block.ordered ? \"ol\" : \"ul\";\n const task = block.items.some((item) => item.checked !== null);\n return (\n <List\n key={index}\n dir=\"auto\"\n start={block.ordered && block.start !== 1 ? block.start : undefined}\n className={`space-y-1.5 ${task ? \"ps-1\" : `ps-5 ${block.ordered ? \"list-decimal\" : \"list-disc\"}`} marker:text-muted-foreground`}\n >\n {block.items.map((item, itemIndex) => (\n <li key={itemIndex} className={`${block.loose ? \"space-y-2\" : \"space-y-1\"} ${item.checked !== null ? \"flex list-none items-start gap-2\" : \"\"}`}>\n {item.checked !== null && (\n <input type=\"checkbox\" checked={item.checked} readOnly disabled className=\"mt-1 accent-primary\" />\n )}\n <div className={item.checked !== null ? \"min-w-0 flex-1 space-y-1\" : \"contents\"}>\n <Blocks blocks={item.children} tight={!block.loose && item.children.length === 1} />\n </div>\n </li>\n ))}\n </List>\n );\n }\n case \"table\":\n return (\n // dir=\"auto\": an English table keeps its column order inside an RTL UI.\n // Code tokens (parameter names, values) never wrap mid-token.\n <div key={index} dir=\"auto\" className=\"overflow-x-auto rounded-lg border border-border\">\n <table dir=\"auto\" className=\"w-full border-collapse text-start text-sm [&_code]:whitespace-nowrap\">\n <thead className=\"bg-muted/60\">\n <tr>\n {block.header.map((cell, column) => (\n <th\n key={column}\n dir=\"auto\"\n style={block.align[column] ? { textAlign: block.align[column] } : undefined}\n className=\"border-b border-border px-3 py-2 text-start font-semibold text-foreground\"\n >\n <Inline nodes={cell} />\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {block.rows.map((row, rowIndex) => (\n <tr key={rowIndex} className=\"border-b border-border last:border-b-0\">\n {row.map((cell, column) => (\n <td\n key={column}\n dir=\"auto\"\n style={block.align[column] ? { textAlign: block.align[column] } : undefined}\n className=\"px-3 py-2 align-top\"\n >\n <Inline nodes={cell} />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n default:\n return null;\n }\n });\n}\n\nexport default function Markdown({ source, className = \"\" }) {\n const locale = useLocale();\n const blocks = useMemo(() => selectLocale(parseMarkdown(source), locale), [source, locale]);\n if (blocks.length === 0) return null;\n\n return (\n <div className={`space-y-3 text-sm leading-relaxed ${className}`}>\n <Blocks blocks={blocks} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,37 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ const METHOD_STYLES = {
3
+ get: "bg-sky-500/15 text-sky-800 dark:text-sky-300",
4
+ post: "bg-emerald-500/15 text-emerald-800 dark:text-emerald-300",
5
+ put: "bg-amber-500/15 text-amber-800 dark:text-amber-300",
6
+ patch: "bg-violet-500/15 text-violet-800 dark:text-violet-300",
7
+ delete: "bg-rose-500/15 text-rose-800 dark:text-rose-300"
8
+ };
9
+ function MethodBadge({ method, size = "md" }) {
10
+ const sizing = size === "sm" ? "w-12 text-[10px] py-0.5" : "px-2 py-1 text-xs";
11
+ return /* @__PURE__ */ jsx(
12
+ "span",
13
+ {
14
+ className: `inline-flex shrink-0 items-center justify-center rounded-md font-mono font-bold uppercase ${sizing} ${METHOD_STYLES[method] ?? "bg-muted text-muted-foreground"}`,
15
+ children: method === "delete" && size === "sm" ? "del" : method
16
+ }
17
+ );
18
+ }
19
+ function statusTone(status, { onDark = false } = {}) {
20
+ if (onDark) {
21
+ if (/^2/.test(status)) return "text-emerald-400";
22
+ if (/^3/.test(status)) return "text-sky-400";
23
+ if (/^4/.test(status)) return "text-amber-400";
24
+ if (/^5/.test(status)) return "text-rose-400";
25
+ return "text-white/60";
26
+ }
27
+ if (/^2/.test(status)) return "text-emerald-700 dark:text-emerald-400";
28
+ if (/^3/.test(status)) return "text-sky-700 dark:text-sky-400";
29
+ if (/^4/.test(status)) return "text-amber-700 dark:text-amber-400";
30
+ if (/^5/.test(status)) return "text-rose-700 dark:text-rose-400";
31
+ return "text-muted-foreground";
32
+ }
33
+ export {
34
+ MethodBadge as default,
35
+ statusTone
36
+ };
37
+ //# sourceMappingURL=method-badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/method-badge.jsx"],"sourcesContent":["const METHOD_STYLES = {\n get: \"bg-sky-500/15 text-sky-800 dark:text-sky-300\",\n post: \"bg-emerald-500/15 text-emerald-800 dark:text-emerald-300\",\n put: \"bg-amber-500/15 text-amber-800 dark:text-amber-300\",\n patch: \"bg-violet-500/15 text-violet-800 dark:text-violet-300\",\n delete: \"bg-rose-500/15 text-rose-800 dark:text-rose-300\",\n};\n\nexport default function MethodBadge({ method, size = \"md\" }) {\n const sizing = size === \"sm\" ? \"w-12 text-[10px] py-0.5\" : \"px-2 py-1 text-xs\";\n\n return (\n <span\n className={`inline-flex shrink-0 items-center justify-center rounded-md font-mono font-bold uppercase ${sizing} ${\n METHOD_STYLES[method] ?? \"bg-muted text-muted-foreground\"\n }`}\n >\n {method === \"delete\" && size === \"sm\" ? \"del\" : method}\n </span>\n );\n}\n\n// Status code colors. `onDark` is for the always-dark code blocks, where the\n// light-theme shades would not reach WCAG AA contrast.\nexport function statusTone(status, { onDark = false } = {}) {\n if (onDark) {\n if (/^2/.test(status)) return \"text-emerald-400\";\n if (/^3/.test(status)) return \"text-sky-400\";\n if (/^4/.test(status)) return \"text-amber-400\";\n if (/^5/.test(status)) return \"text-rose-400\";\n return \"text-white/60\";\n }\n if (/^2/.test(status)) return \"text-emerald-700 dark:text-emerald-400\";\n if (/^3/.test(status)) return \"text-sky-700 dark:text-sky-400\";\n if (/^4/.test(status)) return \"text-amber-700 dark:text-amber-400\";\n if (/^5/.test(status)) return \"text-rose-700 dark:text-rose-400\";\n return \"text-muted-foreground\";\n}\n"],"mappings":"AAYI;AAZJ,MAAM,gBAAgB;AAAA,EACpB,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AACV;AAEe,SAAR,YAA6B,EAAE,QAAQ,OAAO,KAAK,GAAG;AAC3D,QAAM,SAAS,SAAS,OAAO,4BAA4B;AAE3D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,6FAA6F,MAAM,IAC5G,cAAc,MAAM,KAAK,gCAC3B;AAAA,MAEC,qBAAW,YAAY,SAAS,OAAO,QAAQ;AAAA;AAAA,EAClD;AAEJ;AAIO,SAAS,WAAW,QAAQ,EAAE,SAAS,MAAM,IAAI,CAAC,GAAG;AAC1D,MAAI,QAAQ;AACV,QAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,QAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,QAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,QAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,MAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,MAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,MAAI,KAAK,KAAK,MAAM,EAAG,QAAO;AAC9B,SAAO;AACT;","names":[]}
package/dist/models.js ADDED
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { memo, useRef } from "react";
4
+ import { useT } from "./i18n/context.js";
5
+ import { useNearViewport } from "./lazy.js";
6
+ import SchemaTree from "./schema-tree.js";
7
+ function Model({ item }) {
8
+ const ref = useRef(null);
9
+ const near = useNearViewport(ref);
10
+ return /* @__PURE__ */ jsxs("section", { ref, id: item.anchor, "data-anchor": true, className: `rounded-2xl border border-border p-5 ${near ? "" : "min-h-40"}`, children: [
11
+ /* @__PURE__ */ jsx("h3", { className: "font-mono text-base font-semibold [overflow-wrap:anywhere]", children: /* @__PURE__ */ jsx("a", { href: `#${item.anchor}`, className: "hover:text-primary", children: item.name }) }),
12
+ near && /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(SchemaTree, { schema: item.schema, modelName: item.name }) })
13
+ ] });
14
+ }
15
+ function Models({ schemas }) {
16
+ const t = useT();
17
+ if (schemas.length === 0) return null;
18
+ return /* @__PURE__ */ jsxs("section", { className: "py-14", children: [
19
+ /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight", children: t("models.title") }),
20
+ /* @__PURE__ */ jsx("div", { className: "mt-6 space-y-6", children: schemas.map((item) => /* @__PURE__ */ jsx(Model, { item }, item.name)) })
21
+ ] });
22
+ }
23
+ var models_default = memo(Models);
24
+ export {
25
+ models_default as default
26
+ };
27
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models.jsx"],"sourcesContent":["\"use client\";\n\nimport { memo, useRef } from \"react\";\nimport { useT } from \"./i18n/context\";\nimport { useNearViewport } from \"./lazy\";\nimport SchemaTree from \"./schema-tree\";\n\nfunction Model({ item }) {\n const ref = useRef(null);\n const near = useNearViewport(ref);\n\n return (\n <section ref={ref} id={item.anchor} data-anchor className={`rounded-2xl border border-border p-5 ${near ? \"\" : \"min-h-40\"}`}>\n <h3 className=\"font-mono text-base font-semibold [overflow-wrap:anywhere]\">\n <a href={`#${item.anchor}`} className=\"hover:text-primary\">\n {item.name}\n </a>\n </h3>\n {near && (\n <div className=\"mt-3\">\n <SchemaTree schema={item.schema} modelName={item.name} />\n </div>\n )}\n </section>\n );\n}\n\nfunction Models({ schemas }) {\n const t = useT();\n if (schemas.length === 0) return null;\n\n return (\n <section className=\"py-14\">\n <h2 className=\"text-3xl font-bold tracking-tight\">{t(\"models.title\")}</h2>\n <div className=\"mt-6 space-y-6\">\n {schemas.map((item) => (\n <Model key={item.name} item={item} />\n ))}\n </div>\n </section>\n );\n}\n\nexport default memo(Models);\n"],"mappings":";AAYI,SAEI,KAFJ;AAVJ,SAAS,MAAM,cAAc;AAC7B,SAAS,YAAY;AACrB,SAAS,uBAAuB;AAChC,OAAO,gBAAgB;AAEvB,SAAS,MAAM,EAAE,KAAK,GAAG;AACvB,QAAM,MAAM,OAAO,IAAI;AACvB,QAAM,OAAO,gBAAgB,GAAG;AAEhC,SACE,qBAAC,aAAQ,KAAU,IAAI,KAAK,QAAQ,eAAW,MAAC,WAAW,wCAAwC,OAAO,KAAK,UAAU,IACvH;AAAA,wBAAC,QAAG,WAAU,8DACZ,8BAAC,OAAE,MAAM,IAAI,KAAK,MAAM,IAAI,WAAU,sBACnC,eAAK,MACR,GACF;AAAA,IACC,QACC,oBAAC,SAAI,WAAU,QACb,8BAAC,cAAW,QAAQ,KAAK,QAAQ,WAAW,KAAK,MAAM,GACzD;AAAA,KAEJ;AAEJ;AAEA,SAAS,OAAO,EAAE,QAAQ,GAAG;AAC3B,QAAM,IAAI,KAAK;AACf,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,SACE,qBAAC,aAAQ,WAAU,SACjB;AAAA,wBAAC,QAAG,WAAU,qCAAqC,YAAE,cAAc,GAAE;AAAA,IACrE,oBAAC,SAAI,WAAU,kBACZ,kBAAQ,IAAI,CAAC,SACZ,oBAAC,SAAsB,QAAX,KAAK,IAAkB,CACpC,GACH;AAAA,KACF;AAEJ;AAEA,IAAO,iBAAQ,KAAK,MAAM;","names":[]}