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