@dxos/react-ui-form 0.8.4-main.9be5663bfe → 0.8.4-main.abd8ff62ef

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 (123) hide show
  1. package/dist/lib/browser/index.mjs +620 -440
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/translations.mjs +82 -0
  5. package/dist/lib/browser/translations.mjs.map +7 -0
  6. package/dist/lib/node-esm/index.mjs +620 -440
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/lib/node-esm/translations.mjs +84 -0
  10. package/dist/lib/node-esm/translations.mjs.map +7 -0
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  12. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -62
  13. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Form.d.ts +27 -4
  15. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.stories.d.ts +73 -72
  17. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/FormField.d.ts +5 -5
  19. package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -6
  21. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/FormFieldSet.d.ts +5 -8
  24. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
  25. package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
  26. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
  27. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
  29. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
  30. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
  31. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
  32. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
  33. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
  34. package/dist/types/src/components/Form/fields/RefField.d.ts +10 -4
  35. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
  37. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -62
  39. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
  41. package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
  42. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
  43. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
  44. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -1
  45. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +17 -3
  46. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  47. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -62
  48. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  49. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +1 -1
  50. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -1
  51. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +108 -64
  52. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -1
  53. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
  54. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
  55. package/dist/types/src/components/Settings/Settings.d.ts +24 -8
  56. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
  57. package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -62
  58. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
  59. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
  60. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  61. package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
  62. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  63. package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
  64. package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
  65. package/dist/types/src/components/Settings/index.d.ts +2 -0
  66. package/dist/types/src/components/Settings/index.d.ts.map +1 -1
  67. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +2 -2
  68. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  69. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +63 -62
  70. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  71. package/dist/types/src/components/testing.d.ts +4 -4
  72. package/dist/types/src/components/testing.d.ts.map +1 -1
  73. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
  74. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -1
  75. package/dist/types/src/index.d.ts +0 -2
  76. package/dist/types/src/index.d.ts.map +1 -1
  77. package/dist/types/src/translations.d.ts +63 -62
  78. package/dist/types/src/translations.d.ts.map +1 -1
  79. package/dist/types/src/util/field-type.d.ts +19 -0
  80. package/dist/types/src/util/field-type.d.ts.map +1 -0
  81. package/dist/types/src/util/field.d.ts.map +1 -1
  82. package/dist/types/src/util/formatting.d.ts.map +1 -1
  83. package/dist/types/src/util/index.d.ts +1 -0
  84. package/dist/types/src/util/index.d.ts.map +1 -1
  85. package/dist/types/src/util/properties.d.ts.map +1 -1
  86. package/dist/types/src/util/refs.d.ts.map +1 -1
  87. package/dist/types/tsconfig.tsbuildinfo +1 -1
  88. package/package.json +39 -38
  89. package/src/components/FieldEditor/FieldEditor.stories.tsx +3 -4
  90. package/src/components/FieldEditor/FieldEditor.tsx +3 -2
  91. package/src/components/Form/Form.stories.tsx +5 -16
  92. package/src/components/Form/Form.tsx +30 -7
  93. package/src/components/Form/FormField.tsx +7 -5
  94. package/src/components/Form/FormFieldComponent.tsx +3 -0
  95. package/src/components/Form/FormFieldSet.tsx +1 -3
  96. package/src/components/Form/fields/ArrayField.tsx +8 -3
  97. package/src/components/Form/fields/GeoPointField.tsx +2 -1
  98. package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
  99. package/src/components/Form/fields/MarkdownField.tsx +135 -45
  100. package/src/components/Form/fields/RefField.tsx +61 -30
  101. package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -5
  102. package/src/components/Form/fields/SelectOptionField.tsx +3 -2
  103. package/src/components/Form/fields/TextField.tsx +2 -2
  104. package/src/components/ObjectForm/ObjectForm.tsx +6 -5
  105. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +5 -2
  106. package/src/components/ObjectPicker/ObjectPicker.tsx +28 -12
  107. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +321 -22
  108. package/src/components/ObjectProperties/ObjectProperties.test.tsx +101 -0
  109. package/src/components/ObjectProperties/ObjectProperties.tsx +26 -14
  110. package/src/components/Settings/AUDIT.md +52 -0
  111. package/src/components/Settings/Settings.stories.tsx +50 -1
  112. package/src/components/Settings/Settings.tsx +6 -53
  113. package/src/components/Settings/SettingsFieldSet.tsx +257 -0
  114. package/src/components/Settings/SettingsItem.tsx +62 -0
  115. package/src/components/Settings/SettingsSelectField.tsx +59 -0
  116. package/src/components/Settings/index.ts +2 -0
  117. package/src/components/ViewEditor/ViewEditor.stories.tsx +17 -18
  118. package/src/components/ViewEditor/ViewEditor.tsx +4 -3
  119. package/src/components/testing.tsx +20 -21
  120. package/src/index.ts +0 -4
  121. package/src/translations.ts +7 -4
  122. package/src/util/field-type.ts +60 -0
  123. package/src/util/index.ts +1 -0
@@ -1,87 +1,11 @@
1
- // src/translations.ts
2
- var translationKey = "@dxos/react-ui-form";
3
- var translations = [
4
- {
5
- "en-US": {
6
- [translationKey]: {
7
- "fields.label": "Fields",
8
- "hidden-fields.label": "Hidden Fields",
9
- "empty-readonly-ref-field.label": "(none)",
10
- "add-property-button.label": "Add property",
11
- "field-property.label": "Property",
12
- "field-property.placeholder": "Property name",
13
- "field-format.label": "Type",
14
- "field-path.label": "Field path",
15
- "add-field.button": "Add field",
16
- "boolean-input-true.value": "Yes",
17
- "boolean-input-false.value": "No",
18
- "show-field.label": "Show field",
19
- "hide-field.label": "Hide field",
20
- "delete-field.label": "Delete field",
21
- "ref-field-combobox-input.placeholder": "Search\u2026",
22
- "ref-field.placeholder": "Select\u2026",
23
- "ref-field.placeholder_one": "Select\u2026",
24
- "ref-field.placeholder_other": "Select items\u2026",
25
- "create-option.label": "Create",
26
- "add-tag.label": "Add tag",
27
- "example.placeholder": "Example",
28
- "latitude.placeholder": "Latitude (e.g., 40.7128)",
29
- "longitude.placeholder": "Longitude (e.g., -74.0060)",
30
- "cancel-button.label": "Cancel",
31
- "save-button.label": "Save",
32
- // TypeFormat
33
- "format.boolean.label": "Boolean",
34
- "format.currency.label": "Currency",
35
- "format.date.label": "Date",
36
- "format.date-time.label": "DateTime",
37
- "format.did.label": "DID",
38
- "format.duration.label": "Duration",
39
- "format.dxn.label": "DXN",
40
- "format.email.label": "Email",
41
- "format.formula.label": "Formula",
42
- "format.hostname.label": "Hostname",
43
- "format.integer.label": "Integer",
44
- "format.json.label": "JSON",
45
- "format.lnglat.label": "Geopoint",
46
- "format.markdown.label": "Markdown",
47
- "format.percent.label": "Percent",
48
- "format.ref.label": "Reference",
49
- "format.regex.label": "RegExp",
50
- "format.string.label": "String",
51
- "format.single-select.label": "Select",
52
- "format.multi-select.label": "Multi-select",
53
- "format.text.label": "Long text",
54
- "format.time.label": "Time",
55
- "format.timestamp.label": "Timestamp",
56
- "format.user.label": "User",
57
- "format.number.label": "Number",
58
- "format.uri.label": "URI",
59
- "format.url.label": "URL",
60
- "format.uuid.label": "UUID",
61
- // GeoPointField.
62
- "latitude.label": "Latitude",
63
- "longitude.label": "Longitude",
64
- // SelectOptionsField.
65
- "select-option.label": "Label",
66
- "select-option-label.placeholder": "Option label",
67
- "select-option-delete.button": "Delete",
68
- "select-option-add.button": "Add option",
69
- // System schema message.
70
- "system-schema.title": "System type",
71
- "system-schema.description": "System type: cannot add or remove fields.",
72
- "remove.button": "Remove"
73
- }
74
- }
75
- }
76
- ];
77
-
78
1
  // src/components/FieldEditor/FieldEditor.tsx
79
- import React17, { useCallback as useCallback14, useEffect as useEffect6, useMemo as useMemo7, useState as useState5 } from "react";
80
- import { Obj as Obj2 } from "@dxos/echo";
2
+ import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
3
+ import { Obj as Obj3 } from "@dxos/echo";
81
4
  import { Format as Format4, FormatEnums, formatToType } from "@dxos/echo/internal";
82
5
  import { log as log2 } from "@dxos/log";
83
- import { useAsyncEffect, useTranslation as useTranslation8 } from "@dxos/react-ui";
6
+ import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
84
7
  import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
8
+ import { translationKey as translationKey9 } from "#translations";
85
9
 
86
10
  // src/util/field.ts
87
11
  import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
@@ -204,6 +128,46 @@ var pathNotUniqueError = (path) => ({
204
128
  message: `'${path}' is already present`
205
129
  });
206
130
 
131
+ // src/util/field-type.ts
132
+ import * as SchemaAST from "effect/SchemaAST";
133
+ import { getAnnotation, isLiteralUnion } from "@dxos/effect";
134
+ var detectFieldType = (ast) => {
135
+ if (isLiteralUnion(ast)) {
136
+ return "select";
137
+ }
138
+ if (SchemaAST.isTypeLiteral(ast)) {
139
+ return "struct";
140
+ }
141
+ switch (ast._tag) {
142
+ case "BooleanKeyword":
143
+ return "boolean";
144
+ case "StringKeyword":
145
+ return "string";
146
+ case "NumberKeyword":
147
+ return "number";
148
+ }
149
+ return void 0;
150
+ };
151
+ var getSelectOptionsFromAst = (ast) => {
152
+ if (!isLiteralUnion(ast)) {
153
+ return void 0;
154
+ }
155
+ return ast.types.flatMap((literalNode) => {
156
+ const value3 = literalNode.literal;
157
+ if (typeof value3 !== "string" && typeof value3 !== "number") {
158
+ return [];
159
+ }
160
+ const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
161
+ const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
162
+ return [
163
+ {
164
+ value: value3,
165
+ label
166
+ }
167
+ ];
168
+ });
169
+ };
170
+
207
171
  // src/util/formatting.ts
208
172
  import { format as formatDate } from "date-fns/format";
209
173
  import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
@@ -380,20 +344,24 @@ var getRefProps = (ast) => {
380
344
  };
381
345
 
