@dxos/react-ui-form 0.7.5-labs.a279d8c → 0.7.5-labs.c0e040f
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 +601 -283
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +595 -273
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +601 -283
- 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/Defaults.d.ts +1 -0
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +3 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts +4 -1
- package/dist/types/src/components/Form/FormContext.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/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.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 +1 -0
- 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 +3 -2
- package/src/components/Form/ArrayField.tsx +1 -1
- package/src/components/Form/Defaults.tsx +61 -4
- package/src/components/Form/Form.tsx +20 -3
- package/src/components/Form/FormActions.tsx +1 -1
- package/src/components/Form/FormContent.tsx +24 -9
- package/src/components/Form/FormContext.tsx +48 -4
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +58 -0
- package/src/components/Form/custom/SelectOptionsInput.tsx +190 -0
- package/src/components/Form/custom/index.ts +1 -0
- package/src/components/Form/factory.tsx +3 -1
- 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 +6 -1
- 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,198 +80,35 @@ 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
106
|
import { log as log2 } from "@dxos/log";
|
|
88
|
-
import { useTranslation as
|
|
107
|
+
import { useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
89
108
|
import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
|
|
90
109
|
|
|
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 = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
117
|
-
const { t } = useTranslation(translationKey);
|
|
118
|
-
const { status, error } = getStatus();
|
|
119
|
-
const [lng = 0, lat = 0] = getValue3() ?? [];
|
|
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(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(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, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
161
|
-
const { status, error } = getStatus();
|
|
162
|
-
const values = getValue3() ?? {};
|
|
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(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 = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
186
|
-
const { status, error } = getStatus();
|
|
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: getValue3() ?? "",
|
|
195
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
196
|
-
onBlur
|
|
197
|
-
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.Validation, null, error));
|
|
198
|
-
};
|
|
199
|
-
var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
200
|
-
const { status, error } = getStatus();
|
|
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: getValue3() ?? 0,
|
|
210
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
211
|
-
onBlur
|
|
212
|
-
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
213
|
-
};
|
|
214
|
-
var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
|
|
215
|
-
const { status, error } = getStatus();
|
|
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: getValue3(),
|
|
222
|
-
onCheckedChange: (value) => onValueChange(type, value)
|
|
223
|
-
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
224
|
-
};
|
|
225
|
-
var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
|
|
226
|
-
const { status, error } = getStatus();
|
|
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: getValue3(),
|
|
233
|
-
onValueChange: (value) => onValueChange(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 React10, { useMemo as useMemo4 } from "react";
|
|
249
|
-
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
250
|
-
|
|
251
|
-
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
252
|
-
import React7 from "react";
|
|
253
|
-
import { IconButton, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
254
|
-
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
255
|
-
|
|
256
110
|
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
257
|
-
import
|
|
111
|
+
import React2, { createContext, useContext, useEffect as useEffect2 } from "react";
|
|
258
112
|
import { raise } from "@dxos/debug";
|
|
259
113
|
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
260
114
|
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
@@ -270,7 +124,7 @@ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/ho
|
|
|
270
124
|
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
271
125
|
invariant(AST.isTypeLiteral(schema.ast), void 0, {
|
|
272
126
|
F: __dxlog_file,
|
|
273
|
-
L:
|
|
127
|
+
L: 92,
|
|
274
128
|
S: void 0,
|
|
275
129
|
A: [
|
|
276
130
|
"AST.isTypeLiteral(schema.ast)",
|
|
@@ -313,6 +167,11 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
313
167
|
values,
|
|
314
168
|
schemaDirty
|
|
315
169
|
]);
|
|
170
|
+
const formIsValid = useMemo(() => {
|
|
171
|
+
return Object.keys(errors).length === 0;
|
|
172
|
+
}, [
|
|
173
|
+
errors
|
|
174
|
+
]);
|
|
316
175
|
const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors
|
|
317
176
|
!Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
|
|
318
177
|
touched,
|
|
@@ -359,7 +218,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
359
218
|
} catch (err) {
|
|
360
219
|
log.catch(err, void 0, {
|
|
361
220
|
F: __dxlog_file,
|
|
362
|
-
L:
|
|
221
|
+
L: 198,
|
|
363
222
|
S: void 0,
|
|
364
223
|
C: (f, a) => f(...a)
|
|
365
224
|
});
|
|
@@ -400,6 +259,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
400
259
|
changed,
|
|
401
260
|
canSave,
|
|
402
261
|
handleSave,
|
|
262
|
+
formIsValid,
|
|
403
263
|
// Field utils.
|
|
404
264
|
getStatus,
|
|
405
265
|
getValue: getFormValue,
|
|
@@ -410,7 +270,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
410
270
|
var createKeySet = (obj, value) => {
|
|
411
271
|
invariant(obj, void 0, {
|
|
412
272
|
F: __dxlog_file,
|
|
413
|
-
L:
|
|
273
|
+
L: 241,
|
|
414
274
|
S: void 0,
|
|
415
275
|
A: [
|
|
416
276
|
"obj",
|
|
@@ -451,29 +311,445 @@ var useInputProps = (path = []) => {
|
|
|
451
311
|
onBlur: () => onTouched(path)
|
|
452
312
|
};
|
|
453
313
|
};
|
|
454
|
-
var FormProvider = ({ children, ...formOptions }) => {
|
|
455
|
-
const
|
|
456
|
-
|
|
457
|
-
|
|
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
|
+
}
|
|
335
|
+
};
|
|
336
|
+
const formElement = formRef.current;
|
|
337
|
+
formElement.addEventListener("keydown", handleKeyDown);
|
|
338
|
+
return () => formElement.removeEventListener("keydown", handleKeyDown);
|
|
339
|
+
}, [
|
|
340
|
+
formRef,
|
|
341
|
+
form.canSave,
|
|
342
|
+
form.formIsValid,
|
|
343
|
+
form.handleSave,
|
|
344
|
+
autoSave
|
|
345
|
+
]);
|
|
346
|
+
return /* @__PURE__ */ React2.createElement(FormContext.Provider, {
|
|
347
|
+
value: form
|
|
458
348
|
}, children);
|
|
459
349
|
};
|
|
460
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, []);
|
|
426
|
+
}
|
|
427
|
+
}, [
|
|
428
|
+
options,
|
|
429
|
+
onValueChange,
|
|
430
|
+
type
|
|
431
|
+
]);
|
|
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
|
|
475
|
+
];
|
|
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);
|
|
501
|
+
}
|
|
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);
|
|
518
|
+
}
|
|
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`;
|
|
698
|
+
}
|
|
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));
|
|
728
|
+
};
|
|
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
|
+
|
|
461
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";
|
|
462
738
|
var FormActions = ({ onCancel, readonly }) => {
|
|
463
|
-
const { t } =
|
|
739
|
+
const { t } = useTranslation3(translationKey);
|
|
464
740
|
const { canSave, handleSave } = useFormContext();
|
|
465
|
-
return /* @__PURE__ */
|
|
741
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
466
742
|
role: "none",
|
|
467
|
-
className: "flex justify-center"
|
|
468
|
-
}, /* @__PURE__ */
|
|
743
|
+
className: "mt-2 flex justify-center"
|
|
744
|
+
}, /* @__PURE__ */ React8.createElement("div", {
|
|
469
745
|
role: "none",
|
|
470
|
-
className:
|
|
471
|
-
}, onCancel && !readonly && /* @__PURE__ */
|
|
746
|
+
className: mx4(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
747
|
+
}, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
472
748
|
"data-testid": "cancel-button",
|
|
473
749
|
icon: "ph--x--regular",
|
|
474
750
|
label: t("button cancel"),
|
|
475
751
|
onClick: onCancel
|
|
476
|
-
}), handleSave && /* @__PURE__ */
|
|
752
|
+
}), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
477
753
|
type: "submit",
|
|
478
754
|
"data-testid": "save-button",
|
|
479
755
|
disabled: !canSave,
|
|
@@ -486,36 +762,36 @@ var FormActions = ({ onCancel, readonly }) => {
|
|
|
486
762
|
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
487
763
|
import { pipe as pipe2 } from "effect";
|
|
488
764
|
import { capitalize as capitalize2 } from "effect/String";
|
|
489
|
-
import
|
|
765
|
+
import React10, { useMemo as useMemo3 } from "react";
|
|
490
766
|
import { AST as AST3, S } from "@dxos/echo-schema";
|
|
491
767
|
import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
492
|
-
import { mx as
|
|
768
|
+
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
493
769
|
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
494
770
|
import { isNotFalsy } from "@dxos/util";
|
|
495
771
|
|
|
496
772
|
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
497
773
|
import { pipe } from "effect";
|
|
498
774
|
import { capitalize } from "effect/String";
|
|
499
|
-
import
|
|
775
|
+
import React9, { useCallback as useCallback4, useMemo as useMemo2 } from "react";
|
|
500
776
|
import { AST as AST2 } from "@dxos/echo-schema";
|
|
501
777
|
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
502
778
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
503
|
-
import { IconButton as
|
|
504
|
-
import { mx as
|
|
779
|
+
import { IconButton as IconButton3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
780
|
+
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
505
781
|
import { getSchemaProperties } from "@dxos/schema";
|
|
506
782
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
507
783
|
var padding = "px-2";
|
|
508
784
|
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
509
|
-
const { t } =
|
|
785
|
+
const { t } = useTranslation4(translationKey);
|
|
510
786
|
const { ast, name, type, title } = property;
|
|
511
787
|
const values = useFormValues(path ?? []);
|
|
512
|
-
invariant2(Array.isArray(values),
|
|
788
|
+
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
513
789
|
F: __dxlog_file2,
|
|
514
790
|
L: 37,
|
|
515
791
|
S: void 0,
|
|
516
792
|
A: [
|
|
517
793
|
"Array.isArray(values)",
|
|
518
|
-
""
|
|
794
|
+
"`Values at path ${path?.join('.')} must be an array.`"
|
|
519
795
|
]
|
|
520
796
|
});
|
|
521
797
|
const label = title ?? pipe(name, capitalize);
|
|
@@ -542,7 +818,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
542
818
|
type,
|
|
543
819
|
elementType
|
|
544
820
|
]);
|
|
545
|
-
const handleAdd =
|
|
821
|
+
const handleAdd = useCallback4(() => {
|
|
546
822
|
inputProps.onValueChange(type, [
|
|
547
823
|
...values,
|
|
548
824
|
newValue
|
|
@@ -554,7 +830,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
554
830
|
newValue,
|
|
555
831
|
values
|
|
556
832
|
]);
|
|
557
|
-
const handleRemove =
|
|
833
|
+
const handleRemove = useCallback4((index) => {
|
|
558
834
|
const newValues = values.filter((_, i) => i !== index);
|
|
559
835
|
inputProps.onValueChange(type, newValues);
|
|
560
836
|
}, [
|
|
@@ -565,20 +841,20 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
565
841
|
if (!elementType) {
|
|
566
842
|
return null;
|
|
567
843
|
}
|
|
568
|
-
return /* @__PURE__ */
|
|
844
|
+
return /* @__PURE__ */ React9.createElement("div", {
|
|
569
845
|
role: "none",
|
|
570
|
-
className:
|
|
571
|
-
}, /* @__PURE__ */
|
|
846
|
+
className: mx5(padding)
|
|
847
|
+
}, /* @__PURE__ */ React9.createElement(InputHeader, null, label), /* @__PURE__ */ React9.createElement("div", {
|
|
572
848
|
role: "none",
|
|
573
849
|
className: "flex flex-col gap-1"
|
|
574
|
-
}, values.map((_value, index) => /* @__PURE__ */
|
|
850
|
+
}, values.map((_value, index) => /* @__PURE__ */ React9.createElement("div", {
|
|
575
851
|
key: index,
|
|
576
852
|
role: "none",
|
|
577
853
|
className: "flex items-center gap-1"
|
|
578
|
-
}, /* @__PURE__ */
|
|
854
|
+
}, /* @__PURE__ */ React9.createElement("div", {
|
|
579
855
|
role: "none",
|
|
580
856
|
className: "flex-1"
|
|
581
|
-
}, /* @__PURE__ */
|
|
857
|
+
}, /* @__PURE__ */ React9.createElement(FormField, {
|
|
582
858
|
property: {
|
|
583
859
|
...property,
|
|
584
860
|
array: false,
|
|
@@ -592,15 +868,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
592
868
|
inline: true,
|
|
593
869
|
Custom,
|
|
594
870
|
lookupComponent
|
|
595
|
-
})), /* @__PURE__ */
|
|
871
|
+
})), /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
596
872
|
icon: "ph--trash--regular",
|
|
597
873
|
iconOnly: true,
|
|
598
874
|
label: t("button remove"),
|
|
599
875
|
onClick: () => handleRemove(index)
|
|
600
|
-
})))), /* @__PURE__ */
|
|
876
|
+
})))), /* @__PURE__ */ React9.createElement("div", {
|
|
601
877
|
role: "none",
|
|
602
878
|
className: "flex justify-between items-center plb-1"
|
|
603
|
-
}, /* @__PURE__ */
|
|
879
|
+
}, /* @__PURE__ */ React9.createElement(IconButton3, {
|
|
604
880
|
icon: "ph--plus--regular",
|
|
605
881
|
iconOnly: true,
|
|
606
882
|
label: t("button add"),
|
|
@@ -614,6 +890,8 @@ var getInputComponent = (type, format) => {
|
|
|
614
890
|
switch (format) {
|
|
615
891
|
case FormatEnum.LatLng:
|
|
616
892
|
return GeoPointInput;
|
|
893
|
+
case FormatEnum.Markdown:
|
|
894
|
+
return MarkdownInput;
|
|
617
895
|
}
|
|
618
896
|
switch (type) {
|
|
619
897
|
case "string":
|
|
@@ -637,15 +915,6 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
637
915
|
examples,
|
|
638
916
|
description
|
|
639
917
|
]);
|
|
640
|
-
if (array) {
|
|
641
|
-
return /* @__PURE__ */ React9.createElement(ArrayField, {
|
|
642
|
-
property,
|
|
643
|
-
path,
|
|
644
|
-
inputProps,
|
|
645
|
-
readonly,
|
|
646
|
-
Custom
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
918
|
const FoundComponent = lookupComponent?.({
|
|
650
919
|
prop: name,
|
|
651
920
|
schema: S.make(ast),
|
|
@@ -659,12 +928,37 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
659
928
|
}
|
|
660
929
|
});
|
|
661
930
|
if (FoundComponent) {
|
|
662
|
-
return /* @__PURE__ */
|
|
931
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
932
|
+
role: "none"
|
|
933
|
+
}, FoundComponent);
|
|
663
934
|
}
|
|
664
935
|
const jsonPath = createJsonPath3(path ?? []);
|
|
665
|
-
const
|
|
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);
|
|
666
958
|
if (InputComponent) {
|
|
667
|
-
return /* @__PURE__ */
|
|
959
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
960
|
+
role: "none"
|
|
961
|
+
}, /* @__PURE__ */ React10.createElement(InputComponent, {
|
|
668
962
|
type,
|
|
669
963
|
format,
|
|
670
964
|
label,
|
|
@@ -675,9 +969,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
675
969
|
}));
|
|
676
970
|
}
|
|
677
971
|
if (options) {
|
|
678
|
-
return /* @__PURE__ */
|
|
972
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
679
973
|
role: "none"
|
|
680
|
-
}, /* @__PURE__ */
|
|
974
|
+
}, /* @__PURE__ */ React10.createElement(SelectInput, {
|
|
681
975
|
type,
|
|
682
976
|
format,
|
|
683
977
|
disabled: readonly,
|
|
@@ -695,7 +989,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
695
989
|
const baseNode = findNode2(ast, isDiscriminatedUnion2);
|
|
696
990
|
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
|
|
697
991
|
if (typeLiteral) {
|
|
698
|
-
return /* @__PURE__ */
|
|
992
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
993
|
+
role: "none"
|
|
994
|
+
}, !inline && /* @__PURE__ */ React10.createElement("div", null, label), /* @__PURE__ */ React10.createElement(FormFields, {
|
|
699
995
|
schema: S.make(typeLiteral),
|
|
700
996
|
path,
|
|
701
997
|
readonly,
|
|
@@ -717,11 +1013,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
717
1013
|
filter,
|
|
718
1014
|
sort
|
|
719
1015
|
]);
|
|
720
|
-
return /* @__PURE__ */
|
|
1016
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
721
1017
|
role: "form",
|
|
722
|
-
className:
|
|
1018
|
+
className: mx6("flex flex-col w-full gap-2")
|
|
723
1019
|
}, properties.map((property) => {
|
|
724
|
-
return /* @__PURE__ */
|
|
1020
|
+
return /* @__PURE__ */ React10.createElement(FormField, {
|
|
725
1021
|
key: property.name,
|
|
726
1022
|
property,
|
|
727
1023
|
path: [
|
|
@@ -736,23 +1032,37 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
736
1032
|
};
|
|
737
1033
|
|
|
738
1034
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
739
|
-
var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
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);
|
|
740
1037
|
const onValid = useMemo4(() => autoSave ? onSave : void 0, [
|
|
741
1038
|
autoSave,
|
|
742
1039
|
onSave
|
|
743
1040
|
]);
|
|
744
|
-
|
|
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,
|
|
745
1053
|
schema,
|
|
1054
|
+
autoSave,
|
|
746
1055
|
initialValues,
|
|
747
1056
|
onValuesChanged,
|
|
748
1057
|
onValidate,
|
|
749
1058
|
onValid,
|
|
750
1059
|
onSave
|
|
751
|
-
}, /* @__PURE__ */
|
|
1060
|
+
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1061
|
+
ref: formRef,
|
|
752
1062
|
role: "none",
|
|
753
|
-
className:
|
|
1063
|
+
className: mx7("p-2", classNames),
|
|
754
1064
|
"data-testid": testId
|
|
755
|
-
}, /* @__PURE__ */
|
|
1065
|
+
}, /* @__PURE__ */ React11.createElement(FormFields, {
|
|
756
1066
|
schema,
|
|
757
1067
|
path,
|
|
758
1068
|
readonly,
|
|
@@ -760,7 +1070,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
760
1070
|
sort,
|
|
761
1071
|
lookupComponent,
|
|
762
1072
|
Custom
|
|
763
|
-
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */
|
|
1073
|
+
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React11.createElement(FormActions, {
|
|
764
1074
|
onCancel,
|
|
765
1075
|
readonly
|
|
766
1076
|
})));
|
|
@@ -769,14 +1079,14 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
769
1079
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
770
1080
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
771
1081
|
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
772
|
-
const { t } =
|
|
773
|
-
const [props, setProps] =
|
|
774
|
-
|
|
1082
|
+
const { t } = useTranslation5(translationKey);
|
|
1083
|
+
const [props, setProps] = useState3(projection.getFieldProjection(field.id).props);
|
|
1084
|
+
useEffect6(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
775
1085
|
field,
|
|
776
1086
|
projection
|
|
777
1087
|
]);
|
|
778
|
-
const [schemas, setSchemas] =
|
|
779
|
-
|
|
1088
|
+
const [schemas, setSchemas] = useState3([]);
|
|
1089
|
+
useEffect6(() => {
|
|
780
1090
|
if (!registry) {
|
|
781
1091
|
return;
|
|
782
1092
|
}
|
|
@@ -794,17 +1104,17 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
794
1104
|
}, [
|
|
795
1105
|
registry
|
|
796
1106
|
]);
|
|
797
|
-
const [referenceSchema, setReferenceSchema] =
|
|
798
|
-
|
|
1107
|
+
const [referenceSchema, setReferenceSchema] = useState3();
|
|
1108
|
+
useEffect6(() => {
|
|
799
1109
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
800
1110
|
}, [
|
|
801
1111
|
schemas,
|
|
802
1112
|
props?.referenceSchema
|
|
803
1113
|
]);
|
|
804
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
1114
|
+
const [{ fieldSchema }, setFieldSchema] = useState3({
|
|
805
1115
|
fieldSchema: getFormatSchema(props?.format)
|
|
806
1116
|
});
|
|
807
|
-
const handleValuesChanged =
|
|
1117
|
+
const handleValuesChanged = useCallback5((_props) => {
|
|
808
1118
|
setFieldSchema((prev) => {
|
|
809
1119
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
810
1120
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -832,14 +1142,14 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
832
1142
|
type
|
|
833
1143
|
};
|
|
834
1144
|
}
|
|
835
|
-
return
|
|
1145
|
+
return _props;
|
|
836
1146
|
});
|
|
837
1147
|
}, [
|
|
838
1148
|
schemas,
|
|
839
1149
|
props.format,
|
|
840
1150
|
props.referenceSchema
|
|
841
1151
|
]);
|
|
842
|
-
const handleValidate =
|
|
1152
|
+
const handleValidate = useCallback5(({ property }) => {
|
|
843
1153
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
844
1154
|
return [
|
|
845
1155
|
{
|
|
@@ -852,7 +1162,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
852
1162
|
view.fields,
|
|
853
1163
|
field
|
|
854
1164
|
]);
|
|
855
|
-
const handleSave =
|
|
1165
|
+
const handleSave = useCallback5((props2) => {
|
|
856
1166
|
projection.setFieldProjection({
|
|
857
1167
|
field,
|
|
858
1168
|
props: props2
|
|
@@ -863,50 +1173,51 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
863
1173
|
field,
|
|
864
1174
|
onSave
|
|
865
1175
|
]);
|
|
866
|
-
const handleCancel =
|
|
1176
|
+
const handleCancel = useCallback5(() => {
|
|
867
1177
|
requestAnimationFrame(() => onCancel?.());
|
|
868
1178
|
onSave();
|
|
869
1179
|
}, [
|
|
870
1180
|
onSave
|
|
871
1181
|
]);
|
|
872
1182
|
const Custom = useMemo5(() => ({
|
|
873
|
-
["format"]: (props2) => /* @__PURE__ */
|
|
1183
|
+
["format"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
874
1184
|
...props2,
|
|
875
1185
|
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
876
1186
|
value,
|
|
877
1187
|
label: t(`format ${value}`)
|
|
878
1188
|
}))
|
|
879
1189
|
}),
|
|
880
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */
|
|
1190
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
881
1191
|
...props2,
|
|
882
1192
|
options: schemas.map((schema) => ({
|
|
883
1193
|
value: schema.typename
|
|
884
1194
|
}))
|
|
885
1195
|
}),
|
|
886
|
-
["referencePath"]: (props2) => /* @__PURE__ */
|
|
1196
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
887
1197
|
...props2,
|
|
888
1198
|
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
889
1199
|
value: p.name
|
|
890
1200
|
})) : []
|
|
891
|
-
})
|
|
1201
|
+
}),
|
|
1202
|
+
["options"]: (props2) => /* @__PURE__ */ React12.createElement(SelectOptionInput, props2)
|
|
892
1203
|
}), [
|
|
893
1204
|
t,
|
|
894
1205
|
schemas,
|
|
895
1206
|
referenceSchema
|
|
896
1207
|
]);
|
|
897
|
-
const propIsNotType =
|
|
1208
|
+
const propIsNotType = useCallback5((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
898
1209
|
if (!fieldSchema) {
|
|
899
1210
|
log2.warn("invalid format", {
|
|
900
1211
|
props
|
|
901
1212
|
}, {
|
|
902
1213
|
F: __dxlog_file3,
|
|
903
|
-
L:
|
|
1214
|
+
L: 174,
|
|
904
1215
|
S: void 0,
|
|
905
1216
|
C: (f, a) => f(...a)
|
|
906
1217
|
});
|
|
907
1218
|
return null;
|
|
908
1219
|
}
|
|
909
|
-
return /* @__PURE__ */
|
|
1220
|
+
return /* @__PURE__ */ React12.createElement(Form, {
|
|
910
1221
|
key: field.id,
|
|
911
1222
|
autoFocus: true,
|
|
912
1223
|
values: props,
|
|
@@ -925,29 +1236,28 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
925
1236
|
};
|
|
926
1237
|
|
|
927
1238
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
928
|
-
import
|
|
1239
|
+
import React13, { useCallback as useCallback6, useMemo as useMemo6, useState as useState4 } from "react";
|
|
929
1240
|
import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
|
|
930
|
-
import { IconButton as
|
|
931
|
-
import { List } from "@dxos/react-ui-list";
|
|
932
|
-
import { ghostHover, inputTextLabel, mx as
|
|
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";
|
|
933
1244
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
934
|
-
import { arrayMove } from "@dxos/util";
|
|
935
1245
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
936
1246
|
var ViewMetaSchema = S2.Struct({
|
|
937
1247
|
name: S2.String.annotations({
|
|
938
1248
|
[AST4.TitleAnnotationId]: "View"
|
|
939
1249
|
}),
|
|
940
|
-
typename: Format.
|
|
1250
|
+
typename: Format.URL.annotations({
|
|
941
1251
|
[AST4.TitleAnnotationId]: "Typename"
|
|
942
1252
|
})
|
|
943
1253
|
}).pipe(S2.mutable);
|
|
944
1254
|
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
945
|
-
const { t } =
|
|
1255
|
+
const { t } = useTranslation6(translationKey);
|
|
946
1256
|
const projection = useMemo6(() => new ViewProjection(schema, view), [
|
|
947
1257
|
schema,
|
|
948
1258
|
view
|
|
949
1259
|
]);
|
|
950
|
-
const [field, setField] =
|
|
1260
|
+
const [field, setField] = useState4();
|
|
951
1261
|
const viewValues = useMemo6(() => {
|
|
952
1262
|
return {
|
|
953
1263
|
name: view.name,
|
|
@@ -958,7 +1268,7 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
958
1268
|
}, [
|
|
959
1269
|
view
|
|
960
1270
|
]);
|
|
961
|
-
const handleViewUpdate =
|
|
1271
|
+
const handleViewUpdate = useCallback6(({ name, typename }) => {
|
|
962
1272
|
requestAnimationFrame(() => {
|
|
963
1273
|
if (view.name !== name) {
|
|
964
1274
|
view.name = name;
|
|
@@ -972,67 +1282,71 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
972
1282
|
schema,
|
|
973
1283
|
onTypenameChanged
|
|
974
1284
|
]);
|
|
975
|
-
const handleSelect =
|
|
1285
|
+
const handleSelect = useCallback6((field2) => {
|
|
976
1286
|
setField((f) => f === field2 ? void 0 : field2);
|
|
977
1287
|
}, []);
|
|
978
|
-
const handleAdd =
|
|
1288
|
+
const handleAdd = useCallback6(() => {
|
|
979
1289
|
const field2 = projection.createFieldProjection();
|
|
980
1290
|
setField(field2);
|
|
981
1291
|
}, [
|
|
982
1292
|
view
|
|
983
1293
|
]);
|
|
984
|
-
const handleMove =
|
|
985
|
-
|
|
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;
|
|
986
1301
|
}, [
|
|
987
1302
|
view.fields
|
|
988
1303
|
]);
|
|
989
|
-
const handleClose =
|
|
990
|
-
return /* @__PURE__ */
|
|
1304
|
+
const handleClose = useCallback6(() => setField(void 0), []);
|
|
1305
|
+
return /* @__PURE__ */ React13.createElement("div", {
|
|
991
1306
|
role: "none",
|
|
992
|
-
className:
|
|
993
|
-
}, /* @__PURE__ */
|
|
994
|
-
autoFocus: true,
|
|
1307
|
+
className: mx8("flex flex-col w-full divide-y divide-separator", classNames)
|
|
1308
|
+
}, /* @__PURE__ */ React13.createElement(Form, {
|
|
995
1309
|
autoSave: true,
|
|
996
1310
|
schema: ViewMetaSchema,
|
|
997
1311
|
values: viewValues,
|
|
998
1312
|
onSave: handleViewUpdate
|
|
999
|
-
}), /* @__PURE__ */
|
|
1313
|
+
}), /* @__PURE__ */ React13.createElement("div", null, /* @__PURE__ */ React13.createElement("div", {
|
|
1000
1314
|
role: "none",
|
|
1001
1315
|
className: "p-2"
|
|
1002
|
-
}, /* @__PURE__ */
|
|
1003
|
-
className:
|
|
1004
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
1316
|
+
}, /* @__PURE__ */ React13.createElement("label", {
|
|
1317
|
+
className: mx8(inputTextLabel)
|
|
1318
|
+
}, t("fields label"))), /* @__PURE__ */ React13.createElement(List2.Root, {
|
|
1005
1319
|
items: view.fields,
|
|
1006
1320
|
isItem: S2.is(FieldSchema),
|
|
1007
1321
|
getId: (field2) => field2.id,
|
|
1008
1322
|
onMove: handleMove
|
|
1009
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
1323
|
+
}, ({ items: fields }) => /* @__PURE__ */ React13.createElement(React13.Fragment, null, showHeading && /* @__PURE__ */ React13.createElement("div", {
|
|
1010
1324
|
role: "heading",
|
|
1011
1325
|
className: grid
|
|
1012
|
-
}, /* @__PURE__ */
|
|
1326
|
+
}, /* @__PURE__ */ React13.createElement("div", null), /* @__PURE__ */ React13.createElement("div", {
|
|
1013
1327
|
className: "flex items-center text-sm"
|
|
1014
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
1328
|
+
}, t("field path label"))), /* @__PURE__ */ React13.createElement("div", {
|
|
1015
1329
|
role: "list",
|
|
1016
1330
|
className: "flex flex-col w-full"
|
|
1017
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
1331
|
+
}, fields?.map((field2) => /* @__PURE__ */ React13.createElement(List2.Item, {
|
|
1018
1332
|
key: field2.id,
|
|
1019
1333
|
item: field2,
|
|
1020
|
-
classNames:
|
|
1021
|
-
}, /* @__PURE__ */
|
|
1334
|
+
classNames: mx8(grid, ghostHover, "cursor-pointer")
|
|
1335
|
+
}, /* @__PURE__ */ React13.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React13.createElement(List2.ItemTitle, {
|
|
1022
1336
|
onClick: () => handleSelect(field2)
|
|
1023
|
-
}, field2.path), /* @__PURE__ */
|
|
1337
|
+
}, field2.path), /* @__PURE__ */ React13.createElement(List2.ItemDeleteButton, {
|
|
1024
1338
|
disabled: view.fields.length <= 1,
|
|
1025
1339
|
onClick: () => onDelete(field2.id)
|
|
1026
|
-
}))))))), field && /* @__PURE__ */
|
|
1340
|
+
}))))))), field && /* @__PURE__ */ React13.createElement(FieldEditor, {
|
|
1027
1341
|
key: field.id,
|
|
1028
1342
|
view,
|
|
1029
1343
|
projection,
|
|
1030
1344
|
field,
|
|
1031
1345
|
registry,
|
|
1032
1346
|
onSave: handleClose
|
|
1033
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
1347
|
+
}), !readonly && !field && /* @__PURE__ */ React13.createElement("div", {
|
|
1034
1348
|
className: "flex p-2 justify-center"
|
|
1035
|
-
}, /* @__PURE__ */
|
|
1349
|
+
}, /* @__PURE__ */ React13.createElement(IconButton4, {
|
|
1036
1350
|
icon: "ph--plus--regular",
|
|
1037
1351
|
label: t("button add property"),
|
|
1038
1352
|
onClick: handleAdd,
|
|
@@ -1262,13 +1576,16 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
|
1262
1576
|
};
|
|
1263
1577
|
export {
|
|
1264
1578
|
BooleanInput,
|
|
1579
|
+
DeprecatedFormContainer,
|
|
1265
1580
|
DeprecatedFormInput,
|
|
1266
1581
|
FieldEditor,
|
|
1267
1582
|
Form,
|
|
1268
1583
|
GeoPointInput,
|
|
1269
1584
|
InputHeader,
|
|
1585
|
+
MarkdownInput,
|
|
1270
1586
|
NumberInput,
|
|
1271
1587
|
SelectInput,
|
|
1588
|
+
SelectOptionInput,
|
|
1272
1589
|
TextInput,
|
|
1273
1590
|
TupleInput,
|
|
1274
1591
|
ViewEditor,
|
|
@@ -1279,6 +1596,7 @@ export {
|
|
|
1279
1596
|
parseValue,
|
|
1280
1597
|
pathNotUniqueError,
|
|
1281
1598
|
translations_default as translations,
|
|
1282
|
-
useForm
|
|
1599
|
+
useForm,
|
|
1600
|
+
useFormValues
|
|
1283
1601
|
};
|
|
1284
1602
|
//# sourceMappingURL=index.mjs.map
|