@graffiticode/l0185-view 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.
@@ -0,0 +1 @@
1
+ export {}
package/dist/index.js ADDED
@@ -0,0 +1,158 @@
1
+ import { useMemo as e, useState as t } from "react";
2
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
3
+ import { View as i } from "@graffiticode/l0000-view";
4
+ //#region src/components/data/Form.tsx
5
+ var a = 200, o = (e) => e === null || [
6
+ "string",
7
+ "number",
8
+ "boolean"
9
+ ].includes(typeof e), s = (e) => !!e && typeof e == "object" && !Array.isArray(e) && Object.values(e).every(o), c = (e) => Array.isArray(e) && e.length > 0 && e.every(s), l = (e) => {
10
+ let t = /* @__PURE__ */ new Set();
11
+ for (let n of e) for (let e of Object.keys(n)) t.add(e);
12
+ return [...t];
13
+ }, u = (e) => {
14
+ let t = e == null ? "" : String(e);
15
+ return /[",\n]/.test(t) ? `"${t.replace(/"/g, "\"\"")}"` : t;
16
+ }, d = (e) => {
17
+ let t = l(e);
18
+ return [t.map(u).join(","), ...e.map((e) => t.map((t) => u(e[t])).join(","))].join("\n");
19
+ }, f = (e) => {
20
+ try {
21
+ navigator.clipboard?.writeText(e);
22
+ } catch {}
23
+ }, p = "rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-gray-800", m = ({ rows: i }) => {
24
+ let [o, s] = t(a), c = e(() => l(i), [i]), u = e(() => new Set(c.filter((e) => i.every((t) => t[e] === null || t[e] === void 0 || typeof t[e] == "number"))), [c, i]);
25
+ return /* @__PURE__ */ r("div", {
26
+ className: "flex flex-col gap-2",
27
+ children: [/* @__PURE__ */ n("div", {
28
+ className: "max-h-[32rem] overflow-auto rounded border border-gray-200 dark:border-gray-700",
29
+ children: /* @__PURE__ */ r("table", {
30
+ className: "min-w-full border-collapse text-sm",
31
+ children: [/* @__PURE__ */ n("thead", {
32
+ className: "sticky top-0 bg-gray-50 dark:bg-gray-800",
33
+ children: /* @__PURE__ */ n("tr", { children: c.map((e) => /* @__PURE__ */ n("th", {
34
+ scope: "col",
35
+ className: `whitespace-nowrap border-b border-gray-200 px-3 py-1.5 font-medium text-gray-700 dark:border-gray-700 dark:text-gray-200 ${u.has(e) ? "text-right" : "text-left"}`,
36
+ children: e
37
+ }, e)) })
38
+ }), /* @__PURE__ */ n("tbody", { children: i.slice(0, o).map((e, t) => /* @__PURE__ */ n("tr", {
39
+ className: "odd:bg-white even:bg-gray-50 dark:odd:bg-gray-900 dark:even:bg-gray-950",
40
+ children: c.map((t) => /* @__PURE__ */ n("td", {
41
+ className: `whitespace-nowrap px-3 py-1 text-gray-900 dark:text-gray-100 ${u.has(t) ? "text-right tabular-nums" : ""}`,
42
+ children: e[t] === null || e[t] === void 0 ? /* @__PURE__ */ n("span", {
43
+ className: "text-gray-400",
44
+ children: "—"
45
+ }) : String(e[t])
46
+ }, t))
47
+ }, t)) })]
48
+ })
49
+ }), /* @__PURE__ */ r("div", {
50
+ className: "flex flex-wrap items-center gap-2 text-xs text-gray-500 dark:text-gray-400",
51
+ children: [
52
+ /* @__PURE__ */ r("span", { children: [
53
+ i.length,
54
+ " ",
55
+ i.length === 1 ? "record" : "records",
56
+ " · ",
57
+ c.length,
58
+ " ",
59
+ c.length === 1 ? "field" : "fields"
60
+ ] }),
61
+ o < i.length && /* @__PURE__ */ r("button", {
62
+ type: "button",
63
+ className: p,
64
+ onClick: () => s((e) => e + a),
65
+ children: [
66
+ "Show ",
67
+ Math.min(a, i.length - o),
68
+ " more"
69
+ ]
70
+ }),
71
+ /* @__PURE__ */ n("button", {
72
+ type: "button",
73
+ className: p,
74
+ onClick: () => f(d(i)),
75
+ children: "Copy CSV"
76
+ }),
77
+ /* @__PURE__ */ n("button", {
78
+ type: "button",
79
+ className: p,
80
+ onClick: () => f(JSON.stringify(i, null, 2)),
81
+ children: "Copy JSON"
82
+ })
83
+ ]
84
+ })]
85
+ });
86
+ }, h = ({ v: e }) => /* @__PURE__ */ n("span", {
87
+ className: typeof e == "string" ? "text-emerald-700 dark:text-emerald-400" : typeof e == "number" ? "text-blue-700 dark:text-blue-400" : "text-gray-500",
88
+ children: JSON.stringify(e)
89
+ }), g = ({ name: e, v: i, depth: a }) => {
90
+ let [s, c] = t(a < 2), l = e === void 0 ? null : /* @__PURE__ */ r("span", {
91
+ className: "text-gray-700 dark:text-gray-300",
92
+ children: [e, ": "]
93
+ });
94
+ if (o(i)) return /* @__PURE__ */ r("div", {
95
+ className: "pl-4",
96
+ children: [l, /* @__PURE__ */ n(h, { v: i })]
97
+ });
98
+ let u = Array.isArray(i) ? i.map((e, t) => [String(t), e]) : Object.entries(i), d = Array.isArray(i) ? `[${i.length}]` : `{${u.length}}`;
99
+ return /* @__PURE__ */ r("div", {
100
+ className: "pl-4",
101
+ children: [/* @__PURE__ */ r("button", {
102
+ type: "button",
103
+ "aria-expanded": s,
104
+ className: "text-left hover:underline",
105
+ onClick: () => c((e) => !e),
106
+ children: [
107
+ s ? "▾" : "▸",
108
+ " ",
109
+ l,
110
+ /* @__PURE__ */ n("span", {
111
+ className: "text-gray-500",
112
+ children: d
113
+ })
114
+ ]
115
+ }), s && u.map(([e, t]) => /* @__PURE__ */ n(g, {
116
+ name: e,
117
+ v: t,
118
+ depth: a + 1
119
+ }, e))]
120
+ });
121
+ }, _ = ({ data: e }) => /* @__PURE__ */ r("div", {
122
+ className: "flex flex-col gap-2",
123
+ children: [/* @__PURE__ */ n("div", {
124
+ className: "max-h-[32rem] overflow-auto rounded border border-gray-200 p-2 font-mono text-xs dark:border-gray-700",
125
+ children: /* @__PURE__ */ n(g, {
126
+ v: e,
127
+ depth: 0
128
+ })
129
+ }), /* @__PURE__ */ n("div", {
130
+ className: "flex gap-2 text-xs",
131
+ children: /* @__PURE__ */ n("button", {
132
+ type: "button",
133
+ className: p,
134
+ onClick: () => f(JSON.stringify(e, null, 2)),
135
+ children: "Copy JSON"
136
+ })
137
+ })]
138
+ }), v = (e) => /* @__PURE__ */ n("div", {
139
+ className: "flex flex-col gap-2",
140
+ role: "alert",
141
+ children: e.map((e, t) => /* @__PURE__ */ n("div", {
142
+ className: "rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200",
143
+ children: String(e?.message ?? e)
144
+ }, t))
145
+ }), y = ({ data: e }) => e === void 0 ? null : Array.isArray(e) && e.length === 0 ? /* @__PURE__ */ n("p", {
146
+ className: "text-sm text-gray-500",
147
+ children: "No records."
148
+ }) : c(e) ? /* @__PURE__ */ n(m, { rows: e }) : /* @__PURE__ */ n(_, { data: e }), b = ({ state: e }) => {
149
+ let { data: t, errors: r } = e;
150
+ return /* @__PURE__ */ n("div", {
151
+ className: "l0185-data p-2 text-gray-900 dark:text-gray-100",
152
+ children: r && r.length ? v(r) : /* @__PURE__ */ n(y, { data: t })
153
+ });
154
+ };
155
+ //#endregion
156
+ export { y as Data, m as DataTable, b as Form, _ as JsonTree, i as View, l as columnsOf, c as isTable, d as toCsv };
157
+
158
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["PAGE","isScalar","v","isFlatRecord","isTable","data","columnsOf","seen","r","rows","k","csvCell","s","toCsv","cols","c","copy","text","button","DataTable","shown","setShown","useState","useMemo","numeric","i","n","Leaf","Node","open","setOpen","depth","label","name","entries","x","summary","o","JsonTree","renderErrors","errors","error","Data","Form","state","View"],"sources":["../src/components/data/Form.tsx"],"sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * L0185's Form: shows the data a program produced, and nothing else. A list of flat records is a\n * table; anything else — nested records, a single record, a scalar — is a collapsible JSON tree.\n * Compile errors render as alerts. The view never adds to the data: no title, no formatting the\n * program did not ask for.\n */\nimport React, { useMemo, useState } from \"react\";\nimport type { CompileError, FormProps } from \"@graffiticode/l0000-view\";\nimport \"../../index.css\";\n\nconst PAGE = 200;\n\nconst isScalar = (v: unknown) => v === null || [\"string\", \"number\", \"boolean\"].includes(typeof v);\nconst isFlatRecord = (v: unknown) =>\n !!v && typeof v === \"object\" && !Array.isArray(v) && Object.values(v as object).every(isScalar);\n\n/** A list of flat records is a table; everything else is a tree. */\nexport const isTable = (data: unknown): data is Record<string, unknown>[] =>\n Array.isArray(data) && data.length > 0 && data.every(isFlatRecord);\n\nexport const columnsOf = (rows: Record<string, unknown>[]): string[] => {\n const seen = new Set<string>();\n for (const r of rows) for (const k of Object.keys(r)) seen.add(k);\n return [...seen];\n};\n\nconst csvCell = (v: unknown) => {\n const s = v === null || v === undefined ? \"\" : String(v);\n return /[\",\\n]/.test(s) ? `\"${s.replace(/\"/g, '\"\"')}\"` : s;\n};\nexport const toCsv = (rows: Record<string, unknown>[]): string => {\n const cols = columnsOf(rows);\n return [cols.map(csvCell).join(\",\"), ...rows.map((r) => cols.map((c) => csvCell(r[c])).join(\",\"))].join(\"\\n\");\n};\n\nconst copy = (text: string) => {\n try {\n void navigator.clipboard?.writeText(text);\n } catch {\n /* clipboard unavailable: nothing to do */\n }\n};\n\nconst button =\n \"rounded border border-gray-300 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-200 dark:hover:bg-gray-800\";\n\nexport const DataTable = ({ rows }: { rows: Record<string, unknown>[] }) => {\n const [shown, setShown] = useState(PAGE);\n const cols = useMemo(() => columnsOf(rows), [rows]);\n const numeric = useMemo(\n () => new Set(cols.filter((c) => rows.every((r) => r[c] === null || r[c] === undefined || typeof r[c] === \"number\"))),\n [cols, rows],\n );\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"max-h-[32rem] overflow-auto rounded border border-gray-200 dark:border-gray-700\">\n <table className=\"min-w-full border-collapse text-sm\">\n <thead className=\"sticky top-0 bg-gray-50 dark:bg-gray-800\">\n <tr>\n {cols.map((c) => (\n <th key={c} scope=\"col\" className={`whitespace-nowrap border-b border-gray-200 px-3 py-1.5 font-medium text-gray-700 dark:border-gray-700 dark:text-gray-200 ${numeric.has(c) ? \"text-right\" : \"text-left\"}`}>\n {c}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.slice(0, shown).map((r, i) => (\n <tr key={i} className=\"odd:bg-white even:bg-gray-50 dark:odd:bg-gray-900 dark:even:bg-gray-950\">\n {cols.map((c) => (\n <td key={c} className={`whitespace-nowrap px-3 py-1 text-gray-900 dark:text-gray-100 ${numeric.has(c) ? \"text-right tabular-nums\" : \"\"}`}>\n {r[c] === null || r[c] === undefined ? <span className=\"text-gray-400\">—</span> : String(r[c])}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-gray-500 dark:text-gray-400\">\n <span>\n {rows.length} {rows.length === 1 ? \"record\" : \"records\"} · {cols.length} {cols.length === 1 ? \"field\" : \"fields\"}\n </span>\n {shown < rows.length && (\n <button type=\"button\" className={button} onClick={() => setShown((n) => n + PAGE)}>\n Show {Math.min(PAGE, rows.length - shown)} more\n </button>\n )}\n <button type=\"button\" className={button} onClick={() => copy(toCsv(rows))}>\n Copy CSV\n </button>\n <button type=\"button\" className={button} onClick={() => copy(JSON.stringify(rows, null, 2))}>\n Copy JSON\n </button>\n </div>\n </div>\n );\n};\n\nconst Leaf = ({ v }: { v: unknown }) => (\n <span className={typeof v === \"string\" ? \"text-emerald-700 dark:text-emerald-400\" : typeof v === \"number\" ? \"text-blue-700 dark:text-blue-400\" : \"text-gray-500\"}>\n {JSON.stringify(v)}\n </span>\n);\n\nconst Node = ({ name, v, depth }: { name?: string; v: unknown; depth: number }) => {\n const [open, setOpen] = useState(depth < 2);\n const label = name !== undefined ? <span className=\"text-gray-700 dark:text-gray-300\">{name}: </span> : null;\n if (isScalar(v)) {\n return (\n <div className=\"pl-4\">\n {label}\n <Leaf v={v} />\n </div>\n );\n }\n const entries = Array.isArray(v) ? v.map((x, i) => [String(i), x] as const) : Object.entries(v as object);\n const summary = Array.isArray(v) ? `[${v.length}]` : `{${entries.length}}`;\n return (\n <div className=\"pl-4\">\n <button type=\"button\" aria-expanded={open} className=\"text-left hover:underline\" onClick={() => setOpen((o) => !o)}>\n {open ? \"▾\" : \"▸\"} {label}\n <span className=\"text-gray-500\">{summary}</span>\n </button>\n {open && entries.map(([k, x]) => <Node key={k} name={k} v={x} depth={depth + 1} />)}\n </div>\n );\n};\n\nexport const JsonTree = ({ data }: { data: unknown }) => (\n <div className=\"flex flex-col gap-2\">\n <div className=\"max-h-[32rem] overflow-auto rounded border border-gray-200 p-2 font-mono text-xs dark:border-gray-700\">\n <Node v={data} depth={0} />\n </div>\n <div className=\"flex gap-2 text-xs\">\n <button type=\"button\" className={button} onClick={() => copy(JSON.stringify(data, null, 2))}>\n Copy JSON\n </button>\n </div>\n </div>\n);\n\nconst renderErrors = (errors: CompileError[]) => (\n <div className=\"flex flex-col gap-2\" role=\"alert\">\n {errors.map((error, i) => (\n <div key={i} className=\"rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200\">\n {String((error as any)?.message ?? error)}\n </div>\n ))}\n </div>\n);\n\n/** The data a program produced: a table, a tree, or the errors that stopped it. */\nexport const Data = ({ data }: { data: unknown }) => {\n if (data === undefined) return null;\n if (Array.isArray(data) && data.length === 0) return <p className=\"text-sm text-gray-500\">No records.</p>;\n return isTable(data) ? <DataTable rows={data} /> : <JsonTree data={data} />;\n};\n\nexport const Form = ({ state }: FormProps) => {\n const { data, errors } = state;\n return <div className=\"l0185-data p-2 text-gray-900 dark:text-gray-100\">{errors && errors.length ? renderErrors(errors) : <Data data={data} />}</div>;\n};\n"],"mappings":"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"}
package/dist/style.css ADDED
@@ -0,0 +1,2 @@
1
+ *,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }:where(.l0185-data),:where(.l0185-data) *,:where(.l0185-data) :before,:where(.l0185-data) :after{box-sizing:border-box;border-style:solid;border-width:0}:where(.l0185-data) ol,:where(.l0185-data) ul{margin:0;padding:0;list-style:none}:where(.l0185-data) button{font:inherit;color:inherit;cursor:pointer;background-color:#0000;background-image:none;margin:0;padding:0}:where(.l0185-data) img{max-width:100%;height:auto}:where(.l0185-data){-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}:where(.l0185-data) h1,:where(.l0185-data) h2,:where(.l0185-data) h3,:where(.l0185-data) p{font-size:inherit;font-weight:inherit;margin:0}.sticky{position:sticky}.top-0{top:0}.flex{display:flex}.table{display:table}.grid{display:grid}.max-h-\[32rem\]{max-height:32rem}.min-w-full{min-width:100%}.border-collapse{border-collapse:collapse}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.gap-2{gap:.5rem}.overflow-auto{overflow:auto}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1))}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-red-50{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity,1))}.p-2{padding:.5rem}.p-3{padding:.75rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.pl-4{padding-left:1rem}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.text-blue-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1))}.text-emerald-700{--tw-text-opacity:1;color:rgb(4 120 87/var(--tw-text-opacity,1))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-red-800{--tw-text-opacity:1;color:rgb(153 27 27/var(--tw-text-opacity,1))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.odd\:bg-white:nth-child(odd){--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.even\:bg-gray-50:nth-child(2n){--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1))}.hover\:underline:hover{text-decoration-line:underline}@media (prefers-color-scheme:dark){.dark\:border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity,1))}.dark\:border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}.dark\:border-red-800{--tw-border-opacity:1;border-color:rgb(153 27 27/var(--tw-border-opacity,1))}.dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.dark\:bg-red-950{--tw-bg-opacity:1;background-color:rgb(69 10 10/var(--tw-bg-opacity,1))}.dark\:text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.dark\:text-emerald-400{--tw-text-opacity:1;color:rgb(52 211 153/var(--tw-text-opacity,1))}.dark\:text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity,1))}.dark\:text-gray-200{--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity,1))}.dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.dark\:text-red-200{--tw-text-opacity:1;color:rgb(254 202 202/var(--tw-text-opacity,1))}.dark\:odd\:bg-gray-900:nth-child(odd){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}.dark\:even\:bg-gray-950:nth-child(2n){--tw-bg-opacity:1;background-color:rgb(3 7 18/var(--tw-bg-opacity,1))}.dark\:hover\:bg-gray-800:hover{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}}
2
+ /*$vite$:1*/
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "publishConfig": {
3
+ "access": "public"
4
+ },
5
+ "name": "@graffiticode/l0185-view",
6
+ "version": "0.1.0",
7
+ "description": "L0185 view — shows the data a program produced (a record table or a JSON tree), rendered through the shared View inherited from @graffiticode/l0000-view",
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "module": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ },
20
+ "./style.css": "./dist/style.css"
21
+ },
22
+ "scripts": {
23
+ "dev": "vite --config vite.embed.config.ts",
24
+ "build": "tsc -p tsconfig.json && vite build",
25
+ "build:embed": "vite build --config vite.embed.config.ts",
26
+ "test": "vitest run",
27
+ "preview": "vite preview --config vite.embed.config.ts",
28
+ "lint": "eslint src embed",
29
+ "typecheck": "tsc -p tsconfig.json"
30
+ },
31
+ "peerDependencies": {
32
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
33
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
34
+ },
35
+ "dependencies": {
36
+ "@graffiticode/l0000-view": "^0.4.0"
37
+ },
38
+ "devDependencies": {
39
+ "@microsoft/api-extractor": "^7.59.1",
40
+ "@testing-library/dom": "^10.4.0",
41
+ "@testing-library/react": "^16.1.0",
42
+ "@types/react": "^18.3.11",
43
+ "@types/react-dom": "^18.3.0",
44
+ "@vitejs/plugin-react": "^6.1.1",
45
+ "autoprefixer": "^10.4.20",
46
+ "jsdom": "^25.0.1",
47
+ "postcss": "^8.4.47",
48
+ "react": "^18.3.1",
49
+ "react-dom": "^18.3.1",
50
+ "tailwindcss": "^3.4.13",
51
+ "vite": "^8.3.0",
52
+ "vite-plugin-dts": "^5.1.0",
53
+ "vitest": "^5.0.1"
54
+ },
55
+ "sideEffects": [
56
+ "*.css"
57
+ ]
58
+ }