@dxos/react-ui-form 0.8.4-main.5ea62a8 → 0.8.4-main.66e292d

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 (91) hide show
  1. package/dist/lib/browser/index.mjs +534 -348
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +534 -348
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +8 -7
  8. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  10. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +8 -7
  11. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  13. package/dist/types/src/components/Form/Form.d.ts +6 -5
  14. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/Form.stories.d.ts +52 -37
  16. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/FormContent.d.ts +5 -5
  19. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/FormContext.d.ts +4 -4
  21. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/Input.d.ts +2 -2
  23. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/RefField.d.ts +10 -6
  25. package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +8 -7
  27. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/factory.d.ts +2 -2
  29. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  30. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +41 -0
  31. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
  32. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +82 -0
  33. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
  34. package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
  35. package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
  36. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +20 -6
  37. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  38. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +13 -11
  39. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/index.d.ts +1 -0
  41. package/dist/types/src/components/index.d.ts.map +1 -1
  42. package/dist/types/src/hooks/useForm.d.ts +5 -5
  43. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  44. package/dist/types/src/hooks/useQueryRefOptions.d.ts +9 -3
  45. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -1
  47. package/dist/types/src/translations.d.ts +7 -6
  48. package/dist/types/src/translations.d.ts.map +1 -1
  49. package/dist/types/src/util/field.d.ts +3 -3
  50. package/dist/types/src/util/field.d.ts.map +1 -1
  51. package/dist/types/src/util/formatting.d.ts +2 -2
  52. package/dist/types/src/util/formatting.d.ts.map +1 -1
  53. package/dist/types/src/util/refs.d.ts +1 -1
  54. package/dist/types/src/util/refs.d.ts.map +1 -1
  55. package/dist/types/src/util/schema.d.ts +1 -1
  56. package/dist/types/src/util/schema.d.ts.map +1 -1
  57. package/dist/types/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +40 -37
  59. package/src/components/ControlSection/ControlSection.stories.tsx +4 -5
  60. package/src/components/ControlSection/ControlSection.tsx +1 -1
  61. package/src/components/FieldEditor/FieldEditor.stories.tsx +8 -7
  62. package/src/components/FieldEditor/FieldEditor.tsx +7 -4
  63. package/src/components/Form/ArrayField.tsx +7 -4
  64. package/src/components/Form/Defaults.tsx +1 -1
  65. package/src/components/Form/Form.stories.tsx +52 -52
  66. package/src/components/Form/Form.tsx +19 -9
  67. package/src/components/Form/FormActions.tsx +7 -2
  68. package/src/components/Form/FormContent.tsx +83 -23
  69. package/src/components/Form/FormContext.tsx +6 -6
  70. package/src/components/Form/Input.tsx +2 -2
  71. package/src/components/Form/RefField.tsx +50 -66
  72. package/src/components/Form/custom/GeoPointInput.tsx +1 -1
  73. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +5 -6
  74. package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
  75. package/src/components/Form/factory.tsx +7 -4
  76. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +207 -0
  77. package/src/components/ObjectPicker/ObjectPicker.tsx +161 -0
  78. package/src/components/ObjectPicker/index.ts +5 -0
  79. package/src/components/ViewEditor/ViewEditor.stories.tsx +112 -49
  80. package/src/components/ViewEditor/ViewEditor.test.tsx +6 -5
  81. package/src/components/ViewEditor/ViewEditor.tsx +277 -208
  82. package/src/components/index.ts +1 -0
  83. package/src/components/testing.tsx +2 -2
  84. package/src/hooks/useForm.ts +11 -8
  85. package/src/hooks/useQueryRefOptions.ts +15 -6
  86. package/src/hooks/useRefQueryLookupHandler.ts +5 -5
  87. package/src/translations.ts +7 -6
  88. package/src/util/field.ts +25 -25
  89. package/src/util/formatting.ts +22 -22
  90. package/src/util/refs.ts +7 -7
  91. package/src/util/schema.ts +2 -4