382
346
  // src/components/Form/fields/ArrayField.tsx
383
- import * as Option3 from "effect/Option";
384
- import * as SchemaAST3 from "effect/SchemaAST";
347
+ import * as Option4 from "effect/Option";
348
+ import * as SchemaAST4 from "effect/SchemaAST";
385
349
  import React5, { useCallback as useCallback3 } from "react";
386
350
  import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
387
351
  import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
352
+ import { translationKey as translationKey3 } from "#translations";
388
353
 
389
354
  // src/components/Form/Form.tsx
390
355
  import { createContext } from "@radix-ui/react-context";
356
+ import * as Option3 from "effect/Option";
391
357
  import * as Schema2 from "effect/Schema";
392
- import * as SchemaAST2 from "effect/SchemaAST";
358
+ import * as SchemaAST3 from "effect/SchemaAST";
393
359
  import React4, { useEffect as useEffect2, useMemo as useMemo4, useRef } from "react";
360
+ import { Annotation as EchoAnnotation } from "@dxos/echo";
394
361
  import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
395
362
  import { IconButton, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
396
- import { composable, composableProps, mx } from "@dxos/ui-theme";
363
+ import { composable, composableProps, mx, withColumn } from "@dxos/ui-theme";
364
+ import { translationKey as translationKey2 } from "#translations";
397
365
 
398
366
  // src/hooks/useFormHandler.ts
399
367
  import { useControllableState } from "@radix-ui/react-use-controllable-state";
@@ -431,12 +399,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
431
399
  log("validate", {
432
400
  values: values2,
433
401
  errors: errors2
434
- }, {
435
- F: __dxlog_file,
436
- L: 155,
437
- S: void 0,
438
- C: (f, a) => f(...a)
439
- });
402
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
440
403
  if (errors2.length === 0 && onValidate) {
441
404
  const validatedValues = values2;
442
405
  errors2 = onValidate(validatedValues) ?? [];
@@ -524,12 +487,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
524
487
  log("onValueChange", {
525
488
  path,
526
489
  value: value3
527
- }, {
528
- F: __dxlog_file,
529
- L: 254,
530
- S: void 0,
531
- C: (f, a) => f(...a)
532
- });
490
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
533
491
  const jsonPath = createJsonPath(path);
534
492
  const pathArray = path;
535
493
  let parsedValue = value3;
@@ -538,12 +496,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
538
496
  parsedValue = parseFloat(value3) || 0;
539
497
  }
540
498
  } catch (err) {
541
- log.catch(err, void 0, {
542
- F: __dxlog_file,
543
- L: 264,
544
- S: void 0,
545
- C: (f, a) => f(...a)
546
- });
499
+ log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
547
500
  parsedValue = void 0;
548
501
  }
549
502
  const newValues = mergeAtPath(values, pathArray, parsedValue);
@@ -763,12 +716,13 @@ import React3, { useMemo as useMemo3 } from "react";
763
716
  import * as Match from "effect/Match";
764
717
  import * as Option2 from "effect/Option";
765
718
  import * as Schema from "effect/Schema";
766
- import * as SchemaAST from "effect/SchemaAST";
719
+ import * as SchemaAST2 from "effect/SchemaAST";
767
720
  import * as String2 from "effect/String";
768
721
  import React2, { useMemo as useMemo2 } from "react";
769
722
  import { Format as Format3 } from "@dxos/echo";
770
- import { createJsonPath as createJsonPath2, findNode, getAnnotation, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion, isNestedType } from "@dxos/effect";
723
+ import { createJsonPath as createJsonPath2, findNode, getAnnotation as getAnnotation2, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion as isLiteralUnion2, isNestedType } from "@dxos/effect";
771
724
  import { useTranslation } from "@dxos/react-ui";
