@dxos/react-ui-form 0.7.5-labs.071a3e2 → 0.7.5-labs.401163d

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 (32) hide show
  1. package/dist/lib/browser/index.mjs +402 -326
  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 +385 -305
  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 +402 -326
  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 +61 -4
  24. package/src/components/Form/Form.tsx +8 -5
  25. package/src/components/Form/FormActions.tsx +1 -1
  26. package/src/components/Form/FormContent.tsx +10 -13
  27. package/src/components/Form/FormContext.tsx +48 -4
  28. package/src/components/Form/custom/SelectOptionsInput.tsx +5 -7
  29. package/src/components/Form/factory.tsx +3 -1
  30. package/src/components/Form/index.ts +3 -0
  31. package/src/components/ViewEditor/ViewEditor.tsx +2 -2
  32. 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,269 +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
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Root, {
720
+ const checked = Boolean(getValue3());
721
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
494
722
  validationValence: status
495
- }, !inputOnly && /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
723
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
496
724
  error
497
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Switch, {
498
- checked: getValue3(),
725
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Label, null, label)), /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Switch, {
726
+ checked,
499
727
  onCheckedChange: (value) => onValueChange(type, value)
500
- }), 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));
501
729
  };
502
730
  var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
503
731
  const { status, error } = getStatus();
504
- return /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Input.Root, {
732
+ return /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Input.Root, {
505
733
  validationValence: status
506
- }, !inputOnly && /* @__PURE__ */ import_react7.default.createElement(InputHeader, {
734
+ }, !inputOnly && /* @__PURE__ */ import_react9.default.createElement(InputHeader, {
507
735
  error
508
- }, /* @__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, {
509
737
  value: getValue3(),
510
738
  onValueChange: (value) => onValueChange(type, value)
511
- }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.TriggerButton, {
739
+ }, /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.TriggerButton, {
512
740
  classNames: "is-full",
513
741
  disabled,
514
742
  placeholder
515
- }), /* @__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 }) => (
516
744
  // NOTE: Numeric values are converted to and from strings.
517
- /* @__PURE__ */ import_react7.default.createElement(import_react_ui7.Select.Option, {
745
+ /* @__PURE__ */ import_react9.default.createElement(import_react_ui7.Select.Option, {
518
746
  key: String(value),
519
747
  value: String(value)
520
748
  }, label2 ?? String(value))
521
- )))))), 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));
522
750
  };
