@dxos/react-ui-form 0.7.5-feature-compute.4d9d99a → 0.7.5-labs.401163d
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/lib/browser/index.mjs +881 -556
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +910 -596
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +881 -556
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts +16 -0
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -0
- package/dist/types/src/components/Form/Defaults.d.ts +6 -6
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +12 -21
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +2 -1
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts +7 -0
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormContent.d.ts +26 -0
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormContext.d.ts +23 -0
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -0
- package/dist/types/src/components/Form/Input.d.ts +5 -6
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -2
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +4 -0
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +7 -0
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +1 -2
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/index.d.ts +1 -0
- package/dist/types/src/components/Form/custom/index.d.ts.map +1 -1
- package/dist/types/src/components/Form/factory.d.ts +2 -2
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts +2 -0
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts +5 -0
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +10 -10
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +6 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -24
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/FieldEditor/FieldEditor.tsx +7 -6
- package/src/components/Form/ArrayField.tsx +111 -0
- package/src/components/Form/Defaults.tsx +78 -36
- package/src/components/Form/Form.stories.tsx +15 -5
- package/src/components/Form/Form.tsx +50 -355
- package/src/components/Form/FormActions.tsx +41 -0
- package/src/components/Form/FormContent.tsx +170 -0
- package/src/components/Form/FormContext.tsx +92 -0
- package/src/components/Form/Input.tsx +5 -6
- package/src/components/Form/custom/GeoPointInput.tsx +6 -15
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +58 -0
- package/src/components/Form/custom/SelectOptionsInput.tsx +190 -0
- package/src/components/Form/custom/TupleInput.tsx +5 -9
- package/src/components/Form/custom/index.ts +1 -0
- package/src/components/Form/factory.tsx +5 -6
- package/src/components/Form/index.ts +3 -0
- package/src/components/ViewEditor/ViewEditor.tsx +7 -4
- package/src/components/deprecated/FormInput.tsx +20 -7
- package/src/hooks/useForm.ts +60 -47
- package/src/translations.ts +8 -0
|
@@ -37,6 +37,7 @@ var translations_default = [
|
|
|
37
37
|
"format ref": "Reference",
|
|
38
38
|
"format regex": "RegExp",
|
|
39
39
|
"format string": "String",
|
|
40
|
+
"format single-select": "Select",
|
|
40
41
|
"format text": "Long text",
|
|
41
42
|
"format time": "Time",
|
|
42
43
|
"format timestamp": "Timestamp",
|
|
@@ -46,7 +47,13 @@ var translations_default = [
|
|
|
46
47
|
"format uuid": "UUID",
|
|
47
48
|
// Placeholders
|
|
48
49
|
"placeholder latitude": "Latitude",
|
|
49
|
-
"placeholder longitude": "Longitude"
|
|
50
|
+
"placeholder longitude": "Longitude",
|
|
51
|
+
// SelectOptionsInput
|
|
52
|
+
"select option label": "Label",
|
|
53
|
+
"select option label placeholder": "Option label",
|
|
54
|
+
"select option color": "Color",
|
|
55
|
+
"select option delete": "Delete",
|
|
56
|
+
"select option add": "Add option"
|
|
50
57
|
}
|
|
51
58
|
}
|
|
52
59
|
}
|
|
@@ -55,6 +62,16 @@ var translations_default = [
|
|
|
55
62
|
// packages/ui/react-ui-form/src/components/deprecated/FormInput.tsx
|
|
56
63
|
import React from "react";
|
|
57
64
|
import { Input } from "@dxos/react-ui";
|
|
65
|
+
import { mx, textBlockWidth } from "@dxos/react-ui-theme";
|
|
66
|
+
var DeprecatedFormContainer = ({ children, classNames }) => {
|
|
67
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
68
|
+
role: "none",
|
|
69
|
+
className: "w-full p-4 justify-center overflow-x-hidden overflow-y-auto"
|
|
70
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
71
|
+
role: "form",
|
|
72
|
+
className: mx("flex flex-col", textBlockWidth, classNames)
|
|
73
|
+
}, children));
|
|
74
|
+
};
|
|
58
75
|
var DeprecatedFormInput = ({ label, description, secondary, children }) => {
|
|
59
76
|
const primary = /* @__PURE__ */ React.createElement("div", {
|
|
60
77
|
role: "none",
|
|
@@ -63,220 +80,43 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
|
|
|
63
80
|
role: "none",
|
|
64
81
|
className: "flex flex-col w-full"
|
|
65
82
|
}, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
66
|
-
classNames: "flex min-
|
|
83
|
+
classNames: "flex min-bs-[--rail-action] items-center",
|
|
84
|
+
style: {
|
|
85
|
+
fontSize: "unset"
|
|
86
|
+
}
|
|
67
87
|
}, label), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, {
|
|
68
88
|
classNames: "mbs-0.5"
|
|
69
89
|
}, /* @__PURE__ */ React.createElement(Input.Description, null, description))), /* @__PURE__ */ React.createElement("div", {
|
|
70
90
|
role: "none"
|
|
71
91
|
}, /* @__PURE__ */ React.createElement("div", {
|
|
72
92
|
role: "none",
|
|
73
|
-
className: "flex min-
|
|
93
|
+
className: "flex min-bs-[--rail-action] items-center"
|
|
74
94
|
}, children))));
|
|
75
95
|
if (secondary) {
|
|
76
96
|
return /* @__PURE__ */ React.createElement("div", {
|
|
77
|
-
role: "none"
|
|
78
|
-
className: "flex flex-col w-full"
|
|
97
|
+
role: "none"
|
|
79
98
|
}, primary, secondary);
|
|
80
99
|
}
|
|
81
100
|
return primary;
|
|
82
101
|
};
|
|
83
102
|
|
|
84
103
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
85
|
-
import
|
|
104
|
+
import React12, { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useState as useState3 } from "react";
|
|
86
105
|
import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
|
|
87
|
-
import { log as log3 } from "@dxos/log";
|
|
88
|
-
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
89
|
-
import { getFormatSchema, getSchemaProperties as getSchemaProperties2, sortProperties } from "@dxos/schema";
|
|
90
|
-
|
|
91
|
-
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
92
|
-
import React3 from "react";
|
|
93
|
-
import { Input as Input2, useTranslation } from "@dxos/react-ui";
|
|
94
|
-
import { safeParseFloat } from "@dxos/util";
|
|
95
|
-
|
|
96
|
-
// packages/ui/react-ui-form/src/components/Form/Input.tsx
|
|
97
|
-
import React2 from "react";
|
|
98
|
-
import { Icon, Tooltip } from "@dxos/react-ui";
|
|
99
|
-
import { errorText } from "@dxos/react-ui-theme";
|
|
100
|
-
var InputHeader = ({ children, error }) => {
|
|
101
|
-
return /* @__PURE__ */ React2.createElement("div", {
|
|
102
|
-
role: "none",
|
|
103
|
-
className: "flex justify-between items-center mb-1"
|
|
104
|
-
}, children, error && /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
105
|
-
asChild: true
|
|
106
|
-
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
107
|
-
icon: "ph--warning--regular",
|
|
108
|
-
size: 4,
|
|
109
|
-
classNames: errorText
|
|
110
|
-
})), /* @__PURE__ */ React2.createElement(Tooltip.Content, {
|
|
111
|
-
side: "bottom"
|
|
112
|
-
}, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null), error)));
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
116
|
-
var GeoPointInput = ({ property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
117
|
-
const { t } = useTranslation(translationKey);
|
|
118
|
-
const { status, error } = getStatus?.(property);
|
|
119
|
-
const [lng = 0, lat = 0] = getValue2(property) ?? [];
|
|
120
|
-
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
121
|
-
validationValence: status
|
|
122
|
-
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
123
|
-
error
|
|
124
|
-
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement("div", {
|
|
125
|
-
className: "grid grid-cols-2 gap-2"
|
|
126
|
-
}, /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
127
|
-
type: "number",
|
|
128
|
-
disabled,
|
|
129
|
-
placeholder: t("placeholder longitude"),
|
|
130
|
-
value: lng,
|
|
131
|
-
onChange: (event) => onValueChange(property, type, [
|
|
132
|
-
lat,
|
|
133
|
-
safeParseFloat(event.target.value, 0)
|
|
134
|
-
]),
|
|
135
|
-
onBlur
|
|
136
|
-
}), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
137
|
-
type: "number",
|
|
138
|
-
disabled,
|
|
139
|
-
placeholder: t("placeholder latitude"),
|
|
140
|
-
value: lat,
|
|
141
|
-
onChange: (event) => onValueChange(property, type, [
|
|
142
|
-
safeParseFloat(event.target.value, 0),
|
|
143
|
-
lng
|
|
144
|
-
]),
|
|
145
|
-
onBlur
|
|
146
|
-
})));
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// packages/ui/react-ui-form/src/components/Form/custom/TupleInput.tsx
|
|
150
|
-
import React4 from "react";
|
|
151
|
-
import { Input as Input3 } from "@dxos/react-ui";
|
|
152
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
153
|
-
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
154
|
-
var gridCols = [
|
|
155
|
-
"grid-cols-1",
|
|
156
|
-
"grid-cols-2",
|
|
157
|
-
"grid-cols-3",
|
|
158
|
-
"grid-cols-4"
|
|
159
|
-
];
|
|
160
|
-
var TupleInput = ({ binding, property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
161
|
-
const { status, error } = getStatus?.(property);
|
|
162
|
-
const values = getValue2(property) ?? {};
|
|
163
|
-
return /* @__PURE__ */ React4.createElement(Input3.Root, {
|
|
164
|
-
validationValence: status
|
|
165
|
-
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
166
|
-
error
|
|
167
|
-
}, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
168
|
-
className: mx("grid gap-2", gridCols[binding.length - 1])
|
|
169
|
-
}, binding.map((prop) => /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
170
|
-
key: prop,
|
|
171
|
-
type: "number",
|
|
172
|
-
disabled,
|
|
173
|
-
value: values[prop],
|
|
174
|
-
onChange: (event) => onValueChange(property, type, {
|
|
175
|
-
...values,
|
|
176
|
-
[prop]: safeParseFloat2(event.target.value, 0)
|
|
177
|
-
}),
|
|
178
|
-
onBlur
|
|
179
|
-
}))));
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
183
|
-
import React5 from "react";
|
|
184
|
-
import { Input as Input4, Select } from "@dxos/react-ui";
|
|
185
|
-
var TextInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
186
|
-
const { status, error } = getStatus?.(property);
|
|
187
|
-
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
188
|
-
validationValence: status
|
|
189
|
-
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
190
|
-
error
|
|
191
|
-
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Input4.TextInput, {
|
|
192
|
-
disabled,
|
|
193
|
-
placeholder,
|
|
194
|
-
value: getValue2(property) ?? "",
|
|
195
|
-
onChange: (event) => onValueChange(property, type, event.target.value),
|
|
196
|
-
onBlur
|
|
197
|
-
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.Validation, null, error));
|
|
198
|
-
};
|
|
199
|
-
var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
200
|
-
const { status, error } = getStatus?.(property);
|
|
201
|
-
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
202
|
-
validationValence: status
|
|
203
|
-
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
204
|
-
error
|
|
205
|
-
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Input4.TextInput, {
|
|
206
|
-
type: "number",
|
|
207
|
-
disabled,
|
|
208
|
-
placeholder,
|
|
209
|
-
value: getValue2(property) ?? 0,
|
|
210
|
-
onChange: (event) => onValueChange(property, type, event.target.value),
|
|
211
|
-
onBlur
|
|
212
|
-
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
213
|
-
};
|
|
214
|
-
var BooleanInput = ({ property, type, label, inputOnly, getStatus, getValue: getValue2, onValueChange }) => {
|
|
215
|
-
const { status, error } = getStatus?.(property);
|
|
216
|
-
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
217
|
-
validationValence: status
|
|
218
|
-
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
219
|
-
error
|
|
220
|
-
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Input4.Switch, {
|
|
221
|
-
checked: getValue2(property),
|
|
222
|
-
onCheckedChange: (value) => onValueChange(property, type, value)
|
|
223
|
-
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
224
|
-
};
|
|
225
|
-
var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue2, onValueChange }) => {
|
|
226
|
-
const { status, error } = getStatus?.(property);
|
|
227
|
-
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
228
|
-
validationValence: status
|
|
229
|
-
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
230
|
-
error
|
|
231
|
-
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Select.Root, {
|
|
232
|
-
value: getValue2(property),
|
|
233
|
-
onValueChange: (value) => onValueChange(property, type, value)
|
|
234
|
-
}, /* @__PURE__ */ React5.createElement(Select.TriggerButton, {
|
|
235
|
-
classNames: "is-full",
|
|
236
|
-
disabled,
|
|
237
|
-
placeholder
|
|
238
|
-
}), /* @__PURE__ */ React5.createElement(Select.Portal, null, /* @__PURE__ */ React5.createElement(Select.Content, null, /* @__PURE__ */ React5.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
239
|
-
// NOTE: Numeric values are converted to and from strings.
|
|
240
|
-
/* @__PURE__ */ React5.createElement(Select.Option, {
|
|
241
|
-
key: String(value),
|
|
242
|
-
value: String(value)
|
|
243
|
-
}, label2 ?? String(value))
|
|
244
|
-
)))))), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
248
|
-
import { pipe } from "effect";
|
|
249
|
-
import { capitalize } from "effect/String";
|
|
250
|
-
import React6, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
251
|
-
import { AST as AST2, S } from "@dxos/echo-schema";
|
|
252
|
-
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
253
106
|
import { log as log2 } from "@dxos/log";
|
|
254
|
-
import {
|
|
255
|
-
import {
|
|
256
|
-
import { getSchemaProperties } from "@dxos/schema";
|
|
257
|
-
import { isNotFalsy } from "@dxos/util";
|
|
107
|
+
import { useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
108
|
+
import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
|
|
258
109
|
|
|
259
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
260
|
-
import {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return GeoPointInput;
|
|
265
|
-
}
|
|
266
|
-
switch (type) {
|
|
267
|
-
case "string":
|
|
268
|
-
return TextInput;
|
|
269
|
-
case "number":
|
|
270
|
-
return NumberInput;
|
|
271
|
-
case "boolean":
|
|
272
|
-
return BooleanInput;
|
|
273
|
-
}
|
|
274
|
-
};
|
|
110
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
111
|
+
import React2, { createContext, useContext, useEffect as useEffect2 } from "react";
|
|
112
|
+
import { raise } from "@dxos/debug";
|
|
113
|
+
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
114
|
+
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
275
115
|
|
|
276
116
|
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
277
117
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
278
118
|
import { getValue, setValue } from "@dxos/echo-schema";
|
|
279
|
-
import { AST } from "@dxos/effect";
|
|
119
|
+
import { AST, createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
280
120
|
import { invariant } from "@dxos/invariant";
|
|
281
121
|
import { log } from "@dxos/log";
|
|
282
122
|
import { validateSchema } from "@dxos/schema";
|
|
@@ -284,7 +124,7 @@ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/ho
|
|
|
284
124
|
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
285
125
|
invariant(AST.isTypeLiteral(schema.ast), void 0, {
|
|
286
126
|
F: __dxlog_file,
|
|
287
|
-
L:
|
|
127
|
+
L: 92,
|
|
288
128
|
S: void 0,
|
|
289
129
|
A: [
|
|
290
130
|
"AST.isTypeLiteral(schema.ast)",
|
|
@@ -327,8 +167,13 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
327
167
|
values,
|
|
328
168
|
schemaDirty
|
|
329
169
|
]);
|
|
330
|
-
const
|
|
331
|
-
|
|
170
|
+
const formIsValid = useMemo(() => {
|
|
171
|
+
return Object.keys(errors).length === 0;
|
|
172
|
+
}, [
|
|
173
|
+
errors
|
|
174
|
+
]);
|
|
175
|
+
const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors
|
|
176
|
+
!Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
|
|
332
177
|
touched,
|
|
333
178
|
errors,
|
|
334
179
|
saving
|
|
@@ -350,17 +195,21 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
350
195
|
onSave,
|
|
351
196
|
changed
|
|
352
197
|
]);
|
|
353
|
-
const getStatus = useCallback((
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
198
|
+
const getStatus = useCallback((path) => {
|
|
199
|
+
const jsonPath = Array.isArray(path) ? createJsonPath(path) : path;
|
|
200
|
+
const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
|
|
201
|
+
return {
|
|
202
|
+
status: matchingError ? "error" : void 0,
|
|
203
|
+
error: matchingError ? matchingError[1] : void 0
|
|
204
|
+
};
|
|
205
|
+
}, [
|
|
358
206
|
errors
|
|
359
207
|
]);
|
|
360
|
-
const getFormValue = (
|
|
361
|
-
return getValue(values,
|
|
208
|
+
const getFormValue = (path) => {
|
|
209
|
+
return getValue(values, createJsonPath(path));
|
|
362
210
|
};
|
|
363
|
-
const onValueChange = (
|
|
211
|
+
const onValueChange = (path, type, value) => {
|
|
212
|
+
const jsonPath = createJsonPath(path);
|
|
364
213
|
let parsedValue = value;
|
|
365
214
|
try {
|
|
366
215
|
if (type === "number") {
|
|
@@ -369,19 +218,19 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
369
218
|
} catch (err) {
|
|
370
219
|
log.catch(err, void 0, {
|
|
371
220
|
F: __dxlog_file,
|
|
372
|
-
L:
|
|
221
|
+
L: 198,
|
|
373
222
|
S: void 0,
|
|
374
223
|
C: (f, a) => f(...a)
|
|
375
224
|
});
|
|
376
225
|
parsedValue = void 0;
|
|
377
226
|
}
|
|
378
227
|
const newValues = {
|
|
379
|
-
...setValue(values,
|
|
228
|
+
...setValue(values, jsonPath, parsedValue)
|
|
380
229
|
};
|
|
381
230
|
setValues(newValues);
|
|
382
231
|
setChanged((prev) => ({
|
|
383
232
|
...prev,
|
|
384
|
-
[
|
|
233
|
+
[jsonPath]: true
|
|
385
234
|
}));
|
|
386
235
|
onValuesChanged?.(newValues);
|
|
387
236
|
const isValid = validate(newValues);
|
|
@@ -391,15 +240,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
391
240
|
});
|
|
392
241
|
}
|
|
393
242
|
};
|
|
394
|
-
const
|
|
395
|
-
const
|
|
243
|
+
const onTouched = useCallback((path) => {
|
|
244
|
+
const jsonPath = createJsonPath(path);
|
|
396
245
|
setTouched((touched2) => ({
|
|
397
246
|
...touched2,
|
|
398
|
-
[
|
|
247
|
+
[jsonPath]: true
|
|
399
248
|
}));
|
|
400
|
-
if (event.relatedTarget?.getAttribute("type") === "submit") {
|
|
401
|
-
setTouched(createKeySet(values, true));
|
|
402
|
-
}
|
|
403
249
|
validate(values);
|
|
404
250
|
}, [
|
|
405
251
|
validate,
|
|
@@ -413,17 +259,18 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
413
259
|
changed,
|
|
414
260
|
canSave,
|
|
415
261
|
handleSave,
|
|
262
|
+
formIsValid,
|
|
416
263
|
// Field utils.
|
|
417
264
|
getStatus,
|
|
418
265
|
getValue: getFormValue,
|
|
419
266
|
onValueChange,
|
|
420
|
-
|
|
267
|
+
onTouched
|
|
421
268
|
};
|
|
422
269
|
};
|
|
423
270
|
var createKeySet = (obj, value) => {
|
|
424
271
|
invariant(obj, void 0, {
|
|
425
272
|
F: __dxlog_file,
|
|
426
|
-
L:
|
|
273
|
+
L: 241,
|
|
427
274
|
S: void 0,
|
|
428
275
|
A: [
|
|
429
276
|
"obj",
|
|
@@ -437,338 +284,809 @@ var createKeySet = (obj, value) => {
|
|
|
437
284
|
};
|
|
438
285
|
var flatMap = (errors) => {
|
|
439
286
|
return errors.reduce((result, { path, message }) => {
|
|
440
|
-
|
|
441
|
-
|
|
287
|
+
const jsonPath = fromEffectValidationPath(path);
|
|
288
|
+
if (!(jsonPath in result)) {
|
|
289
|
+
result[jsonPath] = message;
|
|
442
290
|
}
|
|
443
291
|
return result;
|
|
444
292
|
}, {});
|
|
445
293
|
};
|
|
446
294
|
|
|
447
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
448
|
-
var
|
|
449
|
-
var
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
295
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
296
|
+
var FormContext = /* @__PURE__ */ createContext(void 0);
|
|
297
|
+
var useFormContext = () => {
|
|
298
|
+
return useContext(FormContext) ?? raise(new Error("Missing FormContext"));
|
|
299
|
+
};
|
|
300
|
+
var useFormValues = (path = []) => {
|
|
301
|
+
const { values: formValues } = useFormContext();
|
|
302
|
+
const jsonPath = createJsonPath2(path);
|
|
303
|
+
return getValue2(formValues, jsonPath);
|
|
304
|
+
};
|
|
305
|
+
var useInputProps = (path = []) => {
|
|
306
|
+
const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
|
|
307
|
+
return {
|
|
308
|
+
getStatus: () => getStatus(path),
|
|
309
|
+
getValue: () => getFormValue(path),
|
|
310
|
+
onValueChange: (type, value) => onValueChange(path, type, value),
|
|
311
|
+
onBlur: () => onTouched(path)
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
315
|
+
const form = useForm(formOptions);
|
|
316
|
+
useEffect2(() => {
|
|
317
|
+
if (!formRef?.current) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const handleKeyDown = (event) => {
|
|
321
|
+
const keyIsEnter = event.key === "Enter";
|
|
322
|
+
const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
|
|
323
|
+
const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
|
|
324
|
+
const inputOptOut = event.target.hasAttribute("data-no-submit");
|
|
325
|
+
const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
|
|
326
|
+
const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
|
|
327
|
+
if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
|
|
328
|
+
if (!autoSave && form.canSave) {
|
|
329
|
+
form.handleSave();
|
|
330
|
+
}
|
|
331
|
+
if (autoSave && form.formIsValid) {
|
|
332
|
+
event.target.blur();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
469
335
|
};
|
|
470
|
-
|
|
336
|
+
const formElement = formRef.current;
|
|
337
|
+
formElement.addEventListener("keydown", handleKeyDown);
|
|
338
|
+
return () => formElement.removeEventListener("keydown", handleKeyDown);
|
|
471
339
|
}, [
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
340
|
+
formRef,
|
|
341
|
+
form.canSave,
|
|
342
|
+
form.formIsValid,
|
|
343
|
+
form.handleSave,
|
|
344
|
+
autoSave
|
|
475
345
|
]);
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
346
|
+
return /* @__PURE__ */ React2.createElement(FormContext.Provider, {
|
|
347
|
+
value: form
|
|
348
|
+
}, children);
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
352
|
+
import React4 from "react";
|
|
353
|
+
import { Input as Input2, useTranslation } from "@dxos/react-ui";
|
|
354
|
+
import { safeParseFloat } from "@dxos/util";
|
|
355
|
+
|
|
356
|
+
// packages/ui/react-ui-form/src/components/Form/Input.tsx
|
|
357
|
+
import React3 from "react";
|
|
358
|
+
import { Icon, Tooltip } from "@dxos/react-ui";
|
|
359
|
+
import { errorText } from "@dxos/react-ui-theme";
|
|
360
|
+
var InputHeader = ({ children, error }) => {
|
|
361
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
362
|
+
role: "none",
|
|
363
|
+
className: "flex justify-between items-center mb-1"
|
|
364
|
+
}, children, error && /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
|
365
|
+
asChild: true
|
|
366
|
+
}, /* @__PURE__ */ React3.createElement(Icon, {
|
|
367
|
+
icon: "ph--warning--regular",
|
|
368
|
+
size: 4,
|
|
369
|
+
classNames: errorText
|
|
370
|
+
})), /* @__PURE__ */ React3.createElement(Tooltip.Content, {
|
|
371
|
+
side: "bottom"
|
|
372
|
+
}, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null), error)));
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
376
|
+
var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
377
|
+
const { t } = useTranslation(translationKey);
|
|
378
|
+
const { status, error } = getStatus();
|
|
379
|
+
const [lng = 0, lat = 0] = getValue3() ?? [];
|
|
380
|
+
return /* @__PURE__ */ React4.createElement(Input2.Root, {
|
|
381
|
+
validationValence: status
|
|
382
|
+
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
383
|
+
error
|
|
384
|
+
}, /* @__PURE__ */ React4.createElement(Input2.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
385
|
+
className: "grid grid-cols-2 gap-2"
|
|
386
|
+
}, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
387
|
+
type: "number",
|
|
388
|
+
disabled,
|
|
389
|
+
placeholder: t("placeholder longitude"),
|
|
390
|
+
value: lng,
|
|
391
|
+
onChange: (event) => onValueChange(type, [
|
|
392
|
+
lat,
|
|
393
|
+
safeParseFloat(event.target.value, 0)
|
|
394
|
+
]),
|
|
395
|
+
onBlur
|
|
396
|
+
}), /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
397
|
+
type: "number",
|
|
398
|
+
disabled,
|
|
399
|
+
placeholder: t("placeholder latitude"),
|
|
400
|
+
value: lat,
|
|
401
|
+
onChange: (event) => onValueChange(type, [
|
|
402
|
+
safeParseFloat(event.target.value, 0),
|
|
403
|
+
lng
|
|
404
|
+
]),
|
|
405
|
+
onBlur
|
|
406
|
+
})));
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
// packages/ui/react-ui-form/src/components/Form/custom/SelectOptionsInput.tsx
|
|
410
|
+
import React5, { useCallback as useCallback2, useEffect as useEffect3, useState as useState2, useRef } from "react";
|
|
411
|
+
import { PublicKey } from "@dxos/keys";
|
|
412
|
+
import { Icon as Icon2, IconButton, Input as Input3, Tag, Toolbar, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
413
|
+
import { List } from "@dxos/react-ui-list";
|
|
414
|
+
import { HuePickerToolbarButton } from "@dxos/react-ui-pickers";
|
|
415
|
+
import { hues, mx as mx2 } from "@dxos/react-ui-theme";
|
|
416
|
+
var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
|
|
417
|
+
const [selected, setSelectedId] = useState2(null);
|
|
418
|
+
const [isNewOption, setIsNewOption] = useState2(false);
|
|
419
|
+
const inputRef = useRef(null);
|
|
420
|
+
const { t } = useTranslation2(translationKey);
|
|
421
|
+
const { status, error } = getStatus();
|
|
422
|
+
const options = getValue3();
|
|
423
|
+
useEffect3(() => {
|
|
424
|
+
if (options === void 0) {
|
|
425
|
+
onValueChange(type, []);
|
|
486
426
|
}
|
|
487
427
|
}, [
|
|
488
|
-
|
|
428
|
+
options,
|
|
429
|
+
onValueChange,
|
|
430
|
+
type
|
|
489
431
|
]);
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
|
|
432
|
+
const randomHue = () => {
|
|
433
|
+
const usedHues = new Set(options?.map((option) => option.color) ?? []);
|
|
434
|
+
const unusedHues = hues.filter((hue) => !usedHues.has(hue));
|
|
435
|
+
if (unusedHues.length > 0) {
|
|
436
|
+
return unusedHues[Math.floor(Math.random() * unusedHues.length)];
|
|
437
|
+
}
|
|
438
|
+
const lastThree = new Set(options?.slice(-3).map((option) => option.color) ?? []);
|
|
439
|
+
const availableHues = hues.filter((hue) => !lastThree.has(hue));
|
|
440
|
+
return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hues[Math.floor(Math.random() * hues.length)];
|
|
441
|
+
};
|
|
442
|
+
const handleAdd = useCallback2(() => {
|
|
443
|
+
const newId = PublicKey.random().truncate();
|
|
444
|
+
const newOption = {
|
|
445
|
+
id: newId,
|
|
446
|
+
title: "",
|
|
447
|
+
color: randomHue()
|
|
448
|
+
};
|
|
449
|
+
onValueChange(type, [
|
|
450
|
+
...options ?? [],
|
|
451
|
+
newOption
|
|
452
|
+
]);
|
|
453
|
+
setSelectedId(newId);
|
|
454
|
+
setIsNewOption(true);
|
|
455
|
+
}, [
|
|
456
|
+
options,
|
|
457
|
+
type,
|
|
458
|
+
onValueChange
|
|
459
|
+
]);
|
|
460
|
+
const handleDelete = useCallback2((id) => {
|
|
461
|
+
const newOptions = options?.filter((option) => option.id !== id) ?? [];
|
|
462
|
+
onValueChange(type, newOptions);
|
|
463
|
+
setSelectedId(null);
|
|
464
|
+
}, [
|
|
465
|
+
options,
|
|
466
|
+
type,
|
|
467
|
+
onValueChange
|
|
468
|
+
]);
|
|
469
|
+
const handleMove = useCallback2((from, to) => {
|
|
470
|
+
if (!options) {
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
const newOptions = [
|
|
474
|
+
...options
|
|
499
475
|
];
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
476
|
+
const [removed] = newOptions.splice(from, 1);
|
|
477
|
+
newOptions.splice(to, 0, removed);
|
|
478
|
+
onValueChange(type, newOptions);
|
|
479
|
+
}, [
|
|
480
|
+
options,
|
|
481
|
+
type,
|
|
482
|
+
onValueChange
|
|
483
|
+
]);
|
|
484
|
+
const handleClick = useCallback2((id) => {
|
|
485
|
+
setSelectedId((current) => current === id ? null : id);
|
|
486
|
+
}, []);
|
|
487
|
+
const handleTitleChange = useCallback2((id) => (e) => {
|
|
488
|
+
const newOptions = options?.map((o) => o.id === id ? {
|
|
489
|
+
...o,
|
|
490
|
+
title: e.target.value
|
|
491
|
+
} : o);
|
|
492
|
+
onValueChange(type, newOptions ?? []);
|
|
493
|
+
}, [
|
|
494
|
+
options,
|
|
495
|
+
type,
|
|
496
|
+
onValueChange
|
|
497
|
+
]);
|
|
498
|
+
const handleKeyDown = useCallback2((e) => {
|
|
499
|
+
if (e.key === "Enter") {
|
|
500
|
+
setSelectedId(null);
|
|
521
501
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
})),
|
|
539
|
-
placeholder,
|
|
540
|
-
...inputProps
|
|
541
|
-
}));
|
|
542
|
-
}
|
|
543
|
-
InputComponent = getInputComponent(type, format);
|
|
544
|
-
if (array) {
|
|
545
|
-
return /* @__PURE__ */ React6.createElement(ArrayField, {
|
|
546
|
-
key: name,
|
|
547
|
-
name,
|
|
548
|
-
type,
|
|
549
|
-
array: true,
|
|
550
|
-
label,
|
|
551
|
-
ast,
|
|
552
|
-
values,
|
|
553
|
-
format,
|
|
554
|
-
readonly,
|
|
555
|
-
placeholder,
|
|
556
|
-
inputProps,
|
|
557
|
-
Custom
|
|
558
|
-
});
|
|
559
|
-
}
|
|
502
|
+
}, []);
|
|
503
|
+
const handleColorChange = useCallback2((id) => (hue) => {
|
|
504
|
+
const newOptions = options?.map((o) => o.id === id ? {
|
|
505
|
+
...o,
|
|
506
|
+
color: hue
|
|
507
|
+
} : o);
|
|
508
|
+
onValueChange(type, newOptions ?? []);
|
|
509
|
+
}, [
|
|
510
|
+
options,
|
|
511
|
+
type,
|
|
512
|
+
onValueChange
|
|
513
|
+
]);
|
|
514
|
+
useEffect3(() => {
|
|
515
|
+
if (selected && isNewOption && inputRef.current) {
|
|
516
|
+
inputRef.current.focus();
|
|
517
|
+
setIsNewOption(false);
|
|
560
518
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
519
|
+
}, [
|
|
520
|
+
selected,
|
|
521
|
+
isNewOption
|
|
522
|
+
]);
|
|
523
|
+
return /* @__PURE__ */ React5.createElement(Input3.Root, {
|
|
524
|
+
validationValence: status
|
|
525
|
+
}, /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
526
|
+
error
|
|
527
|
+
}, /* @__PURE__ */ React5.createElement(Input3.Label, null, label)), /* @__PURE__ */ React5.createElement("div", {
|
|
528
|
+
role: "none"
|
|
529
|
+
}, options && /* @__PURE__ */ React5.createElement(List.Root, {
|
|
530
|
+
items: options,
|
|
531
|
+
isItem: (item) => true,
|
|
532
|
+
onMove: handleMove
|
|
533
|
+
}, ({ items }) => /* @__PURE__ */ React5.createElement("div", {
|
|
534
|
+
role: "list",
|
|
535
|
+
className: "w-full overflow-auto"
|
|
536
|
+
}, items?.map((item) => /* @__PURE__ */ React5.createElement("div", {
|
|
537
|
+
key: item.id
|
|
538
|
+
}, /* @__PURE__ */ React5.createElement(List.Item, {
|
|
539
|
+
role: "button",
|
|
540
|
+
item,
|
|
541
|
+
classNames: mx2("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
|
|
542
|
+
"aria-expanded": selected === item.id
|
|
543
|
+
}, /* @__PURE__ */ React5.createElement("div", {
|
|
544
|
+
className: "flex items-center"
|
|
545
|
+
}, /* @__PURE__ */ React5.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React5.createElement(List.ItemTitle, {
|
|
546
|
+
onClick: () => handleClick(item.id),
|
|
547
|
+
classNames: "flex-1"
|
|
548
|
+
}, /* @__PURE__ */ React5.createElement(Tag, {
|
|
549
|
+
palette: item.color
|
|
550
|
+
}, item.title || "\u200B")), /* @__PURE__ */ React5.createElement(Icon2, {
|
|
551
|
+
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
552
|
+
onClick: () => handleClick(item.id)
|
|
553
|
+
})), selected === item.id && /* @__PURE__ */ React5.createElement("div", {
|
|
554
|
+
className: "mis-4 mbs-2 flex flex-col gap-1"
|
|
555
|
+
}, /* @__PURE__ */ React5.createElement(Input3.Label, {
|
|
556
|
+
classNames: "text-xs"
|
|
557
|
+
}, t("select option label")), /* @__PURE__ */ React5.createElement("div", {
|
|
558
|
+
className: "flex flex-row items-center gap-1"
|
|
559
|
+
}, /* @__PURE__ */ React5.createElement(Input3.TextInput, {
|
|
560
|
+
placeholder: t("select option label placeholder"),
|
|
561
|
+
ref: selected === item.id ? inputRef : void 0,
|
|
562
|
+
value: item.title,
|
|
563
|
+
onChange: handleTitleChange(item.id),
|
|
564
|
+
onKeyDown: handleKeyDown,
|
|
565
|
+
classNames: "flex-1",
|
|
566
|
+
"data-no-submit": true
|
|
567
|
+
}), /* @__PURE__ */ React5.createElement(Toolbar.Root, {
|
|
568
|
+
classNames: "p-0 m-0 !is-auto"
|
|
569
|
+
}, /* @__PURE__ */ React5.createElement(HuePickerToolbarButton, {
|
|
570
|
+
hue: item.color,
|
|
571
|
+
onChangeHue: handleColorChange(item.id)
|
|
572
|
+
})), /* @__PURE__ */ React5.createElement(IconButton, {
|
|
573
|
+
icon: "ph--trash--fill",
|
|
574
|
+
iconOnly: true,
|
|
575
|
+
label: t("select option delete"),
|
|
576
|
+
onClick: () => handleDelete(item.id)
|
|
577
|
+
})))))), /* @__PURE__ */ React5.createElement("div", {
|
|
578
|
+
role: "listitem"
|
|
579
|
+
}, /* @__PURE__ */ React5.createElement("div", {
|
|
580
|
+
role: "button",
|
|
581
|
+
className: mx2("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
|
|
582
|
+
onClick: handleAdd
|
|
583
|
+
}, /* @__PURE__ */ React5.createElement("div", {
|
|
584
|
+
className: "flex items-center gap-1"
|
|
585
|
+
}, /* @__PURE__ */ React5.createElement(Icon2, {
|
|
586
|
+
icon: "ph--plus--regular"
|
|
587
|
+
}), /* @__PURE__ */ React5.createElement("span", {
|
|
588
|
+
className: "text-sm"
|
|
589
|
+
}, t("select option add")))))))));
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
// packages/ui/react-ui-form/src/components/Form/custom/TupleInput.tsx
|
|
593
|
+
import React6 from "react";
|
|
594
|
+
import { Input as Input4 } from "@dxos/react-ui";
|
|
595
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
596
|
+
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
597
|
+
var gridCols = [
|
|
598
|
+
"grid-cols-1",
|
|
599
|
+
"grid-cols-2",
|
|
600
|
+
"grid-cols-3",
|
|
601
|
+
"grid-cols-4"
|
|
602
|
+
];
|
|
603
|
+
var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
604
|
+
const { status, error } = getStatus();
|
|
605
|
+
const values = getValue3() ?? {};
|
|
606
|
+
return /* @__PURE__ */ React6.createElement(Input4.Root, {
|
|
607
|
+
validationValence: status
|
|
608
|
+
}, /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
609
|
+
error
|
|
610
|
+
}, /* @__PURE__ */ React6.createElement(Input4.Label, null, label)), /* @__PURE__ */ React6.createElement("div", {
|
|
611
|
+
className: mx3("grid gap-2", gridCols[binding.length - 1])
|
|
612
|
+
}, binding.map((prop) => /* @__PURE__ */ React6.createElement(Input4.TextInput, {
|
|
613
|
+
key: prop,
|
|
614
|
+
type: "number",
|
|
615
|
+
disabled,
|
|
616
|
+
value: values[prop],
|
|
617
|
+
onChange: (event) => onValueChange(type, {
|
|
618
|
+
...values,
|
|
619
|
+
[prop]: safeParseFloat2(event.target.value, 0)
|
|
620
|
+
}),
|
|
621
|
+
onBlur
|
|
622
|
+
}))));
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
626
|
+
import React7, { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
627
|
+
import { Input as Input5, Select } from "@dxos/react-ui";
|
|
628
|
+
var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
629
|
+
const { status, error } = getStatus();
|
|
630
|
+
return /* @__PURE__ */ React7.createElement(Input5.Root, {
|
|
631
|
+
validationValence: status
|
|
632
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
633
|
+
error
|
|
634
|
+
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Input5.TextInput, {
|
|
635
|
+
disabled,
|
|
636
|
+
placeholder,
|
|
637
|
+
value: getValue3() ?? "",
|
|
638
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
639
|
+
onBlur
|
|
640
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input5.Validation, null, error));
|
|
641
|
+
};
|
|
642
|
+
var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
643
|
+
const { status, error } = getStatus();
|
|
644
|
+
return /* @__PURE__ */ React7.createElement(Input5.Root, {
|
|
645
|
+
validationValence: status
|
|
646
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
647
|
+
error
|
|
648
|
+
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Input5.TextInput, {
|
|
649
|
+
type: "number",
|
|
650
|
+
disabled,
|
|
651
|
+
placeholder,
|
|
652
|
+
value: getValue3() ?? 0,
|
|
653
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
654
|
+
onBlur
|
|
655
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input5.DescriptionAndValidation, null, error));
|
|
656
|
+
};
|
|
657
|
+
var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
|
|
658
|
+
const { status, error } = getStatus();
|
|
659
|
+
const checked = Boolean(getValue3());
|
|
660
|
+
return /* @__PURE__ */ React7.createElement(Input5.Root, {
|
|
661
|
+
validationValence: status
|
|
662
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
663
|
+
error
|
|
664
|
+
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Input5.Switch, {
|
|
665
|
+
checked,
|
|
666
|
+
onCheckedChange: (value) => onValueChange(type, value)
|
|
667
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input5.DescriptionAndValidation, null, error));
|
|
668
|
+
};
|
|
669
|
+
var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
|
|
670
|
+
const { status, error } = getStatus();
|
|
671
|
+
return /* @__PURE__ */ React7.createElement(Input5.Root, {
|
|
672
|
+
validationValence: status
|
|
673
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
674
|
+
error
|
|
675
|
+
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Select.Root, {
|
|
676
|
+
value: getValue3(),
|
|
677
|
+
onValueChange: (value) => onValueChange(type, value)
|
|
678
|
+
}, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
|
|
679
|
+
classNames: "is-full",
|
|
680
|
+
disabled,
|
|
681
|
+
placeholder
|
|
682
|
+
}), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
683
|
+
// NOTE: Numeric values are converted to and from strings.
|
|
684
|
+
/* @__PURE__ */ React7.createElement(Select.Option, {
|
|
685
|
+
key: String(value),
|
|
686
|
+
value: String(value)
|
|
687
|
+
}, label2 ?? String(value))
|
|
688
|
+
)))))), inputOnly && /* @__PURE__ */ React7.createElement(Input5.DescriptionAndValidation, null, error));
|
|
689
|
+
};
|
|
690
|
+
var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
691
|
+
const { status, error } = getStatus();
|
|
692
|
+
const textareaRef = useRef2(null);
|
|
693
|
+
const adjustHeight = useCallback3(() => {
|
|
694
|
+
const textarea = textareaRef.current;
|
|
695
|
+
if (textarea) {
|
|
696
|
+
textarea.style.blockSize = "auto";
|
|
697
|
+
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
593
698
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
699
|
+
}, []);
|
|
700
|
+
useEffect4(() => {
|
|
701
|
+
adjustHeight();
|
|
702
|
+
}, [
|
|
703
|
+
adjustHeight
|
|
704
|
+
]);
|
|
705
|
+
useEffect4(() => {
|
|
706
|
+
adjustHeight();
|
|
707
|
+
}, [
|
|
708
|
+
getValue3(),
|
|
709
|
+
adjustHeight
|
|
710
|
+
]);
|
|
711
|
+
return /* @__PURE__ */ React7.createElement(Input5.Root, {
|
|
712
|
+
validationValence: status
|
|
713
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
714
|
+
error
|
|
715
|
+
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Input5.TextArea, {
|
|
716
|
+
ref: textareaRef,
|
|
717
|
+
disabled,
|
|
718
|
+
placeholder,
|
|
719
|
+
value: getValue3() ?? "",
|
|
720
|
+
classNames: "min-bs-auto overflow-hidden",
|
|
721
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
722
|
+
onBlur,
|
|
723
|
+
style: {
|
|
724
|
+
resize: "none"
|
|
725
|
+
},
|
|
726
|
+
spellCheck: false
|
|
727
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input5.Validation, null, error));
|
|
613
728
|
};
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
729
|
+
|
|
730
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
731
|
+
import React11, { useEffect as useEffect5, useMemo as useMemo4, useRef as useRef3 } from "react";
|
|
732
|
+
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
733
|
+
|
|
734
|
+
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
735
|
+
import React8 from "react";
|
|
736
|
+
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
737
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
|
738
|
+
var FormActions = ({ onCancel, readonly }) => {
|
|
739
|
+
const { t } = useTranslation3(translationKey);
|
|
740
|
+
const { canSave, handleSave } = useFormContext();
|
|
741
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
742
|
+
role: "none",
|
|
743
|
+
className: "mt-2 flex justify-center"
|
|
744
|
+
}, /* @__PURE__ */ React8.createElement("div", {
|
|
745
|
+
role: "none",
|
|
746
|
+
className: mx4(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
747
|
+
}, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
748
|
+
"data-testid": "cancel-button",
|
|
749
|
+
icon: "ph--x--regular",
|
|
750
|
+
label: t("button cancel"),
|
|
751
|
+
onClick: onCancel
|
|
752
|
+
}), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
753
|
+
type: "submit",
|
|
754
|
+
"data-testid": "save-button",
|
|
755
|
+
disabled: !canSave,
|
|
756
|
+
icon: "ph--check--regular",
|
|
757
|
+
label: t("button save"),
|
|
758
|
+
onClick: handleSave
|
|
759
|
+
})));
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
763
|
+
import { pipe as pipe2 } from "effect";
|
|
764
|
+
import { capitalize as capitalize2 } from "effect/String";
|
|
765
|
+
import React10, { useMemo as useMemo3 } from "react";
|
|
766
|
+
import { AST as AST3, S } from "@dxos/echo-schema";
|
|
767
|
+
import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
768
|
+
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
769
|
+
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
770
|
+
import { isNotFalsy } from "@dxos/util";
|
|
771
|
+
|
|
772
|
+
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
773
|
+
import { pipe } from "effect";
|
|
774
|
+
import { capitalize } from "effect/String";
|
|
775
|
+
import React9, { useCallback as useCallback4, useMemo as useMemo2 } from "react";
|
|
776
|
+
import { AST as AST2 } from "@dxos/echo-schema";
|
|
777
|
+
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
778
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
779
|
+
import { IconButton as IconButton3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
780
|
+
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
781
|
+
import { getSchemaProperties } from "@dxos/schema";
|
|
782
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
783
|
+
var padding = "px-2";
|
|
784
|
+
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
785
|
+
const { t } = useTranslation4(translationKey);
|
|
786
|
+
const { ast, name, type, title } = property;
|
|
787
|
+
const values = useFormValues(path ?? []);
|
|
788
|
+
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
789
|
+
F: __dxlog_file2,
|
|
790
|
+
L: 37,
|
|
791
|
+
S: void 0,
|
|
792
|
+
A: [
|
|
793
|
+
"Array.isArray(values)",
|
|
794
|
+
"`Values at path ${path?.join('.')} must be an array.`"
|
|
795
|
+
]
|
|
796
|
+
});
|
|
797
|
+
const label = title ?? pipe(name, capitalize);
|
|
620
798
|
const tupleType = findNode(ast, AST2.isTupleType);
|
|
621
799
|
const elementType = tupleType?.rest[0]?.type;
|
|
622
|
-
|
|
623
|
-
const baseNode = findNode(
|
|
624
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode,
|
|
625
|
-
if (typeLiteral) {
|
|
626
|
-
|
|
627
|
-
return /* @__PURE__ */ React6.createElement("div", {
|
|
628
|
-
key: name,
|
|
629
|
-
role: "none",
|
|
630
|
-
className: mx2(padding)
|
|
631
|
-
}, /* @__PURE__ */ React6.createElement(InputHeader, null, label), /* @__PURE__ */ React6.createElement("div", {
|
|
632
|
-
role: "none",
|
|
633
|
-
className: "flex flex-col gap-1"
|
|
634
|
-
}, arrayValues.map((value, index) => {
|
|
635
|
-
return /* @__PURE__ */ React6.createElement("div", {
|
|
636
|
-
key: index,
|
|
637
|
-
role: "none",
|
|
638
|
-
className: "flex items-center gap-1"
|
|
639
|
-
}, /* @__PURE__ */ React6.createElement("div", {
|
|
640
|
-
role: "none",
|
|
641
|
-
className: "flex-1"
|
|
642
|
-
}, /* @__PURE__ */ React6.createElement(Form, {
|
|
643
|
-
schema,
|
|
644
|
-
path: [
|
|
645
|
-
...key,
|
|
646
|
-
`[${index}]`
|
|
647
|
-
],
|
|
648
|
-
values: value,
|
|
649
|
-
onValuesChanged: (childValues) => {
|
|
650
|
-
const newValues = [
|
|
651
|
-
...arrayValues
|
|
652
|
-
];
|
|
653
|
-
newValues[index] = childValues;
|
|
654
|
-
inputProps.onValueChange(name, "object", newValues);
|
|
655
|
-
},
|
|
656
|
-
Custom
|
|
657
|
-
})), /* @__PURE__ */ React6.createElement(IconButton, {
|
|
658
|
-
icon: "ph--trash--regular",
|
|
659
|
-
iconOnly: true,
|
|
660
|
-
label: t("button remove"),
|
|
661
|
-
onClick: () => {
|
|
662
|
-
const newValues = arrayValues.filter((_, i) => i !== index);
|
|
663
|
-
inputProps.onValueChange(name, type, newValues);
|
|
664
|
-
}
|
|
665
|
-
}));
|
|
666
|
-
})), /* @__PURE__ */ React6.createElement("div", {
|
|
667
|
-
role: "none",
|
|
668
|
-
className: "flex justify-between items-center plb-1"
|
|
669
|
-
}, /* @__PURE__ */ React6.createElement(IconButton, {
|
|
670
|
-
icon: "ph--plus--regular",
|
|
671
|
-
iconOnly: true,
|
|
672
|
-
label: t("button add"),
|
|
673
|
-
onClick: () => {
|
|
674
|
-
const newValues = [
|
|
675
|
-
...arrayValues,
|
|
676
|
-
{}
|
|
677
|
-
];
|
|
678
|
-
inputProps.onValueChange(name, type, newValues);
|
|
679
|
-
}
|
|
680
|
-
})));
|
|
800
|
+
const getDefaultObjectValue = (typeNode) => {
|
|
801
|
+
const baseNode = findNode(typeNode, isDiscriminatedUnion);
|
|
802
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, AST2.isTypeLiteral);
|
|
803
|
+
if (!typeLiteral) {
|
|
804
|
+
return {};
|
|
681
805
|
}
|
|
682
|
-
return
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
}
|
|
687
|
-
const
|
|
688
|
-
|
|
806
|
+
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
|
|
807
|
+
prop.name,
|
|
808
|
+
prop.defaultValue
|
|
809
|
+
]));
|
|
810
|
+
};
|
|
811
|
+
const newValue = useMemo2(() => {
|
|
812
|
+
if (type === "object" && elementType) {
|
|
813
|
+
return getDefaultObjectValue(elementType);
|
|
814
|
+
} else {
|
|
815
|
+
return SimpleType.getDefaultValue(type);
|
|
816
|
+
}
|
|
817
|
+
}, [
|
|
818
|
+
type,
|
|
819
|
+
elementType
|
|
820
|
+
]);
|
|
821
|
+
const handleAdd = useCallback4(() => {
|
|
822
|
+
inputProps.onValueChange(type, [
|
|
823
|
+
...values,
|
|
824
|
+
newValue
|
|
825
|
+
]);
|
|
826
|
+
}, [
|
|
827
|
+
type,
|
|
828
|
+
elementType,
|
|
829
|
+
inputProps,
|
|
830
|
+
newValue,
|
|
831
|
+
values
|
|
832
|
+
]);
|
|
833
|
+
const handleRemove = useCallback4((index) => {
|
|
834
|
+
const newValues = values.filter((_, i) => i !== index);
|
|
835
|
+
inputProps.onValueChange(type, newValues);
|
|
836
|
+
}, [
|
|
837
|
+
type,
|
|
838
|
+
inputProps,
|
|
839
|
+
values
|
|
840
|
+
]);
|
|
841
|
+
if (!elementType) {
|
|
689
842
|
return null;
|
|
690
843
|
}
|
|
691
|
-
return /* @__PURE__ */
|
|
844
|
+
return /* @__PURE__ */ React9.createElement("div", {
|
|
692
845
|
role: "none",
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
}, /* @__PURE__ */ React6.createElement(InputHeader, null, label), /* @__PURE__ */ React6.createElement("div", {
|
|
846
|
+
className: mx5(padding)
|
|
847
|
+
}, /* @__PURE__ */ React9.createElement(InputHeader, null, label), /* @__PURE__ */ React9.createElement("div", {
|
|
696
848
|
role: "none",
|
|
697
849
|
className: "flex flex-col gap-1"
|
|
698
|
-
},
|
|
850
|
+
}, values.map((_value, index) => /* @__PURE__ */ React9.createElement("div", {
|
|
699
851
|
key: index,
|
|
700
852
|
role: "none",
|
|
701
|
-
className: "flex items-
|
|
702
|
-
}, /* @__PURE__ */
|
|
853
|
+
className: "flex items-center gap-1"
|
|
854
|
+
}, /* @__PURE__ */ React9.createElement("div", {
|
|
703
855
|
role: "none",
|
|
704
856
|
className: "flex-1"
|
|
705
|
-
}, /* @__PURE__ */
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
857
|
+
}, /* @__PURE__ */ React9.createElement(FormField, {
|
|
858
|
+
property: {
|
|
859
|
+
...property,
|
|
860
|
+
array: false,
|
|
861
|
+
ast: elementType
|
|
862
|
+
},
|
|
863
|
+
path: [
|
|
864
|
+
...path ?? [],
|
|
865
|
+
index
|
|
866
|
+
],
|
|
867
|
+
readonly,
|
|
868
|
+
inline: true,
|
|
869
|
+
Custom,
|
|
870
|
+
lookupComponent
|
|
871
|
+
})), /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
715
872
|
icon: "ph--trash--regular",
|
|
716
873
|
iconOnly: true,
|
|
717
874
|
label: t("button remove"),
|
|
718
|
-
onClick: () =>
|
|
719
|
-
|
|
720
|
-
inputProps.onValueChange(name, type, newValues);
|
|
721
|
-
}
|
|
722
|
-
})))), /* @__PURE__ */ React6.createElement("div", {
|
|
875
|
+
onClick: () => handleRemove(index)
|
|
876
|
+
})))), /* @__PURE__ */ React9.createElement("div", {
|
|
723
877
|
role: "none",
|
|
724
878
|
className: "flex justify-between items-center plb-1"
|
|
725
|
-
}, /* @__PURE__ */
|
|
879
|
+
}, /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
726
880
|
icon: "ph--plus--regular",
|
|
727
881
|
iconOnly: true,
|
|
728
882
|
label: t("button add"),
|
|
729
|
-
onClick:
|
|
730
|
-
const newValues = [
|
|
731
|
-
...arrayValues,
|
|
732
|
-
SimpleType.getDefaultValue(type)
|
|
733
|
-
];
|
|
734
|
-
inputProps.onValueChange(name, type, newValues);
|
|
735
|
-
}
|
|
883
|
+
onClick: handleAdd
|
|
736
884
|
})));
|
|
737
885
|
};
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
886
|
+
|
|
887
|
+
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
888
|
+
import { FormatEnum } from "@dxos/echo-schema";
|
|
889
|
+
var getInputComponent = (type, format) => {
|
|
890
|
+
switch (format) {
|
|
891
|
+
case FormatEnum.LatLng:
|
|
892
|
+
return GeoPointInput;
|
|
893
|
+
case FormatEnum.Markdown:
|
|
894
|
+
return MarkdownInput;
|
|
895
|
+
}
|
|
896
|
+
switch (type) {
|
|
897
|
+
case "string":
|
|
898
|
+
return TextInput;
|
|
899
|
+
case "number":
|
|
900
|
+
return NumberInput;
|
|
901
|
+
case "boolean":
|
|
902
|
+
return BooleanInput;
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
907
|
+
var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
|
|
908
|
+
const inputProps = useInputProps(path);
|
|
909
|
+
const { ast, name, type, format, title, description, options, examples, array } = property;
|
|
910
|
+
const label = useMemo3(() => title ?? pipe2(name, capitalize2), [
|
|
911
|
+
title,
|
|
912
|
+
name
|
|
913
|
+
]);
|
|
914
|
+
const placeholder = useMemo3(() => examples?.length ? `Example: "${examples[0]}"` : description, [
|
|
915
|
+
examples,
|
|
916
|
+
description
|
|
917
|
+
]);
|
|
918
|
+
const FoundComponent = lookupComponent?.({
|
|
919
|
+
prop: name,
|
|
920
|
+
schema: S.make(ast),
|
|
921
|
+
inputProps: {
|
|
922
|
+
type,
|
|
923
|
+
format,
|
|
924
|
+
label,
|
|
925
|
+
disabled: readonly,
|
|
926
|
+
placeholder,
|
|
927
|
+
...inputProps
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
if (FoundComponent) {
|
|
931
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
932
|
+
role: "none"
|
|
933
|
+
}, FoundComponent);
|
|
934
|
+
}
|
|
935
|
+
const jsonPath = createJsonPath3(path ?? []);
|
|
936
|
+
const CustomComponent = Custom?.[jsonPath];
|
|
937
|
+
if (CustomComponent) {
|
|
938
|
+
return /* @__PURE__ */ React10.createElement(CustomComponent, {
|
|
939
|
+
type,
|
|
940
|
+
format,
|
|
941
|
+
label,
|
|
942
|
+
inputOnly: inline,
|
|
943
|
+
placeholder,
|
|
944
|
+
disabled: readonly,
|
|
945
|
+
...inputProps
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
if (array) {
|
|
949
|
+
return /* @__PURE__ */ React10.createElement(ArrayField, {
|
|
950
|
+
property,
|
|
951
|
+
path,
|
|
952
|
+
inputProps,
|
|
953
|
+
readonly,
|
|
954
|
+
Custom
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
const InputComponent = getInputComponent(type, format);
|
|
958
|
+
if (InputComponent) {
|
|
959
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
960
|
+
role: "none"
|
|
961
|
+
}, /* @__PURE__ */ React10.createElement(InputComponent, {
|
|
962
|
+
type,
|
|
963
|
+
format,
|
|
964
|
+
label,
|
|
965
|
+
inputOnly: inline,
|
|
966
|
+
placeholder,
|
|
967
|
+
disabled: readonly,
|
|
968
|
+
...inputProps
|
|
969
|
+
}));
|
|
970
|
+
}
|
|
971
|
+
if (options) {
|
|
972
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
973
|
+
role: "none"
|
|
974
|
+
}, /* @__PURE__ */ React10.createElement(SelectInput, {
|
|
975
|
+
type,
|
|
976
|
+
format,
|
|
977
|
+
disabled: readonly,
|
|
978
|
+
inputOnly: inline,
|
|
979
|
+
label,
|
|
980
|
+
options: options.map((option) => ({
|
|
981
|
+
value: option,
|
|
982
|
+
label: String(option)
|
|
983
|
+
})),
|
|
984
|
+
placeholder,
|
|
985
|
+
...inputProps
|
|
986
|
+
}));
|
|
987
|
+
}
|
|
988
|
+
if (type === "object") {
|
|
989
|
+
const baseNode = findNode2(ast, isDiscriminatedUnion2);
|
|
990
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
|
|
991
|
+
if (typeLiteral) {
|
|
992
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
993
|
+
role: "none"
|
|
994
|
+
}, !inline && /* @__PURE__ */ React10.createElement("div", null, label), /* @__PURE__ */ React10.createElement(FormFields, {
|
|
995
|
+
schema: S.make(typeLiteral),
|
|
996
|
+
path,
|
|
997
|
+
readonly,
|
|
998
|
+
Custom
|
|
999
|
+
}));
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
return null;
|
|
1003
|
+
};
|
|
1004
|
+
var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
|
|
1005
|
+
const values = useFormValues(path);
|
|
1006
|
+
const properties = useMemo3(() => {
|
|
1007
|
+
const props = getSchemaProperties2(schema.ast, values);
|
|
1008
|
+
const filtered = filter ? filter(props) : props;
|
|
1009
|
+
return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
|
|
1010
|
+
}, [
|
|
1011
|
+
schema,
|
|
1012
|
+
values,
|
|
1013
|
+
filter,
|
|
1014
|
+
sort
|
|
1015
|
+
]);
|
|
1016
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
1017
|
+
role: "form",
|
|
1018
|
+
className: mx6("flex flex-col w-full gap-2")
|
|
1019
|
+
}, properties.map((property) => {
|
|
1020
|
+
return /* @__PURE__ */ React10.createElement(FormField, {
|
|
1021
|
+
key: property.name,
|
|
1022
|
+
property,
|
|
1023
|
+
path: [
|
|
1024
|
+
...path ?? [],
|
|
1025
|
+
property.name
|
|
1026
|
+
],
|
|
1027
|
+
readonly,
|
|
1028
|
+
lookupComponent,
|
|
1029
|
+
Custom
|
|
1030
|
+
});
|
|
1031
|
+
}).filter(isNotFalsy));
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
1035
|
+
var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
1036
|
+
const formRef = useRef3(null);
|
|
1037
|
+
const onValid = useMemo4(() => autoSave ? onSave : void 0, [
|
|
1038
|
+
autoSave,
|
|
1039
|
+
onSave
|
|
1040
|
+
]);
|
|
1041
|
+
useEffect5(() => {
|
|
1042
|
+
if (autoFocus && formRef.current) {
|
|
1043
|
+
const input = formRef.current.querySelector("input");
|
|
1044
|
+
if (input) {
|
|
1045
|
+
input.focus();
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}, [
|
|
1049
|
+
autoFocus
|
|
1050
|
+
]);
|
|
1051
|
+
return /* @__PURE__ */ React11.createElement(FormProvider, {
|
|
1052
|
+
formRef,
|
|
1053
|
+
schema,
|
|
1054
|
+
autoSave,
|
|
1055
|
+
initialValues,
|
|
1056
|
+
onValuesChanged,
|
|
1057
|
+
onValidate,
|
|
1058
|
+
onValid,
|
|
1059
|
+
onSave
|
|
1060
|
+
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1061
|
+
ref: formRef,
|
|
744
1062
|
role: "none",
|
|
745
|
-
className:
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
1063
|
+
className: mx7("p-2", classNames),
|
|
1064
|
+
"data-testid": testId
|
|
1065
|
+
}, /* @__PURE__ */ React11.createElement(FormFields, {
|
|
1066
|
+
schema,
|
|
1067
|
+
path,
|
|
1068
|
+
readonly,
|
|
1069
|
+
filter,
|
|
1070
|
+
sort,
|
|
1071
|
+
lookupComponent,
|
|
1072
|
+
Custom
|
|
1073
|
+
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React11.createElement(FormActions, {
|
|
1074
|
+
onCancel,
|
|
1075
|
+
readonly
|
|
758
1076
|
})));
|
|
759
1077
|
};
|
|
760
1078
|
|
|
761
1079
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
762
1080
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
763
1081
|
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
764
|
-
const { t } =
|
|
765
|
-
const [props, setProps] =
|
|
766
|
-
|
|
1082
|
+
const { t } = useTranslation5(translationKey);
|
|
1083
|
+
const [props, setProps] = useState3(projection.getFieldProjection(field.id).props);
|
|
1084
|
+
useEffect6(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
767
1085
|
field,
|
|
768
1086
|
projection
|
|
769
1087
|
]);
|
|
770
|
-
const [schemas, setSchemas] =
|
|
771
|
-
|
|
1088
|
+
const [schemas, setSchemas] = useState3([]);
|
|
1089
|
+
useEffect6(() => {
|
|
772
1090
|
if (!registry) {
|
|
773
1091
|
return;
|
|
774
1092
|
}
|
|
@@ -786,17 +1104,17 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
786
1104
|
}, [
|
|
787
1105
|
registry
|
|
788
1106
|
]);
|
|
789
|
-
const [referenceSchema, setReferenceSchema] =
|
|
790
|
-
|
|
1107
|
+
const [referenceSchema, setReferenceSchema] = useState3();
|
|
1108
|
+
useEffect6(() => {
|
|
791
1109
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
792
1110
|
}, [
|
|
793
1111
|
schemas,
|
|
794
1112
|
props?.referenceSchema
|
|
795
1113
|
]);
|
|
796
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
1114
|
+
const [{ fieldSchema }, setFieldSchema] = useState3({
|
|
797
1115
|
fieldSchema: getFormatSchema(props?.format)
|
|
798
1116
|
});
|
|
799
|
-
const handleValuesChanged =
|
|
1117
|
+
const handleValuesChanged = useCallback5((_props) => {
|
|
800
1118
|
setFieldSchema((prev) => {
|
|
801
1119
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
802
1120
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -824,14 +1142,14 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
824
1142
|
type
|
|
825
1143
|
};
|
|
826
1144
|
}
|
|
827
|
-
return
|
|
1145
|
+
return _props;
|
|
828
1146
|
});
|
|
829
1147
|
}, [
|
|
830
1148
|
schemas,
|
|
831
1149
|
props.format,
|
|
832
1150
|
props.referenceSchema
|
|
833
1151
|
]);
|
|
834
|
-
const handleValidate =
|
|
1152
|
+
const handleValidate = useCallback5(({ property }) => {
|
|
835
1153
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
836
1154
|
return [
|
|
837
1155
|
{
|
|
@@ -844,7 +1162,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
844
1162
|
view.fields,
|
|
845
1163
|
field
|
|
846
1164
|
]);
|
|
847
|
-
const handleSave =
|
|
1165
|
+
const handleSave = useCallback5((props2) => {
|
|
848
1166
|
projection.setFieldProjection({
|
|
849
1167
|
field,
|
|
850
1168
|
props: props2
|
|
@@ -855,50 +1173,51 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
855
1173
|
field,
|
|
856
1174
|
onSave
|
|
857
1175
|
]);
|
|
858
|
-
const handleCancel =
|
|
1176
|
+
const handleCancel = useCallback5(() => {
|
|
859
1177
|
requestAnimationFrame(() => onCancel?.());
|
|
860
1178
|
onSave();
|
|
861
1179
|
}, [
|
|
862
1180
|
onSave
|
|
863
1181
|
]);
|
|
864
|
-
const Custom =
|
|
865
|
-
["format"]: (props2) => /* @__PURE__ */
|
|
1182
|
+
const Custom = useMemo5(() => ({
|
|
1183
|
+
["format"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
866
1184
|
...props2,
|
|
867
1185
|
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
868
1186
|
value,
|
|
869
1187
|
label: t(`format ${value}`)
|
|
870
1188
|
}))
|
|
871
1189
|
}),
|
|
872
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */
|
|
1190
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
873
1191
|
...props2,
|
|
874
1192
|
options: schemas.map((schema) => ({
|
|
875
1193
|
value: schema.typename
|
|
876
1194
|
}))
|
|
877
1195
|
}),
|
|
878
|
-
["referencePath"]: (props2) => /* @__PURE__ */
|
|
1196
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
879
1197
|
...props2,
|
|
880
|
-
options: referenceSchema ?
|
|
1198
|
+
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
881
1199
|
value: p.name
|
|
882
1200
|
})) : []
|
|
883
|
-
})
|
|
1201
|
+
}),
|
|
1202
|
+
["options"]: (props2) => /* @__PURE__ */ React12.createElement(SelectOptionInput, props2)
|
|
884
1203
|
}), [
|
|
885
1204
|
t,
|
|
886
1205
|
schemas,
|
|
887
1206
|
referenceSchema
|
|
888
1207
|
]);
|
|
889
|
-
const propIsNotType =
|
|
1208
|
+
const propIsNotType = useCallback5((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
890
1209
|
if (!fieldSchema) {
|
|
891
|
-
|
|
1210
|
+
log2.warn("invalid format", {
|
|
892
1211
|
props
|
|
893
1212
|
}, {
|
|
894
1213
|
F: __dxlog_file3,
|
|
895
|
-
L:
|
|
1214
|
+
L: 174,
|
|
896
1215
|
S: void 0,
|
|
897
1216
|
C: (f, a) => f(...a)
|
|
898
1217
|
});
|
|
899
1218
|
return null;
|
|
900
1219
|
}
|
|
901
|
-
return /* @__PURE__ */
|
|
1220
|
+
return /* @__PURE__ */ React12.createElement(Form, {
|
|
902
1221
|
key: field.id,
|
|
903
1222
|
autoFocus: true,
|
|
904
1223
|
values: props,
|
|
@@ -917,30 +1236,29 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
917
1236
|
};
|
|
918
1237
|
|
|
919
1238
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
920
|
-
import
|
|
921
|
-
import { AST as
|
|
922
|
-
import { IconButton as
|
|
923
|
-
import { List } from "@dxos/react-ui-list";
|
|
924
|
-
import { ghostHover, inputTextLabel, mx as
|
|
1239
|
+
import React13, { useCallback as useCallback6, useMemo as useMemo6, useState as useState4 } from "react";
|
|
1240
|
+
import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
|
|
1241
|
+
import { IconButton as IconButton4, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1242
|
+
import { List as List2 } from "@dxos/react-ui-list";
|
|
1243
|
+
import { ghostHover, inputTextLabel, mx as mx8 } from "@dxos/react-ui-theme";
|
|
925
1244
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
926
|
-
import { arrayMove } from "@dxos/util";
|
|
927
1245
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
928
1246
|
var ViewMetaSchema = S2.Struct({
|
|
929
1247
|
name: S2.String.annotations({
|
|
930
|
-
[
|
|
1248
|
+
[AST4.TitleAnnotationId]: "View"
|
|
931
1249
|
}),
|
|
932
|
-
typename: Format.
|
|
933
|
-
[
|
|
1250
|
+
typename: Format.URL.annotations({
|
|
1251
|
+
[AST4.TitleAnnotationId]: "Typename"
|
|
934
1252
|
})
|
|
935
1253
|
}).pipe(S2.mutable);
|
|
936
1254
|
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
937
|
-
const { t } =
|
|
938
|
-
const projection =
|
|
1255
|
+
const { t } = useTranslation6(translationKey);
|
|
1256
|
+
const projection = useMemo6(() => new ViewProjection(schema, view), [
|
|
939
1257
|
schema,
|
|
940
1258
|
view
|
|
941
1259
|
]);
|
|
942
|
-
const [field, setField] =
|
|
943
|
-
const viewValues =
|
|
1260
|
+
const [field, setField] = useState4();
|
|
1261
|
+
const viewValues = useMemo6(() => {
|
|
944
1262
|
return {
|
|
945
1263
|
name: view.name,
|
|
946
1264
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
@@ -950,7 +1268,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
950
1268
|
}, [
|
|
951
1269
|
view
|
|
952
1270
|
]);
|
|
953
|
-
const handleViewUpdate =
|
|
1271
|
+
const handleViewUpdate = useCallback6(({ name, typename }) => {
|
|
954
1272
|
requestAnimationFrame(() => {
|
|
955
1273
|
if (view.name !== name) {
|
|
956
1274
|
view.name = name;
|
|
@@ -964,67 +1282,71 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
964
1282
|
schema,
|
|
965
1283
|
onTypenameChanged
|
|
966
1284
|
]);
|
|
967
|
-
const handleSelect =
|
|
1285
|
+
const handleSelect = useCallback6((field2) => {
|
|
968
1286
|
setField((f) => f === field2 ? void 0 : field2);
|
|
969
1287
|
}, []);
|
|
970
|
-
const handleAdd =
|
|
1288
|
+
const handleAdd = useCallback6(() => {
|
|
971
1289
|
const field2 = projection.createFieldProjection();
|
|
972
1290
|
setField(field2);
|
|
973
1291
|
}, [
|
|
974
1292
|
view
|
|
975
1293
|
]);
|
|
976
|
-
const handleMove =
|
|
977
|
-
|
|
1294
|
+
const handleMove = useCallback6((fromIndex, toIndex) => {
|
|
1295
|
+
const fields = [
|
|
1296
|
+
...view.fields
|
|
1297
|
+
];
|
|
1298
|
+
const [moved] = fields.splice(fromIndex, 1);
|
|
1299
|
+
fields.splice(toIndex, 0, moved);
|
|
1300
|
+
view.fields = fields;
|
|
978
1301
|
}, [
|
|
979
1302
|
view.fields
|
|
980
1303
|
]);
|
|
981
|
-
const handleClose =
|
|
982
|
-
return /* @__PURE__ */
|
|
1304
|
+
const handleClose = useCallback6(() => setField(void 0), []);
|
|
1305
|
+
return /* @__PURE__ */ React13.createElement("div", {
|
|
983
1306
|
role: "none",
|
|
984
|
-
className:
|
|
985
|
-
}, /* @__PURE__ */
|
|
986
|
-
autoFocus: true,
|
|
1307
|
+
className: mx8("flex flex-col w-full divide-y divide-separator", classNames)
|
|
1308
|
+
}, /* @__PURE__ */ React13.createElement(Form, {
|
|
987
1309
|
autoSave: true,
|
|
988
1310
|
schema: ViewMetaSchema,
|
|
989
1311
|
values: viewValues,
|
|
990
1312
|
onSave: handleViewUpdate
|
|
991
|
-
}), /* @__PURE__ */
|
|
1313
|
+
}), /* @__PURE__ */ React13.createElement("div", null, /* @__PURE__ */ React13.createElement("div", {
|
|
992
1314
|
role: "none",
|
|
993
1315
|
className: "p-2"
|
|
994
|
-
}, /* @__PURE__ */
|
|
995
|
-
className:
|
|
996
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
1316
|
+
}, /* @__PURE__ */ React13.createElement("label", {
|
|
1317
|
+
className: mx8(inputTextLabel)
|
|
1318
|
+
}, t("fields label"))), /* @__PURE__ */ React13.createElement(List2.Root, {
|
|
997
1319
|
items: view.fields,
|
|
998
1320
|
isItem: S2.is(FieldSchema),
|
|
999
1321
|
getId: (field2) => field2.id,
|
|
1000
1322
|
onMove: handleMove
|
|
1001
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
1323
|
+
}, ({ items: fields }) => /* @__PURE__ */ React13.createElement(React13.Fragment, null, showHeading && /* @__PURE__ */ React13.createElement("div", {
|
|
1002
1324
|
role: "heading",
|
|
1003
1325
|
className: grid
|
|
1004
|
-
}, /* @__PURE__ */
|
|
1326
|
+
}, /* @__PURE__ */ React13.createElement("div", null), /* @__PURE__ */ React13.createElement("div", {
|
|
1005
1327
|
className: "flex items-center text-sm"
|
|
1006
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
1328
|
+
}, t("field path label"))), /* @__PURE__ */ React13.createElement("div", {
|
|
1007
1329
|
role: "list",
|
|
1008
1330
|
className: "flex flex-col w-full"
|
|
1009
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
1331
|
+
}, fields?.map((field2) => /* @__PURE__ */ React13.createElement(List2.Item, {
|
|
1010
1332
|
key: field2.id,
|
|
1011
1333
|
item: field2,
|
|
1012
|
-
classNames:
|
|
1013
|
-
}, /* @__PURE__ */
|
|
1334
|
+
classNames: mx8(grid, ghostHover, "cursor-pointer")
|
|
1335
|
+
}, /* @__PURE__ */ React13.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React13.createElement(List2.ItemTitle, {
|
|
1014
1336
|
onClick: () => handleSelect(field2)
|
|
1015
|
-
}, field2.path), /* @__PURE__ */
|
|
1337
|
+
}, field2.path), /* @__PURE__ */ React13.createElement(List2.ItemDeleteButton, {
|
|
1016
1338
|
disabled: view.fields.length <= 1,
|
|
1017
1339
|
onClick: () => onDelete(field2.id)
|
|
1018
|
-
}))))))), field && /* @__PURE__ */
|
|
1340
|
+
}))))))), field && /* @__PURE__ */ React13.createElement(FieldEditor, {
|
|
1019
1341
|
key: field.id,
|
|
1020
1342
|
view,
|
|
1021
1343
|
projection,
|
|
1022
1344
|
field,
|
|
1023
1345
|
registry,
|
|
1024
1346
|
onSave: handleClose
|
|
1025
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
1347
|
+
}), !readonly && !field && /* @__PURE__ */ React13.createElement("div", {
|
|
1026
1348
|
className: "flex p-2 justify-center"
|
|
1027
|
-
}, /* @__PURE__ */
|
|
1349
|
+
}, /* @__PURE__ */ React13.createElement(IconButton4, {
|
|
1028
1350
|
icon: "ph--plus--regular",
|
|
1029
1351
|
label: t("button add property"),
|
|
1030
1352
|
onClick: handleAdd,
|
|
@@ -1254,14 +1576,16 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
|
1254
1576
|
};
|
|
1255
1577
|
export {
|
|
1256
1578
|
BooleanInput,
|
|
1579
|
+
DeprecatedFormContainer,
|
|
1257
1580
|
DeprecatedFormInput,
|
|
1258
1581
|
FieldEditor,
|
|
1259
1582
|
Form,
|
|
1260
|
-
FormActions,
|
|
1261
1583
|
GeoPointInput,
|
|
1262
1584
|
InputHeader,
|
|
1585
|
+
MarkdownInput,
|
|
1263
1586
|
NumberInput,
|
|
1264
1587
|
SelectInput,
|
|
1588
|
+
SelectOptionInput,
|
|
1265
1589
|
TextInput,
|
|
1266
1590
|
TupleInput,
|
|
1267
1591
|
ViewEditor,
|
|
@@ -1272,6 +1596,7 @@ export {
|
|
|
1272
1596
|
parseValue,
|
|
1273
1597
|
pathNotUniqueError,
|
|
1274
1598
|
translations_default as translations,
|
|
1275
|
-
useForm
|
|
1599
|
+
useForm,
|
|
1600
|
+
useFormValues
|
|
1276
1601
|
};
|
|
1277
1602
|
//# sourceMappingURL=index.mjs.map
|