725
+ import { translationKey } from "#translations";
772
726
  var FormField = (props) => {
773
727
  const {
774
728
  type,
@@ -786,14 +740,14 @@ var FormField = (props) => {
786
740
  createInitialValuePath,
787
741
  createFieldMap: createFieldMap3,
788
742
  db,
789
- schemaHook,
743
+ useSchema: schemaHook,
790
744
  getOptions,
791
745
  onCreate
792
746
  } = props;
793
747
  const { t } = useTranslation(translationKey);
794
- const title = getAnnotation(SchemaAST.TitleAnnotationId)(type);
795
- const description = getAnnotation(SchemaAST.DescriptionAnnotationId)(type);
796
- const examples = getAnnotation(SchemaAST.ExamplesAnnotationId)(type);
748
+ const title = getAnnotation2(SchemaAST2.TitleAnnotationId)(type);
749
+ const description = getAnnotation2(SchemaAST2.DescriptionAnnotationId)(type);
750
+ const examples = getAnnotation2(SchemaAST2.ExamplesAnnotationId)(type);
797
751
  const label = useMemo2(() => title ?? String2.capitalize(name), [
798
752
  title,
799
753
  name
@@ -811,6 +765,7 @@ var FormField = (props) => {
811
765
  label,
812
766
  placeholder,
813
767
  layout,
768
+ db,
814
769
  ...fieldState
815
770
  };
816
771
  const jsonPath = createJsonPath2(path ?? []);
@@ -864,14 +819,14 @@ var FormField = (props) => {
864
819
  createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
865
820
  createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
866
821
  db,
867
- schemaHook,
822
+ useSchema: schemaHook,
868
823
  getOptions,
869
824
  onCreate
870
825
  });
871
826
  }
872
827
  if (isNestedType(type)) {
873
828
  const baseNode = findNode(type, isDiscriminatedUnion);
874
- const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST.isTypeLiteral);
829
+ const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
875
830
  if (typeLiteral) {
876
831
  const schema = Schema.make(typeLiteral);
877
832
  return /* @__PURE__ */ React2.createElement(FormFieldSet, {
@@ -887,7 +842,7 @@ var FormField = (props) => {
887
842
  createOptionIcon,
888
843
  createInitialValuePath,
889
844
  db,
890
- schemaHook,
845
+ useSchema: schemaHook,
891
846
  getOptions,
892
847
  onCreate
893
848
  });
@@ -913,7 +868,7 @@ var getFormField = ({ type, format }) => {
913
868
  }
914
869
  };
915
870
  var getSelectOptions = (ast) => {
916
- if (isLiteralUnion(ast)) {
871
+ if (isLiteralUnion2(ast)) {
917
872
  return ast.types.map((type) => type.literal).filter((v) => v !== null);
918
873
  }
919
874
  return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
@@ -997,6 +952,11 @@ var useFormFieldSetProperties = ({ schema, exclude, projection, values, sort })
997
952
 
998
953
  // src/components/Form/Form.tsx
999
954
  var omitId = (schema) => schema.pipe(Schema2.omit("id"));
955
+ var omitHiddenFormFields = (schema) => {
956
+ const properties = SchemaAST3.getPropertySignatures(schema.ast);
957
+ const hidden = properties.filter((prop) => Option3.getOrElse(EchoAnnotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false).map((prop) => prop.name);
958
+ return hidden.length === 0 ? schema : schema.pipe(Schema2.omit(...hidden));
959
+ };
1000
960
  var [FormContextProvider, useFormContext] = createContext("Form");
1001
961
  var useFormValues = (componentName, path, defaultValue) => {
1002
962
  const stablePath = useMemo4(() => path ?? [], [
@@ -1009,7 +969,7 @@ var useFormValues = (componentName, path, defaultValue) => {
1009
969
  useEffect2(() => {
1010
970
  if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
1011
971
  lastAppliedPathRef.current = jsonPath;
1012
- onValueChange(stablePath, SchemaAST2.stringKeyword, defaultValue());
972
+ onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
1013
973
  }
1014
974
  }, [
1015
975
  value3,
@@ -1076,7 +1036,7 @@ var FormContent = composable(({ children, ...props }, forwardedRef) => {
1076
1036
  return /* @__PURE__ */ React4.createElement("div", {
1077
1037
  ...composableProps(props, {
1078
1038
  role: "form",
1079
- classNames: "flex flex-col w-full pb-form-gap"
1039
+ classNames: mx(withColumn.center(), "flex flex-col w-full pb-form-gap")
1080
1040
  }),
1081
1041
  "data-testid": testId,
1082
1042
  ref: mergedRef
@@ -1095,14 +1055,14 @@ var FormFieldSet2 = (props) => {
1095
1055
  FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
1096
1056
  var FORM_ACTIONS_NAME = "Form.Actions";
1097
1057
  var FormActions = ({ classNames }) => {
1098
- const { t } = useTranslation2(translationKey);
1058
+ const { t } = useTranslation2(translationKey2);
1099
1059
  const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
1100
1060
  if (readonly || layout === "static") {
1101
1061
  return null;
1102
1062
  }
1103
1063
  return /* @__PURE__ */ React4.createElement("div", {
1104
1064
  role: "none",
1105
- className: mx("grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
1065
+ className: mx(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
1106
1066
  }, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
1107
1067
  icon: "ph--x--regular",
1108
1068
  iconEnd: true,
@@ -1137,7 +1097,7 @@ var FormSection = composable(({ children, label, description, ...props }, forwar
1137
1097
  FormSection.displayName = FORM_SECTION_NAME;
1138
1098
  var FORM_SUBMIT_NAME = "Form.Submit";
1139
1099
  var FormSubmit = ({ classNames, label, icon, disabled }) => {
1140
- const { t } = useTranslation2(translationKey);
1100
+ const { t } = useTranslation2(translationKey2);
1141
1101
  const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
1142
1102
  if (readonly || layout === "static") {
1143
1103
  return null;
@@ -1170,18 +1130,18 @@ var Form = {
1170
1130
 
1171
1131
  // src/components/Form/fields/ArrayField.tsx
1172
1132
  var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
1173
- const { t } = useTranslation3(translationKey);
1133
+ const { t } = useTranslation3(translationKey3);
1174
1134
  const elementType = getArrayElementType2(type);
1175
1135
  const { onValueChange } = inputProps;
1176
1136
  const values = useFormValues(ArrayField.displayName, path, () => []);
1177
1137
  const getDefaultObjectValue = (typeNode) => {
1178
1138
  const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
1179
- const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST3.isTypeLiteral);
1139
+ const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
1180
1140
  if (!typeLiteral) {
1181
1141
  return {};
1182
1142
  }
1183
1143
  return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
1184
- const defaultValue = SchemaAST3.getDefaultAnnotation(prop.type).pipe((annotation) => Option3.getOrUndefined(annotation));
1144
+ const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
1185
1145
  return [
1186
1146
  prop.name,
1187
1147
  defaultValue
@@ -1221,7 +1181,7 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1221
1181
  return /* @__PURE__ */ React5.createElement("div", {
1222
1182
  role: "none",
1223
1183
  key: index,
1224
- className: "flex gap-form-gap last:mb-form-gap items-center"
1184
+ className: "grid grid-cols-[1fr_min-content] gap-form-gap last:mb-form-gap items-center"
1225
1185
  }, /* @__PURE__ */ React5.createElement(FormField, {
1226
1186
  autoFocus: index === values.length - 1,
1227
1187
  type: elementType,
@@ -1248,7 +1208,7 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1248
1208
  })), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
1249
1209
  classNames: "flex w-full",
1250
1210
  icon: "ph--plus--regular",
1251
- label: t("add-field.button"),
1211
+ label: t("add-item.button"),
1252
1212
  onClick: handleAdd
1253
1213
  }));
1254
1214
  };
@@ -1300,8 +1260,9 @@ import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo a
1300
1260
  import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
1301
1261
  import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
1302
1262
  import { safeParseFloat } from "@dxos/util";
1263
+ import { translationKey as translationKey4 } from "#translations";
1303
1264
  var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
1304
- const { t } = useTranslation4(translationKey);
1265
+ const { t } = useTranslation4(translationKey4);
1305
1266
  const { status, error } = getStatus();
1306
1267
  const geoPoint = useMemo5(() => getValue() ?? [
1307
1268
  0,
@@ -1392,56 +1353,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
1392
1353
  };
1393
1354
 
1394
1355
  // src/components/Form/fields/MarkdownField.tsx
1395
- import React8, { useCallback as useCallback6, useEffect as useEffect4, useRef as useRef2 } from "react";
1396
- import { Input as Input4 } from "@dxos/react-ui";
1397
- var MarkdownField = ({ type, readonly, label, placeholder, layout, getStatus, getValue, onValueChange, onBlur }) => {
1356
+ import { useAtomValue } from "@effect-atom/atom-react";
1357
+ import React8, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
1358
+ import { Obj, Ref as Ref2 } from "@dxos/echo";
1359
+ import { AtomRef } from "@dxos/echo-atom";
1360
+ import { createDocAccessor } from "@dxos/echo-db";
1361
+ import { Button, Icon as Icon2, Input as Input4, useTranslation as useTranslation5 } from "@dxos/react-ui";
1362
+ import { Editor, useBasicMarkdownExtensions } from "@dxos/react-ui-editor";
1363
+ import { Text } from "@dxos/schema";
1364
+ import { createDataExtensions } from "@dxos/ui-editor";
1365
+ import { translationKey as translationKey5 } from "#translations";
1366
+ var editorClassNames = "transition-colors bg-input-surface focus-within:bg-focus-surface border border-separator rounded-xs p-1 px-2";
1367
+ var MarkdownField = ({ type, readonly, label, placeholder, layout, db, getStatus, getValue, onValueChange }) => {
1398
1368
  const { status, error } = getStatus();
1399
- const textareaRef = useRef2(null);
1400
- const adjustHeight = useCallback6(() => {
1401
- const textarea = textareaRef.current;
1402
- if (textarea) {
1403
- textarea.style.blockSize = "auto";
1404
- textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
1405
- }
1406
- }, []);
1407
- useEffect4(() => {
1408
- adjustHeight();
1409
- }, [
1410
- adjustHeight
1411
- ]);
1412
- useEffect4(() => {
1413
- adjustHeight();
1414
- }, [
1415
- getValue(),
1416
- adjustHeight
1417
- ]);
1418
- const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
1419
- type,
1420
- onValueChange
1421
- ]);
1369
+ const isRef = Ref2.isRefType(type);
1422
1370
  const value3 = getValue();
1423
- if ((readonly || layout === "static") && !value3) {
1371
+ if ((readonly || layout === "static") && value3 == null) {
1424
1372
  return null;
1425
1373
  }
1374
+ const renderEditor = () => {
1375
+ if (isRef) {
1376
+ const reference = value3;
1377
+ if (reference) {
1378
+ return /* @__PURE__ */ React8.createElement(RefMarkdownEditor, {
1379
+ reference,
1380
+ placeholder
1381
+ });
1382
+ }
1383
+ if (readonly) {
1384
+ return null;
1385
+ }
1386
+ return /* @__PURE__ */ React8.createElement(CreateTextButton, {
1387
+ db,
1388
+ disabled: !db,
1389
+ onCreate: (ref) => onValueChange(type, ref)
1390
+ });
1391
+ }
1392
+ return /* @__PURE__ */ React8.createElement(StringMarkdownEditor, {
1393
+ value: value3 ?? "",
1394
+ placeholder,
1395
+ readonly: !!readonly,
1396
+ onChange: (next) => onValueChange(type, next)
1397
+ });
1398
+ };
1399
+ const renderStatic = () => {
1400
+ if (isRef) {
1401
+ const reference = value3;
1402
+ return reference ? /* @__PURE__ */ React8.createElement(RefStaticText, {
1403
+ reference
1404
+ }) : null;
1405
+ }
1406
+ return /* @__PURE__ */ React8.createElement("p", {
1407
+ className: "whitespace-pre-wrap"
1408
+ }, value3 ?? "");
1409
+ };
1426
1410
  return /* @__PURE__ */ React8.createElement(Input4.Root, {
1427
1411
  validationValence: status
1428
1412
  }, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
1429
1413
  error,
1430
1414
  readonly,
1431
1415
  label
1432
- }), layout === "static" ? /* @__PURE__ */ React8.createElement("p", null, value3) : /* @__PURE__ */ React8.createElement(Input4.TextArea, {
1433
- ref: textareaRef,
1434
- disabled: !!readonly,
1416
+ }), layout === "static" ? renderStatic() : renderEditor(), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
1417
+ };
1418
+ var RefStaticText = ({ reference }) => {
1419
+ const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
1420
+ reference
1421
+ ]));
1422
+ if (!text?.content) {
1423
+ return null;
1424
+ }
1425
+ return /* @__PURE__ */ React8.createElement("p", {
1426
+ className: "whitespace-pre-wrap"
1427
+ }, text.content);
1428
+ };
1429
+ var RefMarkdownEditor = ({ reference, placeholder }) => {
1430
+ const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
1431
+ reference
1432
+ ]));
1433
+ const dataExtensions = useMemo6(() => text ? [
1434
+ createDataExtensions({
1435
+ id: reference.dxn.toString(),
1436
+ text: createDocAccessor(text, [
1437
+ "content"
1438
+ ])
1439
+ })
1440
+ ] : [], [
1441
+ text,
1442
+ reference
1443
+ ]);
1444
+ const extensions = useBasicMarkdownExtensions({
1435
1445
  placeholder,
1436
- value: value3 ?? "",
1437
- classNames: "min-h-auto max-h-40 overflow-auto",
1438
- onChange: handleChange,
1439
- onBlur,
1440
- style: {
1441
- resize: "none"
1442
- },
1443
- spellCheck: false
1444
- }), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
1446
+ extensions: dataExtensions
1447
+ });
1448
+ if (!text) {
1449
+ return null;
1450
+ }
1451
+ return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
1452
+ classNames: editorClassNames,
1453
+ extensions
1454
+ }));
1455
+ };
1456
+ var StringMarkdownEditor = ({ value: value3, placeholder, readonly, onChange }) => {
1457
+ const extensions = useBasicMarkdownExtensions({
1458
+ placeholder
1459
+ });
1460
+ const handleChange = useCallback6((next) => onChange(next), [
1461
+ onChange
1462
+ ]);
1463
+ return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
1464
+ classNames: editorClassNames,
1465
+ extensions,
1466
+ value: value3,
1467
+ onChange: readonly ? void 0 : handleChange
1468
+ }));
1469
+ };
1470
+ var CreateTextButton = ({ db, disabled, onCreate }) => {
1471
+ const { t } = useTranslation5(translationKey5);
1472
+ const handleClick = useCallback6(() => {
1473
+ if (!db) {
1474
+ return;
1475
+ }
1476
+ const text = db.add(Obj.make(Text.Text, {
1477
+ content: ""
1478
+ }));
1479
+ onCreate(Ref2.make(text));
1480
+ }, [
1481
+ db,
1482
+ onCreate
1483
+ ]);
1484
+ return /* @__PURE__ */ React8.createElement(Button, {
1485
+ onClick: handleClick,
1486
+ disabled
1487
+ }, /* @__PURE__ */ React8.createElement(Icon2, {
1488
+ icon: "ph--plus--regular",
1489
+ size: 4
1490
+ }), /* @__PURE__ */ React8.createElement("span", null, t("create-text.label")));
1445
1491
  };
1446
1492
 
1447
1493
  // src/components/Form/fields/NumberField.tsx
@@ -1467,31 +1513,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
1467
1513
  };
1468
1514
 
1469
1515
  // src/components/Form/fields/RefField.tsx
1470
- import React11, { useCallback as useCallback9, useMemo as useMemo6 } from "react";
1516
+ import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
1471
1517
  import "@dxos/lit-ui/dx-tag-picker.pcss";
1472
- import { Entity, Filter, Obj, Ref as Ref2, Type } from "@dxos/echo";
1473
- import { useQuery, useSchema as useSchema$ } from "@dxos/echo-react";
1518
+ import { Entity, Filter, Obj as Obj2, Ref as Ref3, Type } from "@dxos/echo";
1519
+ import { useQuery, useSchema as defaultUseSchema } from "@dxos/echo-react";
1474
1520
  import { ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo/internal";
1475
1521
  import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1476
1522
  import { DXN } from "@dxos/keys";
1477
1523
  import { DxAnchor } from "@dxos/lit-ui/react";
1478
- import { Button, Icon as Icon2, Input as Input6, useTranslation as useTranslation6 } from "@dxos/react-ui";
1524
+ import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
1479
1525
  import { ParentLabelAnnotationId } from "@dxos/schema";
1480
- import { mx as mx2 } from "@dxos/ui-theme";
1526
+ import { translationKey as translationKey7 } from "#translations";
1481
1527
 
1482
1528
  // src/components/ObjectPicker/ObjectPicker.tsx
1483
1529
  import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
1484
- import { Popover, useTranslation as useTranslation5 } from "@dxos/react-ui";
1485
- import { Combobox, useSearchListInput, useSearchListResults } from "@dxos/react-ui-search";
1530
+ import { Popover, useTranslation as useTranslation6 } from "@dxos/react-ui";
1531
+ import { Combobox } from "@dxos/react-ui-list";
1532
+ import { useSearchListResults } from "@dxos/react-ui-search";
1533
+ import { translationKey as translationKey6 } from "#translations";
1486
1534
  var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
1487
- const { t } = useTranslation5(translationKey);
1535
+ const { t } = useTranslation6(translationKey6);
1488
1536
  const [showForm, setShowForm] = useState3(false);
1489
1537
  const [formInitialValue, setFormInitialValue] = useState3("");
1490
- const { results, handleSearch } = useSearchListResults({
1538
+ const { results, query, handleSearch } = useSearchListResults({
1491
1539
  items: options
1492
1540
  });
1493
- const handleFormSave = useCallback8((values) => {
1494
- onCreate?.(values);
1541
+ const handleFormSave = useCallback8(async (values) => {
1542
+ await onCreate?.(values);
1495
1543
  setShowForm(false);
1496
1544
  setFormInitialValue("");
1497
1545
  }, [
@@ -1516,7 +1564,6 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1516
1564
  if (showForm && createSchema) {
1517
1565
  return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1518
1566
  ...props,
1519
- onSearch: handleSearch,
1520
1567
  onKeyDownCapture: handleKeyDown,
1521
1568
  ref: forwardedRef
1522
1569
  }, /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
@@ -1532,12 +1579,13 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1532
1579
  }
1533
1580
  return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1534
1581
  ...props,
1535
- onSearch: handleSearch,
1536
1582
  onKeyDownCapture: handleKeyDown,
1537
1583
  ref: forwardedRef
1538
1584
  }, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1539
1585
  placeholder: t("ref-field-combobox-input.placeholder"),
1540
- autoFocus: true
1586
+ autoFocus: true,
1587
+ value: query,
1588
+ onValueChange: handleSearch
1541
1589
  }), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1542
1590
  key: option.id,
1543
1591
  value: option.id,
@@ -1546,17 +1594,17 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1546
1594
  onSelect: () => onSelect(option.id),
1547
1595
  classNames: "flex items-center gap-2"
1548
1596
  })), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
1597
+ query,
1549
1598
  createOptionLabel,
1550
1599
  createOptionIcon: createOptionIcon ?? "ph--plus--regular",
1551
- onCreateItemSelect: (query) => {
1552
- setFormInitialValue(query);
1600
+ onCreateItemSelect: (currentQuery) => {
1601
+ setFormInitialValue(currentQuery);
1553
1602
  setShowForm(true);
1554
1603
  }
1555
1604
  })), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1556
1605
  });
1557
- var CreateItem = ({ createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1558
- const { t } = useTranslation5(translationKey);
1559
- const { query } = useSearchListInput();
1606
+ var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1607
+ const { t } = useTranslation6(translationKey6);
1560
1608
  const label = createOptionLabel ? t(createOptionLabel[0], {
1561
1609
  ns: createOptionLabel[1].ns,
1562
1610
  text: query
@@ -1587,23 +1635,23 @@ var isRefSnapshot = (val) => {
1587
1635
  };
1588
1636
  var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
1589
1637
  const id = Entity.getDXN(result).toString();
1590
- const parent = parentLabel ? Obj.getParent(result) : void 0;
1638
+ const parent = parentLabel ? Obj2.getParent(result) : void 0;
1591
1639
  const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
1592
1640
  return {
1593
1641
  id,
1594
1642
  label: label ?? id
1595
1643
  };
1596
1644
  });
1597
- var defaultResultsHook = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
1645
+ var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
1598
1646
  var RefField = (props) => {
1599
- const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, resultsHook: useResults = defaultResultsHook, schemaHook: useSchema = useSchema$, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
1600
- const { t } = useTranslation6(translationKey);
1647
+ const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useSchema = defaultUseSchema, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
1648
+ const { t } = useTranslation7(translationKey7);
1601
1649
  const { status, error } = getStatus();
1602
- const typename = useMemo6(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
1650
+ const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
1603
1651
  type
1604
1652
  ]);
1605
1653
  const results = useResults(db, typename);
1606
- const options = useMemo6(() => {
1654
+ const options = useMemo7(() => {
1607
1655
  const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
1608
1656
  return getOptions(results, {
1609
1657
  parentLabel
@@ -1615,11 +1663,13 @@ var RefField = (props) => {
1615
1663
  ]);
1616
1664
  const handleGetValue = useCallback9(() => {
1617
1665
  const formValue = getValue();
1666
+ const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
1618
1667
  const unknownToRefOption = (value3) => {
1619
- const isRef = Ref2.isRef(value3);
1668
+ const isRef = Ref3.isRef(value3);
1620
1669
  if (isRef || isRefSnapshot(value3)) {
1621
1670
  const dxnString = isRef ? value3.dxn.toString() : value3["/"];
1622
- const matchingOption = options.find((option) => option.id === dxnString);
1671
+ const objectId = dxnToObjectId(dxnString);
1672
+ const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
1623
1673
  if (matchingOption) {
1624
1674
  return matchingOption;
1625
1675
  }
@@ -1631,29 +1681,37 @@ var RefField = (props) => {
1631
1681
  options,
1632
1682
  getValue
1633
1683
  ]);
1634
- const handleUpdate = useCallback9((id) => {
1635
- const item2 = options.find((option) => option.id === id);
1636
- const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
1637
- onValueChange(type, ref);
1638
- }, [
1639
- options,
1640
- type,
1641
- onValueChange
1642
- ]);
1643
1684
  const item = handleGetValue();
1644
- const selectedIds = useMemo6(() => item ? [
1685
+ const selectedIds = useMemo7(() => item ? [
1645
1686
  item.id
1646
1687
  ] : [], [
1647
1688
  item
1648
1689
  ]);
1649
1690
  const createSchema = useSchema(db, typename);
1650
- const handleCreate = useCallback9((values) => {
1651
- if (createSchema && onCreate) {
1652
- onCreate(createSchema, values);
1691
+ const [open, setOpen] = useState4(false);
1692
+ const handleCreate = useCallback9(async (values) => {
1693
+ if (!createSchema || !onCreate) {
1694
+ return;
1653
1695
  }
1696
+ const newObject = await onCreate(createSchema, values);
1697
+ if (newObject) {
1698
+ onValueChange(type, Ref3.make(newObject));
1699
+ }
1700
+ setOpen(false);
1654
1701
  }, [
1655
1702
  createSchema,
1656
- onCreate
1703
+ onCreate,
1704
+ type,
1705
+ onValueChange
1706
+ ]);
1707
+ const handleUpdate = useCallback9((id) => {
1708
+ const item2 = options.find((option) => option.id === id);
1709
+ const ref = item2 ? Ref3.fromDXN(DXN.parse(item2.id)) : void 0;
1710
+ onValueChange(type, ref);
1711
+ }, [
1712
+ options,
1713
+ type,
1714
+ onValueChange
1657
1715
  ]);
1658
1716
  const handleSelect = useCallback9((id) => {
1659
1717
  if (item?.id === id) {
@@ -1675,15 +1733,19 @@ var RefField = (props) => {
1675
1733
  readonly,
1676
1734
  label
1677
1735
  }), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
1678
- className: mx2("text-description", "mb-2")
1736
+ className: "text-description mb-2"
1679
1737
  }, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
1680
1738
  key: item.id,
1681
1739
  dxn: item.id,
1682
1740
  rootclassname: "me-1"
1683
- }, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1741
+ }, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, {
1742
+ open,
1743
+ onOpenChange: setOpen
1744
+ }, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1684
1745
  asChild: true,
1685
1746
  classNames: "p-0"
1686
1747
  }, item ? /* @__PURE__ */ React11.createElement("div", {
1748
+ role: "none",
1687
1749
  className: "flex gap-form-gap w-full"
1688
1750
  }, /* @__PURE__ */ React11.createElement(Input6.Root, {
1689
1751
  key: item.id
@@ -1691,21 +1753,24 @@ var RefField = (props) => {
1691
1753
  value: item.label,
1692
1754
  readOnly: true,
1693
1755
  classNames: "w-full"
1694
- }))) : /* @__PURE__ */ React11.createElement(Button, {
1756
+ }))) : /* @__PURE__ */ React11.createElement(Button2, {
1695
1757
  classNames: "w-full text-start gap-form-gap"
1696
1758
  }, /* @__PURE__ */ React11.createElement("div", {
1697
1759
  role: "none",
1698
1760
  className: "grow overflow-hidden"
1699
1761
  }, /* @__PURE__ */ React11.createElement("span", {
1700
- className: "flex truncate text-description"
1701
- }, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon2, {
1762
+ className: "truncate text-description"
1763
+ }, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
1702
1764
  size: 3,
1703
1765
  icon: "ph--caret-down--bold"
1704
1766
  }))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
1705
1767
  classNames: "dx-card-popover-width",
1706
1768
  options,
1707
1769
  selectedIds,
1708
- createSchema: createSchema && omitId(createSchema),
1770
+ // Strip hidden (`FormInputAnnotation.set(false)`) fields so the
1771
+ // form's validator doesn't reject required-but-hidden fields
1772
+ // such as backing-object refs supplied by a `FactoryAnnotation`.
1773
+ createSchema: createSchema && omitHiddenFormFields(omitId(createSchema)),
1709
1774
  createOptionLabel,
1710
1775
  createOptionIcon,
1711
1776
  createInitialValuePath,
@@ -1751,20 +1816,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
1751
1816
  };
1752
1817
 
1753
1818
  // src/components/Form/fields/SelectOptionField.tsx
1754
- import React13, { useCallback as useCallback11, useEffect as useEffect5, useRef as useRef3, useState as useState4 } from "react";
1819
+ import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
1755
1820
  import { PublicKey } from "@dxos/keys";
1756
- import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation7 } from "@dxos/react-ui";
1821
+ import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
1757
1822
  import { List } from "@dxos/react-ui-list";
1758
1823
  import { HuePicker } from "@dxos/react-ui-pickers";
1759
1824
  import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
1825
+ import { translationKey as translationKey8 } from "#translations";
1760
1826
  var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
1761
- const { t } = useTranslation7(translationKey);
1827
+ const { t } = useTranslation8(translationKey8);
1762
1828
  const { status, error } = getStatus();
1763
- const [selected, setSelectedId] = useState4(null);
1764
- const [isNewOption, setIsNewOption] = useState4(false);
1765
- const inputRef = useRef3(null);
1829
+ const [selected, setSelectedId] = useState5(null);
1830
+ const [isNewOption, setIsNewOption] = useState5(false);
1831
+ const inputRef = useRef2(null);
1766
1832
  const options = getValue();
1767
- useEffect5(() => {
1833
+ useEffect4(() => {
1768
1834
  if (options === void 0) {
1769
1835
  onValueChange(type, []);
1770
1836
  }
@@ -1855,7 +1921,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1855
1921
  type,
1856
1922
  onValueChange
1857
1923
  ]);
1858
- useEffect5(() => {
1924
+ useEffect4(() => {
1859
1925
  if (selected && isNewOption && inputRef.current) {
1860
1926
  inputRef.current.focus();
1861
1927
  setIsNewOption(false);
@@ -1902,7 +1968,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1902
1968
  }, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
1903
1969
  iconOnly: true,
1904
1970
  variant: "ghost",
1905
- label: t(selected === item.id ? "collapse label" : "expand label", {
1971
+ label: t(selected === item.id ? "collapse.label" : "expand.label", {
1906
1972
  ns: osTranslations
1907
1973
  }),
1908
1974
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
@@ -1944,7 +2010,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1944
2010
  // src/components/Form/fields/TextField.tsx
1945
2011
  import React14, { useCallback as useCallback12 } from "react";
1946
2012
  import { Input as Input9 } from "@dxos/react-ui";
1947
- var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
2013
+ var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
1948
2014
  const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
1949
2015
  type,
1950
2016
  onValueChange
@@ -1957,8 +2023,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
1957
2023
  disabled: !!readonly,
1958
2024
  placeholder,
1959
2025
  value: value3,
1960
- onChange: handleChange,
1961
- onBlur
2026
+ onBlur,
2027
+ onChange: handleChange
1962
2028
  }));
1963
2029
  };
1964
2030
 
@@ -1986,7 +2052,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
1986
2052
  // src/components/Form/fields/TupleField.tsx
1987
2053
  import React16 from "react";
1988
2054
  import { Input as Input11 } from "@dxos/react-ui";
1989
- import { mx as mx3 } from "@dxos/ui-theme";
2055
+ import { mx as mx2 } from "@dxos/ui-theme";
1990
2056
  import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
1991
2057
  var gridCols = [
1992
2058
  "grid-cols-1",
@@ -2004,7 +2070,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
2004
2070
  readonly,
2005
2071
  label
2006
2072
  }), /* @__PURE__ */ React16.createElement("div", {
2007
- className: mx3("grid gap-form-gap", gridCols[binding.length - 1])
2073
+ className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
2008
2074
  }, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
2009
2075
  key: prop,
2010
2076
  type: "number",
@@ -2023,13 +2089,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
2023
2089
  // src/components/FieldEditor/FieldEditor.tsx
2024
2090
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
2025
2091
  var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
2026
- const { t } = useTranslation8(translationKey);
2027
- const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
2028
- useEffect6(() => setProps(projection.getFieldProjection(field.id).props), [
2092
+ const { t } = useTranslation9(translationKey9);
2093
+ const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
2094
+ useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
2029
2095
  field,
2030
2096
  projection
2031
2097
  ]);
2032
- const [schemas, setSchemas] = useState5([]);
2098
+ const [schemas, setSchemas] = useState6([]);
2033
2099
  useAsyncEffect(async () => {
2034
2100
  if (!registry) {
2035
2101
  return;
@@ -2043,17 +2109,17 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2043
2109
  }, [
2044
2110
  registry
2045
2111
  ]);
2046
- const [referenceSchema, setReferenceSchema] = useState5();
2047
- useEffect6(() => {
2112
+ const [referenceSchema, setReferenceSchema] = useState6();
2113
+ useEffect5(() => {
2048
2114
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
2049
2115
  }, [
2050
2116
  schemas,
2051
2117
  props?.referenceSchema
2052
2118
  ]);
2053
- const [{ fieldSchema }, setFieldSchema] = useState5({
2119
+ const [{ fieldSchema }, setFieldSchema] = useState6({
2054
2120
  fieldSchema: getFormatSchema(props?.format)
2055
2121
  });
2056
- const fieldMap = useMemo7(() => ({
2122
+ const fieldMap = useMemo8(() => ({
2057
2123
  ["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
2058
2124
  ...props2,
2059
2125
  options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
@@ -2132,7 +2198,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2132
2198
  ]);
2133
2199
  const handleSave = useCallback14((props2) => {
2134
2200
  if (view) {
2135
- Obj2.change(view, () => {
2201
+ Obj3.update(view, () => {
2136
2202
  projection.setFieldProjection({
2137
2203
  field,
2138
2204
  props: props2
@@ -2160,12 +2226,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2160
2226
  if (!fieldSchema) {
2161
2227
  log2.warn("invalid format", {
2162
2228
  props
2163
- }, {
2164
- F: __dxlog_file2,
2165
- L: 172,
2166
- S: void 0,
2167
- C: (f, a) => f(...a)
2168
- });
2229
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
2169
2230
  return null;
2170
2231
  }
2171
2232
  return /* @__PURE__ */ React17.createElement(Form.Root, {
@@ -2189,12 +2250,13 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2189
2250
 
2190
2251
  // src/components/ObjectForm/ObjectForm.tsx
2191
2252
  import * as Schema3 from "effect/Schema";
2192
- import React18, { useCallback as useCallback15, useMemo as useMemo8 } from "react";
2193
- import { DXN as DXN2, Obj as Obj3, Ref as Ref3, Tag as Tag2, Type as Type2 } from "@dxos/echo";
2253
+ import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
2254
+ import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
2194
2255
  import { splitJsonPath } from "@dxos/echo/internal";
2195
2256
  import { invariant } from "@dxos/invariant";
2196
2257
  import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
2197
2258
  import { isNonNullable } from "@dxos/util";
2259
+ import { translationKey as translationKey10 } from "#translations";
2198
2260
  var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
2199
2261
  var createFieldMap = {
2200
2262
  hue: ({ type, label, layout, getValue, onValueChange }) => {
@@ -2216,46 +2278,30 @@ var createFieldMap = {
2216
2278
  }
2217
2279
  };
2218
2280
  var ObjectForm = ({ object, schema }) => {
2219
- const db = Obj3.getDatabase(object);
2220
- const meta = Obj3.getMeta(object);
2281
+ const db = Obj4.getDatabase(object);
2282
+ const meta = Obj4.getMeta(object);
2221
2283
  const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
2222
- const values = useMemo8(() => ({
2284
+ const values = useMemo9(() => ({
2223
2285
  tags,
2224
2286
  ...object
2225
2287
  }), [
2226
2288
  object,
2227
2289
  tags
2228
2290
  ]);
2229
- const formSchema = useMemo8(() => omitId(Schema3.Struct({
2230
- tags: Schema3.Array(Ref3.Ref(Tag2.Tag)).pipe(Schema3.optional)
2291
+ const formSchema = useMemo9(() => omitId(Schema3.Struct({
2292
+ tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
2231
2293
  }).pipe(Schema3.extend(schema))), [
2232
2294
  schema
2233
2295
  ]);
2234
2296
  const handleCreate = useCallback15((schema2, values2) => {
2235
- invariant(db, void 0, {
2236
- F: __dxlog_file3,
2237
- L: 51,
2238
- S: void 0,
2239
- A: [
2240
- "db",
2241
- ""
2242
- ]
2243
- });
2244
- invariant(Type2.isObjectSchema(schema2), void 0, {
2245
- F: __dxlog_file3,
2246
- L: 52,
2247
- S: void 0,
2248
- A: [
2249
- "Type.isObjectSchema(schema)",
2250
- ""
2251
- ]
2252
- });
2253
- const newObject = db.add(Obj3.make(schema2, values2));
2254
- if (Obj3.instanceOf(Tag2.Tag, newObject)) {
2255
- Obj3.change(object, (object2) => {
2256
- Obj3.getMeta(object2).tags = [
2257
- ...Obj3.getMeta(object2).tags ?? [],
2258
- Obj3.getDXN(newObject).toString()
2297
+ invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
2298
+ invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
2299
+ const newObject = db.add(Obj4.make(schema2, values2));
2300
+ if (Obj4.instanceOf(Tag2.Tag, newObject)) {
2301
+ Obj4.update(object, (object2) => {
2302
+ Obj4.getMeta(object2).tags = [
2303
+ ...Obj4.getMeta(object2).tags ?? [],
2304
+ Obj4.getDXN(newObject).toString()
2259
2305
  ];
2260
2306
  });
2261
2307
  }
@@ -2267,17 +2313,17 @@ var ObjectForm = ({ object, schema }) => {
2267
2313
  const changedPaths = Object.keys(changed).filter((path) => changed[path]);
2268
2314
  const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
2269
2315
  if (hasTagsChange) {
2270
- Obj3.change(object, (object2) => {
2271
- Obj3.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2316
+ Obj4.update(object, (object2) => {
2317
+ Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2272
2318
  });
2273
2319
  }
2274
2320
  const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
2275
2321
  if (nonTagPaths.length > 0) {
2276
- Obj3.change(object, () => {
2322
+ Obj4.update(object, () => {
2277
2323
  for (const path of nonTagPaths) {
2278
2324
  const parts = splitJsonPath(path);
2279
- const value3 = Obj3.getValue(values2, parts);
2280
- Obj3.setValue(object, parts, value3);
2325
+ const value3 = Obj4.getValue(values2, parts);
2326
+ Obj4.setValue(object, parts, value3);
2281
2327
  }
2282
2328
  });
2283
2329
  }
@@ -2292,7 +2338,7 @@ var ObjectForm = ({ object, schema }) => {
2292
2338
  createOptionLabel: [
2293
2339
  "add-tag.label",
2294
2340
  {
2295
- ns: translationKey
2341
+ ns: translationKey10
2296
2342
  }
2297
2343
  ],
2298
2344
  createInitialValuePath: "label",
@@ -2305,61 +2351,43 @@ var ObjectForm = ({ object, schema }) => {
2305
2351
 
2306
2352
  // src/components/ObjectProperties/ObjectProperties.tsx
2307
2353
  import * as Function from "effect/Function";
2308
- import * as Option4 from "effect/Option";
2354
+ import * as Option5 from "effect/Option";
2309
2355
  import * as Schema4 from "effect/Schema";
2310
- import React19, { useCallback as useCallback16, useMemo as useMemo9 } from "react";
2311
- import { DXN as DXN3, Obj as Obj4, Ref as Ref4, Tag as Tag3, Type as Type3 } from "@dxos/echo";
2356
+ import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
2357
+ import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
2312
2358
  import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
2313
2359
  import { invariant as invariant2 } from "@dxos/invariant";
2314
2360
  import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
2361
+ import { FactoryAnnotation } from "@dxos/schema";
2315
2362
  import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
2316
2363
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
2364
+ import { translationKey as translationKey11 } from "#translations";
2317
2365
  var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
2318
2366
  var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
2319
- const db = Obj4.getDatabase(object);
2320
- const meta = Obj4.getMeta(object);
2367
+ const db = Obj5.getDatabase(object);
2368
+ const meta = Obj5.getMeta(object);
2321
2369
  const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
2322
- const values = useMemo9(() => ({
2370
+ const values = useMemo10(() => ({
2323
2371
  tags,
2324
2372
  ...object
2325
2373
  }), [
2326
2374
  object,
2327
2375
  tags
2328
2376
  ]);
2329
- const formSchema = useMemo9(() => {
2330
- return Function.pipe(Obj4.getSchema(object), Option4.fromNullable, Option4.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option4.getOrUndefined);
2377
+ const formSchema = useMemo10(() => {
2378
+ return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
2331
2379
  }, [
2332
2380
  object
2333
2381
  ]);
2334
2382
  const handleCreate = useCallback16((schema, values2) => {
2335
- invariant2(db, void 0, {
2336
- F: __dxlog_file4,
2337
- L: 40,
2338
- S: void 0,
2339
- A: [
2340
- "db",
2341
- ""
2342
- ]
2343
- });
2344
- invariant2(Type3.isObjectSchema(schema), void 0, {
2345
- F: __dxlog_file4,
2346
- L: 41,
2347
- S: void 0,
2348
- A: [
2349
- "Type.isObjectSchema(schema)",
2350
- ""
2351
- ]
2352
- });
2353
- const newObject = db.add(Obj4.make(schema, values2));
2354
- if (Obj4.instanceOf(Tag3.Tag, newObject)) {
2355
- Obj4.change(object, (object2) => {
2356
- Obj4.getMeta(object2).tags = [
2357
- ...Obj4.getMeta(object2).tags ?? [],
2358
- Obj4.getDXN(newObject).toString()
2359
- ];
2360
- });
2361
- }
2362
- }, []);
2383
+ invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
2384
+ invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
2385
+ const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
2386
+ const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
2387
+ return db.add(newObject);
2388
+ }, [
2389
+ db
2390
+ ]);
2363
2391
  const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
2364
2392
  if (!isValid) {
2365
2393
  return;
@@ -2367,17 +2395,17 @@ var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef
2367
2395
  const changedPaths = Object.keys(changed).filter((path) => changed[path]);
2368
2396
  const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
2369
2397
  if (hasTagsChange) {
2370
- Obj4.change(object, (object2) => {
2371
- Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2398
+ Obj5.update(object, (object2) => {
2399
+ Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2372
2400
  });
2373
2401
  }
2374
2402
  const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
2375
2403
  if (nonTagPaths.length > 0) {
2376
- Obj4.change(object, () => {
2404
+ Obj5.update(object, () => {
2377
2405
  for (const path of nonTagPaths) {
2378
2406
  const parts = splitJsonPath2(path);
2379
- const value3 = Obj4.getValue(values2, parts);
2380
- Obj4.setValue(object, parts, value3);
2407
+ const value3 = Obj5.getValue(values2, parts);
2408
+ Obj5.setValue(object, parts, value3);
2381
2409
  }
2382
2410
  });
2383
2411
  }
@@ -2395,7 +2423,7 @@ var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef
2395
2423
  createOptionLabel: [
2396
2424
  "add-tag.label",
2397
2425
  {
2398
- ns: translationKey
2426
+ ns: translationKey11
2399
2427
  }
2400
2428
  ],
2401
2429
  createInitialValuePath: "label",
@@ -2428,102 +2456,283 @@ var createFieldMap2 = {
2428
2456
  }
2429
2457
  };
2430
2458
  var BaseSchema = Schema4.Struct({
2431
- tags: Schema4.Array(Ref4.Ref(Tag3.Tag)).pipe(Schema4.optional)
2459
+ tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
2432
2460
  });
2433
2461
 
2434
2462
  // src/components/Settings/Settings.tsx
2435
- import React20 from "react";
2436
- import { Input as Input12, ScrollArea as ScrollArea2, toLocalizedString, useTranslation as useTranslation9 } from "@dxos/react-ui";
2463
+ import React22 from "react";
2464
+ import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
2437
2465
  import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
2466
+ import { translationKey as translationKey13 } from "#translations";
2467
+
2468
+ // src/components/Settings/SettingsFieldSet.tsx
2469
+ import * as SchemaAST5 from "effect/SchemaAST";
2470
+ import * as String3 from "effect/String";
2471
+ import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
2472
+ import { getAnnotation as getAnnotation3 } from "@dxos/effect";
2473
+ import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
2474
+
2475
+ // src/components/Settings/SettingsItem.tsx
2476
+ import React20 from "react";
2477
+ import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
2478
+ import { mx as mx3 } from "@dxos/ui-theme";
2479
+ import { translationKey as translationKey12 } from "#translations";
2480
+ var SETTINGS_PANEL_NAME = "Settings.Panel";
2481
+ var SETTINGS_ITEM_NAME = "Settings.Item";
2482
+ var SettingsPanel = ({ classNames, children }) => {
2483
+ return /* @__PURE__ */ React20.createElement("div", {
2484
+ role: "none",
2485
+ className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
2486
+ }, children);
2487
+ };
2488
+ SettingsPanel.displayName = SETTINGS_PANEL_NAME;
2489
+ var SettingsItem = ({ title, description = "", children }) => {
2490
+ const { t } = useTranslation10(translationKey12);
2491
+ return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
2492
+ classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
2493
+ }, /* @__PURE__ */ React20.createElement(Input12.Label, {
2494
+ classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
2495
+ }, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
2496
+ classNames: "text-base text-description"
2497
+ }, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
2498
+ role: "none",
2499
+ className: "text-end py-1"
2500
+ }, children)));
2501
+ };
2502
+ SettingsItem.displayName = SETTINGS_ITEM_NAME;
2503
+
2504
+ // src/components/Settings/SettingsFieldSet.tsx
2505
+ var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
2506
+ const properties = useMemo11(() => {
2507
+ const props = getFormProperties(schema.ast);
2508
+ if (!sort) {
2509
+ return props;
2510
+ }
2511
+ const rank = (name) => {
2512
+ const idx = sort.indexOf(name);
2513
+ return idx === -1 ? Number.POSITIVE_INFINITY : idx;
2514
+ };
2515
+ return [
2516
+ ...props
2517
+ ].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
2518
+ }, [
2519
+ schema,
2520
+ sort
2521
+ ]);
2522
+ const handleChange = useCallback17((name, value3) => {
2523
+ onValuesChanged?.({
2524
+ ...values,
2525
+ [name]: value3
2526
+ });
2527
+ }, [
2528
+ values,
2529
+ onValuesChanged
2530
+ ]);
2531
+ return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
2532
+ const name = property.name.toString();
2533
+ const path = pathPrefix ? `${pathPrefix}.${name}` : name;
2534
+ if (visible && !visible(path, values)) {
2535
+ return null;
2536
+ }
2537
+ const entry = fieldMap?.[name];
2538
+ return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
2539
+ key: name,
2540
+ path,
2541
+ property,
2542
+ value: values[name],
2543
+ onChange: (value3) => handleChange(name, value3),
2544
+ readonly,
2545
+ customField: typeof entry === "function" ? entry : void 0,
2546
+ nestedFieldMap: typeof entry === "object" ? entry : void 0,
2547
+ visible,
2548
+ sort
2549
+ });
2550
+ }));
2551
+ };
2552
+ SettingsFieldSet.displayName = "Settings.FieldSet";
2553
+ var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
2554
+ const { type } = property;
2555
+ const name = property.name.toString();
2556
+ const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
2557
+ const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
2558
+ if (customField) {
2559
+ const CustomField = customField;
2560
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2561
+ title,
2562
+ description
2563
+ }, /* @__PURE__ */ React21.createElement(CustomField, {
2564
+ value: value3,
2565
+ onChange,
2566
+ readonly
2567
+ }));
2568
+ }
2569
+ const fieldType = detectFieldType(type);
2570
+ switch (fieldType) {
2571
+ case "struct":
2572
+ return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
2573
+ schema: {
2574
+ ast: type
2575
+ },
2576
+ values: value3 ?? {},
2577
+ onValuesChanged: onChange,
2578
+ readonly,
2579
+ fieldMap: nestedFieldMap,
2580
+ visible,
2581
+ sort,
2582
+ pathPrefix: path
2583
+ });
2584
+ case "boolean":
2585
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2586
+ title,
2587
+ description
2588
+ }, /* @__PURE__ */ React21.createElement(Input13.Switch, {
2589
+ disabled: readonly,
2590
+ checked: !!value3,
2591
+ onCheckedChange: (checked) => onChange(!!checked)
2592
+ }));
2593
+ case "select": {
2594
+ const options = getSelectOptionsFromAst(type) ?? [];
2595
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2596
+ title,
2597
+ description
2598
+ }, /* @__PURE__ */ React21.createElement(Select2.Root, {
2599
+ disabled: readonly,
2600
+ value: value3 == null ? "" : globalThis.String(value3),
2601
+ onValueChange: (selected) => {
2602
+ const matched = options.find((option) => globalThis.String(option.value) === selected);
2603
+ onChange(matched?.value ?? selected);
2604
+ }
2605
+ }, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
2606
+ disabled: readonly
2607
+ }), /* @__PURE__ */ React21.createElement(Select2.Portal, null, /* @__PURE__ */ React21.createElement(Select2.Content, null, /* @__PURE__ */ React21.createElement(Select2.Viewport, null, options.map((option) => /* @__PURE__ */ React21.createElement(Select2.Option, {
2608
+ key: globalThis.String(option.value),
2609
+ value: globalThis.String(option.value)
2610
+ }, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
2611
+ }
2612
+ case "string":
2613
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2614
+ title,
2615
+ description
2616
+ }, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
2617
+ disabled: readonly,
2618
+ value: value3 ?? "",
2619
+ onChange: (event) => onChange(event.target.value)
2620
+ }));
2621
+ case "number":
2622
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2623
+ title,
2624
+ description
2625
+ }, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
2626
+ disabled: readonly,
2627
+ type: "number",
2628
+ value: value3 ?? "",
2629
+ onChange: (event) => {
2630
+ if (event.target.value === "") {
2631
+ onChange(void 0);
2632
+ return;
2633
+ }
2634
+ const parsed = Number(event.target.value);
2635
+ onChange(Number.isNaN(parsed) ? void 0 : parsed);
2636
+ }
2637
+ }));
2638
+ default:
2639
+ return null;
2640
+ }
2641
+ };
2642
+
2643
+ // src/components/Settings/Settings.tsx
2438
2644
  var SETTINGS_ROOT_NAME = "Settings.Root";
2439
2645
  var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
2440
2646
  var SETTINGS_SECTION_NAME = "Settings.Section";
2441
- var SETTINGS_PANEL_NAME = "Settings.Panel";
2442
- var SETTINGS_ITEM_NAME = "Settings.Item";
2443
2647
  var SettingsRoot = ({ children, classNames }) => {
2444
- return /* @__PURE__ */ React20.createElement("div", {
2648
+ return /* @__PURE__ */ React22.createElement("div", {
2445
2649
  className: mx4("flex flex-col gap-2", classNames)
2446
2650
  }, children);
2447
2651
  };
2448
2652
  SettingsRoot.displayName = SETTINGS_ROOT_NAME;
2449
2653
  var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
2450
- return /* @__PURE__ */ React20.createElement(ScrollArea2.Root, {
2654
+ return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
2451
2655
  ...composableProps3(props),
2452
2656
  orientation: "vertical",
2453
2657
  centered: true,
2454
2658
  thin: true,
2455
2659
  ref: forwardedRef
2456
- }, /* @__PURE__ */ React20.createElement(ScrollArea2.Viewport, {
2660
+ }, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
2457
2661
  classNames: "px-4 pointer-coarse:px-2"
2458
- }, /* @__PURE__ */ React20.createElement("div", {
2662
+ }, /* @__PURE__ */ React22.createElement("div", {
2459
2663
  role: "none",
2460
2664
  className: "dx-document flex flex-col gap-2 py-4"
2461
2665
  }, children)));
2462
2666
  });
2463
2667
  SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
2464
2668
  var SettingsSection = ({ title, description, children }) => {
2465
- const { t } = useTranslation9(translationKey);
2466
- return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement("h2", {
2669
+ const { t } = useTranslation11(translationKey13);
2670
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
2467
2671
  className: "px-trim-md mt-trim-md text-xl"
2468
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React20.createElement("p", {
2672
+ }, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
2469
2673
  className: "px-trim-md text-description"
2470
- }, toLocalizedString(description, t)), /* @__PURE__ */ React20.createElement("div", {
2674
+ }, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
2471
2675
  className: "w-full pt-trim-md space-y-trim-md"
2472
2676
  }, children));
2473
2677
  };
2474
2678
  SettingsSection.displayName = SETTINGS_SECTION_NAME;
2475
- var SettingsPanel = ({ classNames, children }) => {
2476
- return /* @__PURE__ */ React20.createElement("div", {
2477
- role: "none",
2478
- className: mx4("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
2479
- }, children);
2480
- };
2481
- SettingsPanel.displayName = SETTINGS_PANEL_NAME;
2482
- var SettingsItem = ({ title, description = "", children }) => {
2483
- const { t } = useTranslation9(translationKey);
2484
- return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
2485
- classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
2486
- }, /* @__PURE__ */ React20.createElement(Input12.Label, {
2487
- classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
2488
- }, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
2489
- classNames: "text-base text-description"
2490
- }, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
2491
- role: "none",
2492
- className: "text-end py-1"
2493
- }, children)));
2494
- };
2495
- SettingsItem.displayName = SETTINGS_ITEM_NAME;
2496
2679
  var Settings = {
2497
2680
  Root: SettingsRoot,
2498
2681
  Viewport: SettingsViewport,
2499
2682
  Section: SettingsSection,
2500
2683
  Panel: SettingsPanel,
2501
- Item: SettingsItem
2684
+ Item: SettingsItem,
2685
+ FieldSet: SettingsFieldSet
2686
+ };
2687
+
2688
+ // src/components/Settings/SettingsSelectField.tsx
2689
+ import React23 from "react";
2690
+ import { Select as Select3 } from "@dxos/react-ui";
2691
+ var createSelectField = ({ options, defaultLabel = "Default" }) => {
2692
+ const normalized = options.map((option) => typeof option === "string" ? {
2693
+ value: option,
2694
+ label: option
2695
+ } : option);
2696
+ const hasDefault = defaultLabel !== null;
2697
+ const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
2698
+ return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
2699
+ disabled: readonly,
2700
+ value: value3 ?? sentinel,
2701
+ onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
2702
+ }, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
2703
+ disabled: readonly
2704
+ }), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
2705
+ value: sentinel
2706
+ }, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
2707
+ key: option.value,
2708
+ value: option.value
2709
+ }, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
2502
2710
  };
2503
2711
 
2504
2712
  // src/components/ViewEditor/ViewEditor.tsx
2505
2713
  import { RegistryContext } from "@effect-atom/atom-react";
2506
2714
  import * as Array4 from "effect/Array";
2507
2715
  import * as Match2 from "effect/Match";
2508
- import * as Option5 from "effect/Option";
2716
+ import * as Option6 from "effect/Option";
2509
2717
  import * as Schema5 from "effect/Schema";
2510
- import React21, { forwardRef as forwardRef2, useCallback as useCallback17, useContext, useImperativeHandle, useMemo as useMemo10, useState as useState6 } from "react";
2511
- import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj5, Query, QueryAST, Ref as Ref5 } from "@dxos/echo";
2718
+ import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
2719
+ import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6 } from "@dxos/echo";
2512
2720
  import { View } from "@dxos/echo";
2513
2721
  import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
2514
2722
  import { invariant as invariant3 } from "@dxos/invariant";
2515
2723
  import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
2516
- import { IconButton as IconButton4, Input as Input13, Message, useTranslation as useTranslation10 } from "@dxos/react-ui";
2724
+ import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
2517
2725
  import { QueryForm } from "@dxos/react-ui-components";
2518
2726
  import { List as List2 } from "@dxos/react-ui-list";
2519
2727
  import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
2520
2728
  import { mx as mx5, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
2729
+ import { translationKey as translationKey14 } from "#translations";
2521
2730
  var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2522
2731
  var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
2523
2732
  const atomRegistry = useContext(RegistryContext);
2524
2733
  const schemaReadonly = !isMutable(schema);
2525
- const { t } = useTranslation10(translationKey);
2526
- const projectionModel = useMemo10(() => {
2734
+ const { t } = useTranslation12(translationKey14);
2735
+ const projectionModel = useMemo12(() => {
2527
2736
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2528
2737
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2529
2738
  const model = new ProjectionModel({
@@ -2547,20 +2756,20 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2547
2756
  if (from._tag !== "scope") {
2548
2757
  return void 0;
2549
2758
  }
2550
- return Option5.fromNullable(from.scope.queues).pipe(Option5.flatMap((queues) => Array4.head(queues)), Option5.map(String), Option5.getOrUndefined);
2759
+ return Option6.fromNullable(from.scope.queues).pipe(Option6.flatMap((queues) => Array4.head(queues)), Option6.map(String), Option6.getOrUndefined);
2551
2760
  }), Match2.orElse(() => void 0));
2552
2761
  const feeds = useQuery2(db, Filter2.type(Feed.Feed));
2553
- const targetRef = useMemo10(() => {
2762
+ const targetRef = useMemo12(() => {
2554
2763
  if (!queueTarget) {
2555
2764
  return void 0;
2556
2765
  }
2557
2766
  const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
2558
- return feed ? Ref5.fromDXN(Entity2.getDXN(feed)) : void 0;
2767
+ return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
2559
2768
  }, [
2560
2769
  queueTarget,
2561
2770
  feeds
2562
2771
  ]);
2563
- const viewSchema = useMemo10(() => {
2772
+ const viewSchema = useMemo12(() => {
2564
2773
  const base = Schema5.Struct({
2565
2774
  query: mode === "schema" ? Format5.URL.annotations({
2566
2775
  title: "Record type"
@@ -2572,7 +2781,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2572
2781
  return Schema5.Struct({
2573
2782
  ...base.fields,
2574
2783
  // TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
2575
- target: Ref5.Ref(Feed.Feed).pipe(Schema5.annotations({
2784
+ target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
2576
2785
  title: "Target Feed"
2577
2786
  }), ParentLabelAnnotation.set(true), Schema5.optional)
2578
2787
  }).pipe(Schema5.mutable);
@@ -2581,7 +2790,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2581
2790
  }, [
2582
2791
  mode
2583
2792
  ]);
2584
- const viewValues = useMemo10(() => ({
2793
+ const viewValues = useMemo12(() => ({
2585
2794
  query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2586
2795
  target: targetRef
2587
2796
  }), [
@@ -2589,7 +2798,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2589
2798
  view.query.ast,
2590
2799
  targetRef
2591
2800
  ]);
2592
- const fieldMap = useMemo10(() => mode === "tag" ? customFields({
2801
+ const fieldMap = useMemo12(() => mode === "tag" ? customFields({
2593
2802
  types,
2594
2803
  tags
2595
2804
  }) : void 0, [
@@ -2597,12 +2806,12 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2597
2806
  types,
2598
2807
  tags
2599
2808
  ]);
2600
- const handleUpdate = useCallback17((values) => {
2809
+ const handleUpdate = useCallback18((values) => {
2601
2810
  const targetValue = values.target;
2602
2811
  let queueDxn;
2603
- if (Ref5.isRef(targetValue)) {
2812
+ if (Ref6.isRef(targetValue)) {
2604
2813
  const feedDxn = targetValue.dxn.toString();
2605
- const feed = feeds.find((feed2) => Obj5.getDXN(feed2).toString() === feedDxn);
2814
+ const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === feedDxn);
2606
2815
  if (feed) {
2607
2816
  queueDxn = Feed.getQueueDxn(feed)?.toString();
2608
2817
  }
@@ -2614,37 +2823,29 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2614
2823
  mode,
2615
2824
  feeds
2616
2825
  ]);
2617
- const handleDelete = useCallback17((fieldId) => {
2618
- invariant3(!readonly, void 0, {
2619
- F: __dxlog_file5,
2620
- L: 185,
2621
- S: void 0,
2622
- A: [
2623
- "!readonly",
2624
- ""
2625
- ]
2626
- });
2826
+ const handleDelete = useCallback18((fieldId) => {
2827
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 127, S: void 0, A: ["!readonly", ""] });
2627
2828
  onDelete?.(fieldId);
2628
2829
  }, [
2629
2830
  onDelete,
2630
2831
  readonly
2631
2832
  ]);
2632
- return /* @__PURE__ */ React21.createElement("div", {
2833
+ return /* @__PURE__ */ React24.createElement("div", {
2633
2834
  role: "none",
2634
2835
  className: mx5(classNames)
2635
- }, schemaReadonly && !readonly && /* @__PURE__ */ React21.createElement(Message.Root, {
2836
+ }, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
2636
2837
  valence: "info",
2637
2838
  classNames: "my-form-padding"
2638
- }, /* @__PURE__ */ React21.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React21.createElement(Form.Root, {
2839
+ }, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
2639
2840
  schema: viewSchema,
2640
2841
  values: viewValues,
2641
2842
  fieldMap,
2642
2843
  db,
2643
2844
  onValuesChanged: handleUpdate
2644
- }, /* @__PURE__ */ React21.createElement(Form.FieldSet, null), /* @__PURE__ */ React21.createElement(FormFieldLabel, {
2845
+ }, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2645
2846
  label: t("fields.label"),
2646
2847
  asChild: true
2647
- }), /* @__PURE__ */ React21.createElement(FieldList, {
2848
+ }), /* @__PURE__ */ React24.createElement(FieldList, {
2648
2849
  schema,
2649
2850
  view,
2650
2851
  registry,
@@ -2656,9 +2857,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2656
2857
  var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
2657
2858
  const atomRegistry = useContext(RegistryContext);
2658
2859
  const schemaReadonly = !isMutable(schema);
2659
- const { t } = useTranslation10(translationKey);
2860
+ const { t } = useTranslation12(translationKey14);
2660
2861
  const [viewSnapshot] = useObject(view);
2661
- const projectionModel = useMemo10(() => {
2862
+ const projectionModel = useMemo12(() => {
2662
2863
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2663
2864
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2664
2865
  const model = new ProjectionModel({
@@ -2673,38 +2874,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2673
2874
  schema,
2674
2875
  view
2675
2876
  ]);
2676
- const [expandedField, setExpandedField] = useState6();
2677
- const handleAdd = useCallback17(() => {
2678
- invariant3(!readonly, void 0, {
2679
- F: __dxlog_file5,
2680
- L: 250,
2681
- S: void 0,
2682
- A: [
2683
- "!readonly",
2684
- ""
2685
- ]
2686
- });
2877
+ const [expandedField, setExpandedField] = useState7();
2878
+ const handleAdd = useCallback18(() => {
2879
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 183, S: void 0, A: ["!readonly", ""] });
2687
2880
  const field = projectionModel.createFieldProjection();
2688
2881
  setExpandedField(field.id);
2689
2882
  }, [
2690
2883
  projectionModel,
2691
2884
  readonly
2692
2885
  ]);
2693
- const handleToggleField = useCallback17((field) => {
2886
+ const handleToggleField = useCallback18((field) => {
2694
2887
  setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2695
2888
  }, [
2696
2889
  readonly
2697
2890
  ]);
2698
- const handleDelete = useCallback17((fieldId) => {
2699
- invariant3(!readonly, void 0, {
2700
- F: __dxlog_file5,
2701
- L: 264,
2702
- S: void 0,
2703
- A: [
2704
- "!readonly",
2705
- ""
2706
- ]
2707
- });
2891
+ const handleDelete = useCallback18((fieldId) => {
2892
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 196, S: void 0, A: ["!readonly", ""] });
2708
2893
  if (fieldId === expandedField) {
2709
2894
  setExpandedField(void 0);
2710
2895
  }
@@ -2714,17 +2899,9 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2714
2899
  onDelete,
2715
2900
  readonly
2716
2901
  ]);
2717
- const handleMove = useCallback17((fromIndex, toIndex) => {
2718
- invariant3(!readonly, void 0, {
2719
- F: __dxlog_file5,
2720
- L: 276,
2721
- S: void 0,
2722
- A: [
2723
- "!readonly",
2724
- ""
2725
- ]
2726
- });
2727
- Obj5.change(view, (view2) => {
2902
+ const handleMove = useCallback18((fromIndex, toIndex) => {
2903
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 207, S: void 0, A: ["!readonly", ""] });
2904
+ Obj6.update(view, (view2) => {
2728
2905
  const fields = [
2729
2906
  ...view2.projection.fields
2730
2907
  ];
@@ -2736,14 +2913,14 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2736
2913
  view,
2737
2914
  readonly
2738
2915
  ]);
2739
- const handleClose = useCallback17(() => setExpandedField(void 0), []);
2740
- const handleHide = useCallback17((fieldId) => {
2916
+ const handleClose = useCallback18(() => setExpandedField(void 0), []);
2917
+ const handleHide = useCallback18((fieldId) => {
2741
2918
  setExpandedField(void 0);
2742
2919
  projectionModel.hideFieldProjection(fieldId);
2743
2920
  }, [
2744
2921
  projectionModel
2745
2922
  ]);
2746
- const handleShow = useCallback17((property) => {
2923
+ const handleShow = useCallback18((property) => {
2747
2924
  setExpandedField(void 0);
2748
2925
  projectionModel.showFieldProjection(property);
2749
2926
  }, [
@@ -2752,46 +2929,46 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2752
2929
  if (!viewSnapshot) {
2753
2930
  return null;
2754
2931
  }
2755
- return /* @__PURE__ */ React21.createElement(List2.Root, {
2932
+ return /* @__PURE__ */ React24.createElement(List2.Root, {
2756
2933
  items: viewSnapshot.projection.fields,
2757
2934
  isItem: Schema5.is(View.FieldSchema),
2758
2935
  getId: (field) => field.id,
2759
2936
  onMove: readonly ? void 0 : handleMove,
2760
2937
  readonly
2761
- }, ({ items: fields }) => /* @__PURE__ */ React21.createElement(React21.Fragment, null, showHeading && /* @__PURE__ */ React21.createElement("h3", {
2938
+ }, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
2762
2939
  className: "text-sm"
2763
- }, t("field-path.label")), /* @__PURE__ */ React21.createElement("div", {
2940
+ }, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
2764
2941
  role: "list",
2765
2942
  className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
2766
2943
  }, fields?.map((field) => {
2767
2944
  const hidden = field.visible === false;
2768
- return /* @__PURE__ */ React21.createElement(List2.Item, {
2945
+ return /* @__PURE__ */ React24.createElement(List2.Item, {
2769
2946
  key: field.id,
2770
2947
  item: field,
2771
2948
  classNames: "grid grid-cols-subgrid col-span-5",
2772
2949
  "aria-expanded": expandedField === field.id
2773
- }, /* @__PURE__ */ React21.createElement("div", {
2950
+ }, /* @__PURE__ */ React24.createElement("div", {
2774
2951
  role: "none",
2775
2952
  className: mx5(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
2776
- }, /* @__PURE__ */ React21.createElement(List2.ItemDragHandle, {
2953
+ }, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
2777
2954
  disabled: readonly || schemaReadonly
2778
- }), /* @__PURE__ */ React21.createElement(List2.ItemTitle, {
2955
+ }), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
2779
2956
  classNames: hidden && "text-subdued",
2780
2957
  onClick: () => handleToggleField(field)
2781
- }, field.path), /* @__PURE__ */ React21.createElement(List2.ItemIconButton, {
2782
- label: t(hidden ? "show field label" : "hide field label"),
2958
+ }, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
2959
+ label: t(hidden ? "show-field.label" : "hide-field.label"),
2783
2960
  "data-testid": hidden ? "show-field-button" : "hide-field-button",
2784
2961
  icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2785
2962
  autoHide: false,
2786
2963
  disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
2787
2964
  onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2788
- }), !readonly && /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(List2.ItemDeleteButton, {
2965
+ }), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
2789
2966
  label: t("delete-field.label"),
2790
2967
  autoHide: false,
2791
2968
  disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
2792
2969
  onClick: () => handleDelete(field.id),
2793
2970
  "data-testid": "field.delete"
2794
- }), /* @__PURE__ */ React21.createElement(List2.ItemIconButton, {
2971
+ }), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
2795
2972
  iconOnly: true,
2796
2973
  variant: "ghost",
2797
2974
  label: t("toggle-expand.label", {
@@ -2800,20 +2977,20 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2800
2977
  icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2801
2978
  onClick: () => handleToggleField(field),
2802
2979
  "data-testid": "field.toggle"
2803
- }))), expandedField === field.id && !readonly && /* @__PURE__ */ React21.createElement("div", {
2980
+ }))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
2804
2981
  role: "none",
2805
2982
  className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
2806
- }, /* @__PURE__ */ React21.createElement(FieldEditor, {
2983
+ }, /* @__PURE__ */ React24.createElement(FieldEditor, {
2807
2984
  readonly: readonly || schemaReadonly,
2808
2985
  registry,
2809
2986
  projection: projectionModel,
2810
2987
  field,
2811
2988
  onSave: handleClose
2812
2989
  })));
2813
- })), !readonly && !expandedField && /* @__PURE__ */ React21.createElement("div", {
2990
+ })), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
2814
2991
  role: "none",
2815
2992
  className: "my-form-padding"
2816
- }, /* @__PURE__ */ React21.createElement(IconButton4, {
2993
+ }, /* @__PURE__ */ React24.createElement(IconButton4, {
2817
2994
  icon: "ph--plus--regular",
2818
2995
  label: t("add-property-button.label"),
2819
2996
  onClick: handleAdd,
@@ -2823,13 +3000,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2823
3000
  };
2824
3001
  var customFields = ({ types, tags }) => ({
2825
3002
  query: ({ type, readonly, label, getValue, onValueChange }) => {
2826
- const handleChange = useCallback17((query) => onValueChange(type, query.ast), [
3003
+ const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
2827
3004
  onValueChange
2828
3005
  ]);
2829
- return /* @__PURE__ */ React21.createElement(Input13.Root, null, /* @__PURE__ */ React21.createElement(FormFieldLabel, {
3006
+ return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2830
3007
  readonly,
2831
3008
  label
2832
- }), /* @__PURE__ */ React21.createElement(QueryForm, {
3009
+ }), /* @__PURE__ */ React24.createElement(QueryForm, {
2833
3010
  initialQuery: getValue(),
2834
3011
  types,
2835
3012
  tags,
@@ -2860,15 +3037,18 @@ export {
2860
3037
  TupleField,
2861
3038
  ViewEditor,
2862
3039
  cellClassesForFieldType,
3040
+ createSelectField,
3041
+ detectFieldType,
2863
3042
  formatForDisplay,
2864
3043
  formatForEditing,
2865
3044
  getDefaultValue,
2866
3045
  getFormProperties,
2867
3046
  getRefProps,
3047
+ getSelectOptionsFromAst,
3048
+ omitHiddenFormFields,
2868
3049
  omitId,
2869
3050
  parseValue,
2870
3051
  pathNotUniqueError,
2871
- translations,
2872
3052
  useFormContext,
2873
3053
  useFormFieldState,
2874
3054
  useFormHandler,