523
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
524
- var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
525
- (0, import_invariant.invariant)(import_effect2.AST.isTypeLiteral(schema.ast), void 0, {
526
- F: __dxlog_file,
527
- L: 91,
528
- S: void 0,
529
- A: [
530
- "AST.isTypeLiteral(schema.ast)",
531
- ""
532
- ]
533
- });
534
- const [values, setValues] = (0, import_react11.useState)(initialValues);
535
- (0, import_react11.useEffect)(() => {
536
- setValues(initialValues);
537
- }, [
538
- initialValues
539
- ]);
540
- const [touched, setTouched] = (0, import_react11.useState)(createKeySet(initialValues, false));
541
- const [changed, setChanged] = (0, import_react11.useState)(createKeySet(initialValues, false));
542
- const [errors, setErrors] = (0, import_react11.useState)({});
543
- const [saving, setSaving] = (0, import_react11.useState)(false);
544
- const validate = (0, import_react11.useCallback)((values2) => {
545
- let errors2 = (0, import_schema2.validateSchema)(schema, values2) ?? [];
546
- if (errors2.length === 0 && onValidate) {
547
- const validatedValues = values2;
548
- errors2 = onValidate(validatedValues) ?? [];
549
- }
550
- setErrors(flatMap(errors2));
551
- const valid = errors2.length === 0;
552
- return valid;
553
- }, [
554
- schema,
555
- onValidate
556
- ]);
557
- const [schemaDirty, setSchemaDirty] = (0, import_react11.useState)(false);
558
- (0, import_react11.useEffect)(() => setSchemaDirty(true), [
559
- schema
560
- ]);
561
- (0, import_react11.useEffect)(() => {
562
- if (schemaDirty) {
563
- validate(values);
564
- setSchemaDirty(false);
565
- }
566
- }, [
567
- values,
568
- schemaDirty
569
- ]);
570
- const canSave = (0, import_react11.useMemo)(() => !saving && // Check if any error paths that are touched have errors
571
- !Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
572
- touched,
573
- errors,
574
- saving
575
- ]);
576
- const handleSave = (0, import_react11.useCallback)(async () => {
577
- if (validate(values)) {
578
- setSaving(true);
579
- try {
580
- await onSave?.(values, {
581
- changed
582
- });
583
- } finally {
584
- setSaving(false);
585
- }
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`;
586
759
  }
760
+ }, []);
761
+ (0, import_react9.useEffect)(() => {
762
+ adjustHeight();
587
763
  }, [
588
- values,
589
- validate,
590
- onSave,
591
- changed
764
+ adjustHeight
592
765
  ]);
593
- const getStatus = (0, import_react11.useCallback)((path) => {
594
- const jsonPath = Array.isArray(path) ? (0, import_effect2.createJsonPath)(path) : path;
595
- const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
596
- return {
597
- status: matchingError ? "error" : void 0,
598
- error: matchingError ? matchingError[1] : void 0
599
- };
766
+ (0, import_react9.useEffect)(() => {
767
+ adjustHeight();
600
768
  }, [
601
- errors
769
+ getValue3(),
770
+ adjustHeight
602
771
  ]);
603
- const getFormValue = (path) => {
604
- return (0, import_echo_schema3.getValue)(values, (0, import_effect2.createJsonPath)(path));
605
- };
606
- const onValueChange = (path, type, value) => {
607
- const jsonPath = (0, import_effect2.createJsonPath)(path);
608
- let parsedValue = value;
609
- try {
610
- if (type === "number") {
611
- parsedValue = parseFloat(value) || 0;
612
- }
613
- } catch (err) {
614
- import_log2.log.catch(err, void 0, {
615
- F: __dxlog_file,
616
- L: 193,
617
- S: void 0,
618
- C: (f, a) => f(...a)
619
- });
620
- parsedValue = void 0;
621
- }
622
- const newValues = {
623
- ...(0, import_echo_schema3.setValue)(values, jsonPath, parsedValue)
624
- };
625
- setValues(newValues);
626
- setChanged((prev) => ({
627
- ...prev,
628
- [jsonPath]: true
629
- }));
630
- onValuesChanged?.(newValues);
631
- const isValid = validate(newValues);
632
- if (isValid && onValid) {
633
- onValid(newValues, {
634
- changed
635
- });
636
- }
637
- };
638
- const onTouched = (0, import_react11.useCallback)((path) => {
639
- const jsonPath = (0, import_effect2.createJsonPath)(path);
640
- setTouched((touched2) => ({
641
- ...touched2,
642
- [jsonPath]: true
643
- }));
644
- validate(values);
645
- }, [
646
- validate,
647
- values
648
- ]);
649
- return {
650
- // State.
651
- values,
652
- errors,
653
- touched,
654
- changed,
655
- canSave,
656
- handleSave,
657
- // Field utils.
658
- getStatus,
659
- getValue: getFormValue,
660
- onValueChange,
661
- onTouched
662
- };
663
- };
664
- var createKeySet = (obj, value) => {
665
- (0, import_invariant.invariant)(obj, void 0, {
666
- F: __dxlog_file,
667
- L: 235,
668
- S: void 0,
669
- A: [
670
- "obj",
671
- ""
672
- ]
673
- });
674
- return Object.keys(obj).reduce((acc, key) => ({
675
- ...acc,
676
- [key]: value
677
- }), {});
678
- };
679
- var flatMap = (errors) => {
680
- return errors.reduce((result, { path, message }) => {
681
- const jsonPath = (0, import_effect2.fromEffectValidationPath)(path);
682
- if (!(jsonPath in result)) {
683
- result[jsonPath] = message;
684
- }
685
- return result;
686
- }, {});
687
- };
688
- var FormContext = /* @__PURE__ */ (0, import_react10.createContext)(void 0);
689
- var useFormContext = () => {
690
- return (0, import_react10.useContext)(FormContext) ?? (0, import_debug.raise)(new Error("Missing FormContext"));
691
- };
692
- var useFormValues = (path = []) => {
693
- const { values: formValues } = useFormContext();
694
- const jsonPath = (0, import_effect.createJsonPath)(path);
695
- return (0, import_echo_schema2.getValue)(formValues, jsonPath);
696
- };
697
- var useInputProps = (path = []) => {
698
- const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
699
- return {
700
- getStatus: () => getStatus(path),
701
- getValue: () => getFormValue(path),
702
- onValueChange: (type, value) => onValueChange(path, type, value),
703
- onBlur: () => onTouched(path)
704
- };
705
- };
706
- var FormProvider = ({ children, ...formOptions }) => {
707
- const formHandler = useForm(formOptions);
708
- return /* @__PURE__ */ import_react10.default.createElement(FormContext.Provider, {
709
- value: formHandler
710
- }, 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));
711
789
  };
712
790
  var FormActions = ({ onCancel, readonly }) => {
713
791
  const { t } = (0, import_react_ui8.useTranslation)(translationKey);
714
792
  const { canSave, handleSave } = useFormContext();
715
- return /* @__PURE__ */ import_react9.default.createElement("div", {
793
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
716
794
  role: "none",
717
- className: "flex justify-center"
718
- }, /* @__PURE__ */ import_react9.default.createElement("div", {
795
+ className: "mt-2 flex justify-center"
796
+ }, /* @__PURE__ */ import_react11.default.createElement("div", {
719
797
  role: "none",
720
798
  className: (0, import_react_ui_theme6.mx)(onCancel && !readonly && "grid grid-cols-2 gap-2")
721
- }, onCancel && !readonly && /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.IconButton, {
799
+ }, onCancel && !readonly && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
722
800
  "data-testid": "cancel-button",
723
801
  icon: "ph--x--regular",
724
802
  label: t("button cancel"),
725
803
  onClick: onCancel
726
- }), handleSave && /* @__PURE__ */ import_react9.default.createElement(import_react_ui8.IconButton, {
804
+ }), handleSave && /* @__PURE__ */ import_react11.default.createElement(import_react_ui8.IconButton, {
727
805
  type: "submit",
728
806
  "data-testid": "save-button",
729
807
  disabled: !canSave,
@@ -840,6 +918,8 @@ var getInputComponent = (type, format) => {
840
918
  switch (format) {
841
919
  case import_echo_schema6.FormatEnum.LatLng:
842
920
  return GeoPointInput;
921
+ case import_echo_schema6.FormatEnum.Markdown:
922
+ return MarkdownInput;
843
923
  }
844
924
  switch (type) {
845
925
  case "string":
@@ -881,20 +961,15 @@ var FormField = ({ property, path, readonly, inline, lookupComponent, Custom })
881
961
  const jsonPath = (0, import_effect4.createJsonPath)(path ?? []);
882
962
  const CustomComponent = Custom?.[jsonPath];
883
963
  if (CustomComponent) {
884
- return (
885
- // TODO(ZaymonFC): We should try to remove this div wrapper.
886
- /* @__PURE__ */ import_react12.default.createElement("div", {
887
- role: "none"
888
- }, /* @__PURE__ */ import_react12.default.createElement(CustomComponent, {
889
- type,
890
- format,
891
- label,
892
- inputOnly: inline,
893
- placeholder,
894
- disabled: readonly,
895
- ...inputProps
896
- }))
897
- );
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
+ });
898
973
  }
899
974
  if (array) {
900
975
  return /* @__PURE__ */ import_react12.default.createElement(ArrayField, {
@@ -966,7 +1041,7 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
966
1041
  ]);
967
1042
  return /* @__PURE__ */ import_react12.default.createElement("div", {
968
1043
  role: "form",
969
- className: (0, import_react_ui_theme7.mx)("flex flex-col w-full gap-2 py-2")
1044
+ className: (0, import_react_ui_theme7.mx)("flex flex-col w-full gap-2")
970
1045
  }, properties.map((property) => {
971
1046
  return /* @__PURE__ */ import_react12.default.createElement(FormField, {
972
1047
  key: property.name,
@@ -982,13 +1057,14 @@ var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custo
982
1057
  }).filter(import_util3.isNotFalsy));
983
1058
  };
984
1059
  var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
985
- 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, [
986
1062
  autoSave,
987
1063
  onSave
988
1064
  ]);
989
- (0, import_react8.useEffect)(() => {
990
- if (autoFocus) {
991
- const input = document.querySelector("input");
1065
+ (0, import_react10.useEffect)(() => {
1066
+ if (autoFocus && formRef.current) {
1067
+ const input = formRef.current.querySelector("input");
992
1068
  if (input) {
993
1069
  input.focus();
994
1070
  }
@@ -996,18 +1072,21 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
996
1072
  }, [
997
1073
  autoFocus
998
1074
  ]);
999
- return /* @__PURE__ */ import_react8.default.createElement(FormProvider, {
1075
+ return /* @__PURE__ */ import_react10.default.createElement(FormProvider, {
1076
+ formRef,
1000
1077
  schema,
1078
+ autoSave,
1001
1079
  initialValues,
1002
1080
  onValuesChanged,
1003
1081
  onValidate,
1004
1082
  onValid,
1005
1083
  onSave
1006
- }, /* @__PURE__ */ import_react8.default.createElement("div", {
1084
+ }, /* @__PURE__ */ import_react10.default.createElement("div", {
1085
+ ref: formRef,
1007
1086
  role: "none",
1008
1087
  className: (0, import_react_ui_theme5.mx)("p-2", classNames),
1009
1088
  "data-testid": testId
1010
- }, /* @__PURE__ */ import_react8.default.createElement(FormFields, {
1089
+ }, /* @__PURE__ */ import_react10.default.createElement(FormFields, {
1011
1090
  schema,
1012
1091
  path,
1013
1092
  readonly,
@@ -1015,7 +1094,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], autoFocus, r
1015
1094
  sort,
1016
1095
  lookupComponent,
1017
1096
  Custom
1018
- }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react8.default.createElement(FormActions, {
1097
+ }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ import_react10.default.createElement(FormActions, {
1019
1098
  onCancel,
1020
1099
  readonly
1021
1100
  })));
@@ -1182,7 +1261,7 @@ var ViewMetaSchema = import_echo_schema7.S.Struct({
1182
1261
  name: import_echo_schema7.S.String.annotations({
1183
1262
  [import_echo_schema7.AST.TitleAnnotationId]: "View"
1184
1263
  }),
1185
- typename: import_echo_schema7.Format.DXN.annotations({
1264
+ typename: import_echo_schema7.Format.URL.annotations({
1186
1265
  [import_echo_schema7.AST.TitleAnnotationId]: "Typename"
1187
1266
  })
1188
1267
  }).pipe(import_echo_schema7.S.mutable);
@@ -1241,7 +1320,6 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
1241
1320
  role: "none",
1242
1321
  className: (0, import_react_ui_theme9.mx)("flex flex-col w-full divide-y divide-separator", classNames)
1243
1322
  }, /* @__PURE__ */ import_react14.default.createElement(Form, {
1244
- autoFocus: true,
1245
1323
  autoSave: true,
1246
1324
  schema: ViewMetaSchema,
1247
1325
  values: viewValues,
@@ -1513,6 +1591,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1513
1591
  Form,
1514
1592
  GeoPointInput,
1515
1593
  InputHeader,
1594
+ MarkdownInput,
1516
1595
  NumberInput,
1517
1596
  SelectInput,
1518
1597
  SelectOptionInput,
@@ -1526,6 +1605,7 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1526
1605
  parseValue,
1527
1606
  pathNotUniqueError,
1528
1607
  translations,
1529
- useForm
1608
+ useForm,
1609
+ useFormValues
1530
1610
  });
1531
1611
  //# sourceMappingURL=index.cjs.map