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