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