@dxos/react-ui-form 0.7.5-labs.8a82073 → 0.7.5-labs.c0e040f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/lib/browser/index.mjs +398 -323
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +381 -302
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +398 -323
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/Form/Defaults.d.ts +1 -0
  11. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  13. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/FormContext.d.ts +4 -1
  15. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/index.d.ts +2 -0
  19. package/dist/types/src/components/Form/index.d.ts.map +1 -1
  20. package/dist/types/src/hooks/useForm.d.ts +1 -0
  21. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  22. package/package.json +24 -24
  23. package/src/components/Form/Defaults.tsx +59 -3
  24. package/src/components/Form/Form.tsx +8 -5
  25. package/src/components/Form/FormContent.tsx +9 -12
  26. package/src/components/Form/FormContext.tsx +48 -4
  27. package/src/components/Form/custom/SelectOptionsInput.tsx +5 -7
  28. package/src/components/Form/factory.tsx +3 -1
  29. package/src/components/Form/index.ts +3 -0
  30. package/src/components/ViewEditor/ViewEditor.tsx +2 -2
  31. package/src/hooks/useForm.ts +6 -0
@@ -35,6 +35,7 @@ __export(node_exports, {
35
35
  Form: () => Form,
36
36
  GeoPointInput: () => GeoPointInput,
37
37
  InputHeader: () => InputHeader,
38
+ MarkdownInput: () => MarkdownInput,
38
39
  NumberInput: () => NumberInput,
39
40
  SelectInput: () => SelectInput,
40
41
  SelectOptionInput: () => SelectOptionInput,
@@ -48,7 +49,8 @@ __export(node_exports, {
48
49
  parseValue: () => parseValue,
49
50
  pathNotUniqueError: () => pathNotUniqueError,
50
51
  translations: () => translations_default,
51
- useForm: () => useForm
52
+ useForm: () => useForm,
53
+ useFormValues: () => useFormValues
52
54
  });
53
55
  module.exports = __toCommonJS(node_exports);
54
56
  var import_react = __toESM(require("react"));
@@ -60,38 +62,38 @@ var import_log = require("@dxos/log");
60
62
  var import_react_ui2 = require("@dxos/react-ui");
61
63
  var import_schema = require("@dxos/schema");
62
64
  var import_react3 = __toESM(require("react"));
65
+ var import_debug = require("@dxos/debug");
66
+ var import_echo_schema2 = require("@dxos/echo-schema");
67
+ var import_effect = require("@dxos/effect");
68
+ var import_react4 = require("react");
69
+ var import_echo_schema3 = require("@dxos/echo-schema");
70
+ var import_effect2 = require("@dxos/effect");
71
+ var import_invariant = require("@dxos/invariant");
72
+ var import_log2 = require("@dxos/log");
73
+ var import_schema2 = require("@dxos/schema");
74
+ var import_react5 = __toESM(require("react"));
63
75
  var import_react_ui3 = require("@dxos/react-ui");
64
76
  var import_util = require("@dxos/util");
65
- var import_react4 = __toESM(require("react"));
77
+ var import_react6 = __toESM(require("react"));
66
78
  var import_react_ui4 = require("@dxos/react-ui");
67
79
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
68
- var import_react5 = __toESM(require("react"));
80
+ var import_react7 = __toESM(require("react"));
69
81
  var import_keys = require("@dxos/keys");
70
82
  var import_react_ui5 = require("@dxos/react-ui");
71
83
  var import_react_ui_list = require("@dxos/react-ui-list");
72
84
  var import_react_ui_pickers = require("@dxos/react-ui-pickers");
73
85
  var import_react_ui_theme3 = require("@dxos/react-ui-theme");
74
- var import_react6 = __toESM(require("react"));
86
+ var import_react8 = __toESM(require("react"));
75
87
  var import_react_ui6 = require("@dxos/react-ui");
76
88
  var import_react_ui_theme4 = require("@dxos/react-ui-theme");
77
89
  var import_util2 = require("@dxos/util");
78
- var import_react7 = __toESM(require("react"));
90
+ var import_react9 = __toESM(require("react"));
79
91
  var import_react_ui7 = require("@dxos/react-ui");
80
- var import_react8 = __toESM(require("react"));
92
+ var import_react10 = __toESM(require("react"));
81
93
  var import_react_ui_theme5 = require("@dxos/react-ui-theme");
82
- var import_react9 = __toESM(require("react"));
94
+ var import_react11 = __toESM(require("react"));
83
95
  var import_react_ui8 = require("@dxos/react-ui");
84
96
  var import_react_ui_theme6 = require("@dxos/react-ui-theme");
85
- var import_react10 = __toESM(require("react"));
86
- var import_debug = require("@dxos/debug");
87
- var import_echo_schema2 = require("@dxos/echo-schema");
88
- var import_effect = require("@dxos/effect");
89
- var import_react11 = require("react");
90
- var import_echo_schema3 = require("@dxos/echo-schema");
91
- var import_effect2 = require("@dxos/effect");
92
- var import_invariant = require("@dxos/invariant");
93
- var import_log2 = require("@dxos/log");
94
- var import_schema2 = require("@dxos/schema");
95
97
  var import_effect3 = require("effect");
96
98
  var import_String = require("effect/String");
97
99
  var import_react12 = __toESM(require("react"));
@@ -211,31 +213,256 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
211
213
  }
212
214
  return primary;
213
215
  };
