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