@dxos/react-ui-form 0.8.1-main.ae460ac → 0.8.1-staging.31c3ee1
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 +672 -499
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +744 -565
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +672 -499
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ControlSection.d.ts +20 -0
- package/dist/types/src/components/ControlSection.d.ts.map +1 -0
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/ArrayField.d.ts +2 -1
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts +6 -5
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +2 -2
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +9 -9
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts +2 -1
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContent.d.ts +3 -2
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts +1 -1
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts +3 -3
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +2 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +2 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +2 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts +1 -2
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts +2 -1
- package/dist/types/src/components/ViewEditor/Test.stories.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +6 -5
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.d.ts +2 -1
- package/dist/types/src/components/deprecated/Form.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts +2 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts +2 -2
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +3 -3
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +1 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/field.d.ts +0 -1
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/package.json +26 -26
- package/src/components/ControlSection.tsx +113 -0
- package/src/components/FieldEditor/FieldEditor.stories.tsx +1 -1
- package/src/components/Form/Form.stories.tsx +2 -2
- package/src/components/Form/Input.tsx +1 -1
- package/src/components/Form/custom/SelectOptionsInput.tsx +5 -1
- package/src/components/Form/index.ts +1 -3
- package/src/components/ViewEditor/ViewEditor.stories.tsx +1 -1
- package/src/components/ViewEditor/ViewEditor.tsx +105 -20
- package/src/components/index.ts +1 -1
- package/src/hooks/useForm.ts +10 -1
- package/src/translations.ts +1 -0
- package/src/util/field.ts +4 -4
- package/src/util/formatting.ts +9 -10
|
@@ -5,6 +5,7 @@ var translations_default = [
|
|
|
5
5
|
"en-US": {
|
|
6
6
|
[translationKey]: {
|
|
7
7
|
"fields label": "Fields",
|
|
8
|
+
"hidden fields label": "Hidden Fields",
|
|
8
9
|
// TODO(burdon): Standardize field/property.
|
|
9
10
|
"button add property": "Add property",
|
|
10
11
|
"field property label": "Property",
|
|
@@ -98,289 +99,81 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
|
|
|
98
99
|
return primary;
|
|
99
100
|
};
|
|
100
101
|
|
|
101
|
-
// packages/ui/react-ui-form/src/components/
|
|
102
|
-
import
|
|
103
|
-
import {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
112
|
-
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
113
|
-
|
|
114
|
-
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
115
|
-
import { SchemaAST as AST } from "effect";
|
|
116
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
117
|
-
import { getValue, setValue } from "@dxos/echo-schema";
|
|
118
|
-
import { createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
119
|
-
import { invariant } from "@dxos/invariant";
|
|
120
|
-
import { log } from "@dxos/log";
|
|
121
|
-
import { validateSchema } from "@dxos/schema";
|
|
122
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
|
|
123
|
-
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
124
|
-
invariant(AST.isTypeLiteral(schema.ast), void 0, {
|
|
125
|
-
F: __dxlog_file,
|
|
126
|
-
L: 93,
|
|
127
|
-
S: void 0,
|
|
128
|
-
A: [
|
|
129
|
-
"AST.isTypeLiteral(schema.ast)",
|
|
130
|
-
""
|
|
131
|
-
]
|
|
132
|
-
});
|
|
133
|
-
const [values, setValues] = useState(initialValues);
|
|
134
|
-
useEffect(() => {
|
|
135
|
-
setValues(initialValues);
|
|
136
|
-
}, [
|
|
137
|
-
initialValues
|
|
138
|
-
]);
|
|
139
|
-
const [touched, setTouched] = useState(createKeySet(initialValues, false));
|
|
140
|
-
const [changed, setChanged] = useState(createKeySet(initialValues, false));
|
|
141
|
-
const [errors, setErrors] = useState({});
|
|
142
|
-
const [saving, setSaving] = useState(false);
|
|
143
|
-
const validate = useCallback((values2) => {
|
|
144
|
-
let errors2 = validateSchema(schema, values2) ?? [];
|
|
145
|
-
if (errors2.length === 0 && onValidate) {
|
|
146
|
-
const validatedValues = values2;
|
|
147
|
-
errors2 = onValidate(validatedValues) ?? [];
|
|
148
|
-
}
|
|
149
|
-
setErrors(flatMap(errors2));
|
|
150
|
-
const valid = errors2.length === 0;
|
|
151
|
-
return valid;
|
|
152
|
-
}, [
|
|
153
|
-
schema,
|
|
154
|
-
onValidate
|
|
155
|
-
]);
|
|
156
|
-
const [schemaDirty, setSchemaDirty] = useState(false);
|
|
157
|
-
useEffect(() => setSchemaDirty(true), [
|
|
158
|
-
schema
|
|
159
|
-
]);
|
|
160
|
-
useEffect(() => {
|
|
161
|
-
if (schemaDirty) {
|
|
162
|
-
validate(values);
|
|
163
|
-
setSchemaDirty(false);
|
|
164
|
-
}
|
|
165
|
-
}, [
|
|
166
|
-
values,
|
|
167
|
-
schemaDirty
|
|
168
|
-
]);
|
|
169
|
-
const formIsValid = useMemo(() => {
|
|
170
|
-
return Object.keys(errors).length === 0;
|
|
171
|
-
}, [
|
|
172
|
-
errors
|
|
173
|
-
]);
|
|
174
|
-
const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors.
|
|
175
|
-
!Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
|
|
176
|
-
touched,
|
|
177
|
-
errors,
|
|
178
|
-
saving
|
|
179
|
-
]);
|
|
180
|
-
const handleSave = useCallback(async () => {
|
|
181
|
-
if (validate(values)) {
|
|
182
|
-
setSaving(true);
|
|
183
|
-
try {
|
|
184
|
-
await onSave?.(values, {
|
|
185
|
-
changed
|
|
186
|
-
});
|
|
187
|
-
} finally {
|
|
188
|
-
setSaving(false);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}, [
|
|
192
|
-
values,
|
|
193
|
-
validate,
|
|
194
|
-
onSave,
|
|
195
|
-
changed
|
|
196
|
-
]);
|
|
197
|
-
const getStatus = useCallback((path) => {
|
|
198
|
-
const jsonPath = Array.isArray(path) ? createJsonPath(path) : path;
|
|
199
|
-
const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
|
|
200
|
-
return {
|
|
201
|
-
status: matchingError ? "error" : void 0,
|
|
202
|
-
error: matchingError ? matchingError[1] : void 0
|
|
203
|
-
};
|
|
204
|
-
}, [
|
|
205
|
-
errors
|
|
206
|
-
]);
|
|
207
|
-
const getFormValue = useCallback((path) => {
|
|
208
|
-
return getValue(values, createJsonPath(path));
|
|
209
|
-
}, [
|
|
210
|
-
values
|
|
211
|
-
]);
|
|
212
|
-
const onValueChange = useCallback((path, type, value) => {
|
|
213
|
-
const jsonPath = createJsonPath(path);
|
|
214
|
-
let parsedValue = value;
|
|
215
|
-
try {
|
|
216
|
-
if (type === "number") {
|
|
217
|
-
parsedValue = parseFloat(value) || 0;
|
|
218
|
-
}
|
|
219
|
-
} catch (err) {
|
|
220
|
-
log.catch(err, void 0, {
|
|
221
|
-
F: __dxlog_file,
|
|
222
|
-
L: 203,
|
|
223
|
-
S: void 0,
|
|
224
|
-
C: (f, a) => f(...a)
|
|
225
|
-
});
|
|
226
|
-
parsedValue = void 0;
|
|
227
|
-
}
|
|
228
|
-
const newValues = {
|
|
229
|
-
...setValue(values, jsonPath, parsedValue)
|
|
230
|
-
};
|
|
231
|
-
setValues(newValues);
|
|
232
|
-
setChanged((prev) => ({
|
|
233
|
-
...prev,
|
|
234
|
-
[jsonPath]: true
|
|
235
|
-
}));
|
|
236
|
-
onValuesChanged?.(newValues);
|
|
237
|
-
const isValid = validate(newValues);
|
|
238
|
-
if (isValid && onValid) {
|
|
239
|
-
onValid(newValues, {
|
|
240
|
-
changed
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}, [
|
|
244
|
-
values,
|
|
245
|
-
onValuesChanged,
|
|
246
|
-
validate,
|
|
247
|
-
onValid,
|
|
248
|
-
changed
|
|
249
|
-
]);
|
|
250
|
-
const onTouched = useCallback((path) => {
|
|
251
|
-
const jsonPath = createJsonPath(path);
|
|
252
|
-
setTouched((touched2) => ({
|
|
253
|
-
...touched2,
|
|
254
|
-
[jsonPath]: true
|
|
255
|
-
}));
|
|
256
|
-
validate(values);
|
|
257
|
-
}, [
|
|
258
|
-
validate,
|
|
259
|
-
values
|
|
260
|
-
]);
|
|
261
|
-
return useMemo(() => ({
|
|
262
|
-
// State.
|
|
263
|
-
values,
|
|
264
|
-
errors,
|
|
265
|
-
touched,
|
|
266
|
-
changed,
|
|
267
|
-
canSave,
|
|
268
|
-
formIsValid,
|
|
269
|
-
// Actions.
|
|
270
|
-
handleSave,
|
|
271
|
-
// Field utils.
|
|
272
|
-
getStatus,
|
|
273
|
-
getValue: getFormValue,
|
|
274
|
-
onValueChange,
|
|
275
|
-
onTouched
|
|
276
|
-
}), [
|
|
277
|
-
values,
|
|
278
|
-
errors,
|
|
279
|
-
touched,
|
|
280
|
-
changed,
|
|
281
|
-
canSave,
|
|
282
|
-
formIsValid,
|
|
283
|
-
handleSave,
|
|
284
|
-
getStatus,
|
|
285
|
-
getFormValue,
|
|
286
|
-
onValueChange,
|
|
287
|
-
onTouched
|
|
288
|
-
]);
|
|
289
|
-
};
|
|
290
|
-
var createKeySet = (obj, value) => {
|
|
291
|
-
invariant(obj, void 0, {
|
|
292
|
-
F: __dxlog_file,
|
|
293
|
-
L: 265,
|
|
294
|
-
S: void 0,
|
|
295
|
-
A: [
|
|
296
|
-
"obj",
|
|
297
|
-
""
|
|
298
|
-
]
|
|
299
|
-
});
|
|
300
|
-
return Object.keys(obj).reduce((acc, key) => ({
|
|
301
|
-
...acc,
|
|
302
|
-
[key]: value
|
|
303
|
-
}), {});
|
|
304
|
-
};
|
|
305
|
-
var flatMap = (errors) => {
|
|
306
|
-
return errors.reduce((result, { path, message }) => {
|
|
307
|
-
const jsonPath = fromEffectValidationPath(path);
|
|
308
|
-
if (!(jsonPath in result)) {
|
|
309
|
-
result[jsonPath] = message;
|
|
310
|
-
}
|
|
311
|
-
return result;
|
|
312
|
-
}, {});
|
|
102
|
+
// packages/ui/react-ui-form/src/components/ControlSection.tsx
|
|
103
|
+
import React2 from "react";
|
|
104
|
+
import { toLocalizedString, useTranslation, Input as Input2 } from "@dxos/react-ui";
|
|
105
|
+
var ControlSectionHeading = ({ title, description }) => {
|
|
106
|
+
const { t } = useTranslation(translationKey);
|
|
107
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("h2", {
|
|
108
|
+
className: "pli-4 container-max-width text-xl mbs-6 mbe-4"
|
|
109
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
|
|
110
|
+
className: "pli-4 mlb-4 container-max-width text-description"
|
|
111
|
+
}, toLocalizedString(description, t)));
|
|
313
112
|
};
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
113
|
+
var ControlSection = ({ title, description, children }) => {
|
|
114
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ControlSectionHeading, {
|
|
115
|
+
title,
|
|
116
|
+
description
|
|
117
|
+
}), children);
|
|
319
118
|
};
|
|
320
|
-
var
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
119
|
+
var ControlGroup = ({ children }) => /* @__PURE__ */ React2.createElement("div", {
|
|
120
|
+
role: "none",
|
|
121
|
+
className: "group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-4"
|
|
122
|
+
}, children);
|
|
123
|
+
var ControlFrame = ({ children }) => /* @__PURE__ */ React2.createElement("div", {
|
|
124
|
+
role: "none",
|
|
125
|
+
className: "p-4 border border-separator rounded-lg container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-2 md:gap-8"
|
|
126
|
+
}, children);
|
|
127
|
+
var controlItemClasses = "p-4 border border-separator rounded-lg container-max-width grid md:col-span-2 grid-cols-subgrid items-center";
|
|
128
|
+
var controlItemTitleClasses = "text-lg font-normal mbe-2";
|
|
129
|
+
var controlItemDescriptionClasses = "text-base mlb-2 md:mbe-0 text-description";
|
|
130
|
+
var ControlItem = ({ title, description, children }) => {
|
|
131
|
+
const { t } = useTranslation(translationKey);
|
|
132
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
133
|
+
className: controlItemClasses
|
|
134
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
135
|
+
role: "none"
|
|
136
|
+
}, /* @__PURE__ */ React2.createElement("h3", {
|
|
137
|
+
className: controlItemTitleClasses
|
|
138
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
|
|
139
|
+
className: controlItemDescriptionClasses
|
|
140
|
+
}, toLocalizedString(description, t))), children);
|
|
324
141
|
};
|
|
325
|
-
var
|
|
326
|
-
const {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}),
|
|
336
|
-
getStatus,
|
|
337
|
-
getFormValue,
|
|
338
|
-
onValueChange,
|
|
339
|
-
onTouched,
|
|
340
|
-
stablePath
|
|
341
|
-
]);
|
|
142
|
+
var ControlItemInput = ({ title, description, children }) => {
|
|
143
|
+
const { t } = useTranslation(translationKey);
|
|
144
|
+
return /* @__PURE__ */ React2.createElement(Input2.Root, null, /* @__PURE__ */ React2.createElement("div", {
|
|
145
|
+
className: controlItemClasses
|
|
146
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
147
|
+
role: "none"
|
|
148
|
+
}, /* @__PURE__ */ React2.createElement(Input2.Label, {
|
|
149
|
+
classNames: controlItemTitleClasses
|
|
150
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement(Input2.DescriptionAndValidation, null, /* @__PURE__ */ React2.createElement(Input2.Description, {
|
|
151
|
+
classNames: controlItemDescriptionClasses
|
|
152
|
+
}, toLocalizedString(description, t)))), children));
|
|
342
153
|
};
|
|
343
|
-
var
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
const inputOptOut = event.target.hasAttribute("data-no-submit");
|
|
354
|
-
const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
|
|
355
|
-
const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
|
|
356
|
-
if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
|
|
357
|
-
if (!autoSave && form.canSave) {
|
|
358
|
-
form.handleSave();
|
|
359
|
-
}
|
|
360
|
-
if (autoSave && form.formIsValid) {
|
|
361
|
-
event.target.blur();
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
const formElement = formRef.current;
|
|
366
|
-
formElement.addEventListener("keydown", handleKeyDown);
|
|
367
|
-
return () => formElement.removeEventListener("keydown", handleKeyDown);
|
|
368
|
-
}, [
|
|
369
|
-
formRef,
|
|
370
|
-
form.canSave,
|
|
371
|
-
form.formIsValid,
|
|
372
|
-
form.handleSave,
|
|
373
|
-
autoSave
|
|
374
|
-
]);
|
|
375
|
-
return /* @__PURE__ */ React2.createElement(FormContext.Provider, {
|
|
376
|
-
value: form
|
|
377
|
-
}, children);
|
|
154
|
+
var ControlFrameItem = ({ title, description, children }) => {
|
|
155
|
+
const { t } = useTranslation(translationKey);
|
|
156
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
157
|
+
role: "group",
|
|
158
|
+
className: "min-is-0"
|
|
159
|
+
}, /* @__PURE__ */ React2.createElement("h3", {
|
|
160
|
+
className: "text-lg mbe-2"
|
|
161
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
|
|
162
|
+
className: "mlb-2 md:mbe-0 text-description"
|
|
163
|
+
}, toLocalizedString(description, t)), children);
|
|
378
164
|
};
|
|
379
165
|
|
|
166
|
+
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
167
|
+
import React13, { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo7, useState as useState4 } from "react";
|
|
168
|
+
import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
|
|
169
|
+
import { log as log2 } from "@dxos/log";
|
|
170
|
+
import { useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
171
|
+
import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
|
|
172
|
+
|
|
380
173
|
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
381
|
-
import React4, { useCallback
|
|
174
|
+
import React4, { useCallback, useState, useEffect, useMemo } from "react";
|
|
382
175
|
import { GeoLocation } from "@dxos/echo-schema";
|
|
383
|
-
import { Input as
|
|
176
|
+
import { Input as Input3, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
384
177
|
import { safeParseFloat } from "@dxos/util";
|
|
385
178
|
|
|
386
179
|
// packages/ui/react-ui-form/src/components/Form/Input.tsx
|
|
@@ -404,27 +197,27 @@ var InputHeader = ({ children, error }) => {
|
|
|
404
197
|
|
|
405
198
|
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
406
199
|
var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
407
|
-
const { t } =
|
|
200
|
+
const { t } = useTranslation2(translationKey);
|
|
408
201
|
const { status, error } = getStatus();
|
|
409
|
-
const geoPoint =
|
|
202
|
+
const geoPoint = useMemo(() => getValue3() ?? [
|
|
410
203
|
0,
|
|
411
204
|
0
|
|
412
205
|
], [
|
|
413
206
|
getValue3
|
|
414
207
|
]);
|
|
415
|
-
const geoLocation =
|
|
208
|
+
const geoLocation = useMemo(() => GeoLocation.fromGeoPoint(geoPoint), [
|
|
416
209
|
geoPoint
|
|
417
210
|
]);
|
|
418
|
-
const [longitudeText, setLongitudeText] =
|
|
419
|
-
const [latitudeText, setLatitudeText] =
|
|
420
|
-
|
|
211
|
+
const [longitudeText, setLongitudeText] = useState(geoLocation.longitude?.toString());
|
|
212
|
+
const [latitudeText, setLatitudeText] = useState(geoLocation.latitude?.toString());
|
|
213
|
+
useEffect(() => {
|
|
421
214
|
const location = GeoLocation.fromGeoPoint(geoPoint);
|
|
422
215
|
setLongitudeText(location.longitude.toString());
|
|
423
216
|
setLatitudeText(location.latitude.toString());
|
|
424
217
|
}, [
|
|
425
218
|
geoPoint
|
|
426
219
|
]);
|
|
427
|
-
const handleCoordinateChange =
|
|
220
|
+
const handleCoordinateChange = useCallback((coordinateType, setText) => (event) => {
|
|
428
221
|
const inputText = event.target.value;
|
|
429
222
|
setText(inputText);
|
|
430
223
|
if (inputText !== "" && inputText !== "-") {
|
|
@@ -447,14 +240,14 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
|
|
|
447
240
|
onValueChange,
|
|
448
241
|
type
|
|
449
242
|
]);
|
|
450
|
-
return /* @__PURE__ */ React4.createElement(
|
|
243
|
+
return /* @__PURE__ */ React4.createElement(Input3.Root, {
|
|
451
244
|
validationValence: status
|
|
452
245
|
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
453
246
|
error
|
|
454
|
-
}, /* @__PURE__ */ React4.createElement(
|
|
247
|
+
}, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
455
248
|
role: "none",
|
|
456
249
|
className: "grid grid-cols-2 gap-2"
|
|
457
|
-
}, /* @__PURE__ */ React4.createElement(
|
|
250
|
+
}, /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
458
251
|
type: "text",
|
|
459
252
|
pattern: "^-?[0-9]*\\.?[0-9]*$",
|
|
460
253
|
disabled,
|
|
@@ -462,7 +255,7 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
|
|
|
462
255
|
value: latitudeText,
|
|
463
256
|
onChange: handleCoordinateChange("latitude", setLatitudeText),
|
|
464
257
|
onBlur
|
|
465
|
-
}), /* @__PURE__ */ React4.createElement(
|
|
258
|
+
}), /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
466
259
|
type: "text",
|
|
467
260
|
pattern: "^-?[0-9]*\\.?[0-9]*$",
|
|
468
261
|
disabled,
|
|
@@ -474,20 +267,20 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
|
|
|
474
267
|
};
|
|
475
268
|
|
|
476
269
|
// packages/ui/react-ui-form/src/components/Form/custom/SelectOptionsInput.tsx
|
|
477
|
-
import React5, { useCallback as
|
|
270
|
+
import React5, { useCallback as useCallback2, useEffect as useEffect2, useState as useState2, useRef } from "react";
|
|
478
271
|
import { PublicKey } from "@dxos/keys";
|
|
479
|
-
import { Icon as Icon2, IconButton, Input as
|
|
272
|
+
import { Icon as Icon2, IconButton, Input as Input4, Tag, Toolbar, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
480
273
|
import { List } from "@dxos/react-ui-list";
|
|
481
274
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
482
275
|
import { hues, mx as mx2 } from "@dxos/react-ui-theme";
|
|
483
276
|
var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
|
|
484
|
-
const [selected, setSelectedId] =
|
|
485
|
-
const [isNewOption, setIsNewOption] =
|
|
277
|
+
const [selected, setSelectedId] = useState2(null);
|
|
278
|
+
const [isNewOption, setIsNewOption] = useState2(false);
|
|
486
279
|
const inputRef = useRef(null);
|
|
487
|
-
const { t } =
|
|
280
|
+
const { t } = useTranslation3(translationKey);
|
|
488
281
|
const { status, error } = getStatus();
|
|
489
282
|
const options = getValue3();
|
|
490
|
-
|
|
283
|
+
useEffect2(() => {
|
|
491
284
|
if (options === void 0) {
|
|
492
285
|
onValueChange(type, []);
|
|
493
286
|
}
|
|
@@ -506,7 +299,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
506
299
|
const availableHues = hues.filter((hue) => !lastThree.has(hue));
|
|
507
300
|
return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hues[Math.floor(Math.random() * hues.length)];
|
|
508
301
|
};
|
|
509
|
-
const handleAdd =
|
|
302
|
+
const handleAdd = useCallback2(() => {
|
|
510
303
|
const newId = PublicKey.random().truncate();
|
|
511
304
|
const newOption = {
|
|
512
305
|
id: newId,
|
|
@@ -524,7 +317,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
524
317
|
type,
|
|
525
318
|
onValueChange
|
|
526
319
|
]);
|
|
527
|
-
const handleDelete =
|
|
320
|
+
const handleDelete = useCallback2((id) => {
|
|
528
321
|
const newOptions = options?.filter((option) => option.id !== id) ?? [];
|
|
529
322
|
onValueChange(type, newOptions);
|
|
530
323
|
setSelectedId(null);
|
|
@@ -533,7 +326,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
533
326
|
type,
|
|
534
327
|
onValueChange
|
|
535
328
|
]);
|
|
536
|
-
const handleMove =
|
|
329
|
+
const handleMove = useCallback2((from, to) => {
|
|
537
330
|
if (!options) {
|
|
538
331
|
return;
|
|
539
332
|
}
|
|
@@ -548,10 +341,10 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
548
341
|
type,
|
|
549
342
|
onValueChange
|
|
550
343
|
]);
|
|
551
|
-
const handleClick =
|
|
344
|
+
const handleClick = useCallback2((id) => {
|
|
552
345
|
setSelectedId((current) => current === id ? null : id);
|
|
553
346
|
}, []);
|
|
554
|
-
const handleTitleChange =
|
|
347
|
+
const handleTitleChange = useCallback2((id) => (e) => {
|
|
555
348
|
const newOptions = options?.map((o) => o.id === id ? {
|
|
556
349
|
...o,
|
|
557
350
|
title: e.target.value
|
|
@@ -562,12 +355,12 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
562
355
|
type,
|
|
563
356
|
onValueChange
|
|
564
357
|
]);
|
|
565
|
-
const handleKeyDown =
|
|
358
|
+
const handleKeyDown = useCallback2((e) => {
|
|
566
359
|
if (e.key === "Enter") {
|
|
567
360
|
setSelectedId(null);
|
|
568
361
|
}
|
|
569
362
|
}, []);
|
|
570
|
-
const handleColorChange =
|
|
363
|
+
const handleColorChange = useCallback2((id) => (hue) => {
|
|
571
364
|
const newOptions = options?.map((o) => o.id === id ? {
|
|
572
365
|
...o,
|
|
573
366
|
color: hue
|
|
@@ -578,7 +371,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
578
371
|
type,
|
|
579
372
|
onValueChange
|
|
580
373
|
]);
|
|
581
|
-
|
|
374
|
+
useEffect2(() => {
|
|
582
375
|
if (selected && isNewOption && inputRef.current) {
|
|
583
376
|
inputRef.current.focus();
|
|
584
377
|
setIsNewOption(false);
|
|
@@ -587,11 +380,11 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
587
380
|
selected,
|
|
588
381
|
isNewOption
|
|
589
382
|
]);
|
|
590
|
-
return /* @__PURE__ */ React5.createElement(
|
|
383
|
+
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
591
384
|
validationValence: status
|
|
592
385
|
}, /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
593
386
|
error
|
|
594
|
-
}, /* @__PURE__ */ React5.createElement(
|
|
387
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement("div", {
|
|
595
388
|
role: "none"
|
|
596
389
|
}, options && /* @__PURE__ */ React5.createElement(List.Root, {
|
|
597
390
|
items: options,
|
|
@@ -619,11 +412,11 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
619
412
|
onClick: () => handleClick(item.id)
|
|
620
413
|
})), selected === item.id && /* @__PURE__ */ React5.createElement("div", {
|
|
621
414
|
className: "mis-4 mbs-2 flex flex-col gap-1"
|
|
622
|
-
}, /* @__PURE__ */ React5.createElement(
|
|
415
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, {
|
|
623
416
|
classNames: "text-xs"
|
|
624
417
|
}, t("select option label")), /* @__PURE__ */ React5.createElement("div", {
|
|
625
418
|
className: "flex flex-row items-center gap-1"
|
|
626
|
-
}, /* @__PURE__ */ React5.createElement(
|
|
419
|
+
}, /* @__PURE__ */ React5.createElement(Input4.TextInput, {
|
|
627
420
|
placeholder: t("select option label placeholder"),
|
|
628
421
|
ref: selected === item.id ? inputRef : void 0,
|
|
629
422
|
value: item.title,
|
|
@@ -635,7 +428,8 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
635
428
|
classNames: "p-0 m-0 !is-auto"
|
|
636
429
|
}, /* @__PURE__ */ React5.createElement(HuePicker, {
|
|
637
430
|
value: item.color,
|
|
638
|
-
onChange: handleColorChange(item.id)
|
|
431
|
+
onChange: handleColorChange(item.id),
|
|
432
|
+
rootVariant: "toolbar-button"
|
|
639
433
|
})), /* @__PURE__ */ React5.createElement(IconButton, {
|
|
640
434
|
icon: "ph--trash--fill",
|
|
641
435
|
iconOnly: true,
|
|
@@ -658,7 +452,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
|
|
|
658
452
|
|
|
659
453
|
// packages/ui/react-ui-form/src/components/Form/custom/TupleInput.tsx
|
|
660
454
|
import React6 from "react";
|
|
661
|
-
import { Input as
|
|
455
|
+
import { Input as Input5 } from "@dxos/react-ui";
|
|
662
456
|
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
663
457
|
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
664
458
|
var gridCols = [
|
|
@@ -670,13 +464,13 @@ var gridCols = [
|
|
|
670
464
|
var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
671
465
|
const { status, error } = getStatus();
|
|
672
466
|
const values = getValue3() ?? {};
|
|
673
|
-
return /* @__PURE__ */ React6.createElement(
|
|
467
|
+
return /* @__PURE__ */ React6.createElement(Input5.Root, {
|
|
674
468
|
validationValence: status
|
|
675
469
|
}, /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
676
470
|
error
|
|
677
|
-
}, /* @__PURE__ */ React6.createElement(
|
|
471
|
+
}, /* @__PURE__ */ React6.createElement(Input5.Label, null, label)), /* @__PURE__ */ React6.createElement("div", {
|
|
678
472
|
className: mx3("grid gap-2", gridCols[binding.length - 1])
|
|
679
|
-
}, binding.map((prop) => /* @__PURE__ */ React6.createElement(
|
|
473
|
+
}, binding.map((prop) => /* @__PURE__ */ React6.createElement(Input5.TextInput, {
|
|
680
474
|
key: prop,
|
|
681
475
|
type: "number",
|
|
682
476
|
disabled,
|
|
@@ -688,135 +482,417 @@ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValu
|
|
|
688
482
|
onBlur
|
|
689
483
|
}))));
|
|
690
484
|
};
|
|
691
|
-
|
|
692
|
-
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
693
|
-
import React7, { useCallback as
|
|
694
|
-
import { Input as
|
|
695
|
-
var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
696
|
-
const { status, error } = getStatus();
|
|
697
|
-
return /* @__PURE__ */ React7.createElement(
|
|
698
|
-
validationValence: status
|
|
699
|
-
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
700
|
-
error
|
|
701
|
-
}, /* @__PURE__ */ React7.createElement(
|
|
702
|
-
disabled,
|
|
703
|
-
placeholder,
|
|
704
|
-
value: getValue3() ?? "",
|
|
705
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
706
|
-
onBlur
|
|
707
|
-
}), inputOnly && /* @__PURE__ */ React7.createElement(
|
|
485
|
+
|
|
486
|
+
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
487
|
+
import React7, { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
488
|
+
import { Input as Input6, Select } from "@dxos/react-ui";
|
|
489
|
+
var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
490
|
+
const { status, error } = getStatus();
|
|
491
|
+
return /* @__PURE__ */ React7.createElement(Input6.Root, {
|
|
492
|
+
validationValence: status
|
|
493
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
494
|
+
error
|
|
495
|
+
}, /* @__PURE__ */ React7.createElement(Input6.Label, null, label)), /* @__PURE__ */ React7.createElement(Input6.TextInput, {
|
|
496
|
+
disabled,
|
|
497
|
+
placeholder,
|
|
498
|
+
value: getValue3() ?? "",
|
|
499
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
500
|
+
onBlur
|
|
501
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input6.Validation, null, error));
|
|
502
|
+
};
|
|
503
|
+
var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
504
|
+
const { status, error } = getStatus();
|
|
505
|
+
return /* @__PURE__ */ React7.createElement(Input6.Root, {
|
|
506
|
+
validationValence: status
|
|
507
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
508
|
+
error
|
|
509
|
+
}, /* @__PURE__ */ React7.createElement(Input6.Label, null, label)), /* @__PURE__ */ React7.createElement(Input6.TextInput, {
|
|
510
|
+
type: "number",
|
|
511
|
+
disabled,
|
|
512
|
+
placeholder,
|
|
513
|
+
value: getValue3() ?? 0,
|
|
514
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
515
|
+
onBlur
|
|
516
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input6.DescriptionAndValidation, null, error));
|
|
517
|
+
};
|
|
518
|
+
var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
|
|
519
|
+
const { status, error } = getStatus();
|
|
520
|
+
const checked = Boolean(getValue3());
|
|
521
|
+
return /* @__PURE__ */ React7.createElement(Input6.Root, {
|
|
522
|
+
validationValence: status
|
|
523
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
524
|
+
error
|
|
525
|
+
}, /* @__PURE__ */ React7.createElement(Input6.Label, null, label)), /* @__PURE__ */ React7.createElement(Input6.Switch, {
|
|
526
|
+
checked,
|
|
527
|
+
onCheckedChange: (value) => onValueChange(type, value)
|
|
528
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input6.DescriptionAndValidation, null, error));
|
|
529
|
+
};
|
|
530
|
+
var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
|
|
531
|
+
const { status, error } = getStatus();
|
|
532
|
+
return /* @__PURE__ */ React7.createElement(Input6.Root, {
|
|
533
|
+
validationValence: status
|
|
534
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
535
|
+
error
|
|
536
|
+
}, /* @__PURE__ */ React7.createElement(Input6.Label, null, label)), /* @__PURE__ */ React7.createElement(Select.Root, {
|
|
537
|
+
value: getValue3(),
|
|
538
|
+
onValueChange: (value) => onValueChange(type, value)
|
|
539
|
+
}, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
|
|
540
|
+
classNames: "is-full",
|
|
541
|
+
disabled,
|
|
542
|
+
placeholder
|
|
543
|
+
}), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
544
|
+
// NOTE: Numeric values are converted to and from strings.
|
|
545
|
+
/* @__PURE__ */ React7.createElement(Select.Option, {
|
|
546
|
+
key: String(value),
|
|
547
|
+
value: String(value)
|
|
548
|
+
}, label2 ?? String(value))
|
|
549
|
+
)))))), inputOnly && /* @__PURE__ */ React7.createElement(Input6.DescriptionAndValidation, null, error));
|
|
550
|
+
};
|
|
551
|
+
var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
552
|
+
const { status, error } = getStatus();
|
|
553
|
+
const textareaRef = useRef2(null);
|
|
554
|
+
const adjustHeight = useCallback3(() => {
|
|
555
|
+
const textarea = textareaRef.current;
|
|
556
|
+
if (textarea) {
|
|
557
|
+
textarea.style.blockSize = "auto";
|
|
558
|
+
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
559
|
+
}
|
|
560
|
+
}, []);
|
|
561
|
+
useEffect3(() => {
|
|
562
|
+
adjustHeight();
|
|
563
|
+
}, [
|
|
564
|
+
adjustHeight
|
|
565
|
+
]);
|
|
566
|
+
useEffect3(() => {
|
|
567
|
+
adjustHeight();
|
|
568
|
+
}, [
|
|
569
|
+
getValue3(),
|
|
570
|
+
adjustHeight
|
|
571
|
+
]);
|
|
572
|
+
return /* @__PURE__ */ React7.createElement(Input6.Root, {
|
|
573
|
+
validationValence: status
|
|
574
|
+
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
575
|
+
error
|
|
576
|
+
}, /* @__PURE__ */ React7.createElement(Input6.Label, null, label)), /* @__PURE__ */ React7.createElement(Input6.TextArea, {
|
|
577
|
+
ref: textareaRef,
|
|
578
|
+
disabled,
|
|
579
|
+
placeholder,
|
|
580
|
+
value: getValue3() ?? "",
|
|
581
|
+
classNames: "min-bs-auto max-h-40 overflow-auto",
|
|
582
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
583
|
+
onBlur,
|
|
584
|
+
style: {
|
|
585
|
+
resize: "none"
|
|
586
|
+
},
|
|
587
|
+
spellCheck: false
|
|
588
|
+
}), inputOnly && /* @__PURE__ */ React7.createElement(Input6.Validation, null, error));
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
592
|
+
import React12, { useEffect as useEffect6, useMemo as useMemo6, useRef as useRef3 } from "react";
|
|
593
|
+
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
594
|
+
|
|
595
|
+
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
596
|
+
import React9 from "react";
|
|
597
|
+
import { IconButton as IconButton2, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
598
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
|
599
|
+
|
|
600
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
601
|
+
import React8, { createContext, useContext, useEffect as useEffect5, useMemo as useMemo3 } from "react";
|
|
602
|
+
import { raise } from "@dxos/debug";
|
|
603
|
+
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
604
|
+
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
605
|
+
|
|
606
|
+
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
607
|
+
import { SchemaAST as AST } from "effect";
|
|
608
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo2, useState as useState3 } from "react";
|
|
609
|
+
import { getValue, setValue } from "@dxos/echo-schema";
|
|
610
|
+
import { createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
611
|
+
import { invariant } from "@dxos/invariant";
|
|
612
|
+
import { log } from "@dxos/log";
|
|
613
|
+
import { validateSchema } from "@dxos/schema";
|
|
614
|
+
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
|
|
615
|
+
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
616
|
+
invariant(AST.isTypeLiteral(schema.ast), void 0, {
|
|
617
|
+
F: __dxlog_file,
|
|
618
|
+
L: 93,
|
|
619
|
+
S: void 0,
|
|
620
|
+
A: [
|
|
621
|
+
"AST.isTypeLiteral(schema.ast)",
|
|
622
|
+
""
|
|
623
|
+
]
|
|
624
|
+
});
|
|
625
|
+
const [values, setValues] = useState3(initialValues);
|
|
626
|
+
useEffect4(() => {
|
|
627
|
+
setValues(initialValues);
|
|
628
|
+
}, [
|
|
629
|
+
initialValues
|
|
630
|
+
]);
|
|
631
|
+
const [touched, setTouched] = useState3(createKeySet(initialValues, false));
|
|
632
|
+
const [changed, setChanged] = useState3(createKeySet(initialValues, false));
|
|
633
|
+
const [errors, setErrors] = useState3({});
|
|
634
|
+
const [saving, setSaving] = useState3(false);
|
|
635
|
+
const validate = useCallback4((values2) => {
|
|
636
|
+
let errors2 = validateSchema(schema, values2) ?? [];
|
|
637
|
+
if (errors2.length === 0 && onValidate) {
|
|
638
|
+
const validatedValues = values2;
|
|
639
|
+
errors2 = onValidate(validatedValues) ?? [];
|
|
640
|
+
}
|
|
641
|
+
setErrors(flatMap(errors2));
|
|
642
|
+
const valid = errors2.length === 0;
|
|
643
|
+
return valid;
|
|
644
|
+
}, [
|
|
645
|
+
schema,
|
|
646
|
+
onValidate
|
|
647
|
+
]);
|
|
648
|
+
const [schemaDirty, setSchemaDirty] = useState3(false);
|
|
649
|
+
useEffect4(() => setSchemaDirty(true), [
|
|
650
|
+
schema
|
|
651
|
+
]);
|
|
652
|
+
useEffect4(() => {
|
|
653
|
+
if (schemaDirty) {
|
|
654
|
+
validate(values);
|
|
655
|
+
setSchemaDirty(false);
|
|
656
|
+
}
|
|
657
|
+
}, [
|
|
658
|
+
values,
|
|
659
|
+
schemaDirty
|
|
660
|
+
]);
|
|
661
|
+
const formIsValid = useMemo2(() => {
|
|
662
|
+
return Object.keys(errors).length === 0;
|
|
663
|
+
}, [
|
|
664
|
+
errors
|
|
665
|
+
]);
|
|
666
|
+
const canSave = useMemo2(() => !saving && // Check if any error paths that are touched have errors.
|
|
667
|
+
!Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
|
|
668
|
+
touched,
|
|
669
|
+
errors,
|
|
670
|
+
saving
|
|
671
|
+
]);
|
|
672
|
+
const handleSave = useCallback4(async () => {
|
|
673
|
+
if (validate(values)) {
|
|
674
|
+
setSaving(true);
|
|
675
|
+
try {
|
|
676
|
+
await onSave?.(values, {
|
|
677
|
+
changed
|
|
678
|
+
});
|
|
679
|
+
} finally {
|
|
680
|
+
setSaving(false);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}, [
|
|
684
|
+
values,
|
|
685
|
+
validate,
|
|
686
|
+
onSave,
|
|
687
|
+
changed
|
|
688
|
+
]);
|
|
689
|
+
const getStatus = useCallback4((path) => {
|
|
690
|
+
const jsonPath = Array.isArray(path) ? createJsonPath(path) : path;
|
|
691
|
+
const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
|
|
692
|
+
const isTouched = touched[jsonPath];
|
|
693
|
+
if (!isTouched) {
|
|
694
|
+
return {
|
|
695
|
+
status: void 0,
|
|
696
|
+
error: void 0
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
return {
|
|
700
|
+
status: matchingError ? "error" : void 0,
|
|
701
|
+
error: matchingError ? matchingError[1] : void 0
|
|
702
|
+
};
|
|
703
|
+
}, [
|
|
704
|
+
errors,
|
|
705
|
+
touched
|
|
706
|
+
]);
|
|
707
|
+
const getFormValue = useCallback4((path) => {
|
|
708
|
+
return getValue(values, createJsonPath(path));
|
|
709
|
+
}, [
|
|
710
|
+
values
|
|
711
|
+
]);
|
|
712
|
+
const onValueChange = useCallback4((path, type, value) => {
|
|
713
|
+
const jsonPath = createJsonPath(path);
|
|
714
|
+
let parsedValue = value;
|
|
715
|
+
try {
|
|
716
|
+
if (type === "number") {
|
|
717
|
+
parsedValue = parseFloat(value) || 0;
|
|
718
|
+
}
|
|
719
|
+
} catch (err) {
|
|
720
|
+
log.catch(err, void 0, {
|
|
721
|
+
F: __dxlog_file,
|
|
722
|
+
L: 212,
|
|
723
|
+
S: void 0,
|
|
724
|
+
C: (f, a) => f(...a)
|
|
725
|
+
});
|
|
726
|
+
parsedValue = void 0;
|
|
727
|
+
}
|
|
728
|
+
const newValues = {
|
|
729
|
+
...setValue(values, jsonPath, parsedValue)
|
|
730
|
+
};
|
|
731
|
+
setValues(newValues);
|
|
732
|
+
setChanged((prev) => ({
|
|
733
|
+
...prev,
|
|
734
|
+
[jsonPath]: true
|
|
735
|
+
}));
|
|
736
|
+
onValuesChanged?.(newValues);
|
|
737
|
+
const isValid = validate(newValues);
|
|
738
|
+
if (isValid && onValid) {
|
|
739
|
+
onValid(newValues, {
|
|
740
|
+
changed
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
}, [
|
|
744
|
+
values,
|
|
745
|
+
onValuesChanged,
|
|
746
|
+
validate,
|
|
747
|
+
onValid,
|
|
748
|
+
changed
|
|
749
|
+
]);
|
|
750
|
+
const onTouched = useCallback4((path) => {
|
|
751
|
+
const jsonPath = createJsonPath(path);
|
|
752
|
+
setTouched((touched2) => ({
|
|
753
|
+
...touched2,
|
|
754
|
+
[jsonPath]: true
|
|
755
|
+
}));
|
|
756
|
+
validate(values);
|
|
757
|
+
}, [
|
|
758
|
+
validate,
|
|
759
|
+
values
|
|
760
|
+
]);
|
|
761
|
+
return useMemo2(() => ({
|
|
762
|
+
// State.
|
|
763
|
+
values,
|
|
764
|
+
errors,
|
|
765
|
+
touched,
|
|
766
|
+
changed,
|
|
767
|
+
canSave,
|
|
768
|
+
formIsValid,
|
|
769
|
+
// Actions.
|
|
770
|
+
handleSave,
|
|
771
|
+
// Field utils.
|
|
772
|
+
getStatus,
|
|
773
|
+
getValue: getFormValue,
|
|
774
|
+
onValueChange,
|
|
775
|
+
onTouched
|
|
776
|
+
}), [
|
|
777
|
+
values,
|
|
778
|
+
errors,
|
|
779
|
+
touched,
|
|
780
|
+
changed,
|
|
781
|
+
canSave,
|
|
782
|
+
formIsValid,
|
|
783
|
+
handleSave,
|
|
784
|
+
getStatus,
|
|
785
|
+
getFormValue,
|
|
786
|
+
onValueChange,
|
|
787
|
+
onTouched
|
|
788
|
+
]);
|
|
789
|
+
};
|
|
790
|
+
var createKeySet = (obj, value) => {
|
|
791
|
+
invariant(obj, void 0, {
|
|
792
|
+
F: __dxlog_file,
|
|
793
|
+
L: 274,
|
|
794
|
+
S: void 0,
|
|
795
|
+
A: [
|
|
796
|
+
"obj",
|
|
797
|
+
""
|
|
798
|
+
]
|
|
799
|
+
});
|
|
800
|
+
return Object.keys(obj).reduce((acc, key) => ({
|
|
801
|
+
...acc,
|
|
802
|
+
[key]: value
|
|
803
|
+
}), {});
|
|
708
804
|
};
|
|
709
|
-
var
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
disabled,
|
|
718
|
-
placeholder,
|
|
719
|
-
value: getValue3() ?? 0,
|
|
720
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
721
|
-
onBlur
|
|
722
|
-
}), inputOnly && /* @__PURE__ */ React7.createElement(Input5.DescriptionAndValidation, null, error));
|
|
805
|
+
var flatMap = (errors) => {
|
|
806
|
+
return errors.reduce((result, { path, message }) => {
|
|
807
|
+
const jsonPath = fromEffectValidationPath(path);
|
|
808
|
+
if (!(jsonPath in result)) {
|
|
809
|
+
result[jsonPath] = message;
|
|
810
|
+
}
|
|
811
|
+
return result;
|
|
812
|
+
}, {});
|
|
723
813
|
};
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
730
|
-
error
|
|
731
|
-
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Input5.Switch, {
|
|
732
|
-
checked,
|
|
733
|
-
onCheckedChange: (value) => onValueChange(type, value)
|
|
734
|
-
}), inputOnly && /* @__PURE__ */ React7.createElement(Input5.DescriptionAndValidation, null, error));
|
|
814
|
+
|
|
815
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
816
|
+
var FormContext = /* @__PURE__ */ createContext(void 0);
|
|
817
|
+
var useFormContext = () => {
|
|
818
|
+
return useContext(FormContext) ?? raise(new Error("Missing FormContext"));
|
|
735
819
|
};
|
|
736
|
-
var
|
|
737
|
-
const {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
741
|
-
error
|
|
742
|
-
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Select.Root, {
|
|
743
|
-
value: getValue3(),
|
|
744
|
-
onValueChange: (value) => onValueChange(type, value)
|
|
745
|
-
}, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
|
|
746
|
-
classNames: "is-full",
|
|
747
|
-
disabled,
|
|
748
|
-
placeholder
|
|
749
|
-
}), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
750
|
-
// NOTE: Numeric values are converted to and from strings.
|
|
751
|
-
/* @__PURE__ */ React7.createElement(Select.Option, {
|
|
752
|
-
key: String(value),
|
|
753
|
-
value: String(value)
|
|
754
|
-
}, label2 ?? String(value))
|
|
755
|
-
)))))), inputOnly && /* @__PURE__ */ React7.createElement(Input5.DescriptionAndValidation, null, error));
|
|
820
|
+
var useFormValues = (path = []) => {
|
|
821
|
+
const { values: formValues } = useFormContext();
|
|
822
|
+
const jsonPath = createJsonPath2(path);
|
|
823
|
+
return getValue2(formValues, jsonPath);
|
|
756
824
|
};
|
|
757
|
-
var
|
|
758
|
-
const {
|
|
759
|
-
const
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
825
|
+
var useInputProps = (path = []) => {
|
|
826
|
+
const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
|
|
827
|
+
const stablePath = useMemo3(() => path, [
|
|
828
|
+
Array.isArray(path) ? path.join(".") : path
|
|
829
|
+
]);
|
|
830
|
+
return useMemo3(() => ({
|
|
831
|
+
getStatus: () => getStatus(stablePath),
|
|
832
|
+
getValue: () => getFormValue(stablePath),
|
|
833
|
+
onValueChange: (type, value) => onValueChange(stablePath, type, value),
|
|
834
|
+
onBlur: () => onTouched(stablePath)
|
|
835
|
+
}), [
|
|
836
|
+
getStatus,
|
|
837
|
+
getFormValue,
|
|
838
|
+
onValueChange,
|
|
839
|
+
onTouched,
|
|
840
|
+
stablePath
|
|
771
841
|
]);
|
|
842
|
+
};
|
|
843
|
+
var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
844
|
+
const form = useForm(formOptions);
|
|
772
845
|
useEffect5(() => {
|
|
773
|
-
|
|
846
|
+
if (!formRef?.current) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
const handleKeyDown = (event) => {
|
|
850
|
+
const keyIsEnter = event.key === "Enter";
|
|
851
|
+
const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
|
|
852
|
+
const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
|
|
853
|
+
const inputOptOut = event.target.hasAttribute("data-no-submit");
|
|
854
|
+
const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
|
|
855
|
+
const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
|
|
856
|
+
if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
|
|
857
|
+
if (!autoSave && form.canSave) {
|
|
858
|
+
form.handleSave();
|
|
859
|
+
}
|
|
860
|
+
if (autoSave && form.formIsValid) {
|
|
861
|
+
event.target.blur();
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
const formElement = formRef.current;
|
|
866
|
+
formElement.addEventListener("keydown", handleKeyDown);
|
|
867
|
+
return () => formElement.removeEventListener("keydown", handleKeyDown);
|
|
774
868
|
}, [
|
|
775
|
-
|
|
776
|
-
|
|
869
|
+
formRef,
|
|
870
|
+
form.canSave,
|
|
871
|
+
form.formIsValid,
|
|
872
|
+
form.handleSave,
|
|
873
|
+
autoSave
|
|
777
874
|
]);
|
|
778
|
-
return /* @__PURE__ */
|
|
779
|
-
|
|
780
|
-
},
|
|
781
|
-
error
|
|
782
|
-
}, /* @__PURE__ */ React7.createElement(Input5.Label, null, label)), /* @__PURE__ */ React7.createElement(Input5.TextArea, {
|
|
783
|
-
ref: textareaRef,
|
|
784
|
-
disabled,
|
|
785
|
-
placeholder,
|
|
786
|
-
value: getValue3() ?? "",
|
|
787
|
-
classNames: "min-bs-auto max-h-40 overflow-auto",
|
|
788
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
789
|
-
onBlur,
|
|
790
|
-
style: {
|
|
791
|
-
resize: "none"
|
|
792
|
-
},
|
|
793
|
-
spellCheck: false
|
|
794
|
-
}), inputOnly && /* @__PURE__ */ React7.createElement(Input5.Validation, null, error));
|
|
875
|
+
return /* @__PURE__ */ React8.createElement(FormContext.Provider, {
|
|
876
|
+
value: form
|
|
877
|
+
}, children);
|
|
795
878
|
};
|
|
796
879
|
|
|
797
|
-
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
798
|
-
import React11, { useEffect as useEffect6, useMemo as useMemo6, useRef as useRef3 } from "react";
|
|
799
|
-
import { mx as mx7 } from "@dxos/react-ui-theme";
|
|
800
|
-
|
|
801
880
|
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
802
|
-
import React8 from "react";
|
|
803
|
-
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
804
|
-
import { mx as mx4 } from "@dxos/react-ui-theme";
|
|
805
881
|
var FormActions = ({ onCancel, readonly }) => {
|
|
806
|
-
const { t } =
|
|
882
|
+
const { t } = useTranslation4(translationKey);
|
|
807
883
|
const { canSave, handleSave } = useFormContext();
|
|
808
|
-
return /* @__PURE__ */
|
|
884
|
+
return /* @__PURE__ */ React9.createElement("div", {
|
|
809
885
|
role: "none",
|
|
810
886
|
className: "mt-2 flex justify-center"
|
|
811
|
-
}, /* @__PURE__ */
|
|
887
|
+
}, /* @__PURE__ */ React9.createElement("div", {
|
|
812
888
|
role: "none",
|
|
813
889
|
className: mx4(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
814
|
-
}, onCancel && !readonly && /* @__PURE__ */
|
|
890
|
+
}, onCancel && !readonly && /* @__PURE__ */ React9.createElement(IconButton2, {
|
|
815
891
|
"data-testid": "cancel-button",
|
|
816
892
|
icon: "ph--x--regular",
|
|
817
893
|
label: t("button cancel"),
|
|
818
894
|
onClick: onCancel
|
|
819
|
-
}), handleSave && /* @__PURE__ */
|
|
895
|
+
}), handleSave && /* @__PURE__ */ React9.createElement(IconButton2, {
|
|
820
896
|
type: "submit",
|
|
821
897
|
"data-testid": "save-button",
|
|
822
898
|
disabled: !canSave,
|
|
@@ -829,7 +905,7 @@ var FormActions = ({ onCancel, readonly }) => {
|
|
|
829
905
|
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
830
906
|
import { pipe as pipe2 } from "effect";
|
|
831
907
|
import { capitalize as capitalize2 } from "effect/String";
|
|
832
|
-
import
|
|
908
|
+
import React11, { useMemo as useMemo5 } from "react";
|
|
833
909
|
import { AST as AST3, S } from "@dxos/echo-schema";
|
|
834
910
|
import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
835
911
|
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
@@ -839,17 +915,17 @@ import { isNotFalsy } from "@dxos/util";
|
|
|
839
915
|
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
840
916
|
import { pipe } from "effect";
|
|
841
917
|
import { capitalize } from "effect/String";
|
|
842
|
-
import
|
|
918
|
+
import React10, { useCallback as useCallback5, useMemo as useMemo4 } from "react";
|
|
843
919
|
import { AST as AST2 } from "@dxos/echo-schema";
|
|
844
920
|
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
845
921
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
846
|
-
import { IconButton as IconButton3, useTranslation as
|
|
922
|
+
import { IconButton as IconButton3, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
847
923
|
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
848
924
|
import { getSchemaProperties } from "@dxos/schema";
|
|
849
925
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
850
926
|
var padding = "px-2";
|
|
851
927
|
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
852
|
-
const { t } =
|
|
928
|
+
const { t } = useTranslation5(translationKey);
|
|
853
929
|
const { ast, name, type, title } = property;
|
|
854
930
|
const values = useFormValues(path ?? []);
|
|
855
931
|
invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
|
|
@@ -908,20 +984,20 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
908
984
|
if (!elementType) {
|
|
909
985
|
return null;
|
|
910
986
|
}
|
|
911
|
-
return /* @__PURE__ */
|
|
987
|
+
return /* @__PURE__ */ React10.createElement("div", {
|
|
912
988
|
role: "none",
|
|
913
989
|
className: mx5(padding)
|
|
914
|
-
}, /* @__PURE__ */
|
|
990
|
+
}, /* @__PURE__ */ React10.createElement(InputHeader, null, label), /* @__PURE__ */ React10.createElement("div", {
|
|
915
991
|
role: "none",
|
|
916
992
|
className: "flex flex-col gap-1"
|
|
917
|
-
}, values.map((_value, index) => /* @__PURE__ */
|
|
993
|
+
}, values.map((_value, index) => /* @__PURE__ */ React10.createElement("div", {
|
|
918
994
|
key: index,
|
|
919
995
|
role: "none",
|
|
920
996
|
className: "flex items-center gap-1"
|
|
921
|
-
}, /* @__PURE__ */
|
|
997
|
+
}, /* @__PURE__ */ React10.createElement("div", {
|
|
922
998
|
role: "none",
|
|
923
999
|
className: "flex-1"
|
|
924
|
-
}, /* @__PURE__ */
|
|
1000
|
+
}, /* @__PURE__ */ React10.createElement(FormField, {
|
|
925
1001
|
property: {
|
|
926
1002
|
...property,
|
|
927
1003
|
array: false,
|
|
@@ -935,15 +1011,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
|
|
|
935
1011
|
inline: true,
|
|
936
1012
|
Custom,
|
|
937
1013
|
lookupComponent
|
|
938
|
-
})), /* @__PURE__ */
|
|
1014
|
+
})), /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
939
1015
|
icon: "ph--trash--regular",
|
|
940
1016
|
iconOnly: true,
|
|
941
1017
|
label: t("button remove"),
|
|
942
1018
|
onClick: () => handleRemove(index)
|
|
943
|
-
})))), /* @__PURE__ */
|
|
1019
|
+
})))), /* @__PURE__ */ React10.createElement("div", {
|
|
944
1020
|
role: "none",
|
|
945
1021
|
className: "flex justify-between items-center plb-1"
|
|
946
|
-
}, /* @__PURE__ */
|
|
1022
|
+
}, /* @__PURE__ */ React10.createElement(IconButton3, {
|
|
947
1023
|
icon: "ph--plus--regular",
|
|
948
1024
|
iconOnly: true,
|
|
949
1025
|
label: t("button add"),
|
|
@@ -995,14 +1071,14 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
995
1071
|
}
|
|
996
1072
|
});
|
|
997
1073
|
if (FoundComponent) {
|
|
998
|
-
return /* @__PURE__ */
|
|
1074
|
+
return /* @__PURE__ */ React11.createElement("div", {
|
|
999
1075
|
role: "none"
|
|
1000
1076
|
}, FoundComponent);
|
|
1001
1077
|
}
|
|
1002
1078
|
const jsonPath = createJsonPath3(path ?? []);
|
|
1003
1079
|
const CustomComponent = Custom?.[jsonPath];
|
|
1004
1080
|
if (CustomComponent) {
|
|
1005
|
-
return /* @__PURE__ */
|
|
1081
|
+
return /* @__PURE__ */ React11.createElement(CustomComponent, {
|
|
1006
1082
|
type,
|
|
1007
1083
|
format,
|
|
1008
1084
|
label,
|
|
@@ -1013,7 +1089,7 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1013
1089
|
});
|
|
1014
1090
|
}
|
|
1015
1091
|
if (array) {
|
|
1016
|
-
return /* @__PURE__ */
|
|
1092
|
+
return /* @__PURE__ */ React11.createElement(ArrayField, {
|
|
1017
1093
|
property,
|
|
1018
1094
|
path,
|
|
1019
1095
|
inputProps,
|
|
@@ -1023,9 +1099,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1023
1099
|
}
|
|
1024
1100
|
const InputComponent = getInputComponent(type, format);
|
|
1025
1101
|
if (InputComponent) {
|
|
1026
|
-
return /* @__PURE__ */
|
|
1102
|
+
return /* @__PURE__ */ React11.createElement("div", {
|
|
1027
1103
|
role: "none"
|
|
1028
|
-
}, /* @__PURE__ */
|
|
1104
|
+
}, /* @__PURE__ */ React11.createElement(InputComponent, {
|
|
1029
1105
|
type,
|
|
1030
1106
|
format,
|
|
1031
1107
|
label,
|
|
@@ -1036,9 +1112,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1036
1112
|
}));
|
|
1037
1113
|
}
|
|
1038
1114
|
if (options) {
|
|
1039
|
-
return /* @__PURE__ */
|
|
1115
|
+
return /* @__PURE__ */ React11.createElement("div", {
|
|
1040
1116
|
role: "none"
|
|
1041
|
-
}, /* @__PURE__ */
|
|
1117
|
+
}, /* @__PURE__ */ React11.createElement(SelectInput, {
|
|
1042
1118
|
type,
|
|
1043
1119
|
format,
|
|
1044
1120
|
disabled: readonly,
|
|
@@ -1056,9 +1132,9 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
|
|
|
1056
1132
|
const baseNode = findNode2(ast, isDiscriminatedUnion2);
|
|
1057
1133
|
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
|
|
1058
1134
|
if (typeLiteral) {
|
|
1059
|
-
return /* @__PURE__ */
|
|
1135
|
+
return /* @__PURE__ */ React11.createElement("div", {
|
|
1060
1136
|
role: "none"
|
|
1061
|
-
}, !inline && /* @__PURE__ */
|
|
1137
|
+
}, !inline && /* @__PURE__ */ React11.createElement("div", null, label), /* @__PURE__ */ React11.createElement(FormFields, {
|
|
1062
1138
|
schema: S.make(typeLiteral),
|
|
1063
1139
|
path,
|
|
1064
1140
|
readonly,
|
|
@@ -1080,11 +1156,11 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
|
|
|
1080
1156
|
filter,
|
|
1081
1157
|
sort
|
|
1082
1158
|
]);
|
|
1083
|
-
return /* @__PURE__ */
|
|
1159
|
+
return /* @__PURE__ */ React11.createElement("div", {
|
|
1084
1160
|
role: "form",
|
|
1085
1161
|
className: mx6("flex flex-col w-full gap-2")
|
|
1086
1162
|
}, properties.map((property) => {
|
|
1087
|
-
return /* @__PURE__ */
|
|
1163
|
+
return /* @__PURE__ */ React11.createElement(FormField, {
|
|
1088
1164
|
key: property.name,
|
|
1089
1165
|
property,
|
|
1090
1166
|
path: [
|
|
@@ -1115,7 +1191,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
|
|
|
1115
1191
|
}, [
|
|
1116
1192
|
autoFocus
|
|
1117
1193
|
]);
|
|
1118
|
-
return /* @__PURE__ */
|
|
1194
|
+
return /* @__PURE__ */ React12.createElement(FormProvider, {
|
|
1119
1195
|
formRef,
|
|
1120
1196
|
schema,
|
|
1121
1197
|
autoSave,
|
|
@@ -1124,12 +1200,12 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
|
|
|
1124
1200
|
onValidate,
|
|
1125
1201
|
onValid,
|
|
1126
1202
|
onSave
|
|
1127
|
-
}, /* @__PURE__ */
|
|
1203
|
+
}, /* @__PURE__ */ React12.createElement("div", {
|
|
1128
1204
|
ref: formRef,
|
|
1129
1205
|
role: "none",
|
|
1130
1206
|
className: mx7("p-2", classNames),
|
|
1131
1207
|
"data-testid": testId
|
|
1132
|
-
}, /* @__PURE__ */
|
|
1208
|
+
}, /* @__PURE__ */ React12.createElement(FormFields, {
|
|
1133
1209
|
schema,
|
|
1134
1210
|
path,
|
|
1135
1211
|
readonly,
|
|
@@ -1137,7 +1213,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
|
|
|
1137
1213
|
sort,
|
|
1138
1214
|
lookupComponent,
|
|
1139
1215
|
Custom
|
|
1140
|
-
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */
|
|
1216
|
+
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React12.createElement(FormActions, {
|
|
1141
1217
|
onCancel,
|
|
1142
1218
|
readonly
|
|
1143
1219
|
})));
|
|
@@ -1146,7 +1222,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
|
|
|
1146
1222
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
1147
1223
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1148
1224
|
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
1149
|
-
const { t } =
|
|
1225
|
+
const { t } = useTranslation6(translationKey);
|
|
1150
1226
|
const [props, setProps] = useState4(projection.getFieldProjection(field.id).props);
|
|
1151
1227
|
useEffect7(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1152
1228
|
field,
|
|
@@ -1247,26 +1323,26 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1247
1323
|
onSave
|
|
1248
1324
|
]);
|
|
1249
1325
|
const Custom = useMemo7(() => ({
|
|
1250
|
-
["format"]: (props2) => /* @__PURE__ */
|
|
1326
|
+
["format"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
|
|
1251
1327
|
...props2,
|
|
1252
1328
|
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
1253
1329
|
value,
|
|
1254
1330
|
label: t(`format ${value}`)
|
|
1255
1331
|
}))
|
|
1256
1332
|
}),
|
|
1257
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */
|
|
1333
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
|
|
1258
1334
|
...props2,
|
|
1259
1335
|
options: schemas.map((schema) => ({
|
|
1260
1336
|
value: schema.typename
|
|
1261
1337
|
}))
|
|
1262
1338
|
}),
|
|
1263
|
-
["referencePath"]: (props2) => /* @__PURE__ */
|
|
1339
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
|
|
1264
1340
|
...props2,
|
|
1265
1341
|
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
1266
1342
|
value: p.name
|
|
1267
1343
|
})) : []
|
|
1268
1344
|
}),
|
|
1269
|
-
["options"]: (props2) => /* @__PURE__ */
|
|
1345
|
+
["options"]: (props2) => /* @__PURE__ */ React13.createElement(SelectOptionInput, props2)
|
|
1270
1346
|
}), [
|
|
1271
1347
|
t,
|
|
1272
1348
|
schemas,
|
|
@@ -1284,7 +1360,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1284
1360
|
});
|
|
1285
1361
|
return null;
|
|
1286
1362
|
}
|
|
1287
|
-
return /* @__PURE__ */
|
|
1363
|
+
return /* @__PURE__ */ React13.createElement(Form, {
|
|
1288
1364
|
key: field.id,
|
|
1289
1365
|
autoFocus: true,
|
|
1290
1366
|
values: props,
|
|
@@ -1303,12 +1379,14 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
1303
1379
|
};
|
|
1304
1380
|
|
|
1305
1381
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
1306
|
-
import
|
|
1382
|
+
import React14, { useCallback as useCallback7, useMemo as useMemo8, useState as useState5 } from "react";
|
|
1307
1383
|
import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
|
|
1308
|
-
import {
|
|
1384
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
1385
|
+
import { IconButton as IconButton4, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1309
1386
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
1310
1387
|
import { ghostHover, inputTextLabel, mx as mx8 } from "@dxos/react-ui-theme";
|
|
1311
1388
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
1389
|
+
var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
1312
1390
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
1313
1391
|
var ViewMetaSchema = S2.Struct({
|
|
1314
1392
|
name: S2.String.annotations({
|
|
@@ -1319,8 +1397,8 @@ var ViewMetaSchema = S2.Struct({
|
|
|
1319
1397
|
})
|
|
1320
1398
|
}).pipe(S2.mutable);
|
|
1321
1399
|
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
1322
|
-
const { t } =
|
|
1323
|
-
const projection = useMemo8(() => new ViewProjection(schema, view), [
|
|
1400
|
+
const { t } = useTranslation7(translationKey);
|
|
1401
|
+
const projection = useMemo8(() => new ViewProjection(schema.jsonSchema, view), [
|
|
1324
1402
|
schema,
|
|
1325
1403
|
view
|
|
1326
1404
|
]);
|
|
@@ -1335,30 +1413,77 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1335
1413
|
}, [
|
|
1336
1414
|
view
|
|
1337
1415
|
]);
|
|
1338
|
-
const
|
|
1416
|
+
const handleSelect = useCallback7((field2) => {
|
|
1417
|
+
setField((f) => f === field2 ? void 0 : field2);
|
|
1418
|
+
}, []);
|
|
1419
|
+
const handleAdd = useCallback7(() => {
|
|
1420
|
+
invariant3(!schema.readonly, void 0, {
|
|
1421
|
+
F: __dxlog_file4,
|
|
1422
|
+
L: 76,
|
|
1423
|
+
S: void 0,
|
|
1424
|
+
A: [
|
|
1425
|
+
"!schema.readonly",
|
|
1426
|
+
""
|
|
1427
|
+
]
|
|
1428
|
+
});
|
|
1429
|
+
const field2 = projection.createFieldProjection();
|
|
1430
|
+
setField(field2);
|
|
1431
|
+
}, [
|
|
1432
|
+
schema,
|
|
1433
|
+
view
|
|
1434
|
+
]);
|
|
1435
|
+
const handleUpdate = useCallback7(({ name, typename }) => {
|
|
1436
|
+
invariant3(!schema.readonly, void 0, {
|
|
1437
|
+
F: __dxlog_file4,
|
|
1438
|
+
L: 83,
|
|
1439
|
+
S: void 0,
|
|
1440
|
+
A: [
|
|
1441
|
+
"!schema.readonly",
|
|
1442
|
+
""
|
|
1443
|
+
]
|
|
1444
|
+
});
|
|
1339
1445
|
requestAnimationFrame(() => {
|
|
1340
1446
|
if (view.name !== name) {
|
|
1341
1447
|
view.name = name;
|
|
1342
1448
|
}
|
|
1343
1449
|
if (view.query.typename !== typename) {
|
|
1344
|
-
onTypenameChanged(typename);
|
|
1450
|
+
onTypenameChanged?.(typename);
|
|
1345
1451
|
}
|
|
1346
1452
|
});
|
|
1347
1453
|
}, [
|
|
1348
|
-
view,
|
|
1349
1454
|
schema,
|
|
1455
|
+
view,
|
|
1350
1456
|
onTypenameChanged
|
|
1351
1457
|
]);
|
|
1352
|
-
const
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1458
|
+
const handleDelete = useCallback7((fieldId) => {
|
|
1459
|
+
invariant3(!schema.readonly, void 0, {
|
|
1460
|
+
F: __dxlog_file4,
|
|
1461
|
+
L: 99,
|
|
1462
|
+
S: void 0,
|
|
1463
|
+
A: [
|
|
1464
|
+
"!schema.readonly",
|
|
1465
|
+
""
|
|
1466
|
+
]
|
|
1467
|
+
});
|
|
1468
|
+
if (fieldId === field?.id) {
|
|
1469
|
+
setField(void 0);
|
|
1470
|
+
}
|
|
1471
|
+
onDelete?.(fieldId);
|
|
1358
1472
|
}, [
|
|
1359
|
-
|
|
1473
|
+
schema,
|
|
1474
|
+
field,
|
|
1475
|
+
onDelete
|
|
1360
1476
|
]);
|
|
1361
1477
|
const handleMove = useCallback7((fromIndex, toIndex) => {
|
|
1478
|
+
invariant3(!schema.readonly, void 0, {
|
|
1479
|
+
F: __dxlog_file4,
|
|
1480
|
+
L: 111,
|
|
1481
|
+
S: void 0,
|
|
1482
|
+
A: [
|
|
1483
|
+
"!schema.readonly",
|
|
1484
|
+
""
|
|
1485
|
+
]
|
|
1486
|
+
});
|
|
1362
1487
|
const fields = [
|
|
1363
1488
|
...view.fields
|
|
1364
1489
|
];
|
|
@@ -1366,57 +1491,97 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
1366
1491
|
fields.splice(toIndex, 0, moved);
|
|
1367
1492
|
view.fields = fields;
|
|
1368
1493
|
}, [
|
|
1494
|
+
schema,
|
|
1369
1495
|
view.fields
|
|
1370
1496
|
]);
|
|
1371
1497
|
const handleClose = useCallback7(() => setField(void 0), []);
|
|
1372
|
-
|
|
1498
|
+
const hiddenProperties = projection.getHiddenProperties();
|
|
1499
|
+
const handleHide = useCallback7((fieldId) => {
|
|
1500
|
+
setField(void 0);
|
|
1501
|
+
projection.hideFieldProjection(fieldId);
|
|
1502
|
+
}, [
|
|
1503
|
+
projection
|
|
1504
|
+
]);
|
|
1505
|
+
const handleShow = useCallback7((property) => {
|
|
1506
|
+
setField(void 0);
|
|
1507
|
+
projection.showFieldProjection(property);
|
|
1508
|
+
}, [
|
|
1509
|
+
projection
|
|
1510
|
+
]);
|
|
1511
|
+
return /* @__PURE__ */ React14.createElement("div", {
|
|
1373
1512
|
role: "none",
|
|
1374
1513
|
className: mx8("flex flex-col w-full divide-y divide-separator", classNames)
|
|
1375
|
-
}, /* @__PURE__ */
|
|
1514
|
+
}, /* @__PURE__ */ React14.createElement(Form, {
|
|
1376
1515
|
autoSave: true,
|
|
1377
1516
|
schema: ViewMetaSchema,
|
|
1378
1517
|
values: viewValues,
|
|
1379
|
-
onSave:
|
|
1380
|
-
}), /* @__PURE__ */
|
|
1518
|
+
onSave: schema.readonly ? void 0 : handleUpdate
|
|
1519
|
+
}), /* @__PURE__ */ React14.createElement("div", null, /* @__PURE__ */ React14.createElement("div", {
|
|
1381
1520
|
role: "none",
|
|
1382
1521
|
className: "p-2"
|
|
1383
|
-
}, /* @__PURE__ */
|
|
1522
|
+
}, /* @__PURE__ */ React14.createElement("label", {
|
|
1384
1523
|
className: mx8(inputTextLabel)
|
|
1385
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
1524
|
+
}, t("fields label"))), /* @__PURE__ */ React14.createElement(List2.Root, {
|
|
1386
1525
|
items: view.fields,
|
|
1387
1526
|
isItem: S2.is(FieldSchema),
|
|
1388
1527
|
getId: (field2) => field2.id,
|
|
1389
|
-
onMove: handleMove
|
|
1390
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
1528
|
+
onMove: schema.readonly ? void 0 : handleMove
|
|
1529
|
+
}, ({ items: fields }) => /* @__PURE__ */ React14.createElement(React14.Fragment, null, showHeading && /* @__PURE__ */ React14.createElement("div", {
|
|
1391
1530
|
role: "heading",
|
|
1392
1531
|
className: grid
|
|
1393
|
-
}, /* @__PURE__ */
|
|
1532
|
+
}, /* @__PURE__ */ React14.createElement("div", null), /* @__PURE__ */ React14.createElement("div", {
|
|
1394
1533
|
className: "flex items-center text-sm"
|
|
1395
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
1534
|
+
}, t("field path label"))), /* @__PURE__ */ React14.createElement("div", {
|
|
1396
1535
|
role: "list",
|
|
1397
1536
|
className: "flex flex-col w-full"
|
|
1398
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
1537
|
+
}, fields?.map((field2) => /* @__PURE__ */ React14.createElement(List2.Item, {
|
|
1399
1538
|
key: field2.id,
|
|
1400
1539
|
item: field2,
|
|
1401
1540
|
classNames: mx8(grid, ghostHover, "cursor-pointer")
|
|
1402
|
-
}, /* @__PURE__ */
|
|
1541
|
+
}, /* @__PURE__ */ React14.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React14.createElement(List2.ItemTitle, {
|
|
1403
1542
|
onClick: () => handleSelect(field2)
|
|
1404
|
-
}, field2.path), /* @__PURE__ */
|
|
1543
|
+
}, field2.path), /* @__PURE__ */ React14.createElement("div", {
|
|
1544
|
+
className: "flex items-center gap-2 -ml-4"
|
|
1545
|
+
}, /* @__PURE__ */ React14.createElement(List2.ItemButton, {
|
|
1546
|
+
icon: "ph--eye-slash--regular",
|
|
1547
|
+
disabled: view.fields.length <= 1,
|
|
1548
|
+
onClick: () => handleHide(field2.id)
|
|
1549
|
+
}), !schema.readonly && /* @__PURE__ */ React14.createElement(List2.ItemDeleteButton, {
|
|
1550
|
+
icon: "ph--trash--regular",
|
|
1405
1551
|
disabled: view.fields.length <= 1,
|
|
1406
|
-
onClick: () =>
|
|
1407
|
-
}))))))),
|
|
1552
|
+
onClick: () => handleDelete(field2.id)
|
|
1553
|
+
}))))))), hiddenProperties.length > 0 && /* @__PURE__ */ React14.createElement("div", null, /* @__PURE__ */ React14.createElement("div", {
|
|
1554
|
+
role: "none",
|
|
1555
|
+
className: "p-2"
|
|
1556
|
+
}, /* @__PURE__ */ React14.createElement("label", {
|
|
1557
|
+
className: mx8(inputTextLabel)
|
|
1558
|
+
}, t("hidden fields label"))), /* @__PURE__ */ React14.createElement(List2.Root, {
|
|
1559
|
+
items: hiddenProperties,
|
|
1560
|
+
isItem: (item) => typeof item === "string",
|
|
1561
|
+
getId: (property) => property
|
|
1562
|
+
}, ({ items: properties }) => /* @__PURE__ */ React14.createElement("div", {
|
|
1563
|
+
role: "list",
|
|
1564
|
+
className: "flex flex-col w-full"
|
|
1565
|
+
}, properties?.map((property) => /* @__PURE__ */ React14.createElement(List2.Item, {
|
|
1566
|
+
key: property,
|
|
1567
|
+
item: property,
|
|
1568
|
+
classNames: mx8(grid, ghostHover, "cursor-pointer")
|
|
1569
|
+
}, /* @__PURE__ */ React14.createElement("div", null), /* @__PURE__ */ React14.createElement(List2.ItemTitle, null, property), /* @__PURE__ */ React14.createElement(List2.ItemButton, {
|
|
1570
|
+
icon: "ph--eye--regular",
|
|
1571
|
+
onClick: () => handleShow(property)
|
|
1572
|
+
}))))))), field && /* @__PURE__ */ React14.createElement(FieldEditor, {
|
|
1408
1573
|
key: field.id,
|
|
1409
1574
|
view,
|
|
1410
1575
|
projection,
|
|
1411
1576
|
field,
|
|
1412
1577
|
registry,
|
|
1413
1578
|
onSave: handleClose
|
|
1414
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
1579
|
+
}), !readonly && !field && /* @__PURE__ */ React14.createElement("div", {
|
|
1415
1580
|
className: "flex p-2 justify-center"
|
|
1416
|
-
}, /* @__PURE__ */
|
|
1581
|
+
}, /* @__PURE__ */ React14.createElement(IconButton4, {
|
|
1417
1582
|
icon: "ph--plus--regular",
|
|
1418
1583
|
label: t("button add property"),
|
|
1419
|
-
onClick: handleAdd,
|
|
1584
|
+
onClick: schema.readonly ? void 0 : handleAdd,
|
|
1420
1585
|
// TODO(burdon): Show field limit in ux (not tooltip).
|
|
1421
1586
|
disabled: view.fields.length >= VIEW_FIELD_LIMIT
|
|
1422
1587
|
})));
|
|
@@ -1527,18 +1692,21 @@ var cellClassesForFieldType = ({ type, format }) => {
|
|
|
1527
1692
|
switch (format) {
|
|
1528
1693
|
case FormatEnum3.Markdown:
|
|
1529
1694
|
return void 0;
|
|
1695
|
+
case FormatEnum3.Time:
|
|
1530
1696
|
case FormatEnum3.Timestamp:
|
|
1531
1697
|
case FormatEnum3.DateTime:
|
|
1532
1698
|
case FormatEnum3.Date:
|
|
1533
|
-
case FormatEnum3.
|
|
1699
|
+
case FormatEnum3.Duration:
|
|
1534
1700
|
return [
|
|
1535
|
-
"font-mono"
|
|
1701
|
+
"font-mono",
|
|
1702
|
+
"text-right"
|
|
1536
1703
|
];
|
|
1537
1704
|
case FormatEnum3.Currency:
|
|
1538
1705
|
return [
|
|
1539
1706
|
"text-right"
|
|
1540
1707
|
];
|
|
1541
1708
|
case FormatEnum3.JSON:
|
|
1709
|
+
case FormatEnum3.DID:
|
|
1542
1710
|
return [
|
|
1543
1711
|
"font-mono"
|
|
1544
1712
|
];
|
|
@@ -1546,15 +1714,13 @@ var cellClassesForFieldType = ({ type, format }) => {
|
|
|
1546
1714
|
return void 0;
|
|
1547
1715
|
}
|
|
1548
1716
|
};
|
|
1549
|
-
var cellClassesForRowSelection = (selected) => selected ? [
|
|
1550
|
-
"!bg-gridCellSelected"
|
|
1551
|
-
] : void 0;
|
|
1552
1717
|
var pathNotUniqueError = (path) => ({
|
|
1553
1718
|
path: "path",
|
|
1554
1719
|
message: `'${path}' is already present`
|
|
1555
1720
|
});
|
|
1556
1721
|
|
|
1557
1722
|
// packages/ui/react-ui-form/src/util/formatting.ts
|
|
1723
|
+
import { format as formatDate } from "date-fns/format";
|
|
1558
1724
|
import { FormatEnum as FormatEnum4, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
|
|
1559
1725
|
var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
|
|
1560
1726
|
const formatScalar = (type2) => {
|
|
@@ -1596,17 +1762,14 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
|
|
|
1596
1762
|
maximumFractionDigits: 2
|
|
1597
1763
|
});
|
|
1598
1764
|
}
|
|
1599
|
-
case FormatEnum4.
|
|
1600
|
-
|
|
1765
|
+
case FormatEnum4.Date: {
|
|
1766
|
+
return formatDate(new Date(value), "yyyy-MM-dd");
|
|
1767
|
+
}
|
|
1601
1768
|
case FormatEnum4.Time: {
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
return date.toLocaleDateString(locale);
|
|
1607
|
-
} else {
|
|
1608
|
-
return date.toLocaleTimeString(locale);
|
|
1609
|
-
}
|
|
1769
|
+
return formatDate(new Date(value), "HH:mm:ss");
|
|
1770
|
+
}
|
|
1771
|
+
case FormatEnum4.DateTime: {
|
|
1772
|
+
return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
|
|
1610
1773
|
}
|
|
1611
1774
|
case FormatEnum4.GeoPoint: {
|
|
1612
1775
|
if (value === null || value === void 0) {
|
|
@@ -1683,10 +1846,18 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
|
1683
1846
|
};
|
|
1684
1847
|
export {
|
|
1685
1848
|
BooleanInput,
|
|
1849
|
+
ControlFrame,
|
|
1850
|
+
ControlFrameItem,
|
|
1851
|
+
ControlGroup,
|
|
1852
|
+
ControlItem,
|
|
1853
|
+
ControlItemInput,
|
|
1854
|
+
ControlSection,
|
|
1855
|
+
ControlSectionHeading,
|
|
1686
1856
|
DeprecatedFormContainer,
|
|
1687
1857
|
DeprecatedFormInput,
|
|
1688
1858
|
FieldEditor,
|
|
1689
1859
|
Form,
|
|
1860
|
+
FormProvider,
|
|
1690
1861
|
GeoPointInput,
|
|
1691
1862
|
InputHeader,
|
|
1692
1863
|
MarkdownInput,
|
|
@@ -1697,13 +1868,15 @@ export {
|
|
|
1697
1868
|
TupleInput,
|
|
1698
1869
|
ViewEditor,
|
|
1699
1870
|
cellClassesForFieldType,
|
|
1700
|
-
|
|
1871
|
+
controlItemClasses,
|
|
1701
1872
|
formatForDisplay,
|
|
1702
1873
|
formatForEditing,
|
|
1703
1874
|
parseValue,
|
|
1704
1875
|
pathNotUniqueError,
|
|
1705
1876
|
translations_default as translations,
|
|
1706
1877
|
useForm,
|
|
1707
|
-
|
|
1878
|
+
useFormContext,
|
|
1879
|
+
useFormValues,
|
|
1880
|
+
useInputProps
|
|
1708
1881
|
};
|
|
1709
1882
|
//# sourceMappingURL=index.mjs.map
|