216
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
217
+ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
218
+ (0, import_invariant.invariant)(import_effect2.AST.isTypeLiteral(schema.ast), void 0, {
219
+ F: __dxlog_file,
220
+ L: 92,
221
+ S: void 0,
222
+ A: [
223
+ "AST.isTypeLiteral(schema.ast)",
224
+ ""
225
+ ]
226
+ });
227
+ const [values, setValues] = (0, import_react4.useState)(initialValues);
228
+ (0, import_react4.useEffect)(() => {
229
+ setValues(initialValues);
230
+ }, [
231
+ initialValues
232
+ ]);
233
+ const [touched, setTouched] = (0, import_react4.useState)(createKeySet(initialValues, false));
234
+ const [changed, setChanged] = (0, import_react4.useState)(createKeySet(initialValues, false));
235
+ const [errors, setErrors] = (0, import_react4.useState)({});
236
+ const [saving, setSaving] = (0, import_react4.useState)(false);
237
+ const validate = (0, import_react4.useCallback)((values2) => {
238
+ let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
239
+ if (errors2.length === 0 && onValidate) {
240
+ const validatedValues = values2;
241
+ errors2 = onValidate(validatedValues) ?? [];
242
+ }
243
+ setErrors(flatMap(errors2));
244
+ const valid = errors2.length === 0;
245
+ return valid;
246
+ }, [
247
+ schema,
248
+ onValidate
249
+ ]);
250
+ const [schemaDirty, setSchemaDirty] = (0, import_react4.useState)(false);
251
+ (0, import_react4.useEffect)(() => setSchemaDirty(true), [
252
+ schema
253
+ ]);
254
+ (0, import_react4.useEffect)(() => {
255
+ if (schemaDirty) {
256
+ validate(values);
257
+ setSchemaDirty(false);
258
+ }
259
+ }, [
260
+ values,
261
+ schemaDirty
262
+ ]);
263
+ const formIsValid = (0, import_react4.useMemo)(() => {
264
+ return Object.keys(errors).length === 0;
265
+ }, [
266
+ errors
267
+ ]);
268
+ const canSave = (0, import_react4.useMemo)(() => !saving && // Check if any error paths that are touched have errors
269
+ !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
270
+ touched,
271
+ errors,
272
+ saving
273
+ ]);
274
+ const handleSave = (0, import_react4.useCallback)(async () => {
275
+ if (validate(values)) {
276
+ setSaving(true);
277
+ try {
278
+ await onSave?.(values, {
279
+ changed
280
+ });
281
+ } finally {
282
+ setSaving(false);
283
+ }
284
+ }
285
+ }, [
286
+ values,
287
+ validate,
288
+ onSave,
289
+ changed
290
+ ]);
291
+ const getStatus = (0, import_react4.useCallback)((path) => {
292
+ const jsonPath = Array.isArray(path) ? (0, import_effect2.createJsonPath)(path) : path;
293
+ const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
294
+ return {
295
+ status: matchingError ? "error" : void 0,
296
+ error: matchingError ? matchingError[1] : void 0
297
+ };
298
+ }, [
299
+ errors
300
+ ]);
301
+ const getFormValue = (path) => {
302
+ return (0, import_echo_schema3.getValue)(values, (0, import_effect2.createJsonPath)(path));
303
+ };
304
+ const onValueChange = (path, type, value) => {
305
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
306
+ let parsedValue = value;
307
+ try {
308
+ if (type === "number") {
309
+ parsedValue = parseFloat(value) || 0;
310
+ }
311
+ } catch (err) {
312
+ import_log2.log.catch(err, void 0, {
313
+ F: __dxlog_file,
314
+ L: 198,
315
+ S: void 0,
316
+ C: (f, a) => f(...a)
317
+ });
318
+ parsedValue = void 0;
319
+ }
320
+ const newValues = {
321
+ ...(0, import_echo_schema3.setValue)(values, jsonPath, parsedValue)
322
+ };
323
+ setValues(newValues);
324
+ setChanged((prev) => ({
325
+ ...prev,
326
+ [jsonPath]: true
327
+ }));
328
+ onValuesChanged?.(newValues);
329
+ const isValid = validate(newValues);
330
+ if (isValid && onValid) {
331
+ onValid(newValues, {
332
+ changed
333
+ });
334
+ }
335
+ };
336
+ const onTouched = (0, import_react4.useCallback)((path) => {
337
+ const jsonPath = (0, import_effect2.createJsonPath)(path);
338
+ setTouched((touched2) => ({
339
+ ...touched2,
340
+ [jsonPath]: true
341
+ }));
342
+ validate(values);
343
+ }, [
344
+ validate,
345
+ values
346
+ ]);
347
+ return {
348
+ // State.
349
+ values,
350
+ errors,
351
+ touched,
352
+ changed,
353
+ canSave,
354
+ handleSave,
355
+ formIsValid,
356
+ // Field utils.
357
+ getStatus,
358
+ getValue: getFormValue,
359
+ onValueChange,
360
+ onTouched
361
+ };
362
+ };
363
+ var createKeySet = (obj, value) => {
364
+ (0, import_invariant.invariant)(obj, void 0, {
365
+ F: __dxlog_file,
366
+ L: 241,
367
+ S: void 0,
368
+ A: [
369
+ "obj",
370
+ ""
371
+ ]
372
+ });
373
+ return Object.keys(obj).reduce((acc, key) => ({
374
+ ...acc,
375
+ [key]: value
376
+ }), {});
377
+ };
378
+ var flatMap = (errors) => {
379
+ return errors.reduce((result, { path, message }) => {
380
+ const jsonPath = (0, import_effect2.fromEffectValidationPath)(path);
381
+ if (!(jsonPath in result)) {
382
+ result[jsonPath] = message;
383
+ }
384
+ return result;
385
+ }, {});
386
+ };
387
+ var FormContext = /* @__PURE__ */ (0, import_react3.createContext)(void 0);
388
+ var useFormContext = () => {
389
+ return (0, import_react3.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
390
+ };
391
+ var useFormValues = (path = []) => {
392
+ const { values: formValues } = useFormContext();
393
+ const jsonPath = (0, import_effect.createJsonPath)(path);
394
+ return (0, import_echo_schema2.getValue)(formValues, jsonPath);
395
+ };
396
+ var useInputProps = (path = []) => {
397
+ const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
398
+ return {
399
+ getStatus: () => getStatus(path),
400
+ getValue: () => getFormValue(path),
401
+ onValueChange: (type, value) => onValueChange(path, type, value),
402
+ onBlur: () => onTouched(path)
403
+ };
404
+ };
405
+ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
406
+ const form = useForm(formOptions);
407
+ (0, import_react3.useEffect)(() => {
408
+ if (!formRef?.current) {
409
+ return;
410
+ }
411
+ const handleKeyDown = (event) => {
412
+ const keyIsEnter = event.key === "Enter";
413
+ const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
414
+ const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
415
+ const inputOptOut = event.target.hasAttribute("data-no-submit");
416
+ const shouldSubmitRegularInput = !inputIsTextarea && keyIsEnter && !modifierUsed;
417
+ const shouldSubmitTextarea = inputIsTextarea && keyIsEnter && event.metaKey;
418
+ if ((shouldSubmitRegularInput || shouldSubmitTextarea) && !inputOptOut) {
419
+ if (!autoSave && form.canSave) {
420
+ form.handleSave();
421
+ }
422
+ if (autoSave && form.formIsValid) {
423
+ event.target.blur();
424
+ }
425
+ }
426
+ };
427
+ const formElement = formRef.current;
428
+ formElement.addEventListener("keydown", handleKeyDown);
429
+ return () => formElement.removeEventListener("keydown", handleKeyDown);
430
+ }, [
431
+ formRef,
432
+ form.canSave,
433
+ form.formIsValid,
434
+ form.handleSave,
435
+ autoSave
436
+ ]);
437
+ return /* @__PURE__ */ import_react3.default.createElement(FormContext.Provider, {
438
+ value: form
439
+ }, children);
440
+ };
214
441
  var InputHeader = ({ children, error }) => {
215
- return /* @__PURE__ */ import_react4.default.createElement("div", {
442
+ return /* @__PURE__ */ import_react6.default.createElement("div", {
216
443
  role: "none",
217
444
  className: "flex justify-between items-center mb-1"
218
- }, children, error && /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Trigger, {
445
+ }, children, error && /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Trigger, {
219
446
  asChild: true
220
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Icon, {
447
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Icon, {
221
448
  icon: "ph--warning--regular",
222
449
  size: 4,
223
450
  classNames: import_react_ui_theme2.errorText
224
- })), /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Content, {
451
+ })), /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Content, {
225
452
  side: "bottom"
226
- }, /* @__PURE__ */ import_react4.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
453
+ }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui4.Tooltip.Arrow, null), error)));
227
454
  };
