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