@dxos/react-ui-form 0.8.4-main.dedc0f3 → 0.8.4-main.ead640a

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 (88) hide show
  1. package/dist/lib/browser/index.mjs +422 -284
  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 +422 -284
  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 +3 -2
  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 +3 -2
  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 +2 -2
  14. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/Form.stories.d.ts +12 -11
  16. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/FormContent.d.ts +5 -5
  18. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/FormContext.d.ts +2 -2
  20. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/Input.d.ts +1 -1
  22. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/RefField.d.ts +10 -6
  24. package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
  25. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +3 -2
  26. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  27. package/dist/types/src/components/Form/factory.d.ts +1 -1
  28. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  29. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +41 -0
  30. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
  31. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +82 -0
  32. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
  33. package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
  34. package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
  35. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +19 -6
  36. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  37. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +7 -6
  38. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  39. package/dist/types/src/components/index.d.ts +1 -0
  40. package/dist/types/src/components/index.d.ts.map +1 -1
  41. package/dist/types/src/hooks/useForm.d.ts +2 -2
  42. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  43. package/dist/types/src/hooks/useQueryRefOptions.d.ts +9 -3
  44. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -1
  45. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -1
  46. package/dist/types/src/translations.d.ts +2 -1
  47. package/dist/types/src/translations.d.ts.map +1 -1
  48. package/dist/types/src/util/field.d.ts +1 -1
  49. package/dist/types/src/util/field.d.ts.map +1 -1
  50. package/dist/types/src/util/formatting.d.ts +1 -1
  51. package/dist/types/src/util/formatting.d.ts.map +1 -1
  52. package/dist/types/src/util/refs.d.ts +1 -1
  53. package/dist/types/src/util/refs.d.ts.map +1 -1
  54. package/dist/types/src/util/schema.d.ts +1 -1
  55. package/dist/types/src/util/schema.d.ts.map +1 -1
  56. package/dist/types/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +39 -39
  58. package/src/components/ControlSection/ControlSection.stories.tsx +3 -4
  59. package/src/components/ControlSection/ControlSection.tsx +1 -1
  60. package/src/components/FieldEditor/FieldEditor.stories.tsx +6 -5
  61. package/src/components/FieldEditor/FieldEditor.tsx +5 -2
  62. package/src/components/Form/ArrayField.tsx +4 -3
  63. package/src/components/Form/Form.stories.tsx +32 -32
  64. package/src/components/Form/Form.tsx +13 -5
  65. package/src/components/Form/FormContent.tsx +30 -10
  66. package/src/components/Form/FormContext.tsx +3 -3
  67. package/src/components/Form/Input.tsx +1 -1
  68. package/src/components/Form/RefField.tsx +48 -64
  69. package/src/components/Form/custom/GeoPointInput.tsx +1 -1
  70. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +5 -6
  71. package/src/components/Form/custom/SelectOptionsInput.tsx +1 -1
  72. package/src/components/Form/factory.tsx +1 -1
  73. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +207 -0
  74. package/src/components/ObjectPicker/ObjectPicker.tsx +161 -0
  75. package/src/components/ObjectPicker/index.ts +5 -0
  76. package/src/components/ViewEditor/ViewEditor.stories.tsx +103 -56
  77. package/src/components/ViewEditor/ViewEditor.test.tsx +4 -3
  78. package/src/components/ViewEditor/ViewEditor.tsx +270 -229
  79. package/src/components/index.ts +1 -0
  80. package/src/components/testing.tsx +2 -2
  81. package/src/hooks/useForm.ts +7 -4
  82. package/src/hooks/useQueryRefOptions.ts +15 -6
  83. package/src/hooks/useRefQueryLookupHandler.ts +3 -3
  84. package/src/translations.ts +2 -1
  85. package/src/util/field.ts +1 -1
  86. package/src/util/formatting.ts +1 -1
  87. package/src/util/refs.ts +2 -2
  88. package/src/util/schema.ts +2 -4
@@ -23,6 +23,7 @@ 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?
@@ -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",
@@ -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 { FormatEnum as FormatEnum5, 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
 
@@ -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();
@@ -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,8 @@ 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";
959
+ import { getObjectDXN } from "@dxos/echo/internal";
956
960
  import { Filter } from "@dxos/react-client/echo";
957
961
  import { isNonNullable } from "@dxos/util";
958
962
  var useRefQueryLookupHandler = ({ space }) => {
@@ -969,7 +973,7 @@ var useRefQueryLookupHandler = ({ space }) => {
969
973
  }
970
974
  const item = {
971
975
  dxn,
972
- label: object?.name ?? object?.id ?? ""
976
+ label: Obj.getLabel(object) ?? object?.id ?? ""
973
977
  };
974
978
  return item;
975
979
  }).filter(isNonNullable);
@@ -979,12 +983,14 @@ var useRefQueryLookupHandler = ({ space }) => {
979
983
  };
980
984
 
981
985
  // src/hooks/useQueryRefOptions.ts
982
- import { useEffect as useEffect5, useState as useState4 } from "react";
986
+ import { useCallback as useCallback6, useEffect as useEffect5, useState as useState4 } from "react";
983
987
  import { log as log2 } from "@dxos/log";
984
988
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts";
985
989
  var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
986
990
  const [options, setOptions] = useState4([]);
987
991
  const [loading, setLoading] = useState4(false);
992
+ const [state, setState] = useState4({});
993
+ const update = useCallback6(() => setState({}), []);
988
994
  useEffect5(() => {
989
995
  if (!refTypeInfo || !onQueryRefOptions) {
990
996
  return;
@@ -1004,7 +1010,7 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1004
1010
  } catch (error) {
1005
1011
  log2.error("Failed to fetch ref options:", error, {
1006
1012
  F: __dxlog_file2,
1007
- L: 42,
1013
+ L: 51,
1008
1014
  S: void 0,
1009
1015
  C: (f, a) => f(...a)
1010
1016
  });
@@ -1016,10 +1022,12 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1016
1022
  void fetchOptions();
1017
1023
  }, [
1018
1024
  refTypeInfo,
1019
- onQueryRefOptions
1025
+ onQueryRefOptions,
1026
+ state
1020
1027
  ]);
1021
1028
  return {
1022
1029
  options,
1030
+ update,
1023
1031
  loading
1024
1032
  };
1025
1033
  };