228
455
  var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
229
456
  const { t } = (0, import_react_ui3.useTranslation)(translationKey);
230
457
  const { status, error } = getStatus();
231
458
  const [lng = 0, lat = 0] = getValue3() ?? [];
232
- return /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Root, {
459
+ return /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Root, {
233
460
  validationValence: status
234
- }, /* @__PURE__ */ import_react3.default.createElement(InputHeader, {
461
+ }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
235
462
  error
236
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react3.default.createElement("div", {
463
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
237
464
  className: "grid grid-cols-2 gap-2"
238
- }, /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
465
+ }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
239
466
  type: "number",
240
467
  disabled,
241
468
  placeholder: t("placeholder longitude"),
@@ -245,7 +472,7 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
245
472
  (0, import_util.safeParseFloat)(event.target.value, 0)
246
473
  ]),
247
474
  onBlur
248
- }), /* @__PURE__ */ import_react3.default.createElement(import_react_ui3.Input.TextInput, {
475
+ }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui3.Input.TextInput, {
249
476
  type: "number",
250
477
  disabled,
251
478
  placeholder: t("placeholder latitude"),
@@ -258,13 +485,13 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
258
485
  })));
259
486
  };
260
487
  var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
261
- const [selected, setSelectedId] = (0, import_react5.useState)(null);
262
- const [isNewOption, setIsNewOption] = (0, import_react5.useState)(false);
263
- const inputRef = (0, import_react5.useRef)(null);
488
+ const [selected, setSelectedId] = (0, import_react7.useState)(null);
489
+ const [isNewOption, setIsNewOption] = (0, import_react7.useState)(false);
490
+ const inputRef = (0, import_react7.useRef)(null);
264
491
  const { t } = (0, import_react_ui5.useTranslation)(translationKey);