@@ -10,7 +10,7 @@ var translations = [
10
10
  "hidden fields label": "Hidden Fields",
11
11
  "empty readonly ref field label": "(none)",
12
12
  // TODO(burdon): Standardize field/property.
13
- "button add property": "Add property",
13
+ "add property button label": "Add property",
14
14
  "field property label": "Property",
15
15
  "field property placeholder": "Property name",
16
16
  "field format label": "Type",
@@ -23,11 +23,12 @@ var translations = [
23
23
  "show field label": "Show field",
24
24
  "hide field label": "Hide field",
25
25
  "delete field label": "Delete field",
26
+ "ref field combobox input placeholder": "Search\u2026",
26
27
  "ref field placeholder_one": "Select\u2026",
27
28
  "ref field placeholder_other": "Select items\u2026",
28
29
  // TODO(burdon): Factor out?
29
- "button cancel": "Cancel",
30
- "button save": "Save",
30
+ "cancel button label": "Cancel",
31
+ "save button label": "Save",
31
32
  // FormatEnum
32
33
  "format boolean": "Boolean",
33
34
  "format currency": "Currency",
@@ -41,7 +42,7 @@ var translations = [
41
42
  "format hostname": "Hostname",
42
43
  "format integer": "Integer",
43
44
  "format json": "JSON",
44
- "format latlng": "Geopoint",
45
+ "format lnglat": "Geopoint",
45
46
  "format markdown": "Markdown",
46
47
  "format percent": "Percent",
47
48
  "format ref": "Reference",
@@ -67,8 +68,8 @@ var translations = [
67
68
  "select option delete": "Delete",
68
69
  "select option add": "Add option",
69
70
  // System schema message.
70
- "system schema title": "System record type",
71
- "system schema description": "This is a system record type and cannot be modified, though the view can still be configured."
71
+ "system schema title": "System type",
72
+ "system schema description": "This is a system type and cannot be modified, though the view can still be configured."
72
73
  }
73
74
  }
74
75
  }
@@ -84,7 +85,8 @@ var ControlPage = ({ children, classNames, ...props }) => {
84
85
  var _effect = _useSignals();
85
86
  try {
86
87
  return /* @__PURE__ */ React.createElement(StackItem.Content, {
87
- classNames: "block overflow-y-auto [--control-spacing:var(--dx-trimMd)]"
88
+ scrollable: true,
89
+ classNames: "[--control-spacing:var(--dx-trimMd)]"
88
90
  }, /* @__PURE__ */ React.createElement("div", {
89
91
  role: "none",
90
92
  className: mx("pli-cardSpacingInline pbe-trimLg", classNames),
@@ -214,17 +216,17 @@ var ControlFrameItem = ({ title, description, children }) => {
214
216
  };
215
217
 
216
218
  // src/components/FieldEditor/FieldEditor.tsx
217
- import { useSignals as _useSignals13 } from "@preact-signals/safe-react/tracking";
218
- import React13, { useCallback as useCallback9, useEffect as useEffect8, useMemo as useMemo7, useState as useState6 } from "react";
219
- import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo-schema";
219
+ import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
220
+ import React14, { useCallback as useCallback12, useEffect as useEffect8, useMemo as useMemo7, useState as useState6 } from "react";
221
+ import { Format as Format5, FormatEnums, formatToType } from "@dxos/echo/internal";
220
222
  import { log as log3 } from "@dxos/log";
221
- import { useAsyncEffect, useTranslation as useTranslation8 } from "@dxos/react-ui";
222
- import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
223
+ import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
224
+ import { formatToAdditionalPropertyAttributes, getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
223
225
 
224
226
  // src/components/Form/custom/GeoPointInput.tsx
225
227
  import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
226
228
  import React3, { useCallback, useEffect, useMemo, useState } from "react";
227
- import { GeoLocation } from "@dxos/echo-schema";
229
+ import { GeoLocation } from "@dxos/echo/internal";
228
230
  import { Input as Input3, useTranslation as useTranslation2 } from "@dxos/react-ui";
229
231
  import { safeParseFloat } from "@dxos/util";
230
232
 
@@ -472,7 +474,7 @@ var SelectOptionInput = ({ type, label, readonly, getStatus, getValue: getValue3
472
474
  readonly: !!readonly
473
475
  }, ({ items }) => /* @__PURE__ */ React4.createElement("div", {
474
476
  role: "list",
475
- className: "w-full overflow-auto"
477
+ className: "is-full overflow-auto"
476
478
  }, items?.map((item) => /* @__PURE__ */ React4.createElement("div", {
477
479
  key: item.id
478
480
  }, /* @__PURE__ */ React4.createElement(List.Item, {
@@ -637,7 +639,7 @@ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, on
637
639
  }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, t(checked ? "boolean input true value" : "boolean input false value")) : /* @__PURE__ */ React6.createElement(Input6.Switch, {
638
640
  disabled: !!readonly,
639
641
  checked,
640
- onCheckedChange: (value) => onValueChange(type, value)
642
+ onCheckedChange: (value2) => onValueChange(type, value2)
641
643
  }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
642
644
  } finally {
643
645
  _effect.f();
@@ -647,29 +649,29 @@ var SelectInput = ({ type, label, inputOnly, readonly, placeholder, options, get
647
649
  var _effect = _useSignals6();
648
650
  try {
649
651
  const { status, error } = getStatus();
650
- const value = getValue3();
651
- const handleValueChange = useCallback3((value2) => onValueChange(type, value2), [
652
+ const value2 = getValue3();
653
+ const handleValueChange = useCallback3((value3) => onValueChange(type, value3), [
652
654
  type,
653
655
  onValueChange
654
656
  ]);
655
- return readonly && !value ? null : /* @__PURE__ */ React6.createElement(Input6.Root, {
657
+ return readonly && !value2 ? null : /* @__PURE__ */ React6.createElement(Input6.Root, {
656
658
  validationValence: status
657
659
  }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
658
660
  error,
659
661
  label
660
- }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value)?.label ?? String(value)) : /* @__PURE__ */ React6.createElement(Select.Root, {
661
- value,
662
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value2)?.label ?? String(value2)) : /* @__PURE__ */ React6.createElement(Select.Root, {
663
+ value: value2,
662
664
  onValueChange: handleValueChange
663
665
  }, /* @__PURE__ */ React6.createElement(Select.TriggerButton, {
664
666
  classNames: "is-full",
665
667
  disabled: !!readonly,
666
668
  placeholder
667
- }), /* @__PURE__ */ React6.createElement(Select.Portal, null, /* @__PURE__ */ React6.createElement(Select.Content, null, /* @__PURE__ */ React6.createElement(Select.Viewport, null, options?.map(({ value: value2, label: label2 }) => (
669
+ }), /* @__PURE__ */ React6.createElement(Select.Portal, null, /* @__PURE__ */ React6.createElement(Select.Content, null, /* @__PURE__ */ React6.createElement(Select.Viewport, null, options?.map(({ value: value3, label: label2 }) => (
668
670
  // NOTE: Numeric values are converted to and from strings.
669
671
  /* @__PURE__ */ React6.createElement(Select.Option, {
670
- key: String(value2),
671
- value: String(value2)
672
- }, label2 ?? String(value2))
672
+ key: String(value3),
673
+ value: String(value3)
674
+ }, label2 ?? String(value3))
673
675
  ))), /* @__PURE__ */ React6.createElement(Select.Arrow, null)))), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
674
676
  } finally {
675
677
  _effect.f();
@@ -708,7 +710,7 @@ var MarkdownInput = ({ type, label, inputOnly, readonly, placeholder, getStatus,
708
710
  disabled: !!readonly,
709
711
  placeholder,
710
712
  value: getValue3() ?? "",
711
- classNames: "min-bs-auto max-h-40 overflow-auto",
713
+ classNames: "min-bs-auto max-bs-40 overflow-auto",
712
714
  onChange: (event) => onValueChange(type, event.target.value),
713
715
  onBlur,
714
716
  style: {
@@ -722,9 +724,9 @@ var MarkdownInput = ({ type, label, inputOnly, readonly, placeholder, getStatus,
722
724
  };
723
725
 
724
726
  // src/components/Form/Form.tsx
725
- import { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
727
+ import { useSignals as _useSignals13 } from "@preact-signals/safe-react/tracking";
726
728
  import { useFocusFinders } from "@fluentui/react-tabster";
727
- import React12, { useEffect as useEffect7, useMemo as useMemo6, useRef as useRef3 } from "react";
729
+ import React13, { useCallback as useCallback11, useEffect as useEffect7, useRef as useRef3 } from "react";
728
730
  import { cardDialogOverflow, cardSpacing as cardSpacing2 } from "@dxos/react-ui-stack";
729
731
 
730
732
  // src/components/Form/FormActions.tsx
@@ -736,15 +738,15 @@ import { mx as mx4 } from "@dxos/react-ui-theme";
736
738
 
737
739
  // src/components/Form/FormContext.tsx
738
740
  import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
739
- import React7, { createContext, useCallback as useCallback6, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
741
+ import React7, { createContext, useCallback as useCallback7, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
740
742
  import { raise } from "@dxos/debug";
741
- import { getValue as getValue2 } from "@dxos/echo-schema";
743
+ import { getValue as getValue2 } from "@dxos/echo/internal";
742
744
  import { createJsonPath as createJsonPath2 } from "@dxos/effect";
743
745
 
744
746
  // src/hooks/useForm.ts
745
- import { SchemaAST } from "effect";
747
+ import * as SchemaAST from "effect/SchemaAST";
746
748
  import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo2, useState as useState3 } from "react";
747
- import { getValue, setValue } from "@dxos/echo-schema";
749
+ import { getValue, setValue } from "@dxos/echo/internal";
748
750
  import { createJsonPath, fromEffectValidationPath } from "@dxos/effect";
749
751
  import { invariant } from "@dxos/invariant";
750
752
  import { log } from "@dxos/log";
@@ -753,7 +755,7 @@ var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.t
753
755
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
754
756
  invariant(SchemaAST.isTypeLiteral(schema.ast), void 0, {
755
757
  F: __dxlog_file,
756
- L: 95,
758
+ L: 96,
757
759
  S: void 0,
758
760
  A: [
759
761
  "SchemaAST.isTypeLiteral(schema.ast)",
@@ -847,17 +849,17 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
847
849
  }, [
848
850
  values
849
851
  ]);
850
- const onValueChange = useCallback4((path, type, value) => {
852
+ const onValueChange = useCallback4((path, type, value2) => {
851
853
  const jsonPath = createJsonPath(path);
852
- let parsedValue = value;
854
+ let parsedValue = value2;
853
855
  try {
854
856
  if (type === "number") {
855
- parsedValue = parseFloat(value) || 0;
857
+ parsedValue = parseFloat(value2) || 0;
856
858
  }
857
859
  } catch (err) {
858
860
  log.catch(err, void 0, {
859
861
  F: __dxlog_file,
860
- L: 215,
862
+ L: 217,
861
863
  S: void 0,
862
864
  C: (f, a) => f(...a)
863
865
  });
@@ -867,15 +869,16 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
867
869
  ...setValue(values, jsonPath, parsedValue)
868
870
  };
869
871
  setValues(newValues);
870
- setChanged((prev) => ({
871
- ...prev,
872
+ const newChanged = {
873
+ ...changed,
872
874
  [jsonPath]: true
873
- }));
875
+ };
876
+ setChanged(newChanged);
874
877
  onValuesChanged?.(newValues);
875
878
  const isValid = validate(newValues);
876
879
  if (isValid && onValid) {
877
880
  onValid(newValues, {
878
- changed
881
+ changed: newChanged
879
882
  });
880
883
  }
881
884
  }, [
@@ -925,10 +928,10 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
925
928
  onTouched
926
929
  ]);
927
930
  };
928
- var createKeySet = (obj, value) => {
931
+ var createKeySet = (obj, value2) => {
929
932
  invariant(obj, void 0, {
930
933
  F: __dxlog_file,
931
- L: 277,
934
+ L: 280,
932
935
  S: void 0,
933
936
  A: [
934
937
  "obj",
@@ -937,7 +940,7 @@ var createKeySet = (obj, value) => {
937
940
  });
938
941
  return Object.keys(obj).reduce((acc, key) => ({
939
942
  ...acc,
940
- [key]: value
943
+ [key]: value2
941
944
  }), {});
942
945
  };
943
946
  var flatMap = (errors) => {
@@ -952,7 +955,7 @@ var flatMap = (errors) => {
952
955
 
953
956
  // src/hooks/useRefQueryLookupHandler.ts
954
957
  import { useCallback as useCallback5 } from "react";
955
- import { getObjectDXN } from "@dxos/echo-schema";
958
+ import { Obj } from "@dxos/echo";
956
959
  import { Filter } from "@dxos/react-client/echo";
957
960
  import { isNonNullable } from "@dxos/util";
958
961
  var useRefQueryLookupHandler = ({ space }) => {
@@ -963,13 +966,13 @@ var useRefQueryLookupHandler = ({ space }) => {
963
966
  const query = space.db.query(Filter.typename(typeInfo.typename));
964
967
  const { objects } = await query.run();
965
968
  return objects.map((object) => {
966
- const dxn = getObjectDXN(object);
969
+ const dxn = Obj.getDXN(object);
967
970
  if (!dxn) {
968
971
  return void 0;
969
972
  }
970
973
  const item = {
971
974
  dxn,
972
- label: object?.name ?? object?.id ?? ""
975
+ label: Obj.getLabel(object) ?? object?.id ?? ""
973
976
  };
974
977
  return item;
975
978
  }).filter(isNonNullable);
@@ -979,12 +982,14 @@ var useRefQueryLookupHandler = ({ space }) => {
979
982
  };
980
983
 
981
984
  // src/hooks/useQueryRefOptions.ts
982
- import { useEffect as useEffect5, useState as useState4 } from "react";
985
+ import { useCallback as useCallback6, useEffect as useEffect5, useState as useState4 } from "react";
983
986
  import { log as log2 } from "@dxos/log";
984
987
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts";
985
988
  var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
986
989
  const [options, setOptions] = useState4([]);
987
990
  const [loading, setLoading] = useState4(false);
991
+ const [state, setState] = useState4({});
992
+ const update = useCallback6(() => setState({}), []);
988
993
  useEffect5(() => {
989
994
  if (!refTypeInfo || !onQueryRefOptions) {
990
995
  return;
@@ -1004,7 +1009,7 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1004
1009
  } catch (error) {
1005
1010
  log2.error("Failed to fetch ref options:", error, {
1006
1011
  F: __dxlog_file2,
1007
- L: 42,
1012
+ L: 51,
1008
1013
  S: void 0,
1009
1014
  C: (f, a) => f(...a)
1010
1015
  });
@@ -1016,10 +1021,12 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1016
1021
  void fetchOptions();
1017
1022
  }, [
1018
1023
  refTypeInfo,
1019
- onQueryRefOptions
1024
+ onQueryRefOptions,
1025
+ state
1020
1026
  ]);
1021
1027
  return {
1022
1028
  options,
1029
+ update,
1023
1030
  loading
1024
1031
  };
1025
1032
  };
@@ -1042,7 +1049,7 @@ var useInputProps = (path = []) => {
1042
1049
  return useMemo3(() => ({
1043
1050
  getStatus: () => getStatus(stablePath),
1044
1051
  getValue: () => getFormValue(stablePath),
1045
- onValueChange: (type, value) => onValueChange(stablePath, type, value),
1052
+ onValueChange: (type, value2) => onValueChange(stablePath, type, value2),
1046
1053
  onBlur: () => onTouched(stablePath)
1047
1054
  }), [
1048
1055
  getStatus,
@@ -1056,7 +1063,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1056
1063
  var _effect = _useSignals7();
1057
1064
  try {
1058
1065
  const form = useForm(formOptions);
1059
- const handleKeyDown = useCallback6((event) => {
1066
+ const handleKeyDown = useCallback7((event) => {
1060
1067
  const keyIsEnter = event.key === "Enter";
1061
1068
  const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
1062
1069
  const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
@@ -1072,7 +1079,9 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1072
1079
  }
1073
1080
  }
1074
1081
  }, [
1075
- form,
1082
+ form.canSave,
1083
+ form.formIsValid,
1084
+ form.handleSave,
1076
1085
  autoSave
1077
1086
  ]);
1078
1087
  useEffect6(() => {
@@ -1109,14 +1118,14 @@ var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1109
1118
  }, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
1110
1119
  "data-testid": "cancel-button",
1111
1120
  icon: "ph--x--regular",
1112
- label: t("button cancel"),
1121
+ label: t("cancel button label"),
1113
1122
  onClick: onCancel
1114
1123
  }), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
1115
1124
  type: "submit",
1116
1125
  "data-testid": "save-button",
1117
1126
  disabled: !canSave,
1118
1127
  icon: "ph--check--regular",
1119
- label: t("button save"),
1128
+ label: t("save button label"),
1120
1129
  onClick: handleSave
1121
1130
  }));
1122
1131
  } finally {
@@ -1125,44 +1134,46 @@ var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1125
1134
  };
1126
1135
 
1127
1136
  // src/components/Form/FormContent.tsx
1128
- import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
1129
- import { Schema, SchemaAST as SchemaAST4, pipe as pipe2 } from "effect";
1130
- import { capitalize as capitalize2 } from "effect/String";
1131
- import React11, { forwardRef, useMemo as useMemo5 } from "react";
1137
+ import { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
1138
+ import * as Function2 from "effect/Function";
1139
+ import * as Schema from "effect/Schema";
1140
+ import * as SchemaAST4 from "effect/SchemaAST";
1141
+ import * as StringEffect from "effect/String";
1142
+ import React12, { Component, forwardRef as forwardRef2, useMemo as useMemo6 } from "react";
1132
1143
  import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
1133
1144
  import { mx as mx6 } from "@dxos/react-ui-theme";
1134
1145
  import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
1135
- import { isNotFalsy } from "@dxos/util";
1146
+ import { isTruthy } from "@dxos/util";
1136
1147
 
1137
1148
  // src/util/field.ts
1138
- import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1139
- var parseValue = ({ type, format, value }) => {
1140
- if (value === void 0 || value === null || value === "") {
1149
+ import { Format, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo/internal";
1150
+ var parseValue = ({ type, format, value: value2 }) => {
1151
+ if (value2 === void 0 || value2 === null || value2 === "") {
1141
1152
  return void 0;
1142
1153
  }
1143
1154
  const parseScalar = (type2) => {
1144
1155
  switch (type2) {
1145
1156
  case TypeEnum.Boolean: {
1146
- if (typeof value === "string") {
1147
- const lowercaseValue = value.toLowerCase();
1157
+ if (typeof value2 === "string") {
1158
+ const lowercaseValue = value2.toLowerCase();
1148
1159
  if (lowercaseValue === "0" || lowercaseValue === "false") {
1149
1160
  return false;
1150
1161
  } else if (lowercaseValue === "1" || lowercaseValue === "true") {
1151
1162
  return true;
1152
1163
  }
1153
1164
  }
1154
- return Boolean(value);
1165
+ return Boolean(value2);
1155
1166
  }
1156
1167
  case TypeEnum.Number: {
1157
- const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1168
+ const cleaned = typeof value2 === "string" ? value2.replace(/[^0-9.-]+/g, "") : value2;
1158
1169
  const num = Number(cleaned);
1159
1170
  return Number.isNaN(num) ? null : num;
1160
1171
  }
1161
1172
  case TypeEnum.String:
1162
1173
  case TypeEnum.Ref:
1163
- return String(value);
1174
+ return String(value2);
1164
1175
  default: {
1165
- return value;
1176
+ return value2;
1166
1177
  }
1167
1178
  }
1168
1179
  };
@@ -1170,28 +1181,28 @@ var parseValue = ({ type, format, value }) => {
1170
1181
  return parseScalar(type);
1171
1182
  }
1172
1183
  switch (format) {
1173
- case FormatEnum.Boolean:
1184
+ case Format.TypeFormat.Boolean:
1174
1185
  return parseScalar(TypeEnum.Boolean);
1175
- case FormatEnum.Number:
1176
- case FormatEnum.Percent:
1177
- case FormatEnum.Currency:
1186
+ case Format.TypeFormat.Number:
1187
+ case Format.TypeFormat.Percent:
1188
+ case Format.TypeFormat.Currency:
1178
1189
  return parseScalar(TypeEnum.Number);
1179
- case FormatEnum.String:
1180
- case FormatEnum.Markdown: {
1190
+ case Format.TypeFormat.String:
1191
+ case Format.TypeFormat.Markdown: {
1181
1192
  return parseScalar(TypeEnum.String);
1182
1193
  }
1183
- case FormatEnum.Ref:
1184
- throw new Error(`unexpected format: ${FormatEnum.Ref}`);
1185
- case FormatEnum.DateTime:
1186
- case FormatEnum.Date:
1187
- case FormatEnum.Time:
1188
- case FormatEnum.Timestamp: {
1189
- const date = new Date(value);
1194
+ case Format.TypeFormat.Ref:
1195
+ throw new Error(`unexpected format: ${Format.TypeFormat.Ref}`);
1196
+ case Format.TypeFormat.DateTime:
1197
+ case Format.TypeFormat.Date:
1198
+ case Format.TypeFormat.Time:
1199
+ case Format.TypeFormat.Timestamp: {
1200
+ const date = new Date(value2);
1190
1201
  return isNaN(date.getTime()) ? null : date;
1191
1202
  }
1192
- case FormatEnum.GeoPoint: {
1193
- if (typeof value === "string") {
1194
- const cleaned = value.replace(/[^0-9.,-]+/g, "");
1203
+ case Format.TypeFormat.GeoPoint: {
1204
+ if (typeof value2 === "string") {
1205
+ const cleaned = value2.replace(/[^0-9.,-]+/g, "");
1195
1206
  const parts = cleaned.split(",");
1196
1207
  if (parts.length === 2) {
1197
1208
  const lat = parseFloat(parts[0]);
@@ -1210,29 +1221,29 @@ var parseValue = ({ type, format, value }) => {
1210
1221
  ];
1211
1222
  }
1212
1223
  default: {
1213
- return value;
1224
+ return value2;
1214
1225
  }
1215
1226
  }
1216
1227
  };
1217
1228
  var cellClassesForFieldType = ({ type, format }) => {
1218
1229
  switch (format || type) {
1219
- case FormatEnum.Markdown:
1230
+ case Format.TypeFormat.Markdown:
1220
1231
  return void 0;
1221
- case FormatEnum.Time:
1222
- case FormatEnum.Timestamp:
1223
- case FormatEnum.DateTime:
1224
- case FormatEnum.Date:
1225
- case FormatEnum.Duration:
1232
+ case Format.TypeFormat.Time:
1233
+ case Format.TypeFormat.Timestamp:
1234
+ case Format.TypeFormat.DateTime:
1235
+ case Format.TypeFormat.Date:
1236
+ case Format.TypeFormat.Duration:
1226
1237
  return [
1227
1238
  "font-mono",
1228
1239
  "text-right"
1229
1240
  ];
1230
- case FormatEnum.Currency:
1241
+ case Format.TypeFormat.Currency:
1231
1242
  return [
1232
1243
  "text-right"
1233
1244
  ];
1234
- case FormatEnum.JSON:
1235
- case FormatEnum.DID:
1245
+ case Format.TypeFormat.JSON:
1246
+ case Format.TypeFormat.DID:
1236
1247
  return [
1237
1248
  "font-mono"
1238
1249
  ];
@@ -1257,19 +1268,19 @@ var pathNotUniqueError = (path) => ({
1257
1268
 
1258
1269
  // src/util/formatting.ts
1259
1270
  import { format as formatDate } from "date-fns/format";
1260
- import { FormatEnum as FormatEnum2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1261
- var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1271
+ import { Format as Format2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
1272
+ var formatForDisplay = ({ type, format, value: value2, locale = void 0 }) => {
1262
1273
  const formatScalar = (type2) => {
1263
1274
  switch (type2) {
1264
1275
  case TypeEnum2.Boolean:
1265
- return value.toLocaleString().toUpperCase();
1276
+ return value2.toLocaleString().toUpperCase();
1266
1277
  case TypeEnum2.Number:
1267
- return value.toLocaleString(locale);
1278
+ return value2.toLocaleString(locale);
1268
1279
  case TypeEnum2.String:
1269
1280
  case TypeEnum2.Ref:
1270
- return String(value);
1281
+ return String(value2);
1271
1282
  default: {
1272
- return String(value);
1283
+ return String(value2);
1273
1284
  }
1274
1285
  }
1275
1286
  };
@@ -1277,144 +1288,137 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1277
1288
  return formatScalar(type);
1278
1289
  }
1279
1290
  switch (format) {
1280
- case FormatEnum2.Boolean: {
1291
+ case Format2.TypeFormat.Boolean: {
1281
1292
  return formatScalar(TypeEnum2.Boolean);
1282
1293
  }
1283
- case FormatEnum2.Number: {
1294
+ case Format2.TypeFormat.Number: {
1284
1295
  return formatScalar(TypeEnum2.Number);
1285
1296
  }
1286
- case FormatEnum2.String:
1287
- case FormatEnum2.Ref: {
1297
+ case Format2.TypeFormat.String:
1298
+ case Format2.TypeFormat.Ref: {
1288
1299
  return formatScalar(TypeEnum2.String);
1289
1300
  }
1290
- case FormatEnum2.Percent: {
1291
- return `${value * 100}%`;
1301
+ case Format2.TypeFormat.Percent: {
1302
+ return `${value2 * 100}%`;
1292
1303
  }
1293
- case FormatEnum2.Currency: {
1294
- return value.toLocaleString(locale, {
1304
+ case Format2.TypeFormat.Currency: {
1305
+ return value2.toLocaleString(locale, {
1295
1306
  style: "currency",
1296
1307
  currency: "USD",
1297
1308
  minimumFractionDigits: 2,
1298
1309
  maximumFractionDigits: 2
1299
1310
  });
1300
1311
  }
1301
- case FormatEnum2.Date: {
1312
+ case Format2.TypeFormat.Date: {
1302
1313
  try {
1303
- return formatDate(new Date(value), "yyyy-MM-dd");
1314
+ return formatDate(new Date(value2), "yyyy-MM-dd");
1304
1315
  } catch (error) {
1305
1316
  return "Invalid Date";
1306
1317
  }
1307
1318
  }
1308
- case FormatEnum2.Time: {
1319
+ case Format2.TypeFormat.Time: {
1309
1320
  try {
1310
- return formatDate(new Date(value), "HH:mm:ss");
1321
+ return formatDate(new Date(value2), "HH:mm:ss");
1311
1322
  } catch (error) {
1312
1323
  return "Invalid Time";
1313
1324
  }
1314
1325
  }
1315
- case FormatEnum2.DateTime: {
1326
+ case Format2.TypeFormat.DateTime: {
1316
1327
  try {
1317
- return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
1328
+ return formatDate(new Date(value2), "yyyy-MM-dd HH:mm:ss");
1318
1329
  } catch (error) {
1319
1330
  return "Invalid DateTime";
1320
1331
  }
1321
1332
  }
1322
- case FormatEnum2.GeoPoint: {
1323
- if (value === null || value === void 0) {
1333
+ case Format2.TypeFormat.GeoPoint: {
1334
+ if (value2 === null || value2 === void 0) {
1324
1335
  return "";
1325
1336
  }
1326
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1327
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1337
+ if (Array.isArray(value2) && value2.length >= 2 && value2.every(Number.isFinite)) {
1338
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value2);
1328
1339
  return `${latitude},${longitude}`;
1329
1340
  }
1330
- return String(value);
1341
+ return String(value2);
1331
1342
  }
1332
1343
  default: {
1333
- if (value === null || value === "undefined") {
1344
+ if (value2 === null || value2 === "undefined") {
1334
1345
  return "";
1335
1346
  }
1336
- return String(value);
1347
+ return String(value2);
1337
1348
  }
1338
1349
  }
1339
1350
  };
1340
- var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1351
+ var formatForEditing = ({ type, format, value: value2, locale = void 0 }) => {
1341
1352
  const formatScalar = (type2) => {
1342
1353
  switch (type2) {
1343
1354
  case TypeEnum2.Boolean:
1344
1355
  case TypeEnum2.Number:
1345
1356
  case TypeEnum2.String:
1346
1357
  case TypeEnum2.Ref:
1347
- return String(value);
1358
+ return String(value2);
1348
1359
  default:
1349
- return String(value);
1360
+ return String(value2);
1350
1361
  }
1351
1362
  };
1352
1363
  if (!format) {
1353
1364
  return formatScalar(type);
1354
1365
  }
1355
1366
  switch (format) {
1356
- case FormatEnum2.Boolean:
1357
- case FormatEnum2.Number:
1358
- case FormatEnum2.String:
1359
- case FormatEnum2.Ref: {
1367
+ case Format2.TypeFormat.Boolean:
1368
+ case Format2.TypeFormat.Number:
1369
+ case Format2.TypeFormat.String:
1370
+ case Format2.TypeFormat.Ref: {
1360
1371
  return formatScalar(type);
1361
1372
  }
1362
- case FormatEnum2.Percent: {
1363
- return String(value * 100);
1373
+ case Format2.TypeFormat.Percent: {
1374
+ return String(value2 * 100);
1364
1375
  }
1365
- case FormatEnum2.Currency: {
1366
- return String(value);
1376
+ case Format2.TypeFormat.Currency: {
1377
+ return String(value2);
1367
1378
  }
1368
- case FormatEnum2.DateTime: {
1369
- const date = new Date(value);
1379
+ case Format2.TypeFormat.DateTime: {
1380
+ const date = new Date(value2);
1370
1381
  return date.toISOString();
1371
1382
  }
1372
- case FormatEnum2.Date: {
1373
- const date = new Date(value);
1383
+ case Format2.TypeFormat.Date: {
1384
+ const date = new Date(value2);
1374
1385
  return date.toISOString().split("T")[0];
1375
1386
  }
1376
- case FormatEnum2.Time: {
1377
- const date = new Date(value);
1387
+ case Format2.TypeFormat.Time: {
1388
+ const date = new Date(value2);
1378
1389
  return date.toISOString().split("T")[1].split(".")[0];
1379
1390
  }
1380
- case FormatEnum2.GeoPoint: {
1381
- if (value === null || value === void 0) {
1391
+ case Format2.TypeFormat.GeoPoint: {
1392
+ if (value2 === null || value2 === void 0) {
1382
1393
  return "";
1383
1394
  }
1384
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1385
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1395
+ if (Array.isArray(value2) && value2.length >= 2 && value2.every(Number.isFinite)) {
1396
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value2);
1386
1397
  return `${latitude},${longitude}`;
1387
1398
  }
1388
- return String(value);
1399
+ return String(value2);
1389
1400
  }
1390
1401
  default: {
1391
- return String(value);
1402
+ return String(value2);
1392
1403
  }
1393
1404
  }
1394
1405
  };
1395
1406
 
1396
1407
  // src/util/refs.ts
1397
- import { FormatEnum as FormatEnum3, ReferenceAnnotationId } from "@dxos/echo-schema";
1408
+ import { Format as Format3, ReferenceAnnotationId } from "@dxos/echo/internal";
1398
1409
  import { findAnnotation } from "@dxos/effect";
1399
1410
 
1400
1411
  // src/util/schema.ts
1401
- import { SchemaAST as SchemaAST2 } from "effect";
1412
+ import * as SchemaAST2 from "effect/SchemaAST";
1402
1413
  import { findNode } from "@dxos/effect";
1403
1414
  var findArrayElementType = (ast) => {
1404
1415
  const tupleType = findNode(ast, SchemaAST2.isTupleType);
1405
- const elementType = tupleType?.rest[0]?.type;
1406
- return elementType;
1416
+ return tupleType?.rest[0]?.type;
1407
1417
  };
1408
1418
 
1409
1419
  // src/util/refs.ts
1410
1420
  var getRefProps = (property) => {
1411
1421
  const { ast, format, array } = property;
1412
- if (format === FormatEnum3.Ref) {
1413
- return {
1414
- ast,
1415
- isArray: false
1416
- };
1417
- }
1418
1422
  if (array) {
1419
1423
  const elementType = findArrayElementType(ast);
1420
1424
  if (elementType) {
@@ -1427,14 +1431,21 @@ var getRefProps = (property) => {
1427
1431
  }
1428
1432
  }
1429
1433
  }
1434
+ if (format === Format3.TypeFormat.Ref) {
1435
+ return {
1436
+ ast,
1437
+ isArray: false
1438
+ };
1439
+ }
1430
1440
  return void 0;
1431
1441
  };
1432
1442
 
1433
1443
  // src/components/Form/ArrayField.tsx
1434
1444
  import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
1435
- import { SchemaAST as SchemaAST3, pipe } from "effect";
1436
- import { capitalize } from "effect/String";
1437
- import React9, { Fragment, useCallback as useCallback7 } from "react";
1445
+ import * as Function from "effect/Function";
1446
+ import * as SchemaAST3 from "effect/SchemaAST";
1447
+ import * as String2 from "effect/String";
1448
+ import React9, { Fragment, useCallback as useCallback8 } from "react";
1438
1449
  import { SimpleType, findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion } from "@dxos/effect";
1439
1450
  import { invariant as invariant2 } from "@dxos/invariant";
1440
1451
  import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
@@ -1448,14 +1459,14 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1448
1459
  const values = useFormValues(path ?? []) ?? [];
1449
1460
  invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
1450
1461
  F: __dxlog_file3,
1451
- L: 36,
1462
+ L: 37,
1452
1463
  S: void 0,
1453
1464
  A: [
1454
1465
  "Array.isArray(values)",
1455
1466
  "`Values at path ${path?.join('.')} must be an array.`"
1456
1467
  ]
1457
1468
  });
1458
- const label = title ?? pipe(name, capitalize);
1469
+ const label = title ?? Function.pipe(name, String2.capitalize);
1459
1470
  const elementType = findArrayElementType(ast);
1460
1471
  const getDefaultObjectValue = (typeNode) => {
1461
1472
  const baseNode = findNode2(typeNode, isDiscriminatedUnion);
@@ -1463,13 +1474,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1463
1474
  if (!typeLiteral) {
1464
1475
  return {};
1465
1476
  }
1466
- return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
1477
+ return Object.fromEntries(getSchemaProperties(typeLiteral, {}, {
1478
+ form: true
1479
+ }).map((prop) => [
1467
1480
  prop.name,
1468
1481
  prop.defaultValue
1469
1482
  ]));
1470
1483
  };
1471
1484
  const getDefaultValue = () => type === "object" && elementType ? getDefaultObjectValue(elementType) : SimpleType.getDefaultValue(type);
1472
- const handleAdd = useCallback7(() => {
1485
+ const handleAdd = useCallback8(() => {
1473
1486
  inputProps.onValueChange(type, [
1474
1487
  ...values,
1475
1488
  getDefaultValue()
@@ -1480,7 +1493,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1480
1493
  inputProps,
1481
1494
  values
1482
1495
  ]);
1483
- const handleRemove = useCallback7((index) => {
1496
+ const handleRemove = useCallback8((index) => {
1484
1497
  const newValues = values.filter((_, i) => i !== index);
1485
1498
  inputProps.onValueChange(type, newValues);
1486
1499
  }, [
@@ -1536,12 +1549,12 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1536
1549
  };
1537
1550
 
1538
1551
  // src/components/Form/factory.tsx
1539
- import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
1552
+ import { Format as Format4 } from "@dxos/echo/internal";
1540
1553
  var getInputComponent = (type, format) => {
1541
1554
  switch (format) {
1542
- case FormatEnum4.GeoPoint:
1555
+ case Format4.TypeFormat.GeoPoint:
1543
1556
  return GeoPointInput;
1544
- case FormatEnum4.Markdown:
1557
+ case Format4.TypeFormat.Markdown:
1545
1558
  return MarkdownInput;
1546
1559
  }
1547
1560
  switch (type) {
@@ -1555,33 +1568,129 @@ var getInputComponent = (type, format) => {
1555
1568
  };
1556
1569
 
1557
1570
  // src/components/Form/RefField.tsx
1558
- import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1559
- import React10, { useCallback as useCallback8, useMemo as useMemo4, useState as useState5 } from "react";
1560
- import { Expando, Ref, ReferenceAnnotationId as ReferenceAnnotationId2, getTypeAnnotation } from "@dxos/echo-schema";
1571
+ import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
1572
+ import "@dxos/lit-ui/dx-tag-picker.pcss";
1573
+ import React11, { useCallback as useCallback10, useMemo as useMemo5 } from "react";
1574
+ import { Expando, Ref, ReferenceAnnotationId as ReferenceAnnotationId2, getTypeAnnotation } from "@dxos/echo/internal";
1561
1575
  import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1562
1576
  import { DXN } from "@dxos/keys";
1563
- import { DxRefTag } from "@dxos/lit-ui/react";
1564
- import { Button as Button2, Icon as Icon2, Input as Input7, useTranslation as useTranslation7 } from "@dxos/react-ui";
1565
- import { PopoverCombobox } from "@dxos/react-ui-searchlist";
1566
- import { TagPickerItem } from "@dxos/react-ui-tag-picker";
1577
+ import { DxAnchor, DxTagPickerItem } from "@dxos/lit-ui/react";
1578
+ import { Button as Button2, Icon as Icon3, Input as Input7, useTranslation as useTranslation8 } from "@dxos/react-ui";
1567
1579
  import { descriptionText, mx as mx5 } from "@dxos/react-ui-theme";
1568
1580
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
1581
+
1582
+ // src/components/ObjectPicker/ObjectPicker.tsx
1583
+ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1584
+ import React10, { forwardRef, useCallback as useCallback9, useMemo as useMemo4, useState as useState5 } from "react";
1585
+ import { Icon as Icon2, Popover, useTranslation as useTranslation7 } from "@dxos/react-ui";
1586
+ import { Combobox } from "@dxos/react-ui-searchlist";
1587
+ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
1588
+ var _effect = _useSignals10();
1589
+ try {
1590
+ const { t } = useTranslation7(translationKey);
1591
+ const [searchString, setSearchString] = useState5("");
1592
+ const [showForm, setShowForm] = useState5(false);
1593
+ const handleFormSave = useCallback9((values) => {
1594
+ onCreate?.(values);
1595
+ setShowForm(false);
1596
+ setSearchString("");
1597
+ }, [
1598
+ onCreate
1599
+ ]);
1600
+ const handleFormCancel = useCallback9(() => {
1601
+ setShowForm(false);
1602
+ setSearchString("");
1603
+ }, []);
1604
+ const handleClick = useCallback9((event) => {
1605
+ if (createSchema && event.target.closest('[data-value="__create__"]')) {
1606
+ event.stopPropagation();
1607
+ event.preventDefault();
1608
+ setShowForm(true);
1609
+ }
1610
+ }, [
1611
+ createSchema
1612
+ ]);
1613
+ const handleKeyDown = useCallback9((event) => {
1614
+ if (event.key === "Enter" && createSchema && event.currentTarget.querySelector('[role="option"][aria-selected="true"][data-value="__create__"]')) {
1615
+ event.stopPropagation();
1616
+ event.preventDefault();
1617
+ setShowForm(true);
1618
+ }
1619
+ }, [
1620
+ createSchema
1621
+ ]);
1622
+ const labelById = useMemo4(() => options.reduce((acc, option) => {
1623
+ acc[option.id.toLowerCase()] = option.label.toLowerCase();
1624
+ return acc;
1625
+ }, {}), [
1626
+ options
1627
+ ]);
1628
+ return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1629
+ ...props,
1630
+ ref,
1631
+ filter: (value2, search) => value2 === "__create__" || labelById[value2]?.includes(search.toLowerCase()) ? 1 : 0,
1632
+ onClickCapture: handleClick,
1633
+ onKeyDownCapture: handleKeyDown
1634
+ }, showForm && createSchema ? /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form, {
1635
+ schema: createSchema,
1636
+ values: createInitialValuePath ? {
1637
+ [createInitialValuePath]: searchString
1638
+ } : {},
1639
+ onSave: handleFormSave,
1640
+ onCancel: handleFormCancel,
1641
+ testId: "create-referenced-object-form"
1642
+ })) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1643
+ placeholder: t("ref field combobox input placeholder"),
1644
+ value: searchString,
1645
+ onValueChange: setSearchString,
1646
+ autoFocus: true
1647
+ }), /* @__PURE__ */ React10.createElement(Combobox.List, null, options.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1648
+ key: option.id,
1649
+ value: option.id,
1650
+ onSelect: () => onSelect(option.id),
1651
+ classNames: "flex items-center gap-2"
1652
+ }, /* @__PURE__ */ React10.createElement("span", {
1653
+ className: "grow"
1654
+ }, option.label), selectedIds?.includes(option.id) && /* @__PURE__ */ React10.createElement(Icon2, {
1655
+ icon: "ph--check--regular"
1656
+ }))), searchString.length > 0 && createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React10.createElement(Combobox.Item, {
1657
+ value: "__create__",
1658
+ classNames: "flex items-center gap-2"
1659
+ }, /* @__PURE__ */ React10.createElement(Icon2, {
1660
+ icon: createOptionIcon
1661
+ }), t(createOptionLabel[0], {
1662
+ ns: createOptionLabel[1].ns,
1663
+ text: searchString
1664
+ })))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1665
+ } finally {
1666
+ _effect.f();
1667
+ }
1668
+ });
1669
+ ObjectPickerContent.displayName = "ObjectPickerContent";
1670
+ var ObjectPicker = {
1671
+ Root: Combobox.Root,
1672
+ Trigger: Combobox.Trigger,
1673
+ VirtualTrigger: Combobox.VirtualTrigger,
1674
+ Content: ObjectPickerContent
1675
+ };
1676
+
1677
+ // src/components/Form/RefField.tsx
1569
1678
  var isRefSnapShot = (val) => {
1570
1679
  return typeof val === "object" && typeof val?.["/"] === "string";
1571
1680
  };
1572
- var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreateFromQuery, onValueChange, ...restInputProps }) => {
1573
- var _effect = _useSignals10();
1681
+ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, getValue: getValue3, createOptionLabel, createOptionIcon, onBlur, onCreate, createSchema, createInitialValuePath, onQueryRefOptions, onValueChange, ...restInputProps }) => {
1682
+ var _effect = _useSignals11();
1574
1683
  try {
1575
- const { t } = useTranslation7(translationKey);
1576
- const refTypeInfo = useMemo4(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1684
+ const { t } = useTranslation8(translationKey);
1685
+ const refTypeInfo = useMemo5(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1577
1686
  ast
1578
1687
  ]);
1579
- const { options: availableOptions, loading: _loading } = useQueryRefOptions({
1688
+ const { options: availableOptions, update: updateOptions, loading: _loading } = useQueryRefOptions({
1580
1689
  refTypeInfo,
1581
1690
  onQueryRefOptions
1582
1691
  });
1583
1692
  if (refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
1584
- return /* @__PURE__ */ React10.createElement(RefFieldFallback, {
1693
+ return /* @__PURE__ */ React11.createElement(RefFieldFallback, {
1585
1694
  type,
1586
1695
  label,
1587
1696
  placeholder,
@@ -1593,7 +1702,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1593
1702
  ...restInputProps
1594
1703
  });
1595
1704
  }
1596
- const handleGetValue = useCallback8(() => {
1705
+ const handleGetValue = useCallback10(() => {
1597
1706
  const formValue = getValue3();
1598
1707
  const unknownToRefOption = (val) => {
1599
1708
  const isRef = Ref.isRef(val);
@@ -1621,7 +1730,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1621
1730
  availableOptions,
1622
1731
  array
1623
1732
  ]);
1624
- const handleUpdate = useCallback8((ids) => {
1733
+ const handleUpdate = useCallback10((ids) => {
1625
1734
  if (ids.length === 0) {
1626
1735
  onValueChange("object", void 0);
1627
1736
  return;
@@ -1644,22 +1753,22 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1644
1753
  array,
1645
1754
  onValueChange
1646
1755
  ]);
1756
+ const handleCreate = useCallback10((values) => {
1757
+ onCreate?.(values);
1758
+ updateOptions();
1759
+ }, [
1760
+ onCreate,
1761
+ updateOptions
1762
+ ]);
1647
1763
  if (!refTypeInfo) {
1648
1764
  return null;
1649
1765
  }
1650
1766
  const { status, error } = restInputProps.getStatus();
1651
1767
  const items = handleGetValue();
1652
- const selectedIds = useMemo4(() => items.map((i) => i.id), [
1768
+ const selectedIds = useMemo5(() => items.map((i) => i.id), [
1653
1769
  items
1654
1770
  ]);
1655
- const labelById = useMemo4(() => availableOptions.reduce((acc, option) => {
1656
- acc[option.id.toLowerCase()] = option.label.toLowerCase();
1657
- return acc;
1658
- }, {}), [
1659
- availableOptions
1660
- ]);
1661
- const [query, setQuery] = useState5("");
1662
- const toggleSelect = useCallback8((id) => {
1771
+ const toggleSelect = useCallback10((id) => {
1663
1772
  if (array) {
1664
1773
  const nextIds = selectedIds.includes(id) ? selectedIds.filter((x) => x !== id) : [
1665
1774
  ...selectedIds,
@@ -1680,28 +1789,28 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1680
1789
  selectedIds,
1681
1790
  handleUpdate
1682
1791
  ]);
1683
- return readonly && items.length < 1 ? null : /* @__PURE__ */ React10.createElement(Input7.Root, {
1792
+ return readonly && items.length < 1 ? null : /* @__PURE__ */ React11.createElement(Input7.Root, {
1684
1793
  validationValence: status
1685
- }, !inputOnly && /* @__PURE__ */ React10.createElement(InputHeader, {
1794
+ }, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
1686
1795
  error,
1687
1796
  label
1688
- }), /* @__PURE__ */ React10.createElement("div", {
1797
+ }), /* @__PURE__ */ React11.createElement("div", {
1689
1798
  "data-no-submit": true
1690
- }, readonly ? items.length < 1 ? /* @__PURE__ */ React10.createElement("p", {
1799
+ }, readonly ? items.length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1691
1800
  className: mx5(descriptionText, "mbe-2")
1692
- }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React10.createElement(DxRefTag, {
1801
+ }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React11.createElement(DxAnchor, {
1693
1802
  key: item.id,
1694
1803
  refid: item.id,
1695
1804
  rootclassname: "mie-1"
1696
- }, item.label)) : /* @__PURE__ */ React10.createElement(PopoverCombobox.Root, null, /* @__PURE__ */ React10.createElement(PopoverCombobox.Trigger, {
1805
+ }, item.label)) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1697
1806
  asChild: true
1698
- }, /* @__PURE__ */ React10.createElement(Button2, {
1807
+ }, /* @__PURE__ */ React11.createElement(Button2, {
1699
1808
  variant: "ghost",
1700
1809
  classNames: "is-full text-start gap-2"
1701
- }, /* @__PURE__ */ React10.createElement("div", {
1810
+ }, /* @__PURE__ */ React11.createElement("div", {
1702
1811
  role: "none",
1703
1812
  className: "grow"
1704
- }, items?.length ? items?.map((item) => /* @__PURE__ */ React10.createElement(TagPickerItem, {
1813
+ }, items?.length ? items?.map((item) => /* @__PURE__ */ React11.createElement(DxTagPickerItem, {
1705
1814
  key: item.id,
1706
1815
  itemId: item.id,
1707
1816
  label: item.label,
@@ -1714,45 +1823,29 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1714
1823
  toggleSelect(item.id);
1715
1824
  }
1716
1825
  }
1717
- })) : /* @__PURE__ */ React10.createElement("span", {
1826
+ })) : /* @__PURE__ */ React11.createElement("span", {
1718
1827
  className: "text-description"
1719
1828
  }, placeholder ?? t("ref field placeholder", {
1720
1829
  count: array ? 99 : 1
1721
- }))), /* @__PURE__ */ React10.createElement(Icon2, {
1830
+ }))), /* @__PURE__ */ React11.createElement(Icon3, {
1722
1831
  size: 3,
1723
1832
  icon: "ph--caret-down--bold"
1724
- }))), /* @__PURE__ */ React10.createElement(PopoverCombobox.Content, {
1725
- filter: (value, search) => value === "__create__" || labelById[value]?.includes(search.toLowerCase()) ? 1 : 0
1726
- }, /* @__PURE__ */ React10.createElement(PopoverCombobox.Input, {
1727
- placeholder: "Search...",
1728
- value: query,
1729
- onValueChange: (v) => setQuery(v),
1730
- autoFocus: true
1731
- }), /* @__PURE__ */ React10.createElement(PopoverCombobox.List, null, availableOptions.map((option) => /* @__PURE__ */ React10.createElement(PopoverCombobox.Item, {
1732
- key: option.id,
1733
- value: option.id,
1734
- onSelect: () => toggleSelect(option.id),
1735
- classNames: "flex items-center gap-2"
1736
- }, /* @__PURE__ */ React10.createElement("span", {
1737
- className: "grow"
1738
- }, option.label), selectedIds.includes(option.id) && /* @__PURE__ */ React10.createElement(Icon2, {
1739
- icon: "ph--check--regular"
1740
- }))), query.length > 0 && createOptionLabel && createOptionIcon && onCreateFromQuery && /* @__PURE__ */ React10.createElement(PopoverCombobox.Item, {
1741
- value: "__create__",
1742
- onSelect: () => onCreateFromQuery?.(refTypeInfo, query),
1743
- classNames: "flex items-center gap-2"
1744
- }, /* @__PURE__ */ React10.createElement(Icon2, {
1745
- icon: createOptionIcon
1746
- }), t(createOptionLabel[0], {
1747
- ns: createOptionLabel[1].ns,
1748
- text: query
1749
- }))), /* @__PURE__ */ React10.createElement(PopoverCombobox.Arrow, null)))), inputOnly && /* @__PURE__ */ React10.createElement(Input7.DescriptionAndValidation, null, error));
1833
+ }))), /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
1834
+ options: availableOptions,
1835
+ selectedIds,
1836
+ onSelect: toggleSelect,
1837
+ createSchema,
1838
+ createOptionLabel,
1839
+ createOptionIcon,
1840
+ createInitialValuePath,
1841
+ onCreate: handleCreate
1842
+ }))), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
1750
1843
  } finally {
1751
1844
  _effect.f();
1752
1845
  }
1753
1846
  };
1754
1847
  var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1755
- var _effect = _useSignals10();
1848
+ var _effect = _useSignals11();
1756
1849
  try {
1757
1850
  const handleOnValueChange = (_type, dxnString) => {
1758
1851
  const dxn = DXN.tryParse(dxnString);
@@ -1774,7 +1867,7 @@ var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValu
1774
1867
  }
1775
1868
  return void 0;
1776
1869
  };
1777
- return /* @__PURE__ */ React10.createElement(TextInput, {
1870
+ return /* @__PURE__ */ React11.createElement(TextInput, {
1778
1871
  type,
1779
1872
  label,
1780
1873
  readonly,
@@ -1790,16 +1883,16 @@ var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValu
1790
1883
  };
1791
1884
 
1792
1885
  // src/components/Form/FormContent.tsx
1793
- var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreateFromQuery, lookupComponent, Custom }) => {
1794
- var _effect = _useSignals11();
1886
+ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreate, createSchema, createInitialValuePath, lookupComponent, Custom }) => {
1887
+ var _effect = _useSignals12();
1795
1888
  try {
1796
1889
  const { ast, name, type, format, title, description, options, examples, array } = property;
1797
1890
  const inputProps = useInputProps(path);
1798
- const label = useMemo5(() => title ?? pipe2(name, capitalize2), [
1891
+ const label = useMemo6(() => title ?? Function2.pipe(name, StringEffect.capitalize), [
1799
1892
  title,
1800
1893
  name
1801
1894
  ]);
1802
- const placeholder = useMemo5(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1895
+ const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1803
1896
  examples,
1804
1897
  description
1805
1898
  ]);
@@ -1821,7 +1914,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1821
1914
  const jsonPath = createJsonPath3(path ?? []);
1822
1915
  const CustomComponent = Custom?.[jsonPath];
1823
1916
  if (CustomComponent) {
1824
- return /* @__PURE__ */ React11.createElement(CustomComponent, {
1917
+ return /* @__PURE__ */ React12.createElement(CustomComponent, {
1825
1918
  type,
1826
1919
  format,
1827
1920
  label,
@@ -1833,7 +1926,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1833
1926
  }
1834
1927
  const refProps = getRefProps(property);
1835
1928
  if (refProps) {
1836
- return /* @__PURE__ */ React11.createElement(RefField, {
1929
+ return /* @__PURE__ */ React12.createElement(RefField, {
1837
1930
  ast: refProps.ast,
1838
1931
  array: refProps.isArray,
1839
1932
  type,
@@ -1845,12 +1938,14 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1845
1938
  onQueryRefOptions,
1846
1939
  createOptionLabel,
1847
1940
  createOptionIcon,
1848
- onCreateFromQuery,
1941
+ onCreate,
1942
+ createSchema,
1943
+ createInitialValuePath,
1849
1944
  ...inputProps
1850
1945
  });
1851
1946
  }
1852
1947
  if (array) {
1853
- return /* @__PURE__ */ React11.createElement(ArrayField, {
1948
+ return /* @__PURE__ */ React12.createElement(ArrayField, {
1854
1949
  property,
1855
1950
  path,
1856
1951
  inputProps,
@@ -1860,7 +1955,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1860
1955
  }
1861
1956
  const InputComponent = getInputComponent(type, format);
1862
1957
  if (InputComponent) {
1863
- return /* @__PURE__ */ React11.createElement(InputComponent, {
1958
+ return /* @__PURE__ */ React12.createElement(InputComponent, {
1864
1959
  type,
1865
1960
  format,
1866
1961
  label,
@@ -1871,7 +1966,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1871
1966
  });
1872
1967
  }
1873
1968
  if (options) {
1874
- return /* @__PURE__ */ React11.createElement(SelectInput, {
1969
+ return /* @__PURE__ */ React12.createElement(SelectInput, {
1875
1970
  type,
1876
1971
  format,
1877
1972
  readonly,
@@ -1889,9 +1984,9 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1889
1984
  const baseNode = findNode3(ast, isDiscriminatedUnion2);
1890
1985
  const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
1891
1986
  if (typeLiteral) {
1892
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, !inline && /* @__PURE__ */ React11.createElement("h3", {
1987
+ return /* @__PURE__ */ React12.createElement(React12.Fragment, null, !inline && /* @__PURE__ */ React12.createElement("h3", {
1893
1988
  className: mx6("text-lg mlb-inputSpacingBlock first:mbs-0")
1894
- }, label), /* @__PURE__ */ React11.createElement(FormFields, {
1989
+ }, label), /* @__PURE__ */ React12.createElement(FormFields, {
1895
1990
  schema: Schema.make(typeLiteral),
1896
1991
  path,
1897
1992
  readonly,
@@ -1899,7 +1994,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1899
1994
  onQueryRefOptions,
1900
1995
  createOptionLabel,
1901
1996
  createOptionIcon,
1902
- onCreateFromQuery,
1997
+ onCreate,
1903
1998
  Custom,
1904
1999
  lookupComponent
1905
2000
  }));
@@ -1910,12 +2005,14 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1910
2005
  _effect.f();
1911
2006
  }
1912
2007
  };
1913
- var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter, sort, projection, readonly, lookupComponent, Custom, onQueryRefOptions, ...props }, forwardRef2) => {
1914
- var _effect = _useSignals11();
2008
+ var FormFields = /* @__PURE__ */ forwardRef2(({ classNames, schema, path, filter, sort, projection, readonly, lookupComponent, Custom, onQueryRefOptions, ...props }, forwardRef4) => {
2009
+ var _effect = _useSignals12();
1915
2010
  try {
1916
2011
  const values = useFormValues(path);
1917
- const properties = useMemo5(() => {
1918
- const props2 = getSchemaProperties2(schema.ast, values);
2012
+ const properties = useMemo6(() => {
2013
+ const props2 = getSchemaProperties2(schema.ast, values, {
2014
+ form: true
2015
+ });
1919
2016
  if (projection) {
1920
2017
  const fieldProjections = projection.getFieldProjections();
1921
2018
  const hiddenProperties = new Set(projection.getHiddenProperties());
@@ -1942,13 +2039,18 @@ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter,
1942
2039
  sort,
1943
2040
  projection?.fields
1944
2041
  ]);
1945
- return /* @__PURE__ */ React11.createElement("div", {
2042
+ return /* @__PURE__ */ React12.createElement("div", {
1946
2043
  role: "form",
1947
2044
  className: mx6("is-full", classNames),
1948
- ref: forwardRef2
2045
+ ref: forwardRef4
1949
2046
  }, properties.map((property) => {
1950
- return /* @__PURE__ */ React11.createElement(FormField, {
2047
+ return /* @__PURE__ */ React12.createElement(ErrorBoundary, {
1951
2048
  key: property.name,
2049
+ path: [
2050
+ ...path ?? [],
2051
+ property.name
2052
+ ]
2053
+ }, /* @__PURE__ */ React12.createElement(FormField, {
1952
2054
  property,
1953
2055
  path: [
1954
2056
  ...path ?? [],
@@ -1960,16 +2062,46 @@ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter,
1960
2062
  lookupComponent,
1961
2063
  Custom,
1962
2064
  ...props
1963
- });
1964
- }).filter(isNotFalsy));
2065
+ }));
2066
+ }).filter(isTruthy));
1965
2067
  } finally {
1966
2068
  _effect.f();
1967
2069
  }
1968
2070
  });
2071
+ var ErrorBoundary = class extends Component {
2072
+ static getDerivedStateFromError(error) {
2073
+ return {
2074
+ error
2075
+ };
2076
+ }
2077
+ state = {
2078
+ error: void 0
2079
+ };
2080
+ componentDidUpdate(prevProps) {
2081
+ if (prevProps.path !== this.props.path) {
2082
+ this.resetError();
2083
+ }
2084
+ }
2085
+ render() {
2086
+ if (this.state.error) {
2087
+ return /* @__PURE__ */ React12.createElement("div", {
2088
+ className: "flex gap-2 border border-roseFill font-mono text-sm"
2089
+ }, /* @__PURE__ */ React12.createElement("span", {
2090
+ className: "bg-roseFill text-surfaceText pli-1 font-thin"
2091
+ }, "ERROR"), String(this.props.path?.join(".")));
2092
+ }
2093
+ return this.props.children;
2094
+ }
2095
+ resetError() {
2096
+ this.setState({
2097
+ error: void 0
2098
+ });
2099
+ }
2100
+ };
1969
2101
 
1970
2102
  // src/components/Form/Form.tsx
1971
- var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, schema, onCancel, onValuesChanged, onValidate, onSave, ...props }) => {
1972
- var _effect = _useSignals12();
2103
+ var Form = ({ classNames, id, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, schema, onCancel, onValuesChanged, onValidate, onSave, ...props }) => {
2104
+ var _effect = _useSignals13();
1973
2105
  try {
1974
2106
  const formRef = useRef3(null);
1975
2107
  const { findFirstFocusable } = useFocusFinders();
@@ -1983,11 +2115,15 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1983
2115
  }, [
1984
2116
  autoFocus
1985
2117
  ]);
1986
- const handleValid = useMemo6(() => autoSave ? onSave : void 0, [
2118
+ const handleValid = useCallback11(async (values, meta) => {
2119
+ if (autoSave) {
2120
+ await onSave?.(values, meta);
2121
+ }
2122
+ }, [
1987
2123
  autoSave,
1988
2124
  onSave
1989
2125
  ]);
1990
- return /* @__PURE__ */ React12.createElement(FormProvider, {
2126
+ return /* @__PURE__ */ React13.createElement(FormProvider, {
1991
2127
  formRef,
1992
2128
  schema,
1993
2129
  autoSave,
@@ -1996,11 +2132,14 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1996
2132
  onValidate,
1997
2133
  onValid: handleValid,
1998
2134
  onSave
1999
- }, /* @__PURE__ */ React12.createElement("div", {
2135
+ }, /* @__PURE__ */ React13.createElement("div", {
2000
2136
  role: "none",
2001
2137
  className: "contents",
2138
+ ...id && {
2139
+ "data-object-id": id
2140
+ },
2002
2141
  "data-testid": testId
2003
- }, /* @__PURE__ */ React12.createElement(FormFields, {
2142
+ }, /* @__PURE__ */ React13.createElement(FormFields, {
2004
2143
  ...props,
2005
2144
  ref: formRef,
2006
2145
  classNames: [
@@ -2010,7 +2149,7 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
2010
2149
  ],
2011
2150
  readonly,
2012
2151
  schema
2013
- }), (onCancel || onSave) && !autoSave && !readonly && /* @__PURE__ */ React12.createElement(FormActions, {
2152
+ }), (onCancel || onSave) && !autoSave && !readonly && /* @__PURE__ */ React13.createElement(FormActions, {
2014
2153
  readonly,
2015
2154
  onCancel,
2016
2155
  outerSpacing
@@ -2023,9 +2162,9 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
2023
2162
  // src/components/FieldEditor/FieldEditor.tsx
2024
2163
  var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
2025
2164
  var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, outerSpacing }) => {
2026
- var _effect = _useSignals13();
2165
+ var _effect = _useSignals14();
2027
2166
  try {
2028
- const { t } = useTranslation8(translationKey);
2167
+ const { t } = useTranslation9(translationKey);
2029
2168
  const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
2030
2169
  useEffect8(() => setProps(projection.getFieldProjection(field.id).props), [
2031
2170
  field,
@@ -2055,7 +2194,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2055
2194
  const [{ fieldSchema }, setFieldSchema] = useState6({
2056
2195
  fieldSchema: getFormatSchema(props?.format)
2057
2196
  });
2058
- const handleValuesChanged = useCallback9((_props) => {
2197
+ const handleValuesChanged = useCallback12((_props) => {
2059
2198
  setFieldSchema((prev) => {
2060
2199
  const fieldSchema2 = getFormatSchema(_props.format);
2061
2200
  if (prev.fieldSchema === fieldSchema2) {
@@ -2076,10 +2215,12 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2076
2215
  });
2077
2216
  setProps((props2) => {
2078
2217
  const type = formatToType[_props.format];
2218
+ const additionalProps = formatToAdditionalPropertyAttributes[_props.format];
2079
2219
  if (props2.type !== type) {
2080
2220
  return {
2081
2221
  ...props2,
2082
2222
  ..._props,
2223
+ ...additionalProps,
2083
2224
  type
2084
2225
  };
2085
2226
  }
@@ -2090,7 +2231,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2090
2231
  props.format,
2091
2232
  props.referenceSchema
2092
2233
  ]);
2093
- const handleValidate = useCallback9(({ property }) => {
2234
+ const handleValidate = useCallback12(({ property }) => {
2094
2235
  if (property && projection.fields.find((f) => f.path === property && f.path !== field.path)) {
2095
2236
  return [
2096
2237
  {
@@ -2103,7 +2244,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2103
2244
  projection.fields,
2104
2245
  field
2105
2246
  ]);
2106
- const handleSave = useCallback9((props2) => {
2247
+ const handleSave = useCallback12((props2) => {
2107
2248
  projection.setFieldProjection({
2108
2249
  field,
2109
2250
  props: props2
@@ -2114,51 +2255,53 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2114
2255
  field,
2115
2256
  onSave
2116
2257
  ]);
2117
- const handleCancel = useCallback9(() => {
2258
+ const handleCancel = useCallback12(() => {
2118
2259
  requestAnimationFrame(() => onCancel?.());
2119
2260
  onSave();
2120
2261
  }, [
2121
2262
  onSave
2122
2263
  ]);
2123
2264
  const custom = useMemo7(() => ({
2124
- ["format"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2265
+ ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2125
2266
  ...props2,
2126
- options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
2127
- value,
2128
- label: t(`format ${value}`)
2267
+ options: FormatEnums.filter((value2) => value2 !== Format5.TypeFormat.None).map((value2) => ({
2268
+ value: value2,
2269
+ label: t(`format ${value2}`)
2129
2270
  }))
2130
2271
  }),
2131
- ["referenceSchema"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2272
+ ["referenceSchema"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2132
2273
  ...props2,
2133
2274
  options: schemas.map((schema) => ({
2134
2275
  value: schema.typename
2135
2276
  }))
2136
2277
  }),
2137
- ["referencePath"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2278
+ ["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2138
2279
  ...props2,
2139
- options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
2280
+ options: referenceSchema ? getSchemaProperties3(referenceSchema.ast, {}, {
2281
+ form: true
2282
+ }).sort(sortProperties).map((p) => ({
2140
2283
  value: p.name
2141
2284
  })) : []
2142
2285
  }),
2143
- ["options"]: (props2) => /* @__PURE__ */ React13.createElement(SelectOptionInput, props2)
2286
+ ["options"]: (props2) => /* @__PURE__ */ React14.createElement(SelectOptionInput, props2)
2144
2287
  }), [
2145
2288
  t,
2146
2289
  schemas,
2147
2290
  referenceSchema
2148
2291
  ]);
2149
- const propIsNotType = useCallback9((props2) => props2.filter((p) => p.name !== "type"), []);
2292
+ const propIsNotType = useCallback12((props2) => props2.filter((p) => p.name !== "type"), []);
2150
2293
  if (!fieldSchema) {
2151
2294
  log3.warn("invalid format", {
2152
2295
  props
2153
2296
  }, {
2154
2297
  F: __dxlog_file4,
2155
- L: 177,
2298
+ L: 180,
2156
2299
  S: void 0,
2157
2300
  C: (f, a) => f(...a)
2158
2301
  });
2159
2302
  return null;
2160
2303
  }
2161
- return /* @__PURE__ */ React13.createElement(Form, {
2304
+ return /* @__PURE__ */ React14.createElement(Form, {
2162
2305
  key: field.id,
2163
2306
  autoFocus: true,
2164
2307
  readonly,
@@ -2182,55 +2325,83 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2182
2325
  };
2183
2326
 
2184
2327
  // src/components/ViewEditor/ViewEditor.tsx
2185
- import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
2186
- import { Schema as Schema2 } from "effect";
2187
- import React14, { useCallback as useCallback10, useMemo as useMemo8, useState as useState7 } from "react";
2188
- import { EchoSchema, Format, isMutable, toJsonSchema } from "@dxos/echo-schema";
2328
+ import { useSignals as _useSignals15 } from "@preact-signals/safe-react/tracking";
2329
+ import * as Array2 from "effect/Array";
2330
+ import * as Match from "effect/Match";
2331
+ import * as Option from "effect/Option";
2332
+ import * as Schema2 from "effect/Schema";
2333
+ import React15, { forwardRef as forwardRef3, useCallback as useCallback13, useImperativeHandle, useMemo as useMemo8, useState as useState7 } from "react";
2334
+ import { QueryAST } from "@dxos/echo";
2335
+ import { EchoSchema, Format as Format6, isMutable, toJsonSchema } from "@dxos/echo/internal";
2336
+ import { Filter as Filter2, Query } from "@dxos/echo-db";
2189
2337
  import { invariant as invariant3 } from "@dxos/invariant";
2190
- import { Callout, IconButton as IconButton4, useTranslation as useTranslation9 } from "@dxos/react-ui";
2338
+ import { Callout, IconButton as IconButton4, Input as Input8, useTranslation as useTranslation10 } from "@dxos/react-ui";
2339
+ import { QueryForm } from "@dxos/react-ui-components";
2191
2340
  import { List as List2 } from "@dxos/react-ui-list";
2192
2341
  import { cardSpacing as cardSpacing3 } from "@dxos/react-ui-stack";
2193
2342
  import { inputTextLabel, mx as mx7, subtleHover as subtleHover2 } from "@dxos/react-ui-theme";
2194
- import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT } from "@dxos/schema";
2343
+ import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, getTypenameFromQuery } from "@dxos/schema";
2195
2344
  var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2196
2345
  var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
2197
2346
  var listItemGrid = "grid grid-cols-subgrid col-span-5";
2198
- var ViewMetaSchema = Schema2.Struct({
2199
- typename: Format.URL.annotations({
2200
- title: "Record type"
2201
- })
2202
- }).pipe(Schema2.mutable);
2203
- var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete, outerSpacing = true }) => {
2204
- var _effect = _useSignals14();
2347
+ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, types, tags, onQueryChanged, onDelete, outerSpacing = true }, forwardedRef) => {
2348
+ var _effect = _useSignals15();
2205
2349
  try {
2206
2350
  const schemaReadonly = !isMutable(schema);
2207
- const { t } = useTranslation9(translationKey);
2351
+ const { t } = useTranslation10(translationKey);
2208
2352
  const projectionModel = useMemo8(() => {
2209
2353
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2210
2354
  return new ProjectionModel(jsonSchema, view.projection);
2211
2355
  }, [
2212
2356
  schema,
2213
- view.projection
2357
+ JSON.stringify(view.projection)
2358
+ ]);
2359
+ useImperativeHandle(forwardedRef, () => projectionModel, [
2360
+ projectionModel
2214
2361
  ]);
2215
2362
  const [expandedField, setExpandedField] = useState7();
2216
- const viewValues = useMemo8(() => {
2217
- return {
2218
- // TODO(burdon): Need to warn user of possible consequences of editing.
2219
- // TODO(burdon): Settings should have domain name owned by user.
2220
- typename: view.query.typename
2221
- };
2363
+ const queueTarget = Match.value(view.query.ast).pipe(Match.when({
2364
+ type: "options"
2365
+ }, ({ options }) => {
2366
+ return Option.fromNullable(options.queues).pipe(Option.flatMap((queues) => Array2.head(queues)), Option.getOrUndefined);
2367
+ }), Match.orElse(() => void 0));
2368
+ const viewSchema = useMemo8(() => {
2369
+ const base = Schema2.Struct({
2370
+ query: mode === "schema" ? Format6.URL.annotations({
2371
+ title: "Record type"
2372
+ }) : QueryAST.Query.annotations({
2373
+ title: "Query"
2374
+ })
2375
+ });
2376
+ if (mode === "tag") {
2377
+ return Schema2.Struct({
2378
+ ...base.fields,
2379
+ target: Schema2.optional(Schema2.String.annotations({
2380
+ title: "Target Queue"
2381
+ }))
2382
+ }).pipe(Schema2.mutable);
2383
+ }
2384
+ return base.pipe(Schema2.mutable);
2222
2385
  }, [
2223
- view.query.typename
2386
+ mode
2387
+ ]);
2388
+ const viewValues = useMemo8(() => ({
2389
+ query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2390
+ target: queueTarget
2391
+ }), [
2392
+ mode,
2393
+ view.query.ast,
2394
+ queueTarget
2224
2395
  ]);
2225
- const handleToggleField = useCallback10((field) => {
2396
+ const handleToggleField = useCallback13((field) => {
2226
2397
  setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2227
2398
  }, [
2228
2399
  readonly
2229
2400
  ]);
2230
- const handleAdd = useCallback10(() => {
2401
+ const handleAdd = useCallback13(() => {
2231
2402
  invariant3(!readonly, void 0, {
2232
2403
  F: __dxlog_file5,
2233
- L: 86,
2404
+ L: 129,
2234
2405
  S: void 0,
2235
2406
  A: [
2236
2407
  "!readonly",
@@ -2244,30 +2415,21 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
2244
2415
  projectionModel,
2245
2416
  readonly
2246
2417
  ]);
2247
- const handleUpdate = useCallback10(({ typename }) => {
2248
- invariant3(!readonly, void 0, {
2249
- F: __dxlog_file5,
2250
- L: 93,
2251
- S: void 0,
2252
- A: [
2253
- "!readonly",
2254
- ""
2255
- ]
2256
- });
2418
+ const handleUpdate = useCallback13((values) => {
2257
2419
  requestAnimationFrame(() => {
2258
- if (view.query.typename !== typename && !readonly) {
2259
- onTypenameChanged?.(typename);
2260
- }
2420
+ const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : values.query;
2421
+ onQueryChanged?.(query, values.target);
2261
2422
  });
2262
2423
  }, [
2263
- view.query.typename,
2264
- onTypenameChanged,
2265
- readonly
2424
+ onQueryChanged,
2425
+ view,
2426
+ queueTarget,
2427
+ mode
2266
2428
  ]);
2267
- const handleDelete = useCallback10((fieldId) => {
2429
+ const handleDelete = useCallback13((fieldId) => {
2268
2430
  invariant3(!readonly, void 0, {
2269
2431
  F: __dxlog_file5,
2270
- L: 105,
2432
+ L: 146,
2271
2433
  S: void 0,
2272
2434
  A: [
2273
2435
  "!readonly",
@@ -2283,10 +2445,10 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
2283
2445
  onDelete,
2284
2446
  readonly
2285
2447
  ]);
2286
- const handleMove = useCallback10((fromIndex, toIndex) => {
2448
+ const handleMove = useCallback13((fromIndex, toIndex) => {
2287
2449
  invariant3(!readonly, void 0, {
2288
2450
  F: __dxlog_file5,
2289
- L: 117,
2451
+ L: 158,
2290
2452
  S: void 0,
2291
2453
  A: [
2292
2454
  "!readonly",
@@ -2303,80 +2465,88 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
2303
2465
  view.projection.fields,
2304
2466
  readonly
2305
2467
  ]);
2306
- const handleClose = useCallback10(() => setExpandedField(void 0), []);
2307
- const handleHide = useCallback10((fieldId) => {
2468
+ const handleClose = useCallback13(() => setExpandedField(void 0), []);
2469
+ const handleHide = useCallback13((fieldId) => {
2308
2470
  setExpandedField(void 0);
2309
2471
  projectionModel.hideFieldProjection(fieldId);
2310
2472
  }, [
2311
2473
  projectionModel
2312
2474
  ]);
2313
- const handleShow = useCallback10((property) => {
2475
+ const handleShow = useCallback13((property) => {
2314
2476
  setExpandedField(void 0);
2315
2477
  projectionModel.showFieldProjection(property);
2316
2478
  }, [
2317
2479
  projectionModel
2318
2480
  ]);
2319
- return /* @__PURE__ */ React14.createElement("div", {
2481
+ const custom = useMemo8(() => mode === "tag" ? customFields({
2482
+ types,
2483
+ tags
2484
+ }) : void 0, [
2485
+ types,
2486
+ tags,
2487
+ mode
2488
+ ]);
2489
+ return /* @__PURE__ */ React15.createElement("div", {
2320
2490
  role: "none",
2321
2491
  className: mx7(classNames)
2322
- }, schemaReadonly && /* @__PURE__ */ React14.createElement(Callout.Root, {
2492
+ }, schemaReadonly && !readonly && /* @__PURE__ */ React15.createElement(Callout.Root, {
2323
2493
  valence: "info",
2324
2494
  classNames: [
2325
- "is-full mlb-cardSpacingBlock",
2495
+ "mlb-cardSpacingBlock",
2326
2496
  outerSpacing && "mli-cardSpacingInline"
2327
2497
  ]
2328
- }, /* @__PURE__ */ React14.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React14.createElement(Form, {
2498
+ }, /* @__PURE__ */ React15.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React15.createElement(Form, {
2329
2499
  autoSave: true,
2330
- schema: ViewMetaSchema,
2500
+ schema: viewSchema,
2331
2501
  values: viewValues,
2332
- readonly: readonly ? "disabled-input" : false,
2333
2502
  onSave: handleUpdate,
2334
- outerSpacing
2335
- }), /* @__PURE__ */ React14.createElement("div", {
2503
+ outerSpacing,
2504
+ Custom: custom
2505
+ }), /* @__PURE__ */ React15.createElement("div", {
2336
2506
  role: "none",
2337
2507
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2338
- }, /* @__PURE__ */ React14.createElement("h2", {
2508
+ }, /* @__PURE__ */ React15.createElement("h2", {
2339
2509
  className: mx7(inputTextLabel)
2340
- }, t("fields label")), /* @__PURE__ */ React14.createElement(List2.Root, {
2510
+ }, t("fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
2341
2511
  items: view.projection.fields,
2342
2512
  isItem: Schema2.is(FieldSchema),
2343
2513
  getId: (field) => field.id,
2344
2514
  onMove: readonly ? void 0 : handleMove,
2345
2515
  readonly
2346
- }, ({ items: fields }) => /* @__PURE__ */ React14.createElement(React14.Fragment, null, showHeading && /* @__PURE__ */ React14.createElement("h3", {
2516
+ }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("h3", {
2347
2517
  className: "text-sm"
2348
- }, t("field path label")), /* @__PURE__ */ React14.createElement("div", {
2518
+ }, t("field path label")), /* @__PURE__ */ React15.createElement("div", {
2349
2519
  role: "list",
2350
2520
  className: listGrid
2351
2521
  }, fields?.map((field) => {
2352
2522
  const hidden = field.visible === false;
2353
- return /* @__PURE__ */ React14.createElement(List2.Item, {
2523
+ return /* @__PURE__ */ React15.createElement(List2.Item, {
2354
2524
  key: field.id,
2355
2525
  item: field,
2356
2526
  classNames: listItemGrid,
2357
2527
  "aria-expanded": expandedField === field.id
2358
- }, /* @__PURE__ */ React14.createElement("div", {
2528
+ }, /* @__PURE__ */ React15.createElement("div", {
2359
2529
  role: "none",
2360
2530
  className: mx7(subtleHover2, listItemGrid, "rounded-sm cursor-pointer min-bs-10")
2361
- }, /* @__PURE__ */ React14.createElement(List2.ItemDragHandle, {
2362
- disabled: readonly
2363
- }), /* @__PURE__ */ React14.createElement(List2.ItemTitle, {
2531
+ }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, {
2532
+ disabled: readonly || schemaReadonly
2533
+ }), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
2364
2534
  classNames: hidden && "text-subdued",
2365
2535
  onClick: () => handleToggleField(field)
2366
- }, field.path), /* @__PURE__ */ React14.createElement(List2.ItemButton, {
2536
+ }, field.path), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
2367
2537
  label: t(hidden ? "show field label" : "hide field label"),
2368
2538
  "data-testid": hidden ? "show-field-button" : "hide-field-button",
2369
2539
  icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2370
2540
  autoHide: false,
2371
2541
  disabled: readonly || !hidden && projectionModel.fields.length <= 1,
2372
2542
  onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2373
- }), /* @__PURE__ */ React14.createElement(List2.ItemDeleteButton, {
2543
+ }), !readonly && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2374
2544
  label: t("delete field label"),
2375
2545
  autoHide: false,
2376
2546
  disabled: readonly || schemaReadonly || view.projection.fields.length <= 1,
2377
2547
  onClick: () => handleDelete(field.id),
2378
2548
  "data-testid": "field.delete"
2379
- }), /* @__PURE__ */ React14.createElement(IconButton4, {
2549
+ }), /* @__PURE__ */ React15.createElement(IconButton4, {
2380
2550
  iconOnly: true,
2381
2551
  variant: "ghost",
2382
2552
  label: t("toggle expand label", {
@@ -2384,22 +2554,22 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
2384
2554
  }),
2385
2555
  icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2386
2556
  onClick: () => handleToggleField(field)
2387
- })), expandedField === field.id && /* @__PURE__ */ React14.createElement("div", {
2557
+ }))), expandedField === field.id && !readonly && /* @__PURE__ */ React15.createElement("div", {
2388
2558
  role: "none",
2389
2559
  className: "col-span-5 mbs-1 mbe-1 border border-separator rounded-md"
2390
- }, /* @__PURE__ */ React14.createElement(FieldEditor, {
2560
+ }, /* @__PURE__ */ React15.createElement(FieldEditor, {
2391
2561
  readonly: readonly || schemaReadonly ? "disabled-input" : false,
2392
2562
  projection: projectionModel,
2393
2563
  field,
2394
2564
  registry,
2395
2565
  onSave: handleClose
2396
2566
  })));
2397
- }))))), !readonly && !expandedField && /* @__PURE__ */ React14.createElement("div", {
2567
+ }))))), !readonly && !expandedField && /* @__PURE__ */ React15.createElement("div", {
2398
2568
  role: "none",
2399
2569
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2400
- }, /* @__PURE__ */ React14.createElement(IconButton4, {
2570
+ }, /* @__PURE__ */ React15.createElement(IconButton4, {
2401
2571
  icon: "ph--plus--regular",
2402
- label: t("button add property"),
2572
+ label: t("add property button label"),
2403
2573
  onClick: readonly ? void 0 : handleAdd,
2404
2574
  // TODO(burdon): Show field limit in ux (not tooltip).
2405
2575
  disabled: view.projection.fields.length >= VIEW_FIELD_LIMIT,
@@ -2408,7 +2578,22 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
2408
2578
  } finally {
2409
2579
  _effect.f();
2410
2580
  }
2411
- };
2581
+ });
2582
+ var customFields = ({ types, tags }) => ({
2583
+ query: (props) => {
2584
+ const handleChange = useCallback13((query) => props.onValueChange("object", query.ast), [
2585
+ props.onValueChange
2586
+ ]);
2587
+ return /* @__PURE__ */ React15.createElement(Input8.Root, null, /* @__PURE__ */ React15.createElement(InputHeader, {
2588
+ label: props.label
2589
+ }), /* @__PURE__ */ React15.createElement(QueryForm, {
2590
+ initialQuery: props.getValue(),
2591
+ types,
2592
+ tags,
2593
+ onChange: handleChange
2594
+ }));
2595
+ }
2596
+ });
2412
2597
  export {
2413
2598
  BooleanInput,
2414
2599
  ControlFrame,
@@ -2427,6 +2612,7 @@ export {
2427
2612
  InputHeader,
2428
2613
  MarkdownInput,
2429
2614
  NumberInput,
2615
+ ObjectPicker,
2430
2616
  SelectInput,
2431
2617
  SelectOptionInput,
2432
2618
  TextInput,