@@ -1042,7 +1050,7 @@ var useInputProps = (path = []) => {
1042
1050
  return useMemo3(() => ({
1043
1051
  getStatus: () => getStatus(stablePath),
1044
1052
  getValue: () => getFormValue(stablePath),
1045
- onValueChange: (type, value) => onValueChange(stablePath, type, value),
1053
+ onValueChange: (type, value2) => onValueChange(stablePath, type, value2),
1046
1054
  onBlur: () => onTouched(stablePath)
1047
1055
  }), [
1048
1056
  getStatus,
@@ -1056,7 +1064,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1056
1064
  var _effect = _useSignals7();
1057
1065
  try {
1058
1066
  const form = useForm(formOptions);
1059
- const handleKeyDown = useCallback6((event) => {
1067
+ const handleKeyDown = useCallback7((event) => {
1060
1068
  const keyIsEnter = event.key === "Enter";
1061
1069
  const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
1062
1070
  const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
@@ -1072,7 +1080,9 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1072
1080
  }
1073
1081
  }
1074
1082
  }, [
1075
- form,
1083
+ form.canSave,
1084
+ form.formIsValid,
1085
+ form.handleSave,
1076
1086
  autoSave
1077
1087
  ]);
1078
1088
  useEffect6(() => {
@@ -1125,44 +1135,46 @@ var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1125
1135
  };
1126
1136
 
1127
1137
  // 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";
1138
+ import { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
1139
+ import * as Function2 from "effect/Function";
1140
+ import * as Schema from "effect/Schema";
1141
+ import * as SchemaAST4 from "effect/SchemaAST";
1142
+ import * as StringEffect from "effect/String";
1143
+ import React12, { forwardRef as forwardRef2, useMemo as useMemo6 } from "react";
1132
1144
  import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
1133
1145
  import { mx as mx6 } from "@dxos/react-ui-theme";
1134
1146
  import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
1135
- import { isNotFalsy } from "@dxos/util";
1147
+ import { isTruthy } from "@dxos/util";
1136
1148
 
1137
1149
  // 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 === "") {
1150
+ import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo/internal";
1151
+ var parseValue = ({ type, format, value: value2 }) => {
1152
+ if (value2 === void 0 || value2 === null || value2 === "") {
1141
1153
  return void 0;
1142
1154
  }
1143
1155
  const parseScalar = (type2) => {
1144
1156
  switch (type2) {
1145
1157
  case TypeEnum.Boolean: {
1146
- if (typeof value === "string") {
1147
- const lowercaseValue = value.toLowerCase();
1158
+ if (typeof value2 === "string") {
1159
+ const lowercaseValue = value2.toLowerCase();
1148
1160
  if (lowercaseValue === "0" || lowercaseValue === "false") {
1149
1161
  return false;
1150
1162
  } else if (lowercaseValue === "1" || lowercaseValue === "true") {
1151
1163
  return true;
1152
1164
  }
1153
1165
  }
1154
- return Boolean(value);
1166
+ return Boolean(value2);
1155
1167
  }
1156
1168
  case TypeEnum.Number: {
1157
- const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1169
+ const cleaned = typeof value2 === "string" ? value2.replace(/[^0-9.-]+/g, "") : value2;
1158
1170
  const num = Number(cleaned);
1159
1171
  return Number.isNaN(num) ? null : num;
1160
1172
  }
1161
1173
  case TypeEnum.String:
1162
1174
  case TypeEnum.Ref:
1163
- return String(value);
1175
+ return String(value2);
1164
1176
  default: {
1165
- return value;
1177
+ return value2;
1166
1178
  }
1167
1179
  }
1168
1180
  };
@@ -1186,12 +1198,12 @@ var parseValue = ({ type, format, value }) => {
1186
1198
  case FormatEnum.Date:
1187
1199
  case FormatEnum.Time:
1188
1200
  case FormatEnum.Timestamp: {
1189
- const date = new Date(value);
1201
+ const date = new Date(value2);
1190
1202
  return isNaN(date.getTime()) ? null : date;
1191
1203
  }
1192
1204
  case FormatEnum.GeoPoint: {
1193
- if (typeof value === "string") {
1194
- const cleaned = value.replace(/[^0-9.,-]+/g, "");
1205
+ if (typeof value2 === "string") {
1206
+ const cleaned = value2.replace(/[^0-9.,-]+/g, "");
1195
1207
  const parts = cleaned.split(",");
1196
1208
  if (parts.length === 2) {
1197
1209
  const lat = parseFloat(parts[0]);
@@ -1210,7 +1222,7 @@ var parseValue = ({ type, format, value }) => {
1210
1222
  ];
1211
1223
  }
1212
1224
  default: {
1213
- return value;
1225
+ return value2;
1214
1226
  }
1215
1227
  }
1216
1228
  };
@@ -1257,19 +1269,19 @@ var pathNotUniqueError = (path) => ({
1257
1269
 
1258
1270
  // src/util/formatting.ts
1259
1271
  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 }) => {
1272
+ import { FormatEnum as FormatEnum2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
1273
+ var formatForDisplay = ({ type, format, value: value2, locale = void 0 }) => {
1262
1274
  const formatScalar = (type2) => {
1263
1275
  switch (type2) {
1264
1276
  case TypeEnum2.Boolean:
1265
- return value.toLocaleString().toUpperCase();
1277
+ return value2.toLocaleString().toUpperCase();
1266
1278
  case TypeEnum2.Number:
1267
- return value.toLocaleString(locale);
1279
+ return value2.toLocaleString(locale);
1268
1280
  case TypeEnum2.String:
1269
1281
  case TypeEnum2.Ref:
1270
- return String(value);
1282
+ return String(value2);
1271
1283
  default: {
1272
- return String(value);
1284
+ return String(value2);
1273
1285
  }
1274
1286
  }
1275
1287
  };
@@ -1288,10 +1300,10 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1288
1300
  return formatScalar(TypeEnum2.String);
1289
1301
  }
1290
1302
  case FormatEnum2.Percent: {
1291
- return `${value * 100}%`;
1303
+ return `${value2 * 100}%`;
1292
1304
  }
1293
1305
  case FormatEnum2.Currency: {
1294
- return value.toLocaleString(locale, {
1306
+ return value2.toLocaleString(locale, {
1295
1307
  style: "currency",
1296
1308
  currency: "USD",
1297
1309
  minimumFractionDigits: 2,
@@ -1300,53 +1312,53 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1300
1312
  }
1301
1313
  case FormatEnum2.Date: {
1302
1314
  try {
1303
- return formatDate(new Date(value), "yyyy-MM-dd");
1315
+ return formatDate(new Date(value2), "yyyy-MM-dd");
1304
1316
  } catch (error) {
1305
1317
  return "Invalid Date";
1306
1318
  }
1307
1319
  }
1308
1320
  case FormatEnum2.Time: {
1309
1321
  try {
1310
- return formatDate(new Date(value), "HH:mm:ss");
1322
+ return formatDate(new Date(value2), "HH:mm:ss");
1311
1323
  } catch (error) {
1312
1324
  return "Invalid Time";
1313
1325
  }
1314
1326
  }
1315
1327
  case FormatEnum2.DateTime: {
1316
1328
  try {
1317
- return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
1329
+ return formatDate(new Date(value2), "yyyy-MM-dd HH:mm:ss");
1318
1330
  } catch (error) {
1319
1331
  return "Invalid DateTime";
1320
1332
  }
1321
1333
  }
1322
1334
  case FormatEnum2.GeoPoint: {
1323
- if (value === null || value === void 0) {
1335
+ if (value2 === null || value2 === void 0) {
1324
1336
  return "";
1325
1337
  }
1326
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1327
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1338
+ if (Array.isArray(value2) && value2.length >= 2 && value2.every(Number.isFinite)) {
1339
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value2);
1328
1340
  return `${latitude},${longitude}`;
1329
1341
  }
1330
- return String(value);
1342
+ return String(value2);
1331
1343
  }
1332
1344
  default: {
1333
- if (value === null || value === "undefined") {
1345
+ if (value2 === null || value2 === "undefined") {
1334
1346
  return "";
1335
1347
  }
1336
- return String(value);
1348
+ return String(value2);
1337
1349
  }
1338
1350
  }
1339
1351
  };
1340
- var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1352
+ var formatForEditing = ({ type, format, value: value2, locale = void 0 }) => {
1341
1353
  const formatScalar = (type2) => {
1342
1354
  switch (type2) {
1343
1355
  case TypeEnum2.Boolean:
1344
1356
  case TypeEnum2.Number:
1345
1357
  case TypeEnum2.String:
1346
1358
  case TypeEnum2.Ref:
1347
- return String(value);
1359
+ return String(value2);
1348
1360
  default:
1349
- return String(value);
1361
+ return String(value2);
1350
1362
  }
1351
1363
  };
1352
1364
  if (!format) {
@@ -1360,50 +1372,49 @@ var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1360
1372
  return formatScalar(type);
1361
1373
  }
1362
1374
  case FormatEnum2.Percent: {
1363
- return String(value * 100);
1375
+ return String(value2 * 100);
1364
1376
  }
1365
1377
  case FormatEnum2.Currency: {
1366
- return String(value);
1378
+ return String(value2);
1367
1379
  }
1368
1380
  case FormatEnum2.DateTime: {
1369
- const date = new Date(value);
1381
+ const date = new Date(value2);
1370
1382
  return date.toISOString();
1371
1383
  }
1372
1384
  case FormatEnum2.Date: {
1373
- const date = new Date(value);
1385
+ const date = new Date(value2);
1374
1386
  return date.toISOString().split("T")[0];
1375
1387
  }
1376
1388
  case FormatEnum2.Time: {
1377
- const date = new Date(value);
1389
+ const date = new Date(value2);
1378
1390
  return date.toISOString().split("T")[1].split(".")[0];
1379
1391
  }
1380
1392
  case FormatEnum2.GeoPoint: {
1381
- if (value === null || value === void 0) {
1393
+ if (value2 === null || value2 === void 0) {
1382
1394
  return "";
1383
1395
  }
1384
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1385
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1396
+ if (Array.isArray(value2) && value2.length >= 2 && value2.every(Number.isFinite)) {
1397
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value2);
1386
1398
  return `${latitude},${longitude}`;
1387
1399
  }
1388
- return String(value);
1400
+ return String(value2);
1389
1401
  }
1390
1402
  default: {
1391
- return String(value);
1403
+ return String(value2);
1392
1404
  }
1393
1405
  }
1394
1406
  };
1395
1407
 
1396
1408
  // src/util/refs.ts
1397
- import { FormatEnum as FormatEnum3, ReferenceAnnotationId } from "@dxos/echo-schema";
1409
+ import { FormatEnum as FormatEnum3, ReferenceAnnotationId } from "@dxos/echo/internal";
1398
1410
  import { findAnnotation } from "@dxos/effect";
1399
1411
 
1400
1412
  // src/util/schema.ts
1401
- import { SchemaAST as SchemaAST2 } from "effect";
1413
+ import * as SchemaAST2 from "effect/SchemaAST";
1402
1414
  import { findNode } from "@dxos/effect";
1403
1415
  var findArrayElementType = (ast) => {
1404
1416
  const tupleType = findNode(ast, SchemaAST2.isTupleType);
1405
- const elementType = tupleType?.rest[0]?.type;
1406
- return elementType;
1417
+ return tupleType?.rest[0]?.type;
1407
1418
  };
1408
1419
 
1409
1420
  // src/util/refs.ts
@@ -1432,9 +1443,10 @@ var getRefProps = (property) => {
1432
1443
 
1433
1444
  // src/components/Form/ArrayField.tsx
1434
1445
  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";
1446
+ import * as Function from "effect/Function";
1447
+ import * as SchemaAST3 from "effect/SchemaAST";
1448
+ import * as String2 from "effect/String";
1449
+ import React9, { Fragment, useCallback as useCallback8 } from "react";
1438
1450
  import { SimpleType, findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion } from "@dxos/effect";
1439
1451
  import { invariant as invariant2 } from "@dxos/invariant";
1440
1452
  import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
@@ -1448,14 +1460,14 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1448
1460
  const values = useFormValues(path ?? []) ?? [];
1449
1461
  invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
1450
1462
  F: __dxlog_file3,
1451
- L: 36,
1463
+ L: 37,
1452
1464
  S: void 0,
1453
1465
  A: [
1454
1466
  "Array.isArray(values)",
1455
1467
  "`Values at path ${path?.join('.')} must be an array.`"
1456
1468
  ]
1457
1469
  });
1458
- const label = title ?? pipe(name, capitalize);
1470
+ const label = title ?? Function.pipe(name, String2.capitalize);
1459
1471
  const elementType = findArrayElementType(ast);
1460
1472
  const getDefaultObjectValue = (typeNode) => {
1461
1473
  const baseNode = findNode2(typeNode, isDiscriminatedUnion);
@@ -1469,7 +1481,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1469
1481
  ]));
1470
1482
  };
1471
1483
  const getDefaultValue = () => type === "object" && elementType ? getDefaultObjectValue(elementType) : SimpleType.getDefaultValue(type);
1472
- const handleAdd = useCallback7(() => {
1484
+ const handleAdd = useCallback8(() => {
1473
1485
  inputProps.onValueChange(type, [
1474
1486
  ...values,
1475
1487
  getDefaultValue()
@@ -1480,7 +1492,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1480
1492
  inputProps,
1481
1493
  values
1482
1494
  ]);
1483
- const handleRemove = useCallback7((index) => {
1495
+ const handleRemove = useCallback8((index) => {
1484
1496
  const newValues = values.filter((_, i) => i !== index);
1485
1497
  inputProps.onValueChange(type, newValues);
1486
1498
  }, [
@@ -1536,7 +1548,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1536
1548
  };
1537
1549
 
1538
1550
  // src/components/Form/factory.tsx
1539
- import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
1551
+ import { FormatEnum as FormatEnum4 } from "@dxos/echo/internal";
1540
1552
  var getInputComponent = (type, format) => {
1541
1553
  switch (format) {
1542
1554
  case FormatEnum4.GeoPoint:
@@ -1555,33 +1567,129 @@ var getInputComponent = (type, format) => {
1555
1567
  };
1556
1568
 
1557
1569
  // 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";
1570
+ import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
1571
+ import "@dxos/lit-ui/dx-tag-picker.pcss";
1572
+ import React11, { useCallback as useCallback10, useMemo as useMemo5 } from "react";
1573
+ import { Expando, Ref, ReferenceAnnotationId as ReferenceAnnotationId2, getTypeAnnotation } from "@dxos/echo/internal";
1561
1574
  import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1562
1575
  import { DXN } from "@dxos/keys";
1563
- import { DxAnchor } 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";
1576
+ import { DxAnchor, DxTagPickerItem } from "@dxos/lit-ui/react";
1577
+ import { Button as Button2, Icon as Icon3, Input as Input7, useTranslation as useTranslation8 } from "@dxos/react-ui";
1567
1578
  import { descriptionText, mx as mx5 } from "@dxos/react-ui-theme";
1568
1579
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
1580
+
1581
+ // src/components/ObjectPicker/ObjectPicker.tsx
1582
+ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1583
+ import React10, { forwardRef, useCallback as useCallback9, useMemo as useMemo4, useState as useState5 } from "react";
1584
+ import { Icon as Icon2, Popover, useTranslation as useTranslation7 } from "@dxos/react-ui";
1585
+ import { Combobox } from "@dxos/react-ui-searchlist";
1586
+ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
1587
+ var _effect = _useSignals10();
1588
+ try {
1589
+ const { t } = useTranslation7(translationKey);
1590
+ const [searchString, setSearchString] = useState5("");
1591
+ const [showForm, setShowForm] = useState5(false);
1592
+ const handleFormSave = useCallback9((values) => {
1593
+ onCreate?.(values);
1594
+ setShowForm(false);
1595
+ setSearchString("");
1596
+ }, [
1597
+ onCreate
1598
+ ]);
1599
+ const handleFormCancel = useCallback9(() => {
1600
+ setShowForm(false);
1601
+ setSearchString("");
1602
+ }, []);
1603
+ const handleClick = useCallback9((event) => {
1604
+ if (createSchema && event.target.closest('[data-value="__create__"]')) {
1605
+ event.stopPropagation();
1606
+ event.preventDefault();
1607
+ setShowForm(true);
1608
+ }
1609
+ }, [
1610
+ createSchema
1611
+ ]);
1612
+ const handleKeyDown = useCallback9((event) => {
1613
+ if (event.key === "Enter" && createSchema && event.currentTarget.querySelector('[role="option"][aria-selected="true"][data-value="__create__"]')) {
1614
+ event.stopPropagation();
1615
+ event.preventDefault();
1616
+ setShowForm(true);
1617
+ }
1618
+ }, [
1619
+ createSchema
1620
+ ]);
1621
+ const labelById = useMemo4(() => options.reduce((acc, option) => {
1622
+ acc[option.id.toLowerCase()] = option.label.toLowerCase();
1623
+ return acc;
1624
+ }, {}), [
1625
+ options
1626
+ ]);
1627
+ return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1628
+ ...props,
1629
+ ref,
1630
+ filter: (value2, search) => value2 === "__create__" || labelById[value2]?.includes(search.toLowerCase()) ? 1 : 0,
1631
+ onClickCapture: handleClick,
1632
+ onKeyDownCapture: handleKeyDown
1633
+ }, showForm && createSchema ? /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form, {
1634
+ schema: createSchema,
1635
+ values: createInitialValuePath ? {
1636
+ [createInitialValuePath]: searchString
1637
+ } : {},
1638
+ onSave: handleFormSave,
1639
+ onCancel: handleFormCancel,
1640
+ testId: "create-referenced-object-form"
1641
+ })) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1642
+ placeholder: t("ref field combobox input placeholder"),
1643
+ value: searchString,
1644
+ onValueChange: setSearchString,
1645
+ autoFocus: true
1646
+ }), /* @__PURE__ */ React10.createElement(Combobox.List, null, options.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1647
+ key: option.id,
1648
+ value: option.id,
1649
+ onSelect: () => onSelect(option.id),
1650
+ classNames: "flex items-center gap-2"
1651
+ }, /* @__PURE__ */ React10.createElement("span", {
1652
+ className: "grow"
1653
+ }, option.label), selectedIds?.includes(option.id) && /* @__PURE__ */ React10.createElement(Icon2, {
1654
+ icon: "ph--check--regular"
1655
+ }))), searchString.length > 0 && createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React10.createElement(Combobox.Item, {
1656
+ value: "__create__",
1657
+ classNames: "flex items-center gap-2"
1658
+ }, /* @__PURE__ */ React10.createElement(Icon2, {
1659
+ icon: createOptionIcon
1660
+ }), t(createOptionLabel[0], {
1661
+ ns: createOptionLabel[1].ns,
1662
+ text: searchString
1663
+ })))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1664
+ } finally {
1665
+ _effect.f();
1666
+ }
1667
+ });
1668
+ ObjectPickerContent.displayName = "ObjectPickerContent";
1669
+ var ObjectPicker = {
1670
+ Root: Combobox.Root,
1671
+ Trigger: Combobox.Trigger,
1672
+ VirtualTrigger: Combobox.VirtualTrigger,
1673
+ Content: ObjectPickerContent
1674
+ };
1675
+
1676
+ // src/components/Form/RefField.tsx
1569
1677
  var isRefSnapShot = (val) => {
1570
1678
  return typeof val === "object" && typeof val?.["/"] === "string";
1571
1679
  };
1572
- var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreateFromQuery, onValueChange, ...restInputProps }) => {
1573
- var _effect = _useSignals10();
1680
+ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, getValue: getValue3, createOptionLabel, createOptionIcon, onBlur, onCreate, createSchema, createInitialValuePath, onQueryRefOptions, onValueChange, ...restInputProps }) => {
1681
+ var _effect = _useSignals11();
1574
1682
  try {
1575
- const { t } = useTranslation7(translationKey);
1576
- const refTypeInfo = useMemo4(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1683
+ const { t } = useTranslation8(translationKey);
1684
+ const refTypeInfo = useMemo5(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1577
1685
  ast
1578
1686
  ]);
1579
- const { options: availableOptions, loading: _loading } = useQueryRefOptions({
1687
+ const { options: availableOptions, update: updateOptions, loading: _loading } = useQueryRefOptions({
1580
1688
  refTypeInfo,
1581
1689
  onQueryRefOptions
1582
1690
  });
1583
1691
  if (refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
1584
- return /* @__PURE__ */ React10.createElement(RefFieldFallback, {
1692
+ return /* @__PURE__ */ React11.createElement(RefFieldFallback, {
1585
1693
  type,
1586
1694
  label,
1587
1695
  placeholder,
@@ -1593,7 +1701,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1593
1701
  ...restInputProps
1594
1702
  });
1595
1703
  }
1596
- const handleGetValue = useCallback8(() => {
1704
+ const handleGetValue = useCallback10(() => {
1597
1705
  const formValue = getValue3();
1598
1706
  const unknownToRefOption = (val) => {
1599
1707
  const isRef = Ref.isRef(val);
@@ -1621,7 +1729,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1621
1729
  availableOptions,
1622
1730
  array
1623
1731
  ]);
1624
- const handleUpdate = useCallback8((ids) => {
1732
+ const handleUpdate = useCallback10((ids) => {
1625
1733
  if (ids.length === 0) {
1626
1734
  onValueChange("object", void 0);
1627
1735
  return;
@@ -1644,22 +1752,22 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1644
1752
  array,
1645
1753
  onValueChange
1646
1754
  ]);
1755
+ const handleCreate = useCallback10((values) => {
1756
+ onCreate?.(values);
1757
+ updateOptions();
1758
+ }, [
1759
+ onCreate,
1760
+ updateOptions
1761
+ ]);
1647
1762
  if (!refTypeInfo) {
1648
1763
  return null;
1649
1764
  }
1650
1765
  const { status, error } = restInputProps.getStatus();
1651
1766
  const items = handleGetValue();
1652
- const selectedIds = useMemo4(() => items.map((i) => i.id), [
1767
+ const selectedIds = useMemo5(() => items.map((i) => i.id), [
1653
1768
  items
1654
1769
  ]);
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) => {
1770
+ const toggleSelect = useCallback10((id) => {
1663
1771
  if (array) {
1664
1772
  const nextIds = selectedIds.includes(id) ? selectedIds.filter((x) => x !== id) : [
1665
1773
  ...selectedIds,
@@ -1680,28 +1788,28 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1680
1788
  selectedIds,
1681
1789
  handleUpdate
1682
1790
  ]);
1683
- return readonly && items.length < 1 ? null : /* @__PURE__ */ React10.createElement(Input7.Root, {
1791
+ return readonly && items.length < 1 ? null : /* @__PURE__ */ React11.createElement(Input7.Root, {
1684
1792
  validationValence: status
1685
- }, !inputOnly && /* @__PURE__ */ React10.createElement(InputHeader, {
1793
+ }, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
1686
1794
  error,
1687
1795
  label
1688
- }), /* @__PURE__ */ React10.createElement("div", {
1796
+ }), /* @__PURE__ */ React11.createElement("div", {
1689
1797
  "data-no-submit": true
1690
- }, readonly ? items.length < 1 ? /* @__PURE__ */ React10.createElement("p", {
1798
+ }, readonly ? items.length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1691
1799
  className: mx5(descriptionText, "mbe-2")
1692
- }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React10.createElement(DxAnchor, {
1800
+ }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React11.createElement(DxAnchor, {
1693
1801
  key: item.id,
1694
1802
  refid: item.id,
1695
1803
  rootclassname: "mie-1"
1696
- }, item.label)) : /* @__PURE__ */ React10.createElement(PopoverCombobox.Root, null, /* @__PURE__ */ React10.createElement(PopoverCombobox.Trigger, {
1804
+ }, item.label)) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1697
1805
  asChild: true
1698
- }, /* @__PURE__ */ React10.createElement(Button2, {
1806
+ }, /* @__PURE__ */ React11.createElement(Button2, {
1699
1807
  variant: "ghost",
1700
1808
  classNames: "is-full text-start gap-2"
1701
- }, /* @__PURE__ */ React10.createElement("div", {
1809
+ }, /* @__PURE__ */ React11.createElement("div", {
1702
1810
  role: "none",
1703
1811
  className: "grow"
1704
- }, items?.length ? items?.map((item) => /* @__PURE__ */ React10.createElement(TagPickerItem, {
1812
+ }, items?.length ? items?.map((item) => /* @__PURE__ */ React11.createElement(DxTagPickerItem, {
1705
1813
  key: item.id,
1706
1814
  itemId: item.id,
1707
1815
  label: item.label,
@@ -1714,45 +1822,29 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1714
1822
  toggleSelect(item.id);
1715
1823
  }
1716
1824
  }
1717
- })) : /* @__PURE__ */ React10.createElement("span", {
1825
+ })) : /* @__PURE__ */ React11.createElement("span", {
1718
1826
  className: "text-description"
1719
1827
  }, placeholder ?? t("ref field placeholder", {
1720
1828
  count: array ? 99 : 1
1721
- }))), /* @__PURE__ */ React10.createElement(Icon2, {
1829
+ }))), /* @__PURE__ */ React11.createElement(Icon3, {
1722
1830
  size: 3,
1723
1831
  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));
1832
+ }))), /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
1833
+ options: availableOptions,
1834
+ selectedIds,
1835
+ onSelect: toggleSelect,
1836
+ createSchema,
1837
+ createOptionLabel,
1838
+ createOptionIcon,
1839
+ createInitialValuePath,
1840
+ onCreate: handleCreate
1841
+ }))), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
1750
1842
  } finally {
1751
1843
  _effect.f();
1752
1844
  }
1753
1845
  };
1754
1846
  var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1755
- var _effect = _useSignals10();
1847
+ var _effect = _useSignals11();
1756
1848
  try {
1757
1849
  const handleOnValueChange = (_type, dxnString) => {
1758
1850
  const dxn = DXN.tryParse(dxnString);
@@ -1774,7 +1866,7 @@ var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValu
1774
1866
  }
1775
1867
  return void 0;
1776
1868
  };
1777
- return /* @__PURE__ */ React10.createElement(TextInput, {
1869
+ return /* @__PURE__ */ React11.createElement(TextInput, {
1778
1870
  type,
1779
1871
  label,
1780
1872
  readonly,
@@ -1790,16 +1882,16 @@ var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValu
1790
1882
  };
1791
1883
 
1792
1884
  // src/components/Form/FormContent.tsx
1793
- var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreateFromQuery, lookupComponent, Custom }) => {
1794
- var _effect = _useSignals11();
1885
+ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreate, createSchema, createInitialValuePath, lookupComponent, Custom }) => {
1886
+ var _effect = _useSignals12();
1795
1887
  try {
1796
1888
  const { ast, name, type, format, title, description, options, examples, array } = property;
1797
1889
  const inputProps = useInputProps(path);
1798
- const label = useMemo5(() => title ?? pipe2(name, capitalize2), [
1890
+ const label = useMemo6(() => title ?? Function2.pipe(name, StringEffect.capitalize), [
1799
1891
  title,
1800
1892
  name
1801
1893
  ]);
1802
- const placeholder = useMemo5(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1894
+ const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1803
1895
  examples,
1804
1896
  description
1805
1897
  ]);
@@ -1821,7 +1913,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1821
1913
  const jsonPath = createJsonPath3(path ?? []);
1822
1914
  const CustomComponent = Custom?.[jsonPath];
1823
1915
  if (CustomComponent) {
1824
- return /* @__PURE__ */ React11.createElement(CustomComponent, {
1916
+ return /* @__PURE__ */ React12.createElement(CustomComponent, {
1825
1917
  type,
1826
1918
  format,
1827
1919
  label,
@@ -1833,7 +1925,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1833
1925
  }
1834
1926
  const refProps = getRefProps(property);
1835
1927
  if (refProps) {
1836
- return /* @__PURE__ */ React11.createElement(RefField, {
1928
+ return /* @__PURE__ */ React12.createElement(RefField, {
1837
1929
  ast: refProps.ast,
1838
1930
  array: refProps.isArray,
1839
1931
  type,
@@ -1845,12 +1937,14 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1845
1937
  onQueryRefOptions,
1846
1938
  createOptionLabel,
1847
1939
  createOptionIcon,
1848
- onCreateFromQuery,
1940
+ onCreate,
1941
+ createSchema,
1942
+ createInitialValuePath,
1849
1943
  ...inputProps
1850
1944
  });
1851
1945
  }
1852
1946
  if (array) {
1853
- return /* @__PURE__ */ React11.createElement(ArrayField, {
1947
+ return /* @__PURE__ */ React12.createElement(ArrayField, {
1854
1948
  property,
1855
1949
  path,
1856
1950
  inputProps,
@@ -1860,7 +1954,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1860
1954
  }
1861
1955
  const InputComponent = getInputComponent(type, format);
1862
1956
  if (InputComponent) {
1863
- return /* @__PURE__ */ React11.createElement(InputComponent, {
1957
+ return /* @__PURE__ */ React12.createElement(InputComponent, {
1864
1958
  type,
1865
1959
  format,
1866
1960
  label,
@@ -1871,7 +1965,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1871
1965
  });
1872
1966
  }
1873
1967
  if (options) {
1874
- return /* @__PURE__ */ React11.createElement(SelectInput, {
1968
+ return /* @__PURE__ */ React12.createElement(SelectInput, {
1875
1969
  type,
1876
1970
  format,
1877
1971
  readonly,
@@ -1889,9 +1983,9 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1889
1983
  const baseNode = findNode3(ast, isDiscriminatedUnion2);
1890
1984
  const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
1891
1985
  if (typeLiteral) {
1892
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, !inline && /* @__PURE__ */ React11.createElement("h3", {
1986
+ return /* @__PURE__ */ React12.createElement(React12.Fragment, null, !inline && /* @__PURE__ */ React12.createElement("h3", {
1893
1987
  className: mx6("text-lg mlb-inputSpacingBlock first:mbs-0")
1894
- }, label), /* @__PURE__ */ React11.createElement(FormFields, {
1988
+ }, label), /* @__PURE__ */ React12.createElement(FormFields, {
1895
1989
  schema: Schema.make(typeLiteral),
1896
1990
  path,
1897
1991
  readonly,
@@ -1899,7 +1993,7 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1899
1993
  onQueryRefOptions,
1900
1994
  createOptionLabel,
1901
1995
  createOptionIcon,
1902
- onCreateFromQuery,
1996
+ onCreate,
1903
1997
  Custom,
1904
1998
  lookupComponent
1905
1999
  }));
@@ -1910,11 +2004,11 @@ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptio
1910
2004
  _effect.f();
1911
2005
  }
1912
2006
  };
1913
- var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter, sort, projection, readonly, lookupComponent, Custom, onQueryRefOptions, ...props }, forwardRef2) => {
1914
- var _effect = _useSignals11();
2007
+ var FormFields = /* @__PURE__ */ forwardRef2(({ classNames, schema, path, filter, sort, projection, readonly, lookupComponent, Custom, onQueryRefOptions, ...props }, forwardRef4) => {
2008
+ var _effect = _useSignals12();
1915
2009
  try {
1916
2010
  const values = useFormValues(path);
1917
- const properties = useMemo5(() => {
2011
+ const properties = useMemo6(() => {
1918
2012
  const props2 = getSchemaProperties2(schema.ast, values);
1919
2013
  if (projection) {
1920
2014
  const fieldProjections = projection.getFieldProjections();
@@ -1942,12 +2036,12 @@ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter,
1942
2036
  sort,
1943
2037
  projection?.fields
1944
2038
  ]);
1945
- return /* @__PURE__ */ React11.createElement("div", {
2039
+ return /* @__PURE__ */ React12.createElement("div", {
1946
2040
  role: "form",
1947
2041
  className: mx6("is-full", classNames),
1948
- ref: forwardRef2
2042
+ ref: forwardRef4
1949
2043
  }, properties.map((property) => {
1950
- return /* @__PURE__ */ React11.createElement(FormField, {
2044
+ return /* @__PURE__ */ React12.createElement(FormField, {
1951
2045
  key: property.name,
1952
2046
  property,
1953
2047
  path: [
@@ -1961,7 +2055,7 @@ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter,
1961
2055
  Custom,
1962
2056
  ...props
1963
2057
  });
1964
- }).filter(isNotFalsy));
2058
+ }).filter(isTruthy));
1965
2059
  } finally {
1966
2060
  _effect.f();
1967
2061
  }
@@ -1969,7 +2063,7 @@ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter,
1969
2063
 
1970
2064
  // src/components/Form/Form.tsx
1971
2065
  var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, schema, onCancel, onValuesChanged, onValidate, onSave, ...props }) => {
1972
- var _effect = _useSignals12();
2066
+ var _effect = _useSignals13();
1973
2067
  try {
1974
2068
  const formRef = useRef3(null);
1975
2069
  const { findFirstFocusable } = useFocusFinders();
@@ -1983,11 +2077,15 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1983
2077
  }, [
1984
2078
  autoFocus
1985
2079
  ]);
1986
- const handleValid = useMemo6(() => autoSave ? onSave : void 0, [
2080
+ const handleValid = useCallback11(async (values, meta) => {
2081
+ if (autoSave) {
2082
+ await onSave?.(values, meta);
2083
+ }
2084
+ }, [
1987
2085
  autoSave,
1988
2086
  onSave
1989
2087
  ]);
1990
- return /* @__PURE__ */ React12.createElement(FormProvider, {
2088
+ return /* @__PURE__ */ React13.createElement(FormProvider, {
1991
2089
  formRef,
1992
2090
  schema,
1993
2091
  autoSave,
@@ -1996,11 +2094,11 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1996
2094
  onValidate,
1997
2095
  onValid: handleValid,
1998
2096
  onSave
1999
- }, /* @__PURE__ */ React12.createElement("div", {
2097
+ }, /* @__PURE__ */ React13.createElement("div", {
2000
2098
  role: "none",
2001
2099
  className: "contents",
2002
2100
  "data-testid": testId
2003
- }, /* @__PURE__ */ React12.createElement(FormFields, {
2101
+ }, /* @__PURE__ */ React13.createElement(FormFields, {
2004
2102
  ...props,
2005
2103
  ref: formRef,
2006
2104
  classNames: [
@@ -2010,7 +2108,7 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
2010
2108
  ],
2011
2109
  readonly,
2012
2110
  schema
2013
- }), (onCancel || onSave) && !autoSave && !readonly && /* @__PURE__ */ React12.createElement(FormActions, {
2111
+ }), (onCancel || onSave) && !autoSave && !readonly && /* @__PURE__ */ React13.createElement(FormActions, {
2014
2112
  readonly,
2015
2113
  onCancel,
2016
2114
  outerSpacing
@@ -2023,9 +2121,9 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
2023
2121
  // src/components/FieldEditor/FieldEditor.tsx
2024
2122
  var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
2025
2123
  var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, outerSpacing }) => {
2026
- var _effect = _useSignals13();
2124
+ var _effect = _useSignals14();
2027
2125
  try {
2028
- const { t } = useTranslation8(translationKey);
2126
+ const { t } = useTranslation9(translationKey);
2029
2127
  const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
2030
2128
  useEffect8(() => setProps(projection.getFieldProjection(field.id).props), [
2031
2129
  field,
@@ -2055,7 +2153,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2055
2153
  const [{ fieldSchema }, setFieldSchema] = useState6({
2056
2154
  fieldSchema: getFormatSchema(props?.format)
2057
2155
  });
2058
- const handleValuesChanged = useCallback9((_props) => {
2156
+ const handleValuesChanged = useCallback12((_props) => {
2059
2157
  setFieldSchema((prev) => {
2060
2158
  const fieldSchema2 = getFormatSchema(_props.format);
2061
2159
  if (prev.fieldSchema === fieldSchema2) {
@@ -2076,10 +2174,12 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2076
2174
  });
2077
2175
  setProps((props2) => {
2078
2176
  const type = formatToType[_props.format];
2177
+ const additionalProps = formatToAdditionalPropertyAttributes[_props.format];
2079
2178
  if (props2.type !== type) {
2080
2179
  return {
2081
2180
  ...props2,
2082
2181
  ..._props,
2182
+ ...additionalProps,
2083
2183
  type
2084
2184
  };
2085
2185
  }
@@ -2090,7 +2190,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2090
2190
  props.format,
2091
2191
  props.referenceSchema
2092
2192
  ]);
2093
- const handleValidate = useCallback9(({ property }) => {
2193
+ const handleValidate = useCallback12(({ property }) => {
2094
2194
  if (property && projection.fields.find((f) => f.path === property && f.path !== field.path)) {
2095
2195
  return [
2096
2196
  {
@@ -2103,7 +2203,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2103
2203
  projection.fields,
2104
2204
  field
2105
2205
  ]);
2106
- const handleSave = useCallback9((props2) => {
2206
+ const handleSave = useCallback12((props2) => {
2107
2207
  projection.setFieldProjection({
2108
2208
  field,
2109
2209
  props: props2
@@ -2114,51 +2214,51 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2114
2214
  field,
2115
2215
  onSave
2116
2216
  ]);
2117
- const handleCancel = useCallback9(() => {
2217
+ const handleCancel = useCallback12(() => {
2118
2218
  requestAnimationFrame(() => onCancel?.());
2119
2219
  onSave();
2120
2220
  }, [
2121
2221
  onSave
2122
2222
  ]);
2123
2223
  const custom = useMemo7(() => ({
2124
- ["format"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2224
+ ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2125
2225
  ...props2,
2126
- options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
2127
- value,
2128
- label: t(`format ${value}`)
2226
+ options: FormatEnums.filter((value2) => value2 !== FormatEnum5.None).map((value2) => ({
2227
+ value: value2,
2228
+ label: t(`format ${value2}`)
2129
2229
  }))
2130
2230
  }),
2131
- ["referenceSchema"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2231
+ ["referenceSchema"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2132
2232
  ...props2,
2133
2233
  options: schemas.map((schema) => ({
2134
2234
  value: schema.typename
2135
2235
  }))
2136
2236
  }),
2137
- ["referencePath"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2237
+ ["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2138
2238
  ...props2,
2139
2239
  options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
2140
2240
  value: p.name
2141
2241
  })) : []
2142
2242
  }),
2143
- ["options"]: (props2) => /* @__PURE__ */ React13.createElement(SelectOptionInput, props2)
2243
+ ["options"]: (props2) => /* @__PURE__ */ React14.createElement(SelectOptionInput, props2)
2144
2244
  }), [
2145
2245
  t,
2146
2246
  schemas,
2147
2247
  referenceSchema
2148
2248
  ]);
2149
- const propIsNotType = useCallback9((props2) => props2.filter((p) => p.name !== "type"), []);
2249
+ const propIsNotType = useCallback12((props2) => props2.filter((p) => p.name !== "type"), []);
2150
2250
  if (!fieldSchema) {
2151
2251
  log3.warn("invalid format", {
2152
2252
  props
2153
2253
  }, {
2154
2254
  F: __dxlog_file4,
2155
- L: 177,
2255
+ L: 180,
2156
2256
  S: void 0,
2157
2257
  C: (f, a) => f(...a)
2158
2258
  });
2159
2259
  return null;
2160
2260
  }
2161
- return /* @__PURE__ */ React13.createElement(Form, {
2261
+ return /* @__PURE__ */ React14.createElement(Form, {
2162
2262
  key: field.id,
2163
2263
  autoFocus: true,
2164
2264
  readonly,
@@ -2182,67 +2282,88 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2182
2282
  };
2183
2283
 
2184
2284
  // src/components/ViewEditor/ViewEditor.tsx
2185
- import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
2186
- import { Match, 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";
2285
+ import { useSignals as _useSignals15 } from "@preact-signals/safe-react/tracking";
2286
+ import * as Array2 from "effect/Array";
2287
+ import * as Match from "effect/Match";
2288
+ import * as Option from "effect/Option";
2289
+ import * as Schema2 from "effect/Schema";
2290
+ import React15, { forwardRef as forwardRef3, useCallback as useCallback13, useImperativeHandle, useMemo as useMemo8, useState as useState7 } from "react";
2291
+ import { QueryAST } from "@dxos/echo";
2292
+ import { EchoSchema, Format, isMutable, toJsonSchema } from "@dxos/echo/internal";
2293
+ import { Filter as Filter2, Query } from "@dxos/echo-db";
2189
2294
  import { invariant as invariant3 } from "@dxos/invariant";
2190
- import { getSpace } from "@dxos/react-client/echo";
2191
- import { Callout, IconButton as IconButton4, useTranslation as useTranslation9 } from "@dxos/react-ui";
2192
- import { QueryEditor, QuerySerializer, createExpression } from "@dxos/react-ui-components";
2295
+ import { Callout, IconButton as IconButton4, Input as Input8, useTranslation as useTranslation10 } from "@dxos/react-ui";
2296
+ import { QueryForm } from "@dxos/react-ui-components";
2193
2297
  import { List as List2 } from "@dxos/react-ui-list";
2194
2298
  import { cardSpacing as cardSpacing3 } from "@dxos/react-ui-stack";
2195
2299
  import { inputTextLabel, mx as mx7, subtleHover as subtleHover2 } from "@dxos/react-ui-theme";
2196
- import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, typenameFromQuery } from "@dxos/schema";
2300
+ import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, getTypenameFromQuery } from "@dxos/schema";
2197
2301
  var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2198
2302
  var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
2199
2303
  var listItemGrid = "grid grid-cols-subgrid col-span-5";
2200
- var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly, showHeading = false, onQueryChanged, onDelete, outerSpacing = true }) => {
2201
- var _effect = _useSignals14();
2304
+ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, types, tags, onQueryChanged, onDelete, outerSpacing = true }, forwardedRef) => {
2305
+ var _effect = _useSignals15();
2202
2306
  try {
2203
- const space = getSpace(view);
2204
2307
  const schemaReadonly = !isMutable(schema);
2205
- const { t } = useTranslation9(translationKey);
2308
+ const { t } = useTranslation10(translationKey);
2206
2309
  const projectionModel = useMemo8(() => {
2207
2310
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2208
2311
  return new ProjectionModel(jsonSchema, view.projection);
2209
2312
  }, [
2210
2313
  schema,
2211
- view.projection
2314
+ JSON.stringify(view.projection)
2315
+ ]);
2316
+ useImperativeHandle(forwardedRef, () => projectionModel, [
2317
+ projectionModel
2212
2318
  ]);
2213
2319
  const [expandedField, setExpandedField] = useState7();
2214
- const serializedQuery = Match.value(kind).pipe(Match.when("basic", () => typenameFromQuery(view.query)), Match.when("advanced", () => {
2215
- if (view.query.type !== "select") {
2216
- return "";
2217
- }
2218
- const serializer = new QuerySerializer();
2219
- return serializer.serialize(createExpression(view.query.filter));
2220
- }), Match.exhaustive);
2320
+ const queueTarget = Match.value(view.query.ast).pipe(Match.when({
2321
+ type: "options"
2322
+ }, ({ options }) => {
2323
+ return Option.fromNullable(options.queues).pipe(Option.flatMap((queues) => Array2.head(queues)), Option.getOrUndefined);
2324
+ }), Match.orElse(() => void 0));
2221
2325
  const viewSchema = useMemo8(() => {
2222
- return Schema2.Struct({
2223
- query: kind === "basic" ? Format.URL.annotations({
2326
+ const base = Schema2.Struct({
2327
+ query: mode === "schema" ? Format.URL.annotations({
2224
2328
  title: "Record type"
2225
- }) : Schema2.String.annotations({
2329
+ }) : QueryAST.Query.annotations({
2226
2330
  title: "Query"
2227
2331
  })
2228
- }).pipe(Schema2.mutable);
2332
+ });
2333
+ if (mode === "query") {
2334
+ return Schema2.Struct({
2335
+ name: Schema2.optional(Schema2.String.annotations({
2336
+ title: "Name"
2337
+ })),
2338
+ ...base.fields,
2339
+ target: Schema2.optional(Schema2.String.annotations({
2340
+ title: "Target Queue"
2341
+ }))
2342
+ }).pipe(Schema2.mutable);
2343
+ }
2344
+ return base.pipe(Schema2.mutable);
2229
2345
  }, [
2230
- kind
2346
+ mode
2231
2347
  ]);
2232
2348
  const viewValues = useMemo8(() => ({
2233
- query: serializedQuery
2349
+ name: view.name,
2350
+ query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2351
+ target: queueTarget
2234
2352
  }), [
2235
- serializedQuery
2353
+ view.name,
2354
+ mode,
2355
+ view.query.ast,
2356
+ queueTarget
2236
2357
  ]);
2237
- const handleToggleField = useCallback10((field) => {
2358
+ const handleToggleField = useCallback13((field) => {
2238
2359
  setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2239
2360
  }, [
2240
2361
  readonly
2241
2362
  ]);
2242
- const handleAdd = useCallback10(() => {
2363
+ const handleAdd = useCallback13(() => {
2243
2364
  invariant3(!readonly, void 0, {
2244
2365
  F: __dxlog_file5,
2245
- L: 106,
2366
+ L: 131,
2246
2367
  S: void 0,
2247
2368
  A: [
2248
2369
  "!readonly",
@@ -2256,10 +2377,10 @@ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly
2256
2377
  projectionModel,
2257
2378
  readonly
2258
2379
  ]);
2259
- const handleUpdate = useCallback10(({ query }) => {
2380
+ const handleUpdate = useCallback13((values) => {
2260
2381
  invariant3(!readonly, void 0, {
2261
2382
  F: __dxlog_file5,
2262
- L: 113,
2383
+ L: 138,
2263
2384
  S: void 0,
2264
2385
  A: [
2265
2386
  "!readonly",
@@ -2267,19 +2388,24 @@ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly
2267
2388
  ]
2268
2389
  });
2269
2390
  requestAnimationFrame(() => {
2270
- if (serializedQuery !== query && !readonly) {
2271
- onQueryChanged?.(query);
2391
+ if ("name" in values && view.name !== values.name) {
2392
+ view.name = values.name;
2393
+ return;
2272
2394
  }
2395
+ const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : values.query;
2396
+ onQueryChanged?.(query, values.target);
2273
2397
  });
2274
2398
  }, [
2275
- serializedQuery,
2276
2399
  onQueryChanged,
2277
- readonly
2400
+ readonly,
2401
+ view,
2402
+ queueTarget,
2403
+ mode
2278
2404
  ]);
2279
- const handleDelete = useCallback10((fieldId) => {
2405
+ const handleDelete = useCallback13((fieldId) => {
2280
2406
  invariant3(!readonly, void 0, {
2281
2407
  F: __dxlog_file5,
2282
- L: 125,
2408
+ L: 154,
2283
2409
  S: void 0,
2284
2410
  A: [
2285
2411
  "!readonly",
@@ -2295,10 +2421,10 @@ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly
2295
2421
  onDelete,
2296
2422
  readonly
2297
2423
  ]);
2298
- const handleMove = useCallback10((fromIndex, toIndex) => {
2424
+ const handleMove = useCallback13((fromIndex, toIndex) => {
2299
2425
  invariant3(!readonly, void 0, {
2300
2426
  F: __dxlog_file5,
2301
- L: 137,
2427
+ L: 166,
2302
2428
  S: void 0,
2303
2429
  A: [
2304
2430
  "!readonly",
@@ -2315,41 +2441,37 @@ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly
2315
2441
  view.projection.fields,
2316
2442
  readonly
2317
2443
  ]);
2318
- const handleClose = useCallback10(() => setExpandedField(void 0), []);
2319
- const handleHide = useCallback10((fieldId) => {
2444
+ const handleClose = useCallback13(() => setExpandedField(void 0), []);
2445
+ const handleHide = useCallback13((fieldId) => {
2320
2446
  setExpandedField(void 0);
2321
2447
  projectionModel.hideFieldProjection(fieldId);
2322
2448
  }, [
2323
2449
  projectionModel
2324
2450
  ]);
2325
- const handleShow = useCallback10((property) => {
2451
+ const handleShow = useCallback13((property) => {
2326
2452
  setExpandedField(void 0);
2327
2453
  projectionModel.showFieldProjection(property);
2328
2454
  }, [
2329
2455
  projectionModel
2330
2456
  ]);
2331
- const custom = useMemo8(() => kind === "advanced" ? {
2332
- ["query"]: (props) => {
2333
- const handleChange = useCallback10((text) => props.onValueChange("string", text), [
2334
- props.onValueChange
2335
- ]);
2336
- return /* @__PURE__ */ React14.createElement(QueryEditor, {
2337
- space,
2338
- initialValue: props.getValue(),
2339
- onChange: handleChange
2340
- });
2341
- }
2342
- } : {}, []);
2343
- return /* @__PURE__ */ React14.createElement("div", {
2457
+ const custom = useMemo8(() => mode === "query" ? customFields({
2458
+ types,
2459
+ tags
2460
+ }) : void 0, [
2461
+ types,
2462
+ tags,
2463
+ mode
2464
+ ]);
2465
+ return /* @__PURE__ */ React15.createElement("div", {
2344
2466
  role: "none",
2345
2467
  className: mx7(classNames)
2346
- }, schemaReadonly && /* @__PURE__ */ React14.createElement(Callout.Root, {
2468
+ }, schemaReadonly && mode === "schema" && /* @__PURE__ */ React15.createElement(Callout.Root, {
2347
2469
  valence: "info",
2348
2470
  classNames: [
2349
2471
  "mlb-cardSpacingBlock",
2350
2472
  outerSpacing && "mli-cardSpacingInline"
2351
2473
  ]
2352
- }, /* @__PURE__ */ React14.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React14.createElement(Form, {
2474
+ }, /* @__PURE__ */ React15.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React15.createElement(Form, {
2353
2475
  autoSave: true,
2354
2476
  schema: viewSchema,
2355
2477
  values: viewValues,
@@ -2357,51 +2479,51 @@ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly
2357
2479
  onSave: handleUpdate,
2358
2480
  outerSpacing,
2359
2481
  Custom: custom
2360
- }), /* @__PURE__ */ React14.createElement("div", {
2482
+ }), /* @__PURE__ */ React15.createElement("div", {
2361
2483
  role: "none",
2362
2484
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2363
- }, /* @__PURE__ */ React14.createElement("h2", {
2485
+ }, /* @__PURE__ */ React15.createElement("h2", {
2364
2486
  className: mx7(inputTextLabel)
2365
- }, t("fields label")), /* @__PURE__ */ React14.createElement(List2.Root, {
2487
+ }, t("fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
2366
2488
  items: view.projection.fields,
2367
2489
  isItem: Schema2.is(FieldSchema),
2368
2490
  getId: (field) => field.id,
2369
2491
  onMove: readonly ? void 0 : handleMove,
2370
2492
  readonly
2371
- }, ({ items: fields }) => /* @__PURE__ */ React14.createElement(React14.Fragment, null, showHeading && /* @__PURE__ */ React14.createElement("h3", {
2493
+ }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("h3", {
2372
2494
  className: "text-sm"
2373
- }, t("field path label")), /* @__PURE__ */ React14.createElement("div", {
2495
+ }, t("field path label")), /* @__PURE__ */ React15.createElement("div", {
2374
2496
  role: "list",
2375
2497
  className: listGrid
2376
2498
  }, fields?.map((field) => {
2377
2499
  const hidden = field.visible === false;
2378
- return /* @__PURE__ */ React14.createElement(List2.Item, {
2500
+ return /* @__PURE__ */ React15.createElement(List2.Item, {
2379
2501
  key: field.id,
2380
2502
  item: field,
2381
2503
  classNames: listItemGrid,
2382
2504
  "aria-expanded": expandedField === field.id
2383
- }, /* @__PURE__ */ React14.createElement("div", {
2505
+ }, /* @__PURE__ */ React15.createElement("div", {
2384
2506
  role: "none",
2385
2507
  className: mx7(subtleHover2, listItemGrid, "rounded-sm cursor-pointer min-bs-10")
2386
- }, /* @__PURE__ */ React14.createElement(List2.ItemDragHandle, {
2508
+ }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, {
2387
2509
  disabled: readonly
2388
- }), /* @__PURE__ */ React14.createElement(List2.ItemTitle, {
2510
+ }), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
2389
2511
  classNames: hidden && "text-subdued",
2390
2512
  onClick: () => handleToggleField(field)
2391
- }, field.path), /* @__PURE__ */ React14.createElement(List2.ItemButton, {
2513
+ }, field.path), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
2392
2514
  label: t(hidden ? "show field label" : "hide field label"),
2393
2515
  "data-testid": hidden ? "show-field-button" : "hide-field-button",
2394
2516
  icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2395
2517
  autoHide: false,
2396
2518
  disabled: readonly || !hidden && projectionModel.fields.length <= 1,
2397
2519
  onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2398
- }), /* @__PURE__ */ React14.createElement(List2.ItemDeleteButton, {
2520
+ }), mode === "schema" && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2399
2521
  label: t("delete field label"),
2400
2522
  autoHide: false,
2401
2523
  disabled: readonly || schemaReadonly || view.projection.fields.length <= 1,
2402
2524
  onClick: () => handleDelete(field.id),
2403
2525
  "data-testid": "field.delete"
2404
- }), /* @__PURE__ */ React14.createElement(IconButton4, {
2526
+ }), /* @__PURE__ */ React15.createElement(IconButton4, {
2405
2527
  iconOnly: true,
2406
2528
  variant: "ghost",
2407
2529
  label: t("toggle expand label", {
@@ -2409,20 +2531,20 @@ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly
2409
2531
  }),
2410
2532
  icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2411
2533
  onClick: () => handleToggleField(field)
2412
- })), expandedField === field.id && /* @__PURE__ */ React14.createElement("div", {
2534
+ }))), expandedField === field.id && mode === "schema" && /* @__PURE__ */ React15.createElement("div", {
2413
2535
  role: "none",
2414
2536
  className: "col-span-5 mbs-1 mbe-1 border border-separator rounded-md"
2415
- }, /* @__PURE__ */ React14.createElement(FieldEditor, {
2537
+ }, /* @__PURE__ */ React15.createElement(FieldEditor, {
2416
2538
  readonly: readonly || schemaReadonly ? "disabled-input" : false,
2417
2539
  projection: projectionModel,
2418
2540
  field,
2419
2541
  registry,
2420
2542
  onSave: handleClose
2421
2543
  })));
2422
- }))))), !readonly && !expandedField && /* @__PURE__ */ React14.createElement("div", {
2544
+ }))))), !readonly && !expandedField && mode === "schema" && /* @__PURE__ */ React15.createElement("div", {
2423
2545
  role: "none",
2424
2546
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2425
- }, /* @__PURE__ */ React14.createElement(IconButton4, {
2547
+ }, /* @__PURE__ */ React15.createElement(IconButton4, {
2426
2548
  icon: "ph--plus--regular",
2427
2549
  label: t("button add property"),
2428
2550
  onClick: readonly ? void 0 : handleAdd,
@@ -2433,7 +2555,22 @@ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly
2433
2555
  } finally {
2434
2556
  _effect.f();
2435
2557
  }
2436
- };
2558
+ });
2559
+ var customFields = ({ types, tags }) => ({
2560
+ query: (props) => {
2561
+ const handleChange = useCallback13((query) => props.onValueChange("object", query.ast), [
2562
+ props.onValueChange
2563
+ ]);
2564
+ return /* @__PURE__ */ React15.createElement(Input8.Root, null, /* @__PURE__ */ React15.createElement(InputHeader, {
2565
+ label: props.label
2566
+ }), /* @__PURE__ */ React15.createElement(QueryForm, {
2567
+ initialQuery: props.getValue(),
2568
+ types,
2569
+ tags,
2570
+ onChange: handleChange
2571
+ }));
2572
+ }
2573
+ });
2437
2574
  export {
2438
2575
  BooleanInput,
2439
2576
  ControlFrame,
@@ -2452,6 +2589,7 @@ export {
2452
2589
  InputHeader,
2453
2590
  MarkdownInput,
2454
2591
  NumberInput,
2592
+ ObjectPicker,
2455
2593
  SelectInput,
2456
2594
  SelectOptionInput,
2457
2595
  TextInput,