265
492
  const { status, error } = getStatus();
266
493
  const options = getValue3();
267
- (0, import_react5.useEffect)(() => {
494
+ (0, import_react7.useEffect)(() => {
268
495
  if (options === void 0) {
269
496
  onValueChange(type, []);
270
497
  }
@@ -275,16 +502,15 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
275
502
  ]);
276
503
  const randomHue = () => {
277
504
  const usedHues = new Set(options?.map((option) => option.color) ?? []);
278
- const hueKeys = Object.keys(import_react_ui_theme3.hueTokenThemes);
279
- const unusedHues = hueKeys.filter((hue) => !usedHues.has(hue));
505
+ const unusedHues = import_react_ui_theme3.hues.filter((hue) => !usedHues.has(hue));
280
506
  if (unusedHues.length > 0) {
281
507
  return unusedHues[Math.floor(Math.random() * unusedHues.length)];
282
508
  }
283
509
  const lastThree = new Set(options?.slice(-3).map((option) => option.color) ?? []);
284
- const availableHues = hueKeys.filter((hue) => !lastThree.has(hue));
285
- return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hueKeys[Math.floor(Math.random() * hueKeys.length)];
510
+ const availableHues = import_react_ui_theme3.hues.filter((hue) => !lastThree.has(hue));
511
+ return availableHues[Math.floor(Math.random() * availableHues.length)] ?? import_react_ui_theme3.hues[Math.floor(Math.random() * import_react_ui_theme3.hues.length)];
286
512
  };
287
- const handleAdd = (0, import_react5.useCallback)(() => {
513
+ const handleAdd = (0, import_react7.useCallback)(() => {
288
514
  const newId = import_keys.PublicKey.random().truncate();
289
515
  const newOption = {
290
516
  id: newId,
@@ -302,7 +528,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
302
528
  type,
303
529
  onValueChange
304
530
  ]);
305
- const handleDelete = (0, import_react5.useCallback)((id) => {
531
+ const handleDelete = (0, import_react7.useCallback)((id) => {
306
532
  const newOptions = options?.filter((option) => option.id !== id) ?? [];
307
533
  onValueChange(type, newOptions);
308
534
  setSelectedId(null);
@@ -311,7 +537,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
311
537
  type,
312
538
  onValueChange
313
539
  ]);
314
- const handleMove = (0, import_react5.useCallback)((from, to) => {
540
+ const handleMove = (0, import_react7.useCallback)((from, to) => {
315
541
  if (!options) {
316
542
  return;
317
543
  }
@@ -326,10 +552,10 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
326
552
  type,
327
553
  onValueChange
328
554
  ]);
329
- const handleClick = (0, import_react5.useCallback)((id) => {
555
+ const handleClick = (0, import_react7.useCallback)((id) => {
330
556
  setSelectedId((current) => current === id ? null : id);
331
557
  }, []);
332
- const handleTitleChange = (0, import_react5.useCallback)((id) => (e) => {
558
+ const handleTitleChange = (0, import_react7.useCallback)((id) => (e) => {
333
559
  const newOptions = options?.map((o) => o.id === id ? {
334
560
  ...o,
335
561
  title: e.target.value
@@ -340,12 +566,12 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
340
566
  type,
341
567
  onValueChange
342
568
  ]);
343
- const handleKeyDown = (0, import_react5.useCallback)((e) => {
569
+ const handleKeyDown = (0, import_react7.useCallback)((e) => {
344
570
  if (e.key === "Enter") {
345
571
  setSelectedId(null);
346
572
  }
347
573
  }, []);
348
- const handleColorChange = (0, import_react5.useCallback)((id) => (hue) => {
574
+ const handleColorChange = (0, import_react7.useCallback)((id) => (hue) => {
349
575
  const newOptions = options?.map((o) => o.id === id ? {
350
576
  ...o,
351
577
  color: hue
@@ -356,7 +582,7 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
356
582
  type,
357
583
  onValueChange
358
584
  ]);
359
- (0, import_react5.useEffect)(() => {
585
+ (0, import_react7.useEffect)(() => {
360
586
  if (selected && isNewOption && inputRef.current) {
361
587
  inputRef.current.focus();
362
588
  setIsNewOption(false);
@@ -365,70 +591,71 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
365
591
  selected,
366
592
  isNewOption
367
593
  ]);
368
- return /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Root, {
594
+ return /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Root, {
369
595
  validationValence: status
370
- }, /* @__PURE__ */ import_react5.default.createElement(InputHeader, {
596
+ }, /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
371
597
  error
372
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react5.default.createElement("div", {
598
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement("div", {
373
599
  role: "none"
374
- }, options && /* @__PURE__ */ import_react5.default.createElement(import_react_ui_list.List.Root, {
600
+ }, options && /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Root, {
375
601
  items: options,
376
602
  isItem: (item) => true,
377
603
  onMove: handleMove
378
- }, ({ items }) => /* @__PURE__ */ import_react5.default.createElement("div", {
604
+ }, ({ items }) => /* @__PURE__ */ import_react7.default.createElement("div", {
379
605
  role: "list",
380
606
  className: "w-full overflow-auto"
381
- }, items?.map((item) => /* @__PURE__ */ import_react5.default.createElement("div", {
607
+ }, items?.map((item) => /* @__PURE__ */ import_react7.default.createElement("div", {
382
608
  key: item.id
383
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui_list.List.Item, {
609
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.Item, {
384
610
  role: "button",
385
611
  item,
386
612
  classNames: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
387
613
  "aria-expanded": selected === item.id
388
- }, /* @__PURE__ */ import_react5.default.createElement("div", {
614
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
389
615
  className: "flex items-center"
390
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react5.default.createElement(import_react_ui_list.List.ItemTitle, {
616
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemDragHandle, null), /* @__PURE__ */ import_react7.default.createElement(import_react_ui_list.List.ItemTitle, {
391
617
  onClick: () => handleClick(item.id),
392
618
  classNames: "flex-1"
393
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Tag, {
619
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Tag, {
394
620
  palette: item.color
395
- }, item.title || "\u200B")), /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Icon, {
621
+ }, item.title || "\u200B")), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
396
622
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
397
623
  onClick: () => handleClick(item.id)
398
- })), selected === item.id && /* @__PURE__ */ import_react5.default.createElement("div", {
624
+ })), selected === item.id && /* @__PURE__ */ import_react7.default.createElement("div", {
399
625
  className: "mis-4 mbs-2 flex flex-col gap-1"
400
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.Label, {
626
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.Label, {
401
627
  classNames: "text-xs"
402
- }, t("select option label")), /* @__PURE__ */ import_react5.default.createElement("div", {
628
+ }, t("select option label")), /* @__PURE__ */ import_react7.default.createElement("div", {
403
629
  className: "flex flex-row items-center gap-1"
404
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Input.TextInput, {
630
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Input.TextInput, {
405
631
  placeholder: t("select option label placeholder"),
406
632
  ref: selected === item.id ? inputRef : void 0,
407
633
  value: item.title,
408
634
  onChange: handleTitleChange(item.id),
409
635
  onKeyDown: handleKeyDown,
410
- classNames: "flex-1"
411
- }), /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Toolbar.Root, {
636
+ classNames: "flex-1",
637
+ "data-no-submit": true
638
+ }), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Toolbar.Root, {
412
639
  classNames: "p-0 m-0 !is-auto"
413
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui_pickers.HuePickerToolbarButton, {
640
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui_pickers.HuePickerToolbarButton, {
414
641
  hue: item.color,
415
642
  onChangeHue: handleColorChange(item.id)
416
- })), /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.IconButton, {
643
+ })), /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.IconButton, {
417
644
  icon: "ph--trash--fill",
418
645
  iconOnly: true,
419
646
  label: t("select option delete"),
420
647
  onClick: () => handleDelete(item.id)
421
- })))))), /* @__PURE__ */ import_react5.default.createElement("div", {
648
+ })))))), /* @__PURE__ */ import_react7.default.createElement("div", {
422
649
  role: "listitem"
423
- }, /* @__PURE__ */ import_react5.default.createElement("div", {
650
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
424
651
  role: "button",
425
652
  className: (0, import_react_ui_theme3.mx)("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
426
653
  onClick: handleAdd
427
- }, /* @__PURE__ */ import_react5.default.createElement("div", {
654
+ }, /* @__PURE__ */ import_react7.default.createElement("div", {
428
655
  className: "flex items-center gap-1"
429
- }, /* @__PURE__ */ import_react5.default.createElement(import_react_ui5.Icon, {
656
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui5.Icon, {
430
657
  icon: "ph--plus--regular"
431
- }), /* @__PURE__ */ import_react5.default.createElement("span", {
658
+ }), /* @__PURE__ */ import_react7.default.createElement("span", {
432
659
  className: "text-sm"
433
660
  }, t("select option add")))))))));
434
661
  };
@@ -441,13 +668,13 @@ var gridCols = [
441
668
  var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
442
669
  const { status, error } = getStatus();
443
670
  const values = getValue3() ?? {};
444
- return /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Root, {
671
+ return /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Root, {
445
672
  validationValence: status
446
- }, /* @__PURE__ */ import_react6.default.createElement(InputHeader, {
673
+ }, /* @__PURE__ */ import_react8.default.createElement(InputHeader, {
447
674
  error
448
- }, /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react6.default.createElement("div", {
675
+ }, /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.Label, null, label)), /* @__PURE__ */ import_react8.default.createElement("div", {
449
676
  className: (0, import_react_ui_theme4.mx)("grid gap-2", gridCols[binding.length - 1])
450
- }, binding.map((prop) => /* @__PURE__ */ import_react6.default.createElement(import_react_ui6.Input.TextInput, {
677
+ }, binding.map((prop) => /* @__PURE__ */ import_react8.default.createElement(import_react_ui6.Input.TextInput, {
451
678
  key: prop,
452
679
  type: "number",
453
680
  disabled,
@@ -461,270 +688,120 @@ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValu
461
688
  };
462
689
  var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
463
690
  const { status, error } = getStatus();
464
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Root, {
691
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
465
692
  validationValence: status
466
- }, !inputOnly && /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
693
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
467
694
  error
468
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.TextInput, {
695
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
469
696
  disabled,
470
697
  placeholder,
471
698
  value: getValue3() ?? "",
472
699
  onChange: (event) => onValueChange(type, event.target.value),
473
700
  onBlur
474
- }), inputOnly && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Validation, null, error));
701
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Validation, null, error));
475
702
  };
476
703
  var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
477
704
  const { status, error } = getStatus();
478
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Root, {
705
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
479
706
  validationValence: status
480
- }, !inputOnly && /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
707
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
481
708
  error
482
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.TextInput, {
709
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextInput, {
483
710
  type: "number",
484
711
  disabled,
485
712
  placeholder,
486
713
  value: getValue3() ?? 0,
487
714
  onChange: (event) => onValueChange(type, event.target.value),
488
715
  onBlur
489
- }), inputOnly && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
716
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
490
717
  };
491
718
  var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
492
719
  const { status, error } = getStatus();
493
720
  const checked = Boolean(getValue3());
494
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Root, {
721
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
495
722
  validationValence: status
496
- }, !inputOnly && /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
723
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
497
724
  error
498
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Switch, {
725
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Switch, {
499
726
  checked,
500
727
  onCheckedChange: (value) => onValueChange(type, value)
501
- }), inputOnly && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
728
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
502
729
  };
503
730
  var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
504
731
  const { status, error } = getStatus();
505
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Root, {
732
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
506
733
  validationValence: status
507
- }, !inputOnly && /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
734
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
508
735
  error
509
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.Root, {
736
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Root, {
510
737
  value: getValue3(),
511
738
  onValueChange: (value) => onValueChange(type, value)
512
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.TriggerButton, {
739
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.TriggerButton, {
513
740
  classNames: "is-full",
514
741
  disabled,
515
742
  placeholder
516
- }), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.Portal, null, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.Content, null, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.Viewport, null, options?.map(({ value, label: label2 }) => (
743
+ }), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Portal, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Content, null, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Viewport, null, options?.map(({ value, label: label2 }) => (
517
744
  // NOTE: Numeric values are converted to and from strings.
518
- /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.Option, {
745
+ /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Option, {
519
746
  key: String(value),
520
747
  value: String(value)
521
748
  }, label2 ?? String(value))
522
- )))))), inputOnly && /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
749
+ )))))), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.DescriptionAndValidation, null, error));
523
750
  };
524
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
525
- var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
526
- (0, import_invariant.invariant)(import_effect2.AST.isTypeLiteral(schema.ast), void 0, {
527
- F: __dxlog_file,
528
- L: 91,
529
- S: void 0,
530
- A: [
531
- "AST.isTypeLiteral(schema.ast)",
532
- ""
533
- ]
534
- });
535
- const [values, setValues] = (0, import_react11.useState)(initialValues);
536
- (0, import_react11.useEffect)(() => {
537
- setValues(initialValues);
538
- }, [
539
- initialValues
540
- ]);
541
- const [touched, setTouched] = (0, import_react11.useState)(createKeySet(initialValues, false));
542
- const [changed, setChanged] = (0, import_react11.useState)(createKeySet(initialValues, false));
543
- const [errors, setErrors] = (0, import_react11.useState)({});
544
- const [saving, setSaving] = (0, import_react11.useState)(false);
545
- const validate = (0, import_react11.useCallback)((values2) => {
546
- let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
547
- if (errors2.length === 0 && onValidate) {
548
- const validatedValues = values2;
549
- errors2 = onValidate(validatedValues) ?? [];
550
- }
551
- setErrors(flatMap(errors2));
552
- const valid = errors2.length === 0;
553
- return valid;
554
- }, [
555
- schema,
556
- onValidate
557
- ]);
558
- const [schemaDirty, setSchemaDirty] = (0, import_react11.useState)(false);
559
- (0, import_react11.useEffect)(() => setSchemaDirty(true), [
560
- schema
561
- ]);
562
- (0, import_react11.useEffect)(() => {
563
- if (schemaDirty) {
564
- validate(values);
565
- setSchemaDirty(false);
566
- }
567
- }, [
568
- values,
569
- schemaDirty
570
- ]);
571
- const canSave = (0, import_react11.useMemo)(() => !saving && // Check if any error paths that are touched have errors
572
- !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
573
- touched,
574
- errors,
575
- saving
576
- ]);
577
- const handleSave = (0, import_react11.useCallback)(async () => {
578
- if (validate(values)) {
579
- setSaving(true);
580
- try {
581
- await onSave?.(values, {
582
- changed
583
- });
584
- } finally {
585
- setSaving(false);
586
- }
751
+ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
752
+ const { status, error } = getStatus();
753
+ const textareaRef = (0, import_react9.useRef)(null);
754
+ const adjustHeight = (0, import_react9.useCallback)(() => {
755
+ const textarea = textareaRef.current;
756
+ if (textarea) {
757
+ textarea.style.blockSize = "auto";
758
+ textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
587
759
  }
760
+ }, []);
761
+ (0, import_react9.useEffect)(() => {
762
+ adjustHeight();
588
763
  }, [
589
- values,
590
- validate,
591
- onSave,
592
- changed
764
+ adjustHeight
593
765
  ]);
594
- const getStatus = (0, import_react11.useCallback)((path) => {
595
- const jsonPath = Array.isArray(path) ? (0, import_effect2.createJsonPath)(path) : path;
596
- const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
597
- return {
598
- status: matchingError ? "error" : void 0,
599
- error: matchingError ? matchingError[1] : void 0
600
- };
766
+ (0, import_react9.useEffect)(() => {
767
+ adjustHeight();
601
768
  }, [
602
- errors
769
+ getValue3(),
770
+ adjustHeight
603
771
  ]);
604
- const getFormValue = (path) => {
605
- return (0, import_echo_schema3.getValue)(values, (0, import_effect2.createJsonPath)(path));
606
- };
607
- const onValueChange = (path, type, value) => {
608
- const jsonPath = (0, import_effect2.createJsonPath)(path);
609
- let parsedValue = value;
610
- try {
611
- if (type === "number") {
612
- parsedValue = parseFloat(value) || 0;
613
- }
614
- } catch (err) {
615
- import_log2.log.catch(err, void 0, {
616
- F: __dxlog_file,
617
- L: 193,
618
- S: void 0,
619
- C: (f, a) => f(...a)
620
- });
621
- parsedValue = void 0;
622
- }
623
- const newValues = {
624
- ...(0, import_echo_schema3.setValue)(values, jsonPath, parsedValue)
625
- };
626
- setValues(newValues);
627
- setChanged((prev) => ({
628
- ...prev,
629
- [jsonPath]: true
630
- }));
631
- onValuesChanged?.(newValues);
632
- const isValid = validate(newValues);
633
- if (isValid && onValid) {
634
- onValid(newValues, {
635
- changed
636
- });
637
- }
638
- };
639
- const onTouched = (0, import_react11.useCallback)((path) => {
640
- const jsonPath = (0, import_effect2.createJsonPath)(path);
641
- setTouched((touched2) => ({
642
- ...touched2,
643
- [jsonPath]: true
644
- }));
645
- validate(values);
646
- }, [
647
- validate,
648
- values
649
- ]);
650
- return {
651
- // State.
652
- values,
653
- errors,
654
- touched,
655
- changed,
656
- canSave,
657
- handleSave,
658
- // Field utils.
659
- getStatus,
660
- getValue: getFormValue,
661
- onValueChange,
662
- onTouched
663
- };
664
- };
665
- var createKeySet = (obj, value) => {
666
- (0, import_invariant.invariant)(obj, void 0, {
667
- F: __dxlog_file,
668
- L: 235,
669
- S: void 0,
670
- A: [
671
- "obj",
672
- ""
673
- ]
674
- });
675
- return Object.keys(obj).reduce((acc, key) => ({
676
- ...acc,
677
- [key]: value
678
- }), {});
679
- };
680
- var flatMap = (errors) => {
681
- return errors.reduce((result, { path, message }) => {
682
- const jsonPath = (0, import_effect2.fromEffectValidationPath)(path);
683
- if (!(jsonPath in result)) {
684
- result[jsonPath] = message;
685
- }
686
- return result;
687
- }, {});
688
- };
689
- var FormContext = /* @__PURE__ */ (0, import_react10.createContext)(void 0);
690
- var useFormContext = () => {
691
- return (0, import_react10.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
692
- };
693
- var useFormValues = (path = []) => {
694
- const { values: formValues } = useFormContext();
695
- const jsonPath = (0, import_effect.createJsonPath)(path);
696
- return (0, import_echo_schema2.getValue)(formValues, jsonPath);
697
- };
698
- var useInputProps = (path = []) => {
699
- const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
700
- return {
701
- getStatus: () => getStatus(path),
702
- getValue: () => getFormValue(path),
703
- onValueChange: (type, value) => onValueChange(path, type, value),
704
- onBlur: () => onTouched(path)
705
- };
706
- };
707
- var FormProvider = ({ children, ...formOptions }) => {
708
- const formHandler = useForm(formOptions);
709
- return /* @__PURE__ */ import_react10.default.createElement(FormContext.Provider, {
710
- value: formHandler
711
- }, children);
772
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
773
+ validationValence: status
774
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
775
+ error
776
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.TextArea, {
777
+ ref: textareaRef,
778
+ disabled,
779
+ placeholder,
780
+ value: getValue3() ?? "",
781
+ classNames: "min-bs-auto overflow-hidden",
782
+ onChange: (event) => onValueChange(type, event.target.value),
783
+ onBlur,
784
+ style: {
785
+ resize: "none"
786
+ },
787
+ spellCheck: false
788
+ }), inputOnly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Validation, null, error));
712
789
  };
713
790
  var FormActions = ({ onCancel, readonly }) => {
714
791
  const { t } = (0, import_react_ui8.useTranslation)(translationKey);
715
792
  const { canSave, handleSave } = useFormContext();
716
- return /* @__PURE__ */ import_react9.default.createElement("div", {
793
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
717
794
  role: "none",
718
795
  className: "mt-2 flex justify-center"
719
- }, /* @__PURE__ */ import_react9.default.createElement("div", {
796
+ }, /* @__PURE__ */ import_react11.default.createElement("div", {
720
797
  role: "none",
721
798
  className: (0, import_react_ui_theme6.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
722
- }, onCancel && !readonly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.IconButton, {
799
+ }, onCancel && !readonly && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
723
800
  "data-testid": "cancel-button",
724
801
  icon: "ph--x--regular",
725
802
  label: t("button cancel"),
726
803
  onClick: onCancel
727
- }), handleSave && /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.IconButton, {
804
+ }), handleSave && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
728
805
  type: "submit",
729
806
  "data-testid": "save-button",
730
807
  disabled: !canSave,
@@ -841,6 +918,8 @@ var getInputComponent = (type, format) => {
841
918
  switch (format) {
842
919
  case import_echo_schema6.FormatEnum.LatLng:
843
920
  return GeoPointInput;
921
+ case import_echo_schema6.FormatEnum.Markdown:
922
+ return MarkdownInput;
844
923
  }
845
924
  switch (type) {
846
925
  case "string":
@@ -882,20 +961,15 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
882
961
  const jsonPath = (0, import_effect4.createJsonPath)(path ?? []);
883
962
  const CustomComponent = Custom?.[jsonPath];
884
963
  if (CustomComponent) {
885
- return (
886
- // TODO(ZaymonFC): We should try to remove this div wrapper.
887
- /* @__PURE__ */ import_react12.default.createElement("div", {
888
- role: "none"
889
- }, /* @__PURE__ */ import_react12.default.createElement(CustomComponent, {
890
- type,
891
- format,
892
- label,
893
- inputOnly: inline,
894
- placeholder,
895
- disabled: readonly,
896
- ...inputProps
897
- }))
898
- );
964
+ return /* @__PURE__ */ import_react12.default.createElement(CustomComponent, {
965
+ type,
966
+ format,
967
+ label,
968
+ inputOnly: inline,
969
+ placeholder,
970
+ disabled: readonly,
971
+ ...inputProps
972
+ });
899
973
  }
900
974
  if (array) {
901
975
  return /* @__PURE__ */ import_react12.default.createElement(ArrayField, {
@@ -983,13 +1057,14 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
983
1057
  }).filter(import_util3.isNotFalsy));
984
1058
  };
985
1059
  var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
986
- const onValid = (0, import_react8.useMemo)(() => autoSave ? onSave : void 0, [
1060
+ const formRef = (0, import_react10.useRef)(null);
1061
+ const onValid = (0, import_react10.useMemo)(() => autoSave ? onSave : void 0, [
987
1062
  autoSave,
988
1063
  onSave
989
1064
  ]);
990
- (0, import_react8.useEffect)(() => {
991
- if (autoFocus) {
992
- const input = document.querySelector("input");
1065
+ (0, import_react10.useEffect)(() => {
1066
+ if (autoFocus && formRef.current) {
1067
+ const input = formRef.current.querySelector("input");
993
1068
  if (input) {
994
1069
  input.focus();
995
1070
  }
@@ -997,18 +1072,21 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
997
1072
  }, [
998
1073
  autoFocus
999
1074
  ]);
1000
- return /* @__PURE__ */ import_react8.default.createElement(FormProvider, {
1075
+ return /* @__PURE__ */ import_react10.default.createElement(FormProvider, {
1076
+ formRef,
1001
1077
  schema,
1078
+ autoSave,
1002
1079
  initialValues,
1003
1080
  onValuesChanged,
1004
1081
  onValidate,
1005
1082
  onValid,
1006
1083
  onSave
1007
- }, /* @__PURE__ */ import_react8.default.createElement("div", {
1084
+ }, /* @__PURE__ */ import_react10.default.createElement("div", {
1085
+ ref: formRef,
1008
1086
  role: "none",
1009
1087
  className: (0, import_react_ui_theme5.mx)("p-2", classNames),
1010
1088
  "data-testid": testId
1011
- }, /* @__PURE__ */ import_react8.default.createElement(FormFields, {
1089
+ }, /* @__PURE__ */ import_react10.default.createElement(FormFields, {
1012
1090
  schema,
1013
1091
  path,
1014
1092
  readonly,
@@ -1016,7 +1094,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1016
1094
  sort,
1017
1095
  lookupComponent,
1018
1096
  Custom
1019
- }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react8.default.createElement(FormActions, {
1097
+ }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react10.default.createElement(FormActions, {
1020
1098
  onCancel,
1021
1099
  readonly
1022
1100
  })));
@@ -1183,7 +1261,7 @@ var ViewMetaSchema = import_echo_schema7.S.Struct({
1183
1261
  name: import_echo_schema7.S.String.annotations({
1184
1262
  [import_echo_schema7.AST.TitleAnnotationId]: "View"
1185
1263
  }),
1186
- typename: import_echo_schema7.Format.DXN.annotations({
1264
+ typename: import_echo_schema7.Format.URL.annotations({
1187
1265
  [import_echo_schema7.AST.TitleAnnotationId]: "Typename"
1188
1266
  })
1189
1267
  }).pipe(import_echo_schema7.S.mutable);
@@ -1242,7 +1320,6 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1242
1320
  role: "none",
1243
1321
  className: (0, import_react_ui_theme9.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1244
1322
  }, /* @__PURE__ */ import_react14.default.createElement(Form, {
1245
- autoFocus: true,
1246
1323
  autoSave: true,
1247
1324
  schema: ViewMetaSchema,
1248
1325
  values: viewValues,
@@ -1514,6 +1591,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1514
1591
  Form,
1515
1592
  GeoPointInput,
1516
1593
  InputHeader,
1594
+ MarkdownInput,
1517
1595
  NumberInput,
1518
1596
  SelectInput,
1519
1597
  SelectOptionInput,
@@ -1527,6 +1605,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1527
1605
  parseValue,
1528
1606
  pathNotUniqueError,
1529
1607
  translations,
1530
- useForm
1608
+ useForm,
1609
+ useFormValues
1531
1610
  });
1532
1611
  //# sourceMappingURL=index.cjs.map