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