@flanksource/clicky-ui 0.2.8 → 0.2.10
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/components/Combobox.cjs +89 -49
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts +3 -0
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +91 -51
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/FilterBar.cjs +42 -44
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +19 -0
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +43 -45
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +48 -0
- package/dist/components/JsonSchemaForm.cjs.map +1 -0
- package/dist/components/JsonSchemaForm.d.ts +3 -0
- package/dist/components/JsonSchemaForm.d.ts.map +1 -0
- package/dist/components/JsonSchemaForm.js +48 -0
- package/dist/components/JsonSchemaForm.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +169 -0
- package/dist/components/json-schema-form-array.cjs.map +1 -0
- package/dist/components/json-schema-form-array.d.ts +8 -0
- package/dist/components/json-schema-form-array.d.ts.map +1 -0
- package/dist/components/json-schema-form-array.js +169 -0
- package/dist/components/json-schema-form-array.js.map +1 -0
- package/dist/components/json-schema-form-fields.cjs +374 -0
- package/dist/components/json-schema-form-fields.cjs.map +1 -0
- package/dist/components/json-schema-form-fields.d.ts +19 -0
- package/dist/components/json-schema-form-fields.d.ts.map +1 -0
- package/dist/components/json-schema-form-fields.js +374 -0
- package/dist/components/json-schema-form-fields.js.map +1 -0
- package/dist/components/json-schema-form-render.cjs +154 -0
- package/dist/components/json-schema-form-render.cjs.map +1 -0
- package/dist/components/json-schema-form-render.d.ts +40 -0
- package/dist/components/json-schema-form-render.d.ts.map +1 -0
- package/dist/components/json-schema-form-render.js +154 -0
- package/dist/components/json-schema-form-render.js.map +1 -0
- package/dist/components/json-schema-form-resolve.cjs +121 -0
- package/dist/components/json-schema-form-resolve.cjs.map +1 -0
- package/dist/components/json-schema-form-resolve.d.ts +19 -0
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -0
- package/dist/components/json-schema-form-resolve.js +121 -0
- package/dist/components/json-schema-form-resolve.js.map +1 -0
- package/dist/components/json-schema-form-types.d.ts +124 -0
- package/dist/components/json-schema-form-types.d.ts.map +1 -0
- package/dist/components.cjs +7 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +8 -1
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +1 -1
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.js +1 -1
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +16 -15
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +2 -1
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +16 -15
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/Icon.cjs +11 -0
- package/dist/data/Icon.cjs.map +1 -1
- package/dist/data/Icon.d.ts +12 -1
- package/dist/data/Icon.d.ts.map +1 -1
- package/dist/data/Icon.js +12 -1
- package/dist/data/Icon.js.map +1 -1
- package/dist/data/LogDetails.cjs +277 -0
- package/dist/data/LogDetails.cjs.map +1 -0
- package/dist/data/LogDetails.d.ts +5 -0
- package/dist/data/LogDetails.d.ts.map +1 -0
- package/dist/data/LogDetails.js +277 -0
- package/dist/data/LogDetails.js.map +1 -0
- package/dist/data/LogsTable.cjs +6 -202
- package/dist/data/LogsTable.cjs.map +1 -1
- package/dist/data/LogsTable.d.ts.map +1 -1
- package/dist/data/LogsTable.js +4 -200
- package/dist/data/LogsTable.js.map +1 -1
- package/dist/data/Properties.cjs +2 -2
- package/dist/data/Properties.cjs.map +1 -1
- package/dist/data/Properties.js +2 -2
- package/dist/data/Properties.js.map +1 -1
- package/dist/data/cells/TagList.cjs +19 -3
- package/dist/data/cells/TagList.cjs.map +1 -1
- package/dist/data/cells/TagList.d.ts +11 -1
- package/dist/data/cells/TagList.d.ts.map +1 -1
- package/dist/data/cells/TagList.js +19 -3
- package/dist/data/cells/TagList.js.map +1 -1
- package/dist/data/cells/Timestamp.cjs +17 -2
- package/dist/data/cells/Timestamp.cjs.map +1 -1
- package/dist/data/cells/Timestamp.d.ts +2 -0
- package/dist/data/cells/Timestamp.d.ts.map +1 -1
- package/dist/data/cells/Timestamp.js +17 -2
- package/dist/data/cells/Timestamp.js.map +1 -1
- package/dist/data/log-utils.cjs +7 -0
- package/dist/data/log-utils.cjs.map +1 -0
- package/dist/data/log-utils.d.ts +2 -0
- package/dist/data/log-utils.d.ts.map +1 -0
- package/dist/data/log-utils.js +7 -0
- package/dist/data/log-utils.js.map +1 -0
- package/dist/data.cjs +3 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +2 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +5 -2
- package/dist/index.cjs +13 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/dist/rpc/EntityExplorerApp.cjs +3 -2
- package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
- package/dist/rpc/EntityExplorerApp.js +3 -2
- package/dist/rpc/EntityExplorerApp.js.map +1 -1
- package/dist/rpc/OperationActionDialog.cjs +1 -1
- package/dist/rpc/OperationActionDialog.cjs.map +1 -1
- package/dist/rpc/OperationActionDialog.js +1 -1
- package/dist/rpc/OperationActionDialog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs +21 -14
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js +21 -14
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/apiClient.cjs +316 -0
- package/dist/rpc/apiClient.cjs.map +1 -0
- package/dist/rpc/apiClient.d.ts +44 -0
- package/dist/rpc/apiClient.d.ts.map +1 -0
- package/dist/rpc/apiClient.js +316 -0
- package/dist/rpc/apiClient.js.map +1 -0
- package/dist/rpc/useOperations.cjs.map +1 -1
- package/dist/rpc/useOperations.d.ts +2 -1
- package/dist/rpc/useOperations.d.ts.map +1 -1
- package/dist/rpc/useOperations.js.map +1 -1
- package/dist/rpc.cjs +3 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +3 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const utils = require("../lib/utils.cjs");
|
|
5
|
+
const jsonSchemaFormRender = require("./json-schema-form-render.cjs");
|
|
6
|
+
const DEFAULT_LABEL_MAX_WIDTH = "40ch";
|
|
7
|
+
const DEFAULT_VALUE_MAX_WIDTH = "400px";
|
|
8
|
+
function resolveFormLayout(layout, inline) {
|
|
9
|
+
const base = layout ?? { mode: inline ? "inline" : "stacked" };
|
|
10
|
+
if (base.mode !== "inline") return { mode: "stacked" };
|
|
11
|
+
return {
|
|
12
|
+
mode: "inline",
|
|
13
|
+
labelMaxWidth: base.labelMaxWidth ?? DEFAULT_LABEL_MAX_WIDTH,
|
|
14
|
+
valueMaxWidth: base.valueMaxWidth ?? DEFAULT_VALUE_MAX_WIDTH
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function JsonSchemaForm({
|
|
18
|
+
schema,
|
|
19
|
+
value,
|
|
20
|
+
onChange,
|
|
21
|
+
readOnly = false,
|
|
22
|
+
inline = false,
|
|
23
|
+
layout,
|
|
24
|
+
hideReadOnlyFields = false,
|
|
25
|
+
hiddenKeys,
|
|
26
|
+
requiredFirst = false,
|
|
27
|
+
title,
|
|
28
|
+
pre,
|
|
29
|
+
post
|
|
30
|
+
}) {
|
|
31
|
+
const resolvedLayout = resolveFormLayout(layout, inline);
|
|
32
|
+
const ctx = {
|
|
33
|
+
readOnly,
|
|
34
|
+
hideReadOnlyFields,
|
|
35
|
+
layout: resolvedLayout,
|
|
36
|
+
requiredFirst,
|
|
37
|
+
pre: pre ?? [],
|
|
38
|
+
post: post ?? [],
|
|
39
|
+
depth: 0
|
|
40
|
+
};
|
|
41
|
+
const rows = jsonSchemaFormRender.renderObjectFields(schema, value, onChange, ctx, hiddenKeys ? { hiddenKeys } : void 0);
|
|
42
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
|
|
43
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-semibold", children: title }),
|
|
44
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn(resolvedLayout.mode === "inline" ? "grid gap-2" : "grid gap-4"), children: rows })
|
|
45
|
+
] });
|
|
46
|
+
}
|
|
47
|
+
exports.JsonSchemaForm = JsonSchemaForm;
|
|
48
|
+
//# sourceMappingURL=JsonSchemaForm.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonSchemaForm.cjs","sources":["../../src/components/JsonSchemaForm.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { renderObjectFields, type RenderContext } from \"./json-schema-form-render\";\nimport type { FormLayout, JsonSchemaFormProps } from \"./json-schema-form-types\";\n\nconst DEFAULT_LABEL_MAX_WIDTH = \"40ch\";\nconst DEFAULT_VALUE_MAX_WIDTH = \"400px\";\n\n// resolveFormLayout maps the `layout`/`inline` props to a single resolved\n// FormLayout. An explicit `layout` wins; otherwise `inline` selects the inline\n// preset. Width caps are only filled for inline mode.\nfunction resolveFormLayout(layout: FormLayout | undefined, inline: boolean): FormLayout {\n const base = layout ?? { mode: inline ? \"inline\" : \"stacked\" };\n if (base.mode !== \"inline\") return { mode: \"stacked\" };\n return {\n mode: \"inline\",\n labelMaxWidth: base.labelMaxWidth ?? DEFAULT_LABEL_MAX_WIDTH,\n valueMaxWidth: base.valueMaxWidth ?? DEFAULT_VALUE_MAX_WIDTH,\n };\n}\n\n// JsonSchemaForm renders an object subschema as a form: one control per\n// (effective) property. It resolves if/then conditionals internally and recurses\n// through array items and object/map values; every other behaviour is layered on\n// by the pre/post extension functions the consumer supplies. The component holds\n// no domain knowledge.\nexport function JsonSchemaForm({\n schema,\n value,\n onChange,\n readOnly = false,\n inline = false,\n layout,\n hideReadOnlyFields = false,\n hiddenKeys,\n requiredFirst = false,\n title,\n pre,\n post,\n}: JsonSchemaFormProps) {\n const resolvedLayout = resolveFormLayout(layout, inline);\n const ctx: RenderContext = {\n readOnly,\n hideReadOnlyFields,\n layout: resolvedLayout,\n requiredFirst,\n pre: pre ?? [],\n post: post ?? [],\n depth: 0,\n };\n const rows = renderObjectFields(schema, value, onChange, ctx, hiddenKeys ? { hiddenKeys } : undefined);\n\n return (\n <div className=\"space-y-3\">\n {title && <h3 className=\"text-sm font-semibold\">{title}</h3>}\n <div className={cn(resolvedLayout.mode === \"inline\" ? \"grid gap-2\" : \"grid gap-4\")}>{rows}</div>\n </div>\n );\n}\n"],"names":["renderObjectFields","jsxs","jsx","cn"],"mappings":";;;;;AAIA,MAAM,0BAA0B;AAChC,MAAM,0BAA0B;AAKhC,SAAS,kBAAkB,QAAgC,QAA6B;AACtF,QAAM,OAAO,UAAU,EAAE,MAAM,SAAS,WAAW,UAAA;AACnD,MAAI,KAAK,SAAS,SAAU,QAAO,EAAE,MAAM,UAAA;AAC3C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,eAAe,KAAK,iBAAiB;AAAA,IACrC,eAAe,KAAK,iBAAiB;AAAA,EAAA;AAEzC;AAOO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT;AAAA,EACA,qBAAqB;AAAA,EACrB;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,iBAAiB,kBAAkB,QAAQ,MAAM;AACvD,QAAM,MAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,KAAK,OAAO,CAAA;AAAA,IACZ,MAAM,QAAQ,CAAA;AAAA,IACd,OAAO;AAAA,EAAA;AAET,QAAM,OAAOA,qBAAAA,mBAAmB,QAAQ,OAAO,UAAU,KAAK,aAAa,EAAE,WAAA,IAAe,MAAS;AAErG,SACEC,2BAAAA,KAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAA,SAASC,2BAAAA,IAAC,MAAA,EAAG,WAAU,yBAAyB,UAAA,OAAM;AAAA,IACvDA,2BAAAA,IAAC,OAAA,EAAI,WAAWC,MAAAA,GAAG,eAAe,SAAS,WAAW,eAAe,YAAY,GAAI,UAAA,KAAA,CAAK;AAAA,EAAA,GAC5F;AAEJ;;"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { JsonSchemaFormProps } from './json-schema-form-types';
|
|
2
|
+
export declare function JsonSchemaForm({ schema, value, onChange, readOnly, inline, layout, hideReadOnlyFields, hiddenKeys, requiredFirst, title, pre, post, }: JsonSchemaFormProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
//# sourceMappingURL=JsonSchemaForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonSchemaForm.d.ts","sourceRoot":"","sources":["../../src/components/JsonSchemaForm.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAuBhF,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAgB,EAChB,MAAc,EACd,MAAM,EACN,kBAA0B,EAC1B,UAAU,EACV,aAAqB,EACrB,KAAK,EACL,GAAG,EACH,IAAI,GACL,EAAE,mBAAmB,2CAmBrB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { renderObjectFields } from "./json-schema-form-render.js";
|
|
4
|
+
const DEFAULT_LABEL_MAX_WIDTH = "40ch";
|
|
5
|
+
const DEFAULT_VALUE_MAX_WIDTH = "400px";
|
|
6
|
+
function resolveFormLayout(layout, inline) {
|
|
7
|
+
const base = layout ?? { mode: inline ? "inline" : "stacked" };
|
|
8
|
+
if (base.mode !== "inline") return { mode: "stacked" };
|
|
9
|
+
return {
|
|
10
|
+
mode: "inline",
|
|
11
|
+
labelMaxWidth: base.labelMaxWidth ?? DEFAULT_LABEL_MAX_WIDTH,
|
|
12
|
+
valueMaxWidth: base.valueMaxWidth ?? DEFAULT_VALUE_MAX_WIDTH
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function JsonSchemaForm({
|
|
16
|
+
schema,
|
|
17
|
+
value,
|
|
18
|
+
onChange,
|
|
19
|
+
readOnly = false,
|
|
20
|
+
inline = false,
|
|
21
|
+
layout,
|
|
22
|
+
hideReadOnlyFields = false,
|
|
23
|
+
hiddenKeys,
|
|
24
|
+
requiredFirst = false,
|
|
25
|
+
title,
|
|
26
|
+
pre,
|
|
27
|
+
post
|
|
28
|
+
}) {
|
|
29
|
+
const resolvedLayout = resolveFormLayout(layout, inline);
|
|
30
|
+
const ctx = {
|
|
31
|
+
readOnly,
|
|
32
|
+
hideReadOnlyFields,
|
|
33
|
+
layout: resolvedLayout,
|
|
34
|
+
requiredFirst,
|
|
35
|
+
pre: pre ?? [],
|
|
36
|
+
post: post ?? [],
|
|
37
|
+
depth: 0
|
|
38
|
+
};
|
|
39
|
+
const rows = renderObjectFields(schema, value, onChange, ctx, hiddenKeys ? { hiddenKeys } : void 0);
|
|
40
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
41
|
+
title && /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: title }),
|
|
42
|
+
/* @__PURE__ */ jsx("div", { className: cn(resolvedLayout.mode === "inline" ? "grid gap-2" : "grid gap-4"), children: rows })
|
|
43
|
+
] });
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
JsonSchemaForm
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=JsonSchemaForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonSchemaForm.js","sources":["../../src/components/JsonSchemaForm.tsx"],"sourcesContent":["import { cn } from \"../lib/utils\";\nimport { renderObjectFields, type RenderContext } from \"./json-schema-form-render\";\nimport type { FormLayout, JsonSchemaFormProps } from \"./json-schema-form-types\";\n\nconst DEFAULT_LABEL_MAX_WIDTH = \"40ch\";\nconst DEFAULT_VALUE_MAX_WIDTH = \"400px\";\n\n// resolveFormLayout maps the `layout`/`inline` props to a single resolved\n// FormLayout. An explicit `layout` wins; otherwise `inline` selects the inline\n// preset. Width caps are only filled for inline mode.\nfunction resolveFormLayout(layout: FormLayout | undefined, inline: boolean): FormLayout {\n const base = layout ?? { mode: inline ? \"inline\" : \"stacked\" };\n if (base.mode !== \"inline\") return { mode: \"stacked\" };\n return {\n mode: \"inline\",\n labelMaxWidth: base.labelMaxWidth ?? DEFAULT_LABEL_MAX_WIDTH,\n valueMaxWidth: base.valueMaxWidth ?? DEFAULT_VALUE_MAX_WIDTH,\n };\n}\n\n// JsonSchemaForm renders an object subschema as a form: one control per\n// (effective) property. It resolves if/then conditionals internally and recurses\n// through array items and object/map values; every other behaviour is layered on\n// by the pre/post extension functions the consumer supplies. The component holds\n// no domain knowledge.\nexport function JsonSchemaForm({\n schema,\n value,\n onChange,\n readOnly = false,\n inline = false,\n layout,\n hideReadOnlyFields = false,\n hiddenKeys,\n requiredFirst = false,\n title,\n pre,\n post,\n}: JsonSchemaFormProps) {\n const resolvedLayout = resolveFormLayout(layout, inline);\n const ctx: RenderContext = {\n readOnly,\n hideReadOnlyFields,\n layout: resolvedLayout,\n requiredFirst,\n pre: pre ?? [],\n post: post ?? [],\n depth: 0,\n };\n const rows = renderObjectFields(schema, value, onChange, ctx, hiddenKeys ? { hiddenKeys } : undefined);\n\n return (\n <div className=\"space-y-3\">\n {title && <h3 className=\"text-sm font-semibold\">{title}</h3>}\n <div className={cn(resolvedLayout.mode === \"inline\" ? \"grid gap-2\" : \"grid gap-4\")}>{rows}</div>\n </div>\n );\n}\n"],"names":[],"mappings":";;;AAIA,MAAM,0BAA0B;AAChC,MAAM,0BAA0B;AAKhC,SAAS,kBAAkB,QAAgC,QAA6B;AACtF,QAAM,OAAO,UAAU,EAAE,MAAM,SAAS,WAAW,UAAA;AACnD,MAAI,KAAK,SAAS,SAAU,QAAO,EAAE,MAAM,UAAA;AAC3C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,eAAe,KAAK,iBAAiB;AAAA,IACrC,eAAe,KAAK,iBAAiB;AAAA,EAAA;AAEzC;AAOO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,SAAS;AAAA,EACT;AAAA,EACA,qBAAqB;AAAA,EACrB;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,QAAM,iBAAiB,kBAAkB,QAAQ,MAAM;AACvD,QAAM,MAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,KAAK,OAAO,CAAA;AAAA,IACZ,MAAM,QAAQ,CAAA;AAAA,IACd,OAAO;AAAA,EAAA;AAET,QAAM,OAAO,mBAAmB,QAAQ,OAAO,UAAU,KAAK,aAAa,EAAE,WAAA,IAAe,MAAS;AAErG,SACE,qBAAC,OAAA,EAAI,WAAU,aACZ,UAAA;AAAA,IAAA,SAAS,oBAAC,MAAA,EAAG,WAAU,yBAAyB,UAAA,OAAM;AAAA,IACvD,oBAAC,OAAA,EAAI,WAAW,GAAG,eAAe,SAAS,WAAW,eAAe,YAAY,GAAI,UAAA,KAAA,CAAK;AAAA,EAAA,GAC5F;AAEJ;"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
require("react");
|
|
5
|
+
const Icon = require("../data/Icon.cjs");
|
|
6
|
+
const button = require("./button.cjs");
|
|
7
|
+
const jsonSchemaFormFields = require("./json-schema-form-fields.cjs");
|
|
8
|
+
const jsonSchemaFormResolve = require("./json-schema-form-resolve.cjs");
|
|
9
|
+
const jsonSchemaFormRender = require("./json-schema-form-render.cjs");
|
|
10
|
+
const UiAdd = require("../icons/components/UiAdd.cjs");
|
|
11
|
+
const UiClose = require("../icons/components/UiClose.cjs");
|
|
12
|
+
const UiChevronUp = require("../icons/components/UiChevronUp.cjs");
|
|
13
|
+
const UiChevronDown = require("../icons/components/UiChevronDown.cjs");
|
|
14
|
+
const UiTrash = require("../icons/components/UiTrash.cjs");
|
|
15
|
+
function ArrayControl({
|
|
16
|
+
field,
|
|
17
|
+
fieldId,
|
|
18
|
+
ctx
|
|
19
|
+
}) {
|
|
20
|
+
const readOnly = ctx.readOnly || field.readOnly === true;
|
|
21
|
+
if (jsonSchemaFormResolve.isScalarStringItems(field.itemSchema)) {
|
|
22
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TagArray, { field, fieldId, readOnly });
|
|
23
|
+
}
|
|
24
|
+
const items = Array.isArray(field.value) ? field.value : [];
|
|
25
|
+
const itemSchema = field.itemSchema ?? { type: "string" };
|
|
26
|
+
const childCtx = { ...ctx, readOnly, depth: ctx.depth + 1 };
|
|
27
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 rounded-md border border-input p-2", children: [
|
|
28
|
+
items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[1fr_auto] items-start gap-2", children: [
|
|
29
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: jsonSchemaFormRender.renderFieldRow(
|
|
30
|
+
{
|
|
31
|
+
key: `${field.key}[${i}]`,
|
|
32
|
+
prop: itemSchema,
|
|
33
|
+
required: false,
|
|
34
|
+
value: item,
|
|
35
|
+
onChange: (next) => field.onChange(jsonSchemaFormRender.setIndex(items, i, next))
|
|
36
|
+
},
|
|
37
|
+
childCtx,
|
|
38
|
+
{ labelOverride: `Item ${i + 1}` }
|
|
39
|
+
) }),
|
|
40
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
41
|
+
ItemControls,
|
|
42
|
+
{
|
|
43
|
+
onUp: i > 0 ? () => field.onChange(jsonSchemaFormRender.moveItem(items, i, i - 1)) : void 0,
|
|
44
|
+
onDown: i < items.length - 1 ? () => field.onChange(jsonSchemaFormRender.moveItem(items, i, i + 1)) : void 0,
|
|
45
|
+
onRemove: () => field.onChange(jsonSchemaFormRender.removeIndex(items, i)),
|
|
46
|
+
index: i
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
] }, i)),
|
|
50
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
51
|
+
button.Button,
|
|
52
|
+
{
|
|
53
|
+
type: "button",
|
|
54
|
+
variant: "outline",
|
|
55
|
+
size: "sm",
|
|
56
|
+
className: "gap-1.5",
|
|
57
|
+
onClick: () => field.onChange([...items, jsonSchemaFormRender.seedFromSchema(itemSchema)]),
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiAdd.UiAdd, className: "text-sm" }),
|
|
60
|
+
"Add item"
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
] });
|
|
65
|
+
}
|
|
66
|
+
function ItemControls({
|
|
67
|
+
onUp,
|
|
68
|
+
onDown,
|
|
69
|
+
onRemove,
|
|
70
|
+
index
|
|
71
|
+
}) {
|
|
72
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
74
|
+
"button",
|
|
75
|
+
{
|
|
76
|
+
type: "button",
|
|
77
|
+
"aria-label": `Move item ${index + 1} up`,
|
|
78
|
+
disabled: !onUp,
|
|
79
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30",
|
|
80
|
+
onClick: onUp,
|
|
81
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiChevronUp.UiChevronUp, className: "text-sm" })
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85
|
+
"button",
|
|
86
|
+
{
|
|
87
|
+
type: "button",
|
|
88
|
+
"aria-label": `Move item ${index + 1} down`,
|
|
89
|
+
disabled: !onDown,
|
|
90
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30",
|
|
91
|
+
onClick: onDown,
|
|
92
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiChevronDown.UiChevronDown, className: "text-sm" })
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
96
|
+
"button",
|
|
97
|
+
{
|
|
98
|
+
type: "button",
|
|
99
|
+
"aria-label": `Remove item ${index + 1}`,
|
|
100
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
101
|
+
onClick: onRemove,
|
|
102
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiTrash.UiTrash, className: "text-sm" })
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
] });
|
|
106
|
+
}
|
|
107
|
+
function TagArray({
|
|
108
|
+
field,
|
|
109
|
+
fieldId,
|
|
110
|
+
readOnly
|
|
111
|
+
}) {
|
|
112
|
+
const tags = toStringArray(field.value);
|
|
113
|
+
function commit(raw, input) {
|
|
114
|
+
const next = raw.split(",").map((p) => p.trim()).filter(Boolean);
|
|
115
|
+
if (next.length === 0) return;
|
|
116
|
+
field.onChange([...tags, ...next]);
|
|
117
|
+
input.value = "";
|
|
118
|
+
}
|
|
119
|
+
function handleKeyDown(e) {
|
|
120
|
+
const input = e.currentTarget;
|
|
121
|
+
if (e.key === "Enter" || e.key === ",") {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
commit(input.value, input);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (e.key === "Backspace" && input.value === "" && tags.length > 0) {
|
|
127
|
+
field.onChange(tags.slice(0, -1));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm", children: [
|
|
131
|
+
tags.map((tag, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
132
|
+
"span",
|
|
133
|
+
{
|
|
134
|
+
className: "inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted px-2 text-xs",
|
|
135
|
+
children: [
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: tag }),
|
|
137
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
138
|
+
"button",
|
|
139
|
+
{
|
|
140
|
+
type: "button",
|
|
141
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
142
|
+
"aria-label": `Remove ${tag}`,
|
|
143
|
+
onClick: () => field.onChange(tags.filter((_, idx) => idx !== i)),
|
|
144
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClose.UiClose })
|
|
145
|
+
}
|
|
146
|
+
)
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
`${tag}-${i}`
|
|
150
|
+
)),
|
|
151
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
152
|
+
"input",
|
|
153
|
+
{
|
|
154
|
+
id: fieldId,
|
|
155
|
+
"data-jsf-input": true,
|
|
156
|
+
className: "min-w-32 flex-1 bg-transparent px-1 py-1 text-sm outline-none",
|
|
157
|
+
placeholder: tags.length === 0 ? jsonSchemaFormFields.defaultPlaceholder(field.schema) : "",
|
|
158
|
+
onKeyDown: handleKeyDown,
|
|
159
|
+
onBlur: (e) => commit(e.currentTarget.value, e.currentTarget)
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
] });
|
|
163
|
+
}
|
|
164
|
+
function toStringArray(value) {
|
|
165
|
+
if (Array.isArray(value)) return value.map(String);
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
exports.ArrayControl = ArrayControl;
|
|
169
|
+
//# sourceMappingURL=json-schema-form-array.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-array.cjs","sources":["../../src/components/json-schema-form-array.tsx"],"sourcesContent":["import { type KeyboardEvent } from \"react\";\nimport { Icon } from \"../data/Icon\";\nimport { UiAdd, UiChevronDown, UiChevronUp, UiClose, UiTrash } from \"../icons\";\nimport { Button } from \"./button\";\nimport { defaultPlaceholder } from \"./json-schema-form-fields\";\nimport { isScalarStringItems } from \"./json-schema-form-resolve\";\nimport {\n moveItem,\n removeIndex,\n renderFieldRow,\n seedFromSchema,\n setIndex,\n type RenderContext,\n} from \"./json-schema-form-render\";\nimport type { FieldControl } from \"./json-schema-form-types\";\n\n// ArrayControl is a hybrid: plain string-item arrays keep the compact tag UI;\n// anything richer (objects, numbers, enums, nested arrays) renders one recursive\n// control per item with add / remove / reorder.\nexport function ArrayControl({\n field,\n fieldId,\n ctx,\n}: {\n field: FieldControl;\n fieldId: string;\n ctx: RenderContext;\n}) {\n // A read-only array marks its whole subtree non-editable: no add/remove/reorder\n // and item inputs disabled (a child the schema marks readOnly still renders as\n // a value span).\n const readOnly = ctx.readOnly || field.readOnly === true;\n if (isScalarStringItems(field.itemSchema)) {\n return <TagArray field={field} fieldId={fieldId} readOnly={readOnly} />;\n }\n const items = Array.isArray(field.value) ? field.value : [];\n const itemSchema = field.itemSchema ?? { type: \"string\" };\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n\n return (\n <div className=\"space-y-2 rounded-md border border-input p-2\">\n {items.map((item, i) => (\n <div key={i} className=\"grid grid-cols-[1fr_auto] items-start gap-2\">\n <div className=\"min-w-0\">\n {renderFieldRow(\n {\n key: `${field.key}[${i}]`,\n prop: itemSchema,\n required: false,\n value: item,\n onChange: (next) => field.onChange(setIndex(items, i, next)),\n },\n childCtx,\n { labelOverride: `Item ${i + 1}` },\n )}\n </div>\n {!readOnly && (\n <ItemControls\n onUp={i > 0 ? () => field.onChange(moveItem(items, i, i - 1)) : undefined}\n onDown={i < items.length - 1 ? () => field.onChange(moveItem(items, i, i + 1)) : undefined}\n onRemove={() => field.onChange(removeIndex(items, i))}\n index={i}\n />\n )}\n </div>\n ))}\n {!readOnly && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n onClick={() => field.onChange([...items, seedFromSchema(itemSchema)])}\n >\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add item\n </Button>\n )}\n </div>\n );\n}\n\nfunction ItemControls({\n onUp,\n onDown,\n onRemove,\n index,\n}: {\n onUp: (() => void) | undefined;\n onDown: (() => void) | undefined;\n onRemove: () => void;\n index: number;\n}) {\n return (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n aria-label={`Move item ${index + 1} up`}\n disabled={!onUp}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30\"\n onClick={onUp}\n >\n <Icon icon={UiChevronUp} className=\"text-sm\" />\n </button>\n <button\n type=\"button\"\n aria-label={`Move item ${index + 1} down`}\n disabled={!onDown}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30\"\n onClick={onDown}\n >\n <Icon icon={UiChevronDown} className=\"text-sm\" />\n </button>\n <button\n type=\"button\"\n aria-label={`Remove item ${index + 1}`}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground\"\n onClick={onRemove}\n >\n <Icon icon={UiTrash} className=\"text-sm\" />\n </button>\n </div>\n );\n}\n\n// TagArray is the compact tag editor for plain string-item arrays.\nfunction TagArray({\n field,\n fieldId,\n readOnly,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n}) {\n const tags = toStringArray(field.value);\n\n function commit(raw: string, input: HTMLInputElement) {\n const next = raw\n .split(\",\")\n .map((p) => p.trim())\n .filter(Boolean);\n if (next.length === 0) return;\n field.onChange([...tags, ...next]);\n input.value = \"\";\n }\n\n function handleKeyDown(e: KeyboardEvent<HTMLInputElement>) {\n const input = e.currentTarget;\n if (e.key === \"Enter\" || e.key === \",\") {\n e.preventDefault();\n commit(input.value, input);\n return;\n }\n if (e.key === \"Backspace\" && input.value === \"\" && tags.length > 0) {\n field.onChange(tags.slice(0, -1));\n }\n }\n\n return (\n <div className=\"flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\">\n {tags.map((tag, i) => (\n <span\n key={`${tag}-${i}`}\n className=\"inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted px-2 text-xs\"\n >\n <span className=\"truncate\">{tag}</span>\n {!readOnly && (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground\"\n aria-label={`Remove ${tag}`}\n onClick={() => field.onChange(tags.filter((_, idx) => idx !== i))}\n >\n <Icon icon={UiClose} />\n </button>\n )}\n </span>\n ))}\n {!readOnly && (\n <input\n id={fieldId}\n data-jsf-input\n className=\"min-w-32 flex-1 bg-transparent px-1 py-1 text-sm outline-none\"\n placeholder={tags.length === 0 ? defaultPlaceholder(field.schema) : \"\"}\n onKeyDown={handleKeyDown}\n onBlur={(e) => commit(e.currentTarget.value, e.currentTarget)}\n />\n )}\n </div>\n );\n}\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) return value.map(String);\n return [];\n}\n"],"names":["isScalarStringItems","jsx","jsxs","renderFieldRow","setIndex","moveItem","removeIndex","Button","seedFromSchema","Icon","UiAdd","UiChevronUp","UiChevronDown","UiTrash","UiClose","defaultPlaceholder"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RenderContext } from './json-schema-form-render';
|
|
2
|
+
import { FieldControl } from './json-schema-form-types';
|
|
3
|
+
export declare function ArrayControl({ field, fieldId, ctx, }: {
|
|
4
|
+
field: FieldControl;
|
|
5
|
+
fieldId: string;
|
|
6
|
+
ctx: RenderContext;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=json-schema-form-array.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-array.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-array.tsx"],"names":[],"mappings":"AAMA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAK7D,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,aAAa,CAAC;CACpB,2CAqDA"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import { Icon } from "../data/Icon.js";
|
|
4
|
+
import { Button } from "./button.js";
|
|
5
|
+
import { defaultPlaceholder } from "./json-schema-form-fields.js";
|
|
6
|
+
import { isScalarStringItems } from "./json-schema-form-resolve.js";
|
|
7
|
+
import { renderFieldRow, setIndex, removeIndex, moveItem, seedFromSchema } from "./json-schema-form-render.js";
|
|
8
|
+
import { UiAdd } from "../icons/components/UiAdd.js";
|
|
9
|
+
import { UiClose } from "../icons/components/UiClose.js";
|
|
10
|
+
import { UiChevronUp } from "../icons/components/UiChevronUp.js";
|
|
11
|
+
import { UiChevronDown } from "../icons/components/UiChevronDown.js";
|
|
12
|
+
import { UiTrash } from "../icons/components/UiTrash.js";
|
|
13
|
+
function ArrayControl({
|
|
14
|
+
field,
|
|
15
|
+
fieldId,
|
|
16
|
+
ctx
|
|
17
|
+
}) {
|
|
18
|
+
const readOnly = ctx.readOnly || field.readOnly === true;
|
|
19
|
+
if (isScalarStringItems(field.itemSchema)) {
|
|
20
|
+
return /* @__PURE__ */ jsx(TagArray, { field, fieldId, readOnly });
|
|
21
|
+
}
|
|
22
|
+
const items = Array.isArray(field.value) ? field.value : [];
|
|
23
|
+
const itemSchema = field.itemSchema ?? { type: "string" };
|
|
24
|
+
const childCtx = { ...ctx, readOnly, depth: ctx.depth + 1 };
|
|
25
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2 rounded-md border border-input p-2", children: [
|
|
26
|
+
items.map((item, i) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_auto] items-start gap-2", children: [
|
|
27
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: renderFieldRow(
|
|
28
|
+
{
|
|
29
|
+
key: `${field.key}[${i}]`,
|
|
30
|
+
prop: itemSchema,
|
|
31
|
+
required: false,
|
|
32
|
+
value: item,
|
|
33
|
+
onChange: (next) => field.onChange(setIndex(items, i, next))
|
|
34
|
+
},
|
|
35
|
+
childCtx,
|
|
36
|
+
{ labelOverride: `Item ${i + 1}` }
|
|
37
|
+
) }),
|
|
38
|
+
!readOnly && /* @__PURE__ */ jsx(
|
|
39
|
+
ItemControls,
|
|
40
|
+
{
|
|
41
|
+
onUp: i > 0 ? () => field.onChange(moveItem(items, i, i - 1)) : void 0,
|
|
42
|
+
onDown: i < items.length - 1 ? () => field.onChange(moveItem(items, i, i + 1)) : void 0,
|
|
43
|
+
onRemove: () => field.onChange(removeIndex(items, i)),
|
|
44
|
+
index: i
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
] }, i)),
|
|
48
|
+
!readOnly && /* @__PURE__ */ jsxs(
|
|
49
|
+
Button,
|
|
50
|
+
{
|
|
51
|
+
type: "button",
|
|
52
|
+
variant: "outline",
|
|
53
|
+
size: "sm",
|
|
54
|
+
className: "gap-1.5",
|
|
55
|
+
onClick: () => field.onChange([...items, seedFromSchema(itemSchema)]),
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ jsx(Icon, { icon: UiAdd, className: "text-sm" }),
|
|
58
|
+
"Add item"
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
function ItemControls({
|
|
65
|
+
onUp,
|
|
66
|
+
onDown,
|
|
67
|
+
onRemove,
|
|
68
|
+
index
|
|
69
|
+
}) {
|
|
70
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
"button",
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
"aria-label": `Move item ${index + 1} up`,
|
|
76
|
+
disabled: !onUp,
|
|
77
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30",
|
|
78
|
+
onClick: onUp,
|
|
79
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiChevronUp, className: "text-sm" })
|
|
80
|
+
}
|
|
81
|
+
),
|
|
82
|
+
/* @__PURE__ */ jsx(
|
|
83
|
+
"button",
|
|
84
|
+
{
|
|
85
|
+
type: "button",
|
|
86
|
+
"aria-label": `Move item ${index + 1} down`,
|
|
87
|
+
disabled: !onDown,
|
|
88
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30",
|
|
89
|
+
onClick: onDown,
|
|
90
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiChevronDown, className: "text-sm" })
|
|
91
|
+
}
|
|
92
|
+
),
|
|
93
|
+
/* @__PURE__ */ jsx(
|
|
94
|
+
"button",
|
|
95
|
+
{
|
|
96
|
+
type: "button",
|
|
97
|
+
"aria-label": `Remove item ${index + 1}`,
|
|
98
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
99
|
+
onClick: onRemove,
|
|
100
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiTrash, className: "text-sm" })
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
] });
|
|
104
|
+
}
|
|
105
|
+
function TagArray({
|
|
106
|
+
field,
|
|
107
|
+
fieldId,
|
|
108
|
+
readOnly
|
|
109
|
+
}) {
|
|
110
|
+
const tags = toStringArray(field.value);
|
|
111
|
+
function commit(raw, input) {
|
|
112
|
+
const next = raw.split(",").map((p) => p.trim()).filter(Boolean);
|
|
113
|
+
if (next.length === 0) return;
|
|
114
|
+
field.onChange([...tags, ...next]);
|
|
115
|
+
input.value = "";
|
|
116
|
+
}
|
|
117
|
+
function handleKeyDown(e) {
|
|
118
|
+
const input = e.currentTarget;
|
|
119
|
+
if (e.key === "Enter" || e.key === ",") {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
commit(input.value, input);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (e.key === "Backspace" && input.value === "" && tags.length > 0) {
|
|
125
|
+
field.onChange(tags.slice(0, -1));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm", children: [
|
|
129
|
+
tags.map((tag, i) => /* @__PURE__ */ jsxs(
|
|
130
|
+
"span",
|
|
131
|
+
{
|
|
132
|
+
className: "inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted px-2 text-xs",
|
|
133
|
+
children: [
|
|
134
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: tag }),
|
|
135
|
+
!readOnly && /* @__PURE__ */ jsx(
|
|
136
|
+
"button",
|
|
137
|
+
{
|
|
138
|
+
type: "button",
|
|
139
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
140
|
+
"aria-label": `Remove ${tag}`,
|
|
141
|
+
onClick: () => field.onChange(tags.filter((_, idx) => idx !== i)),
|
|
142
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiClose })
|
|
143
|
+
}
|
|
144
|
+
)
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
`${tag}-${i}`
|
|
148
|
+
)),
|
|
149
|
+
!readOnly && /* @__PURE__ */ jsx(
|
|
150
|
+
"input",
|
|
151
|
+
{
|
|
152
|
+
id: fieldId,
|
|
153
|
+
"data-jsf-input": true,
|
|
154
|
+
className: "min-w-32 flex-1 bg-transparent px-1 py-1 text-sm outline-none",
|
|
155
|
+
placeholder: tags.length === 0 ? defaultPlaceholder(field.schema) : "",
|
|
156
|
+
onKeyDown: handleKeyDown,
|
|
157
|
+
onBlur: (e) => commit(e.currentTarget.value, e.currentTarget)
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
] });
|
|
161
|
+
}
|
|
162
|
+
function toStringArray(value) {
|
|
163
|
+
if (Array.isArray(value)) return value.map(String);
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
export {
|
|
167
|
+
ArrayControl
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=json-schema-form-array.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-array.js","sources":["../../src/components/json-schema-form-array.tsx"],"sourcesContent":["import { type KeyboardEvent } from \"react\";\nimport { Icon } from \"../data/Icon\";\nimport { UiAdd, UiChevronDown, UiChevronUp, UiClose, UiTrash } from \"../icons\";\nimport { Button } from \"./button\";\nimport { defaultPlaceholder } from \"./json-schema-form-fields\";\nimport { isScalarStringItems } from \"./json-schema-form-resolve\";\nimport {\n moveItem,\n removeIndex,\n renderFieldRow,\n seedFromSchema,\n setIndex,\n type RenderContext,\n} from \"./json-schema-form-render\";\nimport type { FieldControl } from \"./json-schema-form-types\";\n\n// ArrayControl is a hybrid: plain string-item arrays keep the compact tag UI;\n// anything richer (objects, numbers, enums, nested arrays) renders one recursive\n// control per item with add / remove / reorder.\nexport function ArrayControl({\n field,\n fieldId,\n ctx,\n}: {\n field: FieldControl;\n fieldId: string;\n ctx: RenderContext;\n}) {\n // A read-only array marks its whole subtree non-editable: no add/remove/reorder\n // and item inputs disabled (a child the schema marks readOnly still renders as\n // a value span).\n const readOnly = ctx.readOnly || field.readOnly === true;\n if (isScalarStringItems(field.itemSchema)) {\n return <TagArray field={field} fieldId={fieldId} readOnly={readOnly} />;\n }\n const items = Array.isArray(field.value) ? field.value : [];\n const itemSchema = field.itemSchema ?? { type: \"string\" };\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n\n return (\n <div className=\"space-y-2 rounded-md border border-input p-2\">\n {items.map((item, i) => (\n <div key={i} className=\"grid grid-cols-[1fr_auto] items-start gap-2\">\n <div className=\"min-w-0\">\n {renderFieldRow(\n {\n key: `${field.key}[${i}]`,\n prop: itemSchema,\n required: false,\n value: item,\n onChange: (next) => field.onChange(setIndex(items, i, next)),\n },\n childCtx,\n { labelOverride: `Item ${i + 1}` },\n )}\n </div>\n {!readOnly && (\n <ItemControls\n onUp={i > 0 ? () => field.onChange(moveItem(items, i, i - 1)) : undefined}\n onDown={i < items.length - 1 ? () => field.onChange(moveItem(items, i, i + 1)) : undefined}\n onRemove={() => field.onChange(removeIndex(items, i))}\n index={i}\n />\n )}\n </div>\n ))}\n {!readOnly && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"gap-1.5\"\n onClick={() => field.onChange([...items, seedFromSchema(itemSchema)])}\n >\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add item\n </Button>\n )}\n </div>\n );\n}\n\nfunction ItemControls({\n onUp,\n onDown,\n onRemove,\n index,\n}: {\n onUp: (() => void) | undefined;\n onDown: (() => void) | undefined;\n onRemove: () => void;\n index: number;\n}) {\n return (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n aria-label={`Move item ${index + 1} up`}\n disabled={!onUp}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30\"\n onClick={onUp}\n >\n <Icon icon={UiChevronUp} className=\"text-sm\" />\n </button>\n <button\n type=\"button\"\n aria-label={`Move item ${index + 1} down`}\n disabled={!onDown}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground disabled:opacity-30\"\n onClick={onDown}\n >\n <Icon icon={UiChevronDown} className=\"text-sm\" />\n </button>\n <button\n type=\"button\"\n aria-label={`Remove item ${index + 1}`}\n className=\"inline-flex h-8 w-8 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground\"\n onClick={onRemove}\n >\n <Icon icon={UiTrash} className=\"text-sm\" />\n </button>\n </div>\n );\n}\n\n// TagArray is the compact tag editor for plain string-item arrays.\nfunction TagArray({\n field,\n fieldId,\n readOnly,\n}: {\n field: FieldControl;\n fieldId: string;\n readOnly: boolean;\n}) {\n const tags = toStringArray(field.value);\n\n function commit(raw: string, input: HTMLInputElement) {\n const next = raw\n .split(\",\")\n .map((p) => p.trim())\n .filter(Boolean);\n if (next.length === 0) return;\n field.onChange([...tags, ...next]);\n input.value = \"\";\n }\n\n function handleKeyDown(e: KeyboardEvent<HTMLInputElement>) {\n const input = e.currentTarget;\n if (e.key === \"Enter\" || e.key === \",\") {\n e.preventDefault();\n commit(input.value, input);\n return;\n }\n if (e.key === \"Backspace\" && input.value === \"\" && tags.length > 0) {\n field.onChange(tags.slice(0, -1));\n }\n }\n\n return (\n <div className=\"flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1 shadow-sm\">\n {tags.map((tag, i) => (\n <span\n key={`${tag}-${i}`}\n className=\"inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted px-2 text-xs\"\n >\n <span className=\"truncate\">{tag}</span>\n {!readOnly && (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground\"\n aria-label={`Remove ${tag}`}\n onClick={() => field.onChange(tags.filter((_, idx) => idx !== i))}\n >\n <Icon icon={UiClose} />\n </button>\n )}\n </span>\n ))}\n {!readOnly && (\n <input\n id={fieldId}\n data-jsf-input\n className=\"min-w-32 flex-1 bg-transparent px-1 py-1 text-sm outline-none\"\n placeholder={tags.length === 0 ? defaultPlaceholder(field.schema) : \"\"}\n onKeyDown={handleKeyDown}\n onBlur={(e) => commit(e.currentTarget.value, e.currentTarget)}\n />\n )}\n </div>\n );\n}\n\nfunction toStringArray(value: unknown): string[] {\n if (Array.isArray(value)) return value.map(String);\n return [];\n}\n"],"names":[],"mappings":"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"}
|