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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/lib/browser/index.mjs +223 -205
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +223 -205
  5. package/dist/lib/node-esm/index.mjs.map +3 -3
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +5 -5
  8. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +5 -5
  9. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  10. package/dist/types/src/components/Form/Form.d.ts +5 -4
  11. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  12. package/dist/types/src/components/Form/Form.stories.d.ts +47 -33
  13. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/FormContext.d.ts +3 -3
  17. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/Input.d.ts +2 -2
  19. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/RefField.d.ts +1 -0
  21. package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +5 -5
  23. package/dist/types/src/components/Form/factory.d.ts +2 -2
  24. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  25. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +1 -1
  26. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  27. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +6 -5
  28. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  29. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +11 -9
  30. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  31. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +8 -8
  32. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  33. package/dist/types/src/hooks/useForm.d.ts +4 -4
  34. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  35. package/dist/types/src/hooks/useQueryRefOptions.d.ts +1 -0
  36. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -1
  37. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -1
  38. package/dist/types/src/translations.d.ts +5 -5
  39. package/dist/types/src/util/field.d.ts +3 -3
  40. package/dist/types/src/util/field.d.ts.map +1 -1
  41. package/dist/types/src/util/formatting.d.ts +2 -2
  42. package/dist/types/src/util/formatting.d.ts.map +1 -1
  43. package/dist/types/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +32 -31
  45. package/src/components/ControlSection/ControlSection.stories.tsx +1 -1
  46. package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
  47. package/src/components/FieldEditor/FieldEditor.tsx +3 -3
  48. package/src/components/Form/ArrayField.tsx +3 -1
  49. package/src/components/Form/Defaults.tsx +1 -1
  50. package/src/components/Form/Form.stories.tsx +24 -24
  51. package/src/components/Form/Form.tsx +8 -5
  52. package/src/components/Form/FormActions.tsx +7 -2
  53. package/src/components/Form/FormContent.tsx +53 -13
  54. package/src/components/Form/FormContext.tsx +4 -4
  55. package/src/components/Form/Input.tsx +2 -2
  56. package/src/components/Form/RefField.tsx +16 -2
  57. package/src/components/Form/custom/SelectOptionsInput.tsx +1 -1
  58. package/src/components/Form/factory.tsx +7 -4
  59. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +25 -25
  60. package/src/components/ObjectPicker/ObjectPicker.tsx +14 -14
  61. package/src/components/ViewEditor/ViewEditor.stories.tsx +46 -32
  62. package/src/components/ViewEditor/ViewEditor.test.tsx +4 -3
  63. package/src/components/ViewEditor/ViewEditor.tsx +41 -97
  64. package/src/hooks/useForm.ts +8 -7
  65. package/src/hooks/useQueryRefOptions.ts +6 -3
  66. package/src/hooks/useRefQueryLookupHandler.ts +5 -5
  67. package/src/translations.ts +5 -5
  68. package/src/util/field.ts +25 -25
  69. package/src/util/formatting.ts +22 -22
  70. package/src/util/refs.ts +6 -6
@@ -8,7 +8,7 @@ var translations = [
8
8
  "hidden fields label": "Hidden Fields",
9
9
  "empty readonly ref field label": "(none)",
10
10
  // TODO(burdon): Standardize field/property.
11
- "button add property": "Add property",
11
+ "add property button label": "Add property",
12
12
  "field property label": "Property",
13
13
  "field property placeholder": "Property name",
14
14
  "field format label": "Type",
@@ -25,8 +25,8 @@ var translations = [
25
25
  "ref field placeholder_one": "Select\u2026",
26
26
  "ref field placeholder_other": "Select items\u2026",
27
27
  // TODO(burdon): Factor out?
28
- "button cancel": "Cancel",
29
- "button save": "Save",
28
+ "cancel button label": "Cancel",
29
+ "save button label": "Save",
30
30
  // FormatEnum
31
31
  "format boolean": "Boolean",
32
32
  "format currency": "Currency",
@@ -66,8 +66,8 @@ var translations = [
66
66
  "select option delete": "Delete",
67
67
  "select option add": "Add option",
68
68
  // System schema message.
69
- "system schema title": "System record type",
70
- "system schema description": "This is a system record type and cannot be modified, though the view can still be configured."
69
+ "system schema title": "System type",
70
+ "system schema description": "This is a system type and cannot be modified, though the view can still be configured."
71
71
  }
72
72
  }
73
73
  }
@@ -215,8 +215,8 @@ var ControlFrameItem = ({ title, description, children }) => {
215
215
 
216
216
  // src/components/FieldEditor/FieldEditor.tsx
217
217
  import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
218
- import React14, { useCallback as useCallback11, useEffect as useEffect8, useMemo as useMemo7, useState as useState6 } from "react";
219
- import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo/internal";
218
+ import React14, { useCallback as useCallback12, useEffect as useEffect8, useMemo as useMemo7, useState as useState6 } from "react";
219
+ import { Format as Format5, FormatEnums, formatToType } from "@dxos/echo/internal";
220
220
  import { log as log3 } from "@dxos/log";
221
221
  import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
222
222
  import { formatToAdditionalPropertyAttributes, getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
@@ -472,7 +472,7 @@ var SelectOptionInput = ({ type, label, readonly, getStatus, getValue: getValue3
472
472
  readonly: !!readonly
473
473
  }, ({ items }) => /* @__PURE__ */ React4.createElement("div", {
474
474
  role: "list",
475
- className: "w-full overflow-auto"
475
+ className: "is-full overflow-auto"
476
476
  }, items?.map((item) => /* @__PURE__ */ React4.createElement("div", {
477
477
  key: item.id
478
478
  }, /* @__PURE__ */ React4.createElement(List.Item, {
@@ -708,7 +708,7 @@ var MarkdownInput = ({ type, label, inputOnly, readonly, placeholder, getStatus,
708
708
  disabled: !!readonly,
709
709
  placeholder,
710
710
  value: getValue3() ?? "",
711
- classNames: "min-bs-auto max-h-40 overflow-auto",
711
+ classNames: "min-bs-auto max-bs-40 overflow-auto",
712
712
  onChange: (event) => onValueChange(type, event.target.value),
713
713
  onBlur,
714
714
  style: {
@@ -724,7 +724,7 @@ var MarkdownInput = ({ type, label, inputOnly, readonly, placeholder, getStatus,
724
724
  // src/components/Form/Form.tsx
725
725
  import { useSignals as _useSignals13 } from "@preact-signals/safe-react/tracking";
726
726
  import { useFocusFinders } from "@fluentui/react-tabster";
727
- import React13, { useCallback as useCallback10, useEffect as useEffect7, useRef as useRef3 } from "react";
727
+ import React13, { useCallback as useCallback11, useEffect as useEffect7, useRef as useRef3 } from "react";
728
728
  import { cardDialogOverflow, cardSpacing as cardSpacing2 } from "@dxos/react-ui-stack";
729
729
 
730
730
  // src/components/Form/FormActions.tsx
@@ -736,7 +736,7 @@ import { mx as mx4 } from "@dxos/react-ui-theme";
736
736
 
737
737
  // src/components/Form/FormContext.tsx
738
738
  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";
739
+ import React7, { createContext, useCallback as useCallback7, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
740
740
  import { raise } from "@dxos/debug";
741
741
  import { getValue as getValue2 } from "@dxos/echo/internal";
742
742
  import { createJsonPath as createJsonPath2 } from "@dxos/effect";
@@ -867,15 +867,16 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
867
867
  ...setValue(values, jsonPath, parsedValue)
868
868
  };
869
869
  setValues(newValues);
870
- setChanged((prev) => ({
871
- ...prev,
870
+ const newChanged = {
871
+ ...changed,
872
872
  [jsonPath]: true
873
- }));
873
+ };
874
+ setChanged(newChanged);
874
875
  onValuesChanged?.(newValues);
875
876
  const isValid = validate(newValues);
876
877
  if (isValid && onValid) {
877
878
  onValid(newValues, {
878
- changed
879
+ changed: newChanged
879
880
  });
880
881
  }
881
882
  }, [
@@ -928,7 +929,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
928
929
  var createKeySet = (obj, value2) => {
929
930
  invariant(obj, void 0, {
930
931
  F: __dxlog_file,
931
- L: 279,
932
+ L: 280,
932
933
  S: void 0,
933
934
  A: [
934
935
  "obj",
@@ -952,7 +953,7 @@ var flatMap = (errors) => {
952
953
 
953
954
  // src/hooks/useRefQueryLookupHandler.ts
954
955
  import { useCallback as useCallback5 } from "react";
955
- import { getObjectDXN } from "@dxos/echo/internal";
956
+ import { Obj } from "@dxos/echo";
956
957
  import { Filter } from "@dxos/react-client/echo";
957
958
  import { isNonNullable } from "@dxos/util";
958
959
  var useRefQueryLookupHandler = ({ space }) => {
@@ -963,13 +964,13 @@ var useRefQueryLookupHandler = ({ space }) => {
963
964
  const query = space.db.query(Filter.typename(typeInfo.typename));
964
965
  const { objects } = await query.run();
965
966
  return objects.map((object) => {
966
- const dxn = getObjectDXN(object);
967
+ const dxn = Obj.getDXN(object);
967
968
  if (!dxn) {
968
969
  return void 0;
969
970
  }
970
971
  const item = {
971
972
  dxn,
972
- label: object?.name ?? object?.id ?? ""
973
+ label: Obj.getLabel(object) ?? object?.id ?? ""
973
974
  };
974
975
  return item;
975
976
  }).filter(isNonNullable);
@@ -979,12 +980,14 @@ var useRefQueryLookupHandler = ({ space }) => {
979
980
  };
980
981
 
981
982
  // src/hooks/useQueryRefOptions.ts
982
- import { useEffect as useEffect5, useState as useState4 } from "react";
983
+ import { useCallback as useCallback6, useEffect as useEffect5, useState as useState4 } from "react";
983
984
  import { log as log2 } from "@dxos/log";
984
985
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts";
985
986
  var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
986
987
  const [options, setOptions] = useState4([]);
987
988
  const [loading, setLoading] = useState4(false);
989
+ const [state, setState] = useState4({});
990
+ const update = useCallback6(() => setState({}), []);
988
991
  useEffect5(() => {
989
992
  if (!refTypeInfo || !onQueryRefOptions) {
990
993
  return;
@@ -1004,7 +1007,7 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1004
1007
  } catch (error) {
1005
1008
  log2.error("Failed to fetch ref options:", error, {
1006
1009
  F: __dxlog_file2,
1007
- L: 48,
1010
+ L: 51,
1008
1011
  S: void 0,
1009
1012
  C: (f, a) => f(...a)
1010
1013
  });
@@ -1016,10 +1019,12 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1016
1019
  void fetchOptions();
1017
1020
  }, [
1018
1021
  refTypeInfo,
1019
- onQueryRefOptions
1022
+ onQueryRefOptions,
1023
+ state
1020
1024
  ]);
1021
1025
  return {
1022
1026
  options,
1027
+ update,
1023
1028
  loading
1024
1029
  };
1025
1030
  };
@@ -1056,7 +1061,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1056
1061
  var _effect = _useSignals7();
1057
1062
  try {
1058
1063
  const form = useForm(formOptions);
1059
- const handleKeyDown = useCallback6((event) => {
1064
+ const handleKeyDown = useCallback7((event) => {
1060
1065
  const keyIsEnter = event.key === "Enter";
1061
1066
  const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
1062
1067
  const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
@@ -1111,14 +1116,14 @@ var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1111
1116
  }, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
1112
1117
  "data-testid": "cancel-button",
1113
1118
  icon: "ph--x--regular",
1114
- label: t("button cancel"),
1119
+ label: t("cancel button label"),
1115
1120
  onClick: onCancel
1116
1121
  }), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
1117
1122
  type: "submit",
1118
1123
  "data-testid": "save-button",
1119
1124
  disabled: !canSave,
1120
1125
  icon: "ph--check--regular",
1121
- label: t("button save"),
1126
+ label: t("save button label"),
1122
1127
  onClick: handleSave
1123
1128
  }));
1124
1129
  } finally {
@@ -1132,14 +1137,14 @@ import * as Function2 from "effect/Function";
1132
1137
  import * as Schema from "effect/Schema";
1133
1138
  import * as SchemaAST4 from "effect/SchemaAST";
1134
1139
  import * as StringEffect from "effect/String";
1135
- import React12, { forwardRef as forwardRef2, useMemo as useMemo6 } from "react";
1140
+ import React12, { Component, forwardRef as forwardRef2, useMemo as useMemo6 } from "react";
1136
1141
  import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
1137
1142
  import { mx as mx6 } from "@dxos/react-ui-theme";
1138
1143
  import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
1139
1144
  import { isTruthy } from "@dxos/util";
1140
1145
 
1141
1146
  // src/util/field.ts
1142
- import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo/internal";
1147
+ import { Format, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo/internal";
1143
1148
  var parseValue = ({ type, format, value: value2 }) => {
1144
1149
  if (value2 === void 0 || value2 === null || value2 === "") {
1145
1150
  return void 0;
@@ -1174,26 +1179,26 @@ var parseValue = ({ type, format, value: value2 }) => {
1174
1179
  return parseScalar(type);
1175
1180
  }
1176
1181
  switch (format) {
1177
- case FormatEnum.Boolean:
1182
+ case Format.TypeFormat.Boolean:
1178
1183
  return parseScalar(TypeEnum.Boolean);
1179
- case FormatEnum.Number:
1180
- case FormatEnum.Percent:
1181
- case FormatEnum.Currency:
1184
+ case Format.TypeFormat.Number:
1185
+ case Format.TypeFormat.Percent:
1186
+ case Format.TypeFormat.Currency:
1182
1187
  return parseScalar(TypeEnum.Number);
1183
- case FormatEnum.String:
1184
- case FormatEnum.Markdown: {
1188
+ case Format.TypeFormat.String:
1189
+ case Format.TypeFormat.Markdown: {
1185
1190
  return parseScalar(TypeEnum.String);
1186
1191
  }
1187
- case FormatEnum.Ref:
1188
- throw new Error(`unexpected format: ${FormatEnum.Ref}`);
1189
- case FormatEnum.DateTime:
1190
- case FormatEnum.Date:
1191
- case FormatEnum.Time:
1192
- case FormatEnum.Timestamp: {
1192
+ case Format.TypeFormat.Ref:
1193
+ throw new Error(`unexpected format: ${Format.TypeFormat.Ref}`);
1194
+ case Format.TypeFormat.DateTime:
1195
+ case Format.TypeFormat.Date:
1196
+ case Format.TypeFormat.Time:
1197
+ case Format.TypeFormat.Timestamp: {
1193
1198
  const date = new Date(value2);
1194
1199
  return isNaN(date.getTime()) ? null : date;
1195
1200
  }
1196
- case FormatEnum.GeoPoint: {
1201
+ case Format.TypeFormat.GeoPoint: {
1197
1202
  if (typeof value2 === "string") {
1198
1203
  const cleaned = value2.replace(/[^0-9.,-]+/g, "");
1199
1204
  const parts = cleaned.split(",");
@@ -1220,23 +1225,23 @@ var parseValue = ({ type, format, value: value2 }) => {
1220
1225
  };
1221
1226
  var cellClassesForFieldType = ({ type, format }) => {
1222
1227
  switch (format || type) {
1223
- case FormatEnum.Markdown:
1228
+ case Format.TypeFormat.Markdown:
1224
1229
  return void 0;
1225
- case FormatEnum.Time:
1226
- case FormatEnum.Timestamp:
1227
- case FormatEnum.DateTime:
1228
- case FormatEnum.Date:
1229
- case FormatEnum.Duration:
1230
+ case Format.TypeFormat.Time:
1231
+ case Format.TypeFormat.Timestamp:
1232
+ case Format.TypeFormat.DateTime:
1233
+ case Format.TypeFormat.Date:
1234
+ case Format.TypeFormat.Duration:
1230
1235
  return [
1231
1236
  "font-mono",
1232
1237
  "text-right"
1233
1238
  ];
1234
- case FormatEnum.Currency:
1239
+ case Format.TypeFormat.Currency:
1235
1240
  return [
1236
1241
  "text-right"
1237
1242
  ];
1238
- case FormatEnum.JSON:
1239
- case FormatEnum.DID:
1243
+ case Format.TypeFormat.JSON:
1244
+ case Format.TypeFormat.DID:
1240
1245
  return [
1241
1246
  "font-mono"
1242
1247
  ];
@@ -1261,7 +1266,7 @@ var pathNotUniqueError = (path) => ({
1261
1266
 
1262
1267
  // src/util/formatting.ts
1263
1268
  import { format as formatDate } from "date-fns/format";
1264
- import { FormatEnum as FormatEnum2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
1269
+ import { Format as Format2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
1265
1270
  var formatForDisplay = ({ type, format, value: value2, locale = void 0 }) => {
1266
1271
  const formatScalar = (type2) => {
1267
1272
  switch (type2) {
@@ -1281,20 +1286,20 @@ var formatForDisplay = ({ type, format, value: value2, locale = void 0 }) => {
1281
1286
  return formatScalar(type);
1282
1287
  }
1283
1288
  switch (format) {
1284
- case FormatEnum2.Boolean: {
1289
+ case Format2.TypeFormat.Boolean: {
1285
1290
  return formatScalar(TypeEnum2.Boolean);
1286
1291
  }
1287
- case FormatEnum2.Number: {
1292
+ case Format2.TypeFormat.Number: {
1288
1293
  return formatScalar(TypeEnum2.Number);
1289
1294
  }
1290
- case FormatEnum2.String:
1291
- case FormatEnum2.Ref: {
1295
+ case Format2.TypeFormat.String:
1296
+ case Format2.TypeFormat.Ref: {
1292
1297
  return formatScalar(TypeEnum2.String);
1293
1298
  }
1294
- case FormatEnum2.Percent: {
1299
+ case Format2.TypeFormat.Percent: {
1295
1300
  return `${value2 * 100}%`;
1296
1301
  }
1297
- case FormatEnum2.Currency: {
1302
+ case Format2.TypeFormat.Currency: {
1298
1303
  return value2.toLocaleString(locale, {
1299
1304
  style: "currency",
1300
1305
  currency: "USD",
@@ -1302,28 +1307,28 @@ var formatForDisplay = ({ type, format, value: value2, locale = void 0 }) => {
1302
1307
  maximumFractionDigits: 2
1303
1308
  });
1304
1309
  }
1305
- case FormatEnum2.Date: {
1310
+ case Format2.TypeFormat.Date: {
1306
1311
  try {
1307
1312
  return formatDate(new Date(value2), "yyyy-MM-dd");
1308
1313
  } catch (error) {
1309
1314
  return "Invalid Date";
1310
1315
  }
1311
1316
  }
1312
- case FormatEnum2.Time: {
1317
+ case Format2.TypeFormat.Time: {
1313
1318
  try {
1314
1319
  return formatDate(new Date(value2), "HH:mm:ss");
1315
1320
  } catch (error) {
1316
1321
  return "Invalid Time";
1317
1322
  }
1318
1323
  }
1319
- case FormatEnum2.DateTime: {
1324
+ case Format2.TypeFormat.DateTime: {
1320
1325
  try {
1321
1326
  return formatDate(new Date(value2), "yyyy-MM-dd HH:mm:ss");
1322
1327
  } catch (error) {
1323
1328
  return "Invalid DateTime";
1324
1329
  }
1325
1330
  }
1326
- case FormatEnum2.GeoPoint: {
1331
+ case Format2.TypeFormat.GeoPoint: {
1327
1332
  if (value2 === null || value2 === void 0) {
1328
1333
  return "";
1329
1334
  }
@@ -1357,31 +1362,31 @@ var formatForEditing = ({ type, format, value: value2, locale = void 0 }) => {
1357
1362
  return formatScalar(type);
1358
1363
  }
1359
1364
  switch (format) {
1360
- case FormatEnum2.Boolean:
1361
- case FormatEnum2.Number:
1362
- case FormatEnum2.String:
1363
- case FormatEnum2.Ref: {
1365
+ case Format2.TypeFormat.Boolean:
1366
+ case Format2.TypeFormat.Number:
1367
+ case Format2.TypeFormat.String:
1368
+ case Format2.TypeFormat.Ref: {
1364
1369
  return formatScalar(type);
1365
1370
  }
1366
- case FormatEnum2.Percent: {
1371
+ case Format2.TypeFormat.Percent: {
1367
1372
  return String(value2 * 100);
1368
1373
  }
1369
- case FormatEnum2.Currency: {
1374
+ case Format2.TypeFormat.Currency: {
1370
1375
  return String(value2);
1371
1376
  }
1372
- case FormatEnum2.DateTime: {
1377
+ case Format2.TypeFormat.DateTime: {
1373
1378
  const date = new Date(value2);
1374
1379
  return date.toISOString();
1375
1380
  }
1376
- case FormatEnum2.Date: {
1381
+ case Format2.TypeFormat.Date: {
1377
1382
  const date = new Date(value2);
1378
1383
  return date.toISOString().split("T")[0];
1379
1384
  }
1380
- case FormatEnum2.Time: {
1385
+ case Format2.TypeFormat.Time: {
1381
1386
  const date = new Date(value2);
1382
1387
  return date.toISOString().split("T")[1].split(".")[0];
1383
1388
  }
1384
- case FormatEnum2.GeoPoint: {
1389
+ case Format2.TypeFormat.GeoPoint: {
1385
1390
  if (value2 === null || value2 === void 0) {
1386
1391
  return "";
1387
1392
  }
@@ -1398,7 +1403,7 @@ var formatForEditing = ({ type, format, value: value2, locale = void 0 }) => {
1398
1403
  };
1399
1404
 
1400
1405
  // src/util/refs.ts
1401
- import { FormatEnum as FormatEnum3, ReferenceAnnotationId } from "@dxos/echo/internal";
1406
+ import { Format as Format3, ReferenceAnnotationId } from "@dxos/echo/internal";
1402
1407
  import { findAnnotation } from "@dxos/effect";
1403
1408
 
1404
1409
  // src/util/schema.ts
@@ -1412,12 +1417,6 @@ var findArrayElementType = (ast) => {
1412
1417
  // src/util/refs.ts
1413
1418
  var getRefProps = (property) => {
1414
1419
  const { ast, format, array } = property;
1415
- if (format === FormatEnum3.Ref) {
1416
- return {
1417
- ast,
1418
- isArray: false
1419
- };
1420
- }
1421
1420
  if (array) {
1422
1421
  const elementType = findArrayElementType(ast);
1423
1422
  if (elementType) {
@@ -1430,6 +1429,12 @@ var getRefProps = (property) => {
1430
1429
  }
1431
1430
  }
1432
1431
  }
1432
+ if (format === Format3.TypeFormat.Ref) {
1433
+ return {
1434
+ ast,
1435
+ isArray: false
1436
+ };
1437
+ }
1433
1438
  return void 0;
1434
1439
  };
1435
1440
 
@@ -1438,7 +1443,7 @@ import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking"
1438
1443
  import * as Function from "effect/Function";
1439
1444
  import * as SchemaAST3 from "effect/SchemaAST";
1440
1445
  import * as String2 from "effect/String";
1441
- import React9, { Fragment, useCallback as useCallback7 } from "react";
1446
+ import React9, { Fragment, useCallback as useCallback8 } from "react";
1442
1447
  import { SimpleType, findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion } from "@dxos/effect";
1443
1448
  import { invariant as invariant2 } from "@dxos/invariant";
1444
1449
  import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
@@ -1467,13 +1472,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1467
1472
  if (!typeLiteral) {
1468
1473
  return {};
1469
1474
  }
1470
- return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
1475
+ return Object.fromEntries(getSchemaProperties(typeLiteral, {}, {
1476
+ form: true
1477
+ }).map((prop) => [
1471
1478
  prop.name,
1472
1479
  prop.defaultValue
1473
1480
  ]));
1474
1481
  };
1475
1482
  const getDefaultValue = () => type === "object" && elementType ? getDefaultObjectValue(elementType) : SimpleType.getDefaultValue(type);
1476
- const handleAdd = useCallback7(() => {
1483
+ const handleAdd = useCallback8(() => {
1477
1484
  inputProps.onValueChange(type, [
1478
1485
  ...values,
1479
1486
  getDefaultValue()
@@ -1484,7 +1491,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1484
1491
  inputProps,
1485
1492
  values
1486
1493
  ]);
1487
- const handleRemove = useCallback7((index) => {
1494
+ const handleRemove = useCallback8((index) => {
1488
1495
  const newValues = values.filter((_, i) => i !== index);
1489
1496
  inputProps.onValueChange(type, newValues);
1490
1497
  }, [
@@ -1540,12 +1547,12 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1540
1547
  };
1541
1548
 
1542
1549
  // src/components/Form/factory.tsx
1543
- import { FormatEnum as FormatEnum4 } from "@dxos/echo/internal";
1550
+ import { Format as Format4 } from "@dxos/echo/internal";
1544
1551
  var getInputComponent = (type, format) => {
1545
1552
  switch (format) {
1546
- case FormatEnum4.GeoPoint:
1553
+ case Format4.TypeFormat.GeoPoint:
1547
1554
  return GeoPointInput;
1548
- case FormatEnum4.Markdown:
1555
+ case Format4.TypeFormat.Markdown:
1549
1556
  return MarkdownInput;
1550
1557
  }
1551
1558
  switch (type) {
@@ -1560,7 +1567,8 @@ var getInputComponent = (type, format) => {
1560
1567
 
1561
1568
  // src/components/Form/RefField.tsx
1562
1569
  import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
1563
- import React11, { useCallback as useCallback9, useMemo as useMemo5 } from "react";
1570
+ import "@dxos/lit-ui/dx-tag-picker.pcss";
1571
+ import React11, { useCallback as useCallback10, useMemo as useMemo5 } from "react";
1564
1572
  import { Expando, Ref, ReferenceAnnotationId as ReferenceAnnotationId2, getTypeAnnotation } from "@dxos/echo/internal";
1565
1573
  import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1566
1574
  import { DXN } from "@dxos/keys";
@@ -1571,27 +1579,27 @@ import { isNonNullable as isNonNullable2 } from "@dxos/util";
1571
1579
 
1572
1580
  // src/components/ObjectPicker/ObjectPicker.tsx
1573
1581
  import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1574
- import React10, { forwardRef, useCallback as useCallback8, useMemo as useMemo4, useState as useState5 } from "react";
1582
+ import React10, { forwardRef, useCallback as useCallback9, useMemo as useMemo4, useState as useState5 } from "react";
1575
1583
  import { Icon as Icon2, Popover, useTranslation as useTranslation7 } from "@dxos/react-ui";
1576
- import { PopoverCombobox } from "@dxos/react-ui-searchlist";
1584
+ import { Combobox } from "@dxos/react-ui-searchlist";
1577
1585
  var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
1578
1586
  var _effect = _useSignals10();
1579
1587
  try {
1580
1588
  const { t } = useTranslation7(translationKey);
1581
1589
  const [searchString, setSearchString] = useState5("");
1582
1590
  const [showForm, setShowForm] = useState5(false);
1583
- const handleFormSave = useCallback8((values) => {
1591
+ const handleFormSave = useCallback9((values) => {
1584
1592
  onCreate?.(values);
1585
1593
  setShowForm(false);
1586
1594
  setSearchString("");
1587
1595
  }, [
1588
1596
  onCreate
1589
1597
  ]);
1590
- const handleFormCancel = useCallback8(() => {
1598
+ const handleFormCancel = useCallback9(() => {
1591
1599
  setShowForm(false);
1592
1600
  setSearchString("");
1593
1601
  }, []);
1594
- const handleClick = useCallback8((event) => {
1602
+ const handleClick = useCallback9((event) => {
1595
1603
  if (createSchema && event.target.closest('[data-value="__create__"]')) {
1596
1604
  event.stopPropagation();
1597
1605
  event.preventDefault();
@@ -1600,7 +1608,7 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1600
1608
  }, [
1601
1609
  createSchema
1602
1610
  ]);
1603
- const handleKeyDown = useCallback8((event) => {
1611
+ const handleKeyDown = useCallback9((event) => {
1604
1612
  if (event.key === "Enter" && createSchema && event.currentTarget.querySelector('[role="option"][aria-selected="true"][data-value="__create__"]')) {
1605
1613
  event.stopPropagation();
1606
1614
  event.preventDefault();
@@ -1615,7 +1623,7 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1615
1623
  }, {}), [
1616
1624
  options
1617
1625
  ]);
1618
- return /* @__PURE__ */ React10.createElement(PopoverCombobox.Content, {
1626
+ return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1619
1627
  ...props,
1620
1628
  ref,
1621
1629
  filter: (value2, search) => value2 === "__create__" || labelById[value2]?.includes(search.toLowerCase()) ? 1 : 0,
@@ -1629,12 +1637,12 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1629
1637
  onSave: handleFormSave,
1630
1638
  onCancel: handleFormCancel,
1631
1639
  testId: "create-referenced-object-form"
1632
- })) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(PopoverCombobox.Input, {
1640
+ })) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1633
1641
  placeholder: t("ref field combobox input placeholder"),
1634
1642
  value: searchString,
1635
1643
  onValueChange: setSearchString,
1636
1644
  autoFocus: true
1637
- }), /* @__PURE__ */ React10.createElement(PopoverCombobox.List, null, options.map((option) => /* @__PURE__ */ React10.createElement(PopoverCombobox.Item, {
1645
+ }), /* @__PURE__ */ React10.createElement(Combobox.List, null, options.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1638
1646
  key: option.id,
1639
1647
  value: option.id,
1640
1648
  onSelect: () => onSelect(option.id),
@@ -1643,7 +1651,7 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1643
1651
  className: "grow"
1644
1652
  }, option.label), selectedIds?.includes(option.id) && /* @__PURE__ */ React10.createElement(Icon2, {
1645
1653
  icon: "ph--check--regular"
1646
- }))), searchString.length > 0 && createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React10.createElement(PopoverCombobox.Item, {
1654
+ }))), searchString.length > 0 && createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React10.createElement(Combobox.Item, {
1647
1655
  value: "__create__",
1648
1656
  classNames: "flex items-center gap-2"
1649
1657
  }, /* @__PURE__ */ React10.createElement(Icon2, {
@@ -1651,16 +1659,16 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1651
1659
  }), t(createOptionLabel[0], {
1652
1660
  ns: createOptionLabel[1].ns,
1653
1661
  text: searchString
1654
- })))), /* @__PURE__ */ React10.createElement(PopoverCombobox.Arrow, null));
1662
+ })))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1655
1663
  } finally {
1656
1664
  _effect.f();
1657
1665
  }
1658
1666
  });
1659
1667
  ObjectPickerContent.displayName = "ObjectPickerContent";
1660
1668
  var ObjectPicker = {
1661
- Root: PopoverCombobox.Root,
1662
- Trigger: PopoverCombobox.Trigger,
1663
- VirtualTrigger: PopoverCombobox.VirtualTrigger,
1669
+ Root: Combobox.Root,
1670
+ Trigger: Combobox.Trigger,
1671
+ VirtualTrigger: Combobox.VirtualTrigger,
1664
1672
  Content: ObjectPickerContent
1665
1673
  };
1666
1674
 
@@ -1675,7 +1683,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1675
1683
  const refTypeInfo = useMemo5(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1676
1684
  ast
1677
1685
  ]);
1678
- const { options: availableOptions, loading: _loading } = useQueryRefOptions({
1686
+ const { options: availableOptions, update: updateOptions, loading: _loading } = useQueryRefOptions({
1679
1687
  refTypeInfo,
1680
1688
  onQueryRefOptions
1681
1689
  });
@@ -1692,7 +1700,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1692
1700
  ...restInputProps
1693
1701
  });
1694
1702
  }
1695
- const handleGetValue = useCallback9(() => {
1703
+ const handleGetValue = useCallback10(() => {
1696
1704
  const formValue = getValue3();
1697
1705
  const unknownToRefOption = (val) => {
1698
1706
  const isRef = Ref.isRef(val);
@@ -1720,7 +1728,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1720
1728
  availableOptions,
1721
1729
  array
1722
1730
  ]);
1723
- const handleUpdate = useCallback9((ids) => {
1731
+ const handleUpdate = useCallback10((ids) => {
1724
1732
  if (ids.length === 0) {
1725
1733
  onValueChange("object", void 0);
1726
1734
  return;
@@ -1743,6 +1751,13 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1743
1751
  array,
1744
1752
  onValueChange
1745
1753
  ]);
1754
+ const handleCreate = useCallback10((values) => {
1755
+ onCreate?.(values);
1756
+ updateOptions();
1757
+ }, [
1758
+ onCreate,
1759
+ updateOptions
1760
+ ]);
1746
1761
  if (!refTypeInfo) {
1747
1762
  return null;
1748
1763
  }
@@ -1751,7 +1766,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1751
1766
  const selectedIds = useMemo5(() => items.map((i) => i.id), [
1752
1767
  items
1753
1768
  ]);
1754
- const toggleSelect = useCallback9((id) => {
1769
+ const toggleSelect = useCallback10((id) => {
1755
1770
  if (array) {
1756
1771
  const nextIds = selectedIds.includes(id) ? selectedIds.filter((x) => x !== id) : [
1757
1772
  ...selectedIds,
@@ -1821,7 +1836,7 @@ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, get
1821
1836
  createOptionLabel,
1822
1837
  createOptionIcon,
1823
1838
  createInitialValuePath,
1824
- onCreate
1839
+ onCreate: handleCreate
1825
1840
  }))), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
1826
1841
  } finally {
1827
1842
  _effect.f();
@@ -1993,7 +2008,9 @@ var FormFields = /* @__PURE__ */ forwardRef2(({ classNames, schema, path, filter
1993
2008
  try {
1994
2009
  const values = useFormValues(path);
1995
2010
  const properties = useMemo6(() => {
1996
- const props2 = getSchemaProperties2(schema.ast, values);
2011
+ const props2 = getSchemaProperties2(schema.ast, values, {
2012
+ form: true
2013
+ });
1997
2014
  if (projection) {
1998
2015
  const fieldProjections = projection.getFieldProjections();
1999
2016
  const hiddenProperties = new Set(projection.getHiddenProperties());
@@ -2025,8 +2042,13 @@ var FormFields = /* @__PURE__ */ forwardRef2(({ classNames, schema, path, filter
2025
2042
  className: mx6("is-full", classNames),
2026
2043
  ref: forwardRef4
2027
2044
  }, properties.map((property) => {
2028
- return /* @__PURE__ */ React12.createElement(FormField, {
2045
+ return /* @__PURE__ */ React12.createElement(ErrorBoundary, {
2029
2046
  key: property.name,
2047
+ path: [
2048
+ ...path ?? [],
2049
+ property.name
2050
+ ]
2051
+ }, /* @__PURE__ */ React12.createElement(FormField, {
2030
2052
  property,
2031
2053
  path: [
2032
2054
  ...path ?? [],
@@ -2038,15 +2060,45 @@ var FormFields = /* @__PURE__ */ forwardRef2(({ classNames, schema, path, filter
2038
2060
  lookupComponent,
2039
2061
  Custom,
2040
2062
  ...props
2041
- });
2063
+ }));
2042
2064
  }).filter(isTruthy));
2043
2065
  } finally {
2044
2066
  _effect.f();
2045
2067
  }
2046
2068
  });
2069
+ var ErrorBoundary = class extends Component {
2070
+ static getDerivedStateFromError(error) {
2071
+ return {
2072
+ error
2073
+ };
2074
+ }
2075
+ state = {
2076
+ error: void 0
2077
+ };
2078
+ componentDidUpdate(prevProps) {
2079
+ if (prevProps.path !== this.props.path) {
2080
+ this.resetError();
2081
+ }
2082
+ }
2083
+ render() {
2084
+ if (this.state.error) {
2085
+ return /* @__PURE__ */ React12.createElement("div", {
2086
+ className: "flex gap-2 border border-roseFill font-mono text-sm"
2087
+ }, /* @__PURE__ */ React12.createElement("span", {
2088
+ className: "bg-roseFill text-surfaceText pli-1 font-thin"
2089
+ }, "ERROR"), String(this.props.path?.join(".")));
2090
+ }
2091
+ return this.props.children;
2092
+ }
2093
+ resetError() {
2094
+ this.setState({
2095
+ error: void 0
2096
+ });
2097
+ }
2098
+ };
2047
2099
 
2048
2100
  // src/components/Form/Form.tsx
2049
- var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, schema, onCancel, onValuesChanged, onValidate, onSave, ...props }) => {
2101
+ var Form = ({ classNames, id, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, schema, onCancel, onValuesChanged, onValidate, onSave, ...props }) => {
2050
2102
  var _effect = _useSignals13();
2051
2103
  try {
2052
2104
  const formRef = useRef3(null);
@@ -2061,7 +2113,7 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
2061
2113
  }, [
2062
2114
  autoFocus
2063
2115
  ]);
2064
- const handleValid = useCallback10(async (values, meta) => {
2116
+ const handleValid = useCallback11(async (values, meta) => {
2065
2117
  if (autoSave) {
2066
2118
  await onSave?.(values, meta);
2067
2119
  }
@@ -2081,6 +2133,9 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
2081
2133
  }, /* @__PURE__ */ React13.createElement("div", {
2082
2134
  role: "none",
2083
2135
  className: "contents",
2136
+ ...id && {
2137
+ "data-object-id": id
2138
+ },
2084
2139
  "data-testid": testId
2085
2140
  }, /* @__PURE__ */ React13.createElement(FormFields, {
2086
2141
  ...props,
@@ -2137,7 +2192,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2137
2192
  const [{ fieldSchema }, setFieldSchema] = useState6({
2138
2193
  fieldSchema: getFormatSchema(props?.format)
2139
2194
  });
2140
- const handleValuesChanged = useCallback11((_props) => {
2195
+ const handleValuesChanged = useCallback12((_props) => {
2141
2196
  setFieldSchema((prev) => {
2142
2197
  const fieldSchema2 = getFormatSchema(_props.format);
2143
2198
  if (prev.fieldSchema === fieldSchema2) {
@@ -2174,7 +2229,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2174
2229
  props.format,
2175
2230
  props.referenceSchema
2176
2231
  ]);
2177
- const handleValidate = useCallback11(({ property }) => {
2232
+ const handleValidate = useCallback12(({ property }) => {
2178
2233
  if (property && projection.fields.find((f) => f.path === property && f.path !== field.path)) {
2179
2234
  return [
2180
2235
  {
@@ -2187,7 +2242,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2187
2242
  projection.fields,
2188
2243
  field
2189
2244
  ]);
2190
- const handleSave = useCallback11((props2) => {
2245
+ const handleSave = useCallback12((props2) => {
2191
2246
  projection.setFieldProjection({
2192
2247
  field,
2193
2248
  props: props2
@@ -2198,7 +2253,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2198
2253
  field,
2199
2254
  onSave
2200
2255
  ]);
2201
- const handleCancel = useCallback11(() => {
2256
+ const handleCancel = useCallback12(() => {
2202
2257
  requestAnimationFrame(() => onCancel?.());
2203
2258
  onSave();
2204
2259
  }, [
@@ -2207,7 +2262,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2207
2262
  const custom = useMemo7(() => ({
2208
2263
  ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2209
2264
  ...props2,
2210
- options: FormatEnums.filter((value2) => value2 !== FormatEnum5.None).map((value2) => ({
2265
+ options: FormatEnums.filter((value2) => value2 !== Format5.TypeFormat.None).map((value2) => ({
2211
2266
  value: value2,
2212
2267
  label: t(`format ${value2}`)
2213
2268
  }))
@@ -2220,7 +2275,9 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2220
2275
  }),
2221
2276
  ["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2222
2277
  ...props2,
2223
- options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
2278
+ options: referenceSchema ? getSchemaProperties3(referenceSchema.ast, {}, {
2279
+ form: true
2280
+ }).sort(sortProperties).map((p) => ({
2224
2281
  value: p.name
2225
2282
  })) : []
2226
2283
  }),
@@ -2230,7 +2287,7 @@ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, ou
2230
2287
  schemas,
2231
2288
  referenceSchema
2232
2289
  ]);
2233
- const propIsNotType = useCallback11((props2) => props2.filter((p) => p.name !== "type"), []);
2290
+ const propIsNotType = useCallback12((props2) => props2.filter((p) => p.name !== "type"), []);
2234
2291
  if (!fieldSchema) {
2235
2292
  log3.warn("invalid format", {
2236
2293
  props
@@ -2271,20 +2328,21 @@ import * as Array2 from "effect/Array";
2271
2328
  import * as Match from "effect/Match";
2272
2329
  import * as Option from "effect/Option";
2273
2330
  import * as Schema2 from "effect/Schema";
2274
- import React15, { forwardRef as forwardRef3, useCallback as useCallback12, useEffect as useEffect9, useImperativeHandle, useMemo as useMemo8, useRef as useRef4, useState as useState7 } from "react";
2275
- import { EchoSchema, Format, isMutable, toJsonSchema } from "@dxos/echo/internal";
2331
+ import React15, { forwardRef as forwardRef3, useCallback as useCallback13, useImperativeHandle, useMemo as useMemo8, useState as useState7 } from "react";
2332
+ import { QueryAST } from "@dxos/echo";
2333
+ import { EchoSchema, Format as Format6, isMutable, toJsonSchema } from "@dxos/echo/internal";
2334
+ import { Filter as Filter2, Query } from "@dxos/echo-db";
2276
2335
  import { invariant as invariant3 } from "@dxos/invariant";
2277
- import { Callout, IconButton as IconButton4, Input as Input8, useDensityContext, useElevationContext, useThemeContext, useTranslation as useTranslation10 } from "@dxos/react-ui";
2278
- import { Editor, createBasicExtensions, createThemeExtensions } from "@dxos/react-ui-editor";
2336
+ import { Callout, IconButton as IconButton4, Input as Input8, useTranslation as useTranslation10 } from "@dxos/react-ui";
2337
+ import { QueryForm } from "@dxos/react-ui-components";
2279
2338
  import { List as List2 } from "@dxos/react-ui-list";
2280
2339
  import { cardSpacing as cardSpacing3 } from "@dxos/react-ui-stack";
2281
- import { inputTheme } from "@dxos/react-ui-theme";
2282
2340
  import { inputTextLabel, mx as mx7, subtleHover as subtleHover2 } from "@dxos/react-ui-theme";
2283
2341
  import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, getTypenameFromQuery } from "@dxos/schema";
2284
2342
  var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2285
2343
  var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
2286
2344
  var listItemGrid = "grid grid-cols-subgrid col-span-5";
2287
- var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, onQueryChanged, onDelete, outerSpacing = true }, forwardedRef) => {
2345
+ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, types, tags, onQueryChanged, onDelete, outerSpacing = true }, forwardedRef) => {
2288
2346
  var _effect = _useSignals15();
2289
2347
  try {
2290
2348
  const schemaReadonly = !isMutable(schema);
@@ -2300,13 +2358,6 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2300
2358
  projectionModel
2301
2359
  ]);
2302
2360
  const [expandedField, setExpandedField] = useState7();
2303
- const serializedQuery = Match.value(mode).pipe(Match.when("schema", () => getTypenameFromQuery(view.query.ast)), Match.when("query", () => {
2304
- if (view.query.string) {
2305
- return view.query.string;
2306
- } else {
2307
- return "Serializing query AST is not currently supported.";
2308
- }
2309
- }), Match.exhaustive);
2310
2361
  const queueTarget = Match.value(view.query.ast).pipe(Match.when({
2311
2362
  type: "options"
2312
2363
  }, ({ options }) => {
@@ -2314,17 +2365,14 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2314
2365
  }), Match.orElse(() => void 0));
2315
2366
  const viewSchema = useMemo8(() => {
2316
2367
  const base = Schema2.Struct({
2317
- query: mode === "schema" ? Format.URL.annotations({
2368
+ query: mode === "schema" ? Format6.URL.annotations({
2318
2369
  title: "Record type"
2319
- }) : Schema2.String.annotations({
2370
+ }) : QueryAST.Query.annotations({
2320
2371
  title: "Query"
2321
2372
  })
2322
2373
  });
2323
- if (mode === "query") {
2374
+ if (mode === "tag") {
2324
2375
  return Schema2.Struct({
2325
- name: Schema2.optional(Schema2.String.annotations({
2326
- title: "Name"
2327
- })),
2328
2376
  ...base.fields,
2329
2377
  target: Schema2.optional(Schema2.String.annotations({
2330
2378
  title: "Target Queue"
@@ -2336,23 +2384,22 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2336
2384
  mode
2337
2385
  ]);
2338
2386
  const viewValues = useMemo8(() => ({
2339
- name: view.name,
2340
- query: serializedQuery,
2387
+ query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2341
2388
  target: queueTarget
2342
2389
  }), [
2343
- view.name,
2344
- serializedQuery,
2390
+ mode,
2391
+ view.query.ast,
2345
2392
  queueTarget
2346
2393
  ]);
2347
- const handleToggleField = useCallback12((field) => {
2394
+ const handleToggleField = useCallback13((field) => {
2348
2395
  setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2349
2396
  }, [
2350
2397
  readonly
2351
2398
  ]);
2352
- const handleAdd = useCallback12(() => {
2399
+ const handleAdd = useCallback13(() => {
2353
2400
  invariant3(!readonly, void 0, {
2354
2401
  F: __dxlog_file5,
2355
- L: 144,
2402
+ L: 129,
2356
2403
  S: void 0,
2357
2404
  A: [
2358
2405
  "!readonly",
@@ -2366,38 +2413,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2366
2413
  projectionModel,
2367
2414
  readonly
2368
2415
  ]);
2369
- const handleUpdate = useCallback12((values) => {
2370
- invariant3(!readonly, void 0, {
2371
- F: __dxlog_file5,
2372
- L: 151,
2373
- S: void 0,
2374
- A: [
2375
- "!readonly",
2376
- ""
2377
- ]
2378
- });
2416
+ const handleUpdate = useCallback13((values) => {
2379
2417
  requestAnimationFrame(() => {
2380
- if ("name" in values && view.name !== values.name) {
2381
- view.name = values.name;
2382
- }
2383
- const queryChanged = serializedQuery !== values.query;
2384
- const targetValue = "target" in values ? values.target : void 0;
2385
- const targetChanged = "target" in values && values.target && queueTarget !== targetValue;
2386
- if ((queryChanged || targetChanged) && !readonly) {
2387
- onQueryChanged?.(values.query, targetValue);
2388
- }
2418
+ const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : values.query;
2419
+ onQueryChanged?.(query, values.target);
2389
2420
  });
2390
2421
  }, [
2391
- serializedQuery,
2392
2422
  onQueryChanged,
2393
- readonly,
2394
2423
  view,
2395
- queueTarget
2424
+ queueTarget,
2425
+ mode
2396
2426
  ]);
2397
- const handleDelete = useCallback12((fieldId) => {
2427
+ const handleDelete = useCallback13((fieldId) => {
2398
2428
  invariant3(!readonly, void 0, {
2399
2429
  F: __dxlog_file5,
2400
- L: 171,
2430
+ L: 146,
2401
2431
  S: void 0,
2402
2432
  A: [
2403
2433
  "!readonly",
@@ -2413,10 +2443,10 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2413
2443
  onDelete,
2414
2444
  readonly
2415
2445
  ]);
2416
- const handleMove = useCallback12((fromIndex, toIndex) => {
2446
+ const handleMove = useCallback13((fromIndex, toIndex) => {
2417
2447
  invariant3(!readonly, void 0, {
2418
2448
  F: __dxlog_file5,
2419
- L: 183,
2449
+ L: 158,
2420
2450
  S: void 0,
2421
2451
  A: [
2422
2452
  "!readonly",
@@ -2433,23 +2463,31 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2433
2463
  view.projection.fields,
2434
2464
  readonly
2435
2465
  ]);
2436
- const handleClose = useCallback12(() => setExpandedField(void 0), []);
2437
- const handleHide = useCallback12((fieldId) => {
2466
+ const handleClose = useCallback13(() => setExpandedField(void 0), []);
2467
+ const handleHide = useCallback13((fieldId) => {
2438
2468
  setExpandedField(void 0);
2439
2469
  projectionModel.hideFieldProjection(fieldId);
2440
2470
  }, [
2441
2471
  projectionModel
2442
2472
  ]);
2443
- const handleShow = useCallback12((property) => {
2473
+ const handleShow = useCallback13((property) => {
2444
2474
  setExpandedField(void 0);
2445
2475
  projectionModel.showFieldProjection(property);
2446
2476
  }, [
2447
2477
  projectionModel
2448
2478
  ]);
2479
+ const custom = useMemo8(() => mode === "tag" ? customFields({
2480
+ types,
2481
+ tags
2482
+ }) : void 0, [
2483
+ types,
2484
+ tags,
2485
+ mode
2486
+ ]);
2449
2487
  return /* @__PURE__ */ React15.createElement("div", {
2450
2488
  role: "none",
2451
2489
  className: mx7(classNames)
2452
- }, schemaReadonly && mode === "schema" && /* @__PURE__ */ React15.createElement(Callout.Root, {
2490
+ }, schemaReadonly && !readonly && /* @__PURE__ */ React15.createElement(Callout.Root, {
2453
2491
  valence: "info",
2454
2492
  classNames: [
2455
2493
  "mlb-cardSpacingBlock",
@@ -2459,10 +2497,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2459
2497
  autoSave: true,
2460
2498
  schema: viewSchema,
2461
2499
  values: viewValues,
2462
- readonly: readonly ? "disabled-input" : false,
2463
2500
  onSave: handleUpdate,
2464
2501
  outerSpacing,
2465
- Custom: mode === "query" ? customFields : void 0
2502
+ Custom: custom
2466
2503
  }), /* @__PURE__ */ React15.createElement("div", {
2467
2504
  role: "none",
2468
2505
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
@@ -2490,7 +2527,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2490
2527
  role: "none",
2491
2528
  className: mx7(subtleHover2, listItemGrid, "rounded-sm cursor-pointer min-bs-10")
2492
2529
  }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, {
2493
- disabled: readonly
2530
+ disabled: readonly || schemaReadonly
2494
2531
  }), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
2495
2532
  classNames: hidden && "text-subdued",
2496
2533
  onClick: () => handleToggleField(field)
@@ -2501,7 +2538,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2501
2538
  autoHide: false,
2502
2539
  disabled: readonly || !hidden && projectionModel.fields.length <= 1,
2503
2540
  onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2504
- }), mode === "schema" && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2541
+ }), !readonly && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2505
2542
  label: t("delete field label"),
2506
2543
  autoHide: false,
2507
2544
  disabled: readonly || schemaReadonly || view.projection.fields.length <= 1,
@@ -2515,7 +2552,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2515
2552
  }),
2516
2553
  icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2517
2554
  onClick: () => handleToggleField(field)
2518
- }))), expandedField === field.id && mode === "schema" && /* @__PURE__ */ React15.createElement("div", {
2555
+ }))), expandedField === field.id && !readonly && /* @__PURE__ */ React15.createElement("div", {
2519
2556
  role: "none",
2520
2557
  className: "col-span-5 mbs-1 mbe-1 border border-separator rounded-md"
2521
2558
  }, /* @__PURE__ */ React15.createElement(FieldEditor, {
@@ -2525,12 +2562,12 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2525
2562
  registry,
2526
2563
  onSave: handleClose
2527
2564
  })));
2528
- }))))), !readonly && !expandedField && mode === "schema" && /* @__PURE__ */ React15.createElement("div", {
2565
+ }))))), !readonly && !expandedField && /* @__PURE__ */ React15.createElement("div", {
2529
2566
  role: "none",
2530
2567
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2531
2568
  }, /* @__PURE__ */ React15.createElement(IconButton4, {
2532
2569
  icon: "ph--plus--regular",
2533
- label: t("button add property"),
2570
+ label: t("add property button label"),
2534
2571
  onClick: readonly ? void 0 : handleAdd,
2535
2572
  // TODO(burdon): Show field limit in ux (not tooltip).
2536
2573
  disabled: view.projection.fields.length >= VIEW_FIELD_LIMIT,
@@ -2540,40 +2577,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2540
2577
  _effect.f();
2541
2578
  }
2542
2579
  });
2543
- var customFields = {
2580
+ var customFields = ({ types, tags }) => ({
2544
2581
  query: (props) => {
2545
- const { themeMode } = useThemeContext();
2546
- const { t } = useTranslation10(translationKey);
2547
- const density = useDensityContext();
2548
- const elevation = useElevationContext();
2549
- const onValueChange = useRef4(props.onValueChange);
2550
- useEffect9(() => {
2551
- onValueChange.current = props.onValueChange;
2552
- }, [
2582
+ const handleChange = useCallback13((query) => props.onValueChange("object", query.ast), [
2553
2583
  props.onValueChange
2554
2584
  ]);
2555
- const handleChange = useCallback12((text) => onValueChange.current("string", text), []);
2556
- const extensions = useMemo8(() => [
2557
- createBasicExtensions({
2558
- placeholder: t("query placeholder")
2559
- }),
2560
- createThemeExtensions({
2561
- themeMode
2562
- })
2563
- ], []);
2564
2585
  return /* @__PURE__ */ React15.createElement(Input8.Root, null, /* @__PURE__ */ React15.createElement(InputHeader, {
2565
2586
  label: props.label
2566
- }), /* @__PURE__ */ React15.createElement(Editor, {
2567
- classNames: mx7(inputTheme.input({
2568
- density,
2569
- elevation
2570
- }), "flex items-center", "focus-within:bg-focusSurface focus-within:border-separator focus-within:hover:bg-focusSurface"),
2571
- extensions,
2572
- value: props.getValue(),
2587
+ }), /* @__PURE__ */ React15.createElement(QueryForm, {
2588
+ initialQuery: props.getValue(),
2589
+ types,
2590
+ tags,
2573
2591
  onChange: handleChange
2574
2592
  }));
2575
2593
  }
2576
- };
2594
+ });
2577
2595
  export {
2578
2596
  BooleanInput,
2579
2597
  ControlFrame,