@dxos/react-ui-form 0.8.4-main.74a063c4e0 → 0.8.4-main.765dc60934

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 (134) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +873 -446
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/translations.mjs +82 -0
  6. package/dist/lib/browser/translations.mjs.map +7 -0
  7. package/dist/lib/node-esm/index.mjs +873 -446
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/lib/node-esm/translations.mjs +84 -0
  11. package/dist/lib/node-esm/translations.mjs.map +7 -0
  12. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  13. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -61
  14. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/Form.d.ts +34 -12
  16. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/Form.stories.d.ts +73 -71
  18. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/FormField.d.ts +5 -5
  20. package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -6
  22. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/FormFieldSet.d.ts +5 -8
  25. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
  27. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
  29. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
  31. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
  33. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
  34. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
  35. package/dist/types/src/components/Form/fields/RefField.d.ts +10 -4
  36. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
  37. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
  39. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
  40. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
  41. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
  42. package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
  43. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
  44. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
  45. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
  46. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
  47. package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
  48. package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
  49. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +17 -3
  50. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  51. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
  52. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  53. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
  54. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
  55. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
  56. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
  57. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
  58. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
  59. package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
  60. package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
  61. package/dist/types/src/components/Settings/Settings.d.ts +24 -12
  62. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
  63. package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
  64. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
  66. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  67. package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
  68. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  69. package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
  70. package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
  71. package/dist/types/src/components/Settings/index.d.ts +2 -0
  72. package/dist/types/src/components/Settings/index.d.ts.map +1 -1
  73. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +3 -4
  74. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  75. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +63 -61
  76. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/index.d.ts +2 -0
  78. package/dist/types/src/components/index.d.ts.map +1 -1
  79. package/dist/types/src/components/testing.d.ts +4 -4
  80. package/dist/types/src/components/testing.d.ts.map +1 -1
  81. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
  82. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -1
  83. package/dist/types/src/index.d.ts +0 -2
  84. package/dist/types/src/index.d.ts.map +1 -1
  85. package/dist/types/src/translations.d.ts +63 -61
  86. package/dist/types/src/translations.d.ts.map +1 -1
  87. package/dist/types/src/util/field-type.d.ts +19 -0
  88. package/dist/types/src/util/field-type.d.ts.map +1 -0
  89. package/dist/types/src/util/field.d.ts.map +1 -1
  90. package/dist/types/src/util/formatting.d.ts.map +1 -1
  91. package/dist/types/src/util/index.d.ts +1 -0
  92. package/dist/types/src/util/index.d.ts.map +1 -1
  93. package/dist/types/src/util/properties.d.ts.map +1 -1
  94. package/dist/types/src/util/refs.d.ts.map +1 -1
  95. package/dist/types/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +40 -38
  97. package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -1
  98. package/src/components/FieldEditor/FieldEditor.tsx +3 -2
  99. package/src/components/Form/Form.stories.tsx +9 -19
  100. package/src/components/Form/Form.tsx +59 -7
  101. package/src/components/Form/FormField.tsx +12 -10
  102. package/src/components/Form/FormFieldComponent.tsx +6 -3
  103. package/src/components/Form/FormFieldSet.tsx +47 -31
  104. package/src/components/Form/fields/ArrayField.tsx +7 -6
  105. package/src/components/Form/fields/GeoPointField.tsx +3 -2
  106. package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
  107. package/src/components/Form/fields/MarkdownField.tsx +135 -45
  108. package/src/components/Form/fields/RefField.tsx +61 -30
  109. package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -5
  110. package/src/components/Form/fields/SelectOptionField.tsx +6 -5
  111. package/src/components/Form/fields/TextField.tsx +2 -2
  112. package/src/components/ObjectForm/ObjectForm.tsx +114 -0
  113. package/src/components/ObjectForm/index.ts +5 -0
  114. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +9 -6
  115. package/src/components/ObjectPicker/ObjectPicker.tsx +28 -12
  116. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +362 -0
  117. package/src/components/ObjectProperties/ObjectProperties.test.tsx +101 -0
  118. package/src/components/ObjectProperties/ObjectProperties.tsx +141 -0
  119. package/src/components/ObjectProperties/index.ts +5 -0
  120. package/src/components/Settings/AUDIT.md +52 -0
  121. package/src/components/Settings/Settings.stories.tsx +50 -1
  122. package/src/components/Settings/Settings.tsx +7 -56
  123. package/src/components/Settings/SettingsFieldSet.tsx +257 -0
  124. package/src/components/Settings/SettingsItem.tsx +58 -0
  125. package/src/components/Settings/SettingsSelectField.tsx +59 -0
  126. package/src/components/Settings/index.ts +2 -0
  127. package/src/components/ViewEditor/ViewEditor.stories.tsx +10 -10
  128. package/src/components/ViewEditor/ViewEditor.tsx +19 -26
  129. package/src/components/index.ts +2 -0
  130. package/src/components/testing.tsx +20 -21
  131. package/src/index.ts +0 -4
  132. package/src/translations.ts +7 -3
  133. package/src/util/field-type.ts +60 -0
  134. package/src/util/index.ts +1 -0
@@ -1,88 +1,13 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
- // src/translations.ts
4
- var translationKey = "@dxos/react-ui-form";
5
- var translations = [
6
- {
7
- "en-US": {
8
- [translationKey]: {
9
- "fields.label": "Fields",
10
- "hidden-fields.label": "Hidden Fields",
11
- "empty-readonly-ref-field.label": "(none)",
12
- "add-property-button.label": "Add property",
13
- "field-property.label": "Property",
14
- "field-property.placeholder": "Property name",
15
- "field-format.label": "Type",
16
- "field-path.label": "Field path",
17
- "add-field.button": "Add field",
18
- "boolean-input-true.value": "Yes",
19
- "boolean-input-false.value": "No",
20
- "show-field.label": "Show field",
21
- "hide-field.label": "Hide field",
22
- "delete-field.label": "Delete field",
23
- "ref-field-combobox-input.placeholder": "Search\u2026",
24
- "ref-field.placeholder": "Select\u2026",
25
- "ref-field.placeholder_one": "Select\u2026",
26
- "ref-field.placeholder_other": "Select items\u2026",
27
- "create-option.label": "Create",
28
- "example.placeholder": "Example",
29
- "latitude.placeholder": "Latitude (e.g., 40.7128)",
30
- "longitude.placeholder": "Longitude (e.g., -74.0060)",
31
- "cancel-button.label": "Cancel",
32
- "save-button.label": "Save",
33
- // TypeFormat
34
- "format.boolean.label": "Boolean",
35
- "format.currency.label": "Currency",
36
- "format.date.label": "Date",
37
- "format.date-time.label": "DateTime",
38
- "format.did.label": "DID",
39
- "format.duration.label": "Duration",
40
- "format.dxn.label": "DXN",
41
- "format.email.label": "Email",
42
- "format.formula.label": "Formula",
43
- "format.hostname.label": "Hostname",
44
- "format.integer.label": "Integer",
45
- "format.json.label": "JSON",
46
- "format.lnglat.label": "Geopoint",
47
- "format.markdown.label": "Markdown",
48
- "format.percent.label": "Percent",
49
- "format.ref.label": "Reference",
50
- "format.regex.label": "RegExp",
51
- "format.string.label": "String",
52
- "format.single-select.label": "Select",
53
- "format.multi-select.label": "Multi-select",
54
- "format.text.label": "Long text",
55
- "format.time.label": "Time",
56
- "format.timestamp.label": "Timestamp",
57
- "format.user.label": "User",
58
- "format.number.label": "Number",
59
- "format.uri.label": "URI",
60
- "format.url.label": "URL",
61
- "format.uuid.label": "UUID",
62
- // GeoPointField.
63
- "latitude.label": "Latitude",
64
- "longitude.label": "Longitude",
65
- // SelectOptionsField.
66
- "select-option.label": "Label",
67
- "select-option-label.placeholder": "Option label",
68
- "select-option-delete.button": "Delete",
69
- "select-option-add.button": "Add option",
70
- // System schema message.
71
- "system-schema.title": "System type",
72
- "system-schema.description": "System type: cannot add or remove fields.",
73
- "remove.button": "Remove"
74
- }
75
- }
76
- }
77
- ];
78
-
79
3
  // src/components/FieldEditor/FieldEditor.tsx
80
- import React17, { useCallback as useCallback14, useEffect as useEffect6, useMemo as useMemo7, useState as useState5 } from "react";
81
- import { Obj as Obj2 } from "@dxos/echo";
4
+ import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
5
+ import { Obj as Obj3 } from "@dxos/echo";
82
6
  import { Format as Format4, FormatEnums, formatToType } from "@dxos/echo/internal";
83
7
  import { log as log2 } from "@dxos/log";
84
- import { useAsyncEffect, useTranslation as useTranslation8 } from "@dxos/react-ui";
8
+ import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
85
9
  import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
10
+ import { translationKey as translationKey9 } from "#translations";
86
11
 
87
12
  // src/util/field.ts
88
13
  import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
@@ -205,6 +130,46 @@ var pathNotUniqueError = (path) => ({
205
130
  message: `'${path}' is already present`
206
131
  });
207
132
 
133
+ // src/util/field-type.ts
134
+ import * as SchemaAST from "effect/SchemaAST";
135
+ import { getAnnotation, isLiteralUnion } from "@dxos/effect";
136
+ var detectFieldType = (ast) => {
137
+ if (isLiteralUnion(ast)) {
138
+ return "select";
139
+ }
140
+ if (SchemaAST.isTypeLiteral(ast)) {
141
+ return "struct";
142
+ }
143
+ switch (ast._tag) {
144
+ case "BooleanKeyword":
145
+ return "boolean";
146
+ case "StringKeyword":
147
+ return "string";
148
+ case "NumberKeyword":
149
+ return "number";
150
+ }
151
+ return void 0;
152
+ };
153
+ var getSelectOptionsFromAst = (ast) => {
154
+ if (!isLiteralUnion(ast)) {
155
+ return void 0;
156
+ }
157
+ return ast.types.flatMap((literalNode) => {
158
+ const value3 = literalNode.literal;
159
+ if (typeof value3 !== "string" && typeof value3 !== "number") {
160
+ return [];
161
+ }
162
+ const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
163
+ const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
164
+ return [
165
+ {
166
+ value: value3,
167
+ label
168
+ }
169
+ ];
170
+ });
171
+ };
172
+
208
173
  // src/util/formatting.ts
209
174
  import { format as formatDate } from "date-fns/format";
210
175
  import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
@@ -381,20 +346,24 @@ var getRefProps = (ast) => {
381
346
  };
382
347
 
383
348
  // src/components/Form/fields/ArrayField.tsx
384
- import * as Option3 from "effect/Option";
385
- import * as SchemaAST3 from "effect/SchemaAST";
349
+ import * as Option4 from "effect/Option";
350
+ import * as SchemaAST4 from "effect/SchemaAST";
386
351
  import React5, { useCallback as useCallback3 } from "react";
387
352
  import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
388
353
  import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
354
+ import { translationKey as translationKey3 } from "#translations";
389
355
 
390
356
  // src/components/Form/Form.tsx
391
357
  import { createContext } from "@radix-ui/react-context";
358
+ import * as Option3 from "effect/Option";
392
359
  import * as Schema2 from "effect/Schema";
393
- import * as SchemaAST2 from "effect/SchemaAST";
360
+ import * as SchemaAST3 from "effect/SchemaAST";
394
361
  import React4, { useEffect as useEffect2, useMemo as useMemo4, useRef } from "react";
362
+ import { Annotation as EchoAnnotation } from "@dxos/echo";
395
363
  import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
396
364
  import { IconButton, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
397
- import { composable, composableProps, mx } from "@dxos/ui-theme";
365
+ import { composable, composableProps, mx, withColumn } from "@dxos/ui-theme";
366
+ import { translationKey as translationKey2 } from "#translations";
398
367
 
399
368
  // src/hooks/useFormHandler.ts
400
369
  import { useControllableState } from "@radix-ui/react-use-controllable-state";
@@ -432,12 +401,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
432
401
  log("validate", {
433
402
  values: values2,
434
403
  errors: errors2
435
- }, {
436
- F: __dxlog_file,
437
- L: 155,
438
- S: void 0,
439
- C: (f, a) => f(...a)
440
- });
404
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
441
405
  if (errors2.length === 0 && onValidate) {
442
406
  const validatedValues = values2;
443
407
  errors2 = onValidate(validatedValues) ?? [];
@@ -525,12 +489,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
525
489
  log("onValueChange", {
526
490
  path,
527
491
  value: value3
528
- }, {
529
- F: __dxlog_file,
530
- L: 254,
531
- S: void 0,
532
- C: (f, a) => f(...a)
533
- });
492
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
534
493
  const jsonPath = createJsonPath(path);
535
494
  const pathArray = path;
536
495
  let parsedValue = value3;
@@ -539,12 +498,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
539
498
  parsedValue = parseFloat(value3) || 0;
540
499
  }
541
500
  } catch (err) {
542
- log.catch(err, void 0, {
543
- F: __dxlog_file,
544
- L: 264,
545
- S: void 0,
546
- C: (f, a) => f(...a)
547
- });
501
+ log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
548
502
  parsedValue = void 0;
549
503
  }
550
504
  const newValues = mergeAtPath(values, pathArray, parsedValue);
@@ -690,7 +644,6 @@ import { inputTextLabel } from "@dxos/ui-theme";
690
644
  var FormFieldLabel = ({ label, error, readonly, asChild }) => {
691
645
  const Label = readonly || asChild ? "span" : Input.Label;
692
646
  return /* @__PURE__ */ React.createElement("div", {
693
- role: "none",
694
647
  className: "flex items-center justify-between"
695
648
  }, /* @__PURE__ */ React.createElement(Label, {
696
649
  className: inputTextLabel
@@ -714,7 +667,6 @@ var FormFieldWrapper = (props) => {
714
667
  }
715
668
  const str = String(value3 ?? "");
716
669
  return /* @__PURE__ */ React.createElement("div", {
717
- role: "none",
718
670
  className: "contents"
719
671
  }, /* @__PURE__ */ React.createElement(Input.Root, {
720
672
  validationValence: status
@@ -745,7 +697,7 @@ var FormFieldErrorBoundary = class extends Component {
745
697
  return /* @__PURE__ */ React.createElement("div", {
746
698
  className: "flex gap-2 border border-rose-fill font-mono text-sm"
747
699
  }, /* @__PURE__ */ React.createElement("span", {
748
- className: "bg-rose-fill text-surface-text px-1 font-thin"
700
+ className: "bg-rose-fill text-base-foreground px-1 font-thin"
749
701
  }, "ERROR"), String(this.props.path?.join(".")));
750
702
  }
751
703
  return this.props.children;
@@ -764,12 +716,13 @@ import React3, { useMemo as useMemo3 } from "react";
764
716
  import * as Match from "effect/Match";
765
717
  import * as Option2 from "effect/Option";
766
718
  import * as Schema from "effect/Schema";
767
- import * as SchemaAST from "effect/SchemaAST";
719
+ import * as SchemaAST2 from "effect/SchemaAST";
768
720
  import * as String2 from "effect/String";
769
721
  import React2, { useMemo as useMemo2 } from "react";
770
722
  import { Format as Format3 } from "@dxos/echo";
771
- 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";
772
724
  import { useTranslation } from "@dxos/react-ui";
725
+ import { translationKey } from "#translations";
773
726
  var FormField = (props) => {
774
727
  const {
775
728
  type,
@@ -785,16 +738,16 @@ var FormField = (props) => {
785
738
  createOptionLabel,
786
739
  createOptionIcon,
787
740
  createInitialValuePath,
788
- createFieldMap,
741
+ createFieldMap: createFieldMap3,
789
742
  db,
790
- schemaHook,
791
- getOptions: getRefOptions,
743
+ useSchema: schemaHook,
744
+ getOptions,
792
745
  onCreate
793
746
  } = props;
794
747
  const { t } = useTranslation(translationKey);
795
- const title = getAnnotation(SchemaAST.TitleAnnotationId)(type);
796
- const description = getAnnotation(SchemaAST.DescriptionAnnotationId)(type);
797
- 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);
798
751
  const label = useMemo2(() => title ?? String2.capitalize(name), [
799
752
  title,
800
753
  name
@@ -812,6 +765,7 @@ var FormField = (props) => {
812
765
  label,
813
766
  placeholder,
814
767
  layout,
768
+ db,
815
769
  ...fieldState
816
770
  };
817
771
  const jsonPath = createJsonPath2(path ?? []);
@@ -838,7 +792,7 @@ var FormField = (props) => {
838
792
  if (Field) {
839
793
  return /* @__PURE__ */ React2.createElement(Field, fieldProps);
840
794
  }
841
- const options = getOptions(type);
795
+ const options = getSelectOptions(type);
842
796
  if (options) {
843
797
  const fieldProjections = projection?.getFieldProjections();
844
798
  const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
@@ -863,16 +817,16 @@ var FormField = (props) => {
863
817
  createOptionLabel: isCreateTarget ? createOptionLabel : void 0,
864
818
  createOptionIcon: isCreateTarget ? createOptionIcon : void 0,
865
819
  createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
866
- createFieldMap: isCreateTarget ? createFieldMap : void 0,
820
+ createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
867
821
  db,
868
- schemaHook,
869
- getOptions: getRefOptions,
822
+ useSchema: schemaHook,
823
+ getOptions,
870
824
  onCreate
871
825
  });
872
826
  }
873
827
  if (isNestedType(type)) {
874
828
  const baseNode = findNode(type, isDiscriminatedUnion);
875
- const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST.isTypeLiteral);
829
+ const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
876
830
  if (typeLiteral) {
877
831
  const schema = Schema.make(typeLiteral);
878
832
  return /* @__PURE__ */ React2.createElement(FormFieldSet, {
@@ -888,8 +842,8 @@ var FormField = (props) => {
888
842
  createOptionIcon,
889
843
  createInitialValuePath,
890
844
  db,
891
- schemaHook,
892
- getOptions: getRefOptions,
845
+ useSchema: schemaHook,
846
+ getOptions,
893
847
  onCreate
894
848
  });
895
849
  }
@@ -913,8 +867,8 @@ var getFormField = ({ type, format }) => {
913
867
  return BooleanField;
914
868
  }
915
869
  };
916
- var getOptions = (ast) => {
917
- if (isLiteralUnion(ast)) {
870
+ var getSelectOptions = (ast) => {
871
+ if (isLiteralUnion2(ast)) {
918
872
  return ast.types.map((type) => type.literal).filter((v) => v !== null);
919
873
  }
920
874
  return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
@@ -924,39 +878,13 @@ var getOptions = (ast) => {
924
878
  var FORM_FIELDSET_NAME = "Form.FieldSet";
925
879
  var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
926
880
  const values = useFormValues(FORM_FIELDSET_NAME, path);
927
- const properties = useMemo3(() => {
928
- if (!schema) {
929
- return [];
930
- }
931
- const schemaProps = getFormProperties(schema.ast);
932
- const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
933
- if (projection) {
934
- const fieldProjections = projection.getFieldProjections();
935
- const hiddenProperties = new Set(projection.getHiddenProperties());
936
- const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
937
- const orderedProps = [];
938
- for (const fieldProjection of fieldProjections) {
939
- const fieldPath = String(fieldProjection.field.path);
940
- const prop = visibleProps.find((p) => p.name === fieldPath);
941
- if (prop) {
942
- orderedProps.push(prop);
943
- }
944
- }
945
- const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
946
- const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
947
- orderedProps.push(...remainingProps);
948
- return orderedProps;
949
- }
950
- return sort ? [
951
- ...filteredProps
952
- ].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
953
- }, [
881
+ const properties = useFormFieldSetProperties({
954
882
  schema,
955
883
  values,
956
884
  exclude,
957
885
  sort,
958
886
  projection
959
- ]);
887
+ });
960
888
  if ((readonly || layout === "static") && values == null) {
961
889
  return null;
962
890
  }
@@ -986,9 +914,49 @@ var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection,
986
914
  }));
987
915
  };
988
916
  FormFieldSet.displayName = FORM_FIELDSET_NAME;
917
+ var useFormFieldSetProperties = ({ schema, exclude, projection, values, sort }) => {
918
+ return useMemo3(() => {
919
+ if (!schema) {
920
+ return [];
921
+ }
922
+ const schemaProps = getFormProperties(schema.ast);
923
+ const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
924
+ if (projection) {
925
+ const fieldProjections = projection.getFieldProjections();
926
+ const hiddenProperties = new Set(projection.getHiddenProperties());
927
+ const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
928
+ const orderedProps = [];
929
+ for (const fieldProjection of fieldProjections) {
930
+ const fieldPath = String(fieldProjection.field.path);
931
+ const prop = visibleProps.find((prop2) => prop2.name === fieldPath);
932
+ if (prop) {
933
+ orderedProps.push(prop);
934
+ }
935
+ }
936
+ const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
937
+ const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
938
+ orderedProps.push(...remainingProps);
939
+ return orderedProps;
940
+ }
941
+ return sort ? [
942
+ ...filteredProps
943
+ ].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
944
+ }, [
945
+ schema,
946
+ values,
947
+ exclude,
948
+ sort,
949
+ projection
950
+ ]);
951
+ };
989
952
 
990
953
  // src/components/Form/Form.tsx
991
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
+ };
992
960
  var [FormContextProvider, useFormContext] = createContext("Form");
993
961
  var useFormValues = (componentName, path, defaultValue) => {
994
962
  const stablePath = useMemo4(() => path ?? [], [
@@ -1001,7 +969,7 @@ var useFormValues = (componentName, path, defaultValue) => {
1001
969
  useEffect2(() => {
1002
970
  if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
1003
971
  lastAppliedPathRef.current = jsonPath;
1004
- onValueChange(stablePath, SchemaAST2.stringKeyword, defaultValue());
972
+ onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
1005
973
  }
1006
974
  }, [
1007
975
  value3,
@@ -1068,7 +1036,7 @@ var FormContent = composable(({ children, ...props }, forwardedRef) => {
1068
1036
  return /* @__PURE__ */ React4.createElement("div", {
1069
1037
  ...composableProps(props, {
1070
1038
  role: "form",
1071
- classNames: "flex flex-col w-full pb-form-gap"
1039
+ classNames: mx(withColumn.center(), "flex flex-col w-full pb-form-gap")
1072
1040
  }),
1073
1041
  "data-testid": testId,
1074
1042
  ref: mergedRef
@@ -1087,14 +1055,13 @@ var FormFieldSet2 = (props) => {
1087
1055
  FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
1088
1056
  var FORM_ACTIONS_NAME = "Form.Actions";
1089
1057
  var FormActions = ({ classNames }) => {
1090
- const { t } = useTranslation2(translationKey);
1058
+ const { t } = useTranslation2(translationKey2);
1091
1059
  const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
1092
1060
  if (readonly || layout === "static") {
1093
1061
  return null;
1094
1062
  }
1095
1063
  return /* @__PURE__ */ React4.createElement("div", {
1096
- role: "none",
1097
- className: mx("grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
1064
+ className: mx(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
1098
1065
  }, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
1099
1066
  icon: "ph--x--regular",
1100
1067
  iconEnd: true,
@@ -1113,15 +1080,28 @@ var FormActions = ({ classNames }) => {
1113
1080
  }));
1114
1081
  };
1115
1082
  FormActions.displayName = FORM_ACTIONS_NAME;
1083
+ var FORM_SECTION_NAME = "Form.Section";
1084
+ var FormSection = composable(({ children, label, description, ...props }, forwardedRef) => {
1085
+ return /* @__PURE__ */ React4.createElement("div", {
1086
+ ...composableProps(props, {
1087
+ classNames: "flex flex-col pt-form-section-gap first:pt-0"
1088
+ }),
1089
+ ref: forwardedRef
1090
+ }, /* @__PURE__ */ React4.createElement("h2", {
1091
+ className: "text-lg"
1092
+ }, label), description && /* @__PURE__ */ React4.createElement("p", {
1093
+ className: "text-description"
1094
+ }, description), children);
1095
+ });
1096
+ FormSection.displayName = FORM_SECTION_NAME;
1116
1097
  var FORM_SUBMIT_NAME = "Form.Submit";
1117
1098
  var FormSubmit = ({ classNames, label, icon, disabled }) => {
1118
- const { t } = useTranslation2(translationKey);
1099
+ const { t } = useTranslation2(translationKey2);
1119
1100
  const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
1120
1101
  if (readonly || layout === "static") {
1121
1102
  return null;
1122
1103
  }
1123
1104
  return /* @__PURE__ */ React4.createElement("div", {
1124
- role: "none",
1125
1105
  className: mx("flex w-full pt-form-padding", classNames)
1126
1106
  }, /* @__PURE__ */ React4.createElement(IconButton, {
1127
1107
  classNames: "w-full",
@@ -1139,6 +1119,7 @@ var Form = {
1139
1119
  Root: FormRoot,
1140
1120
  Viewport: FormViewport,
1141
1121
  Content: FormContent,
1122
+ Section: FormSection,
1142
1123
  FieldSet: FormFieldSet2,
1143
1124
  Label: FormFieldLabel,
1144
1125
  Actions: FormActions,
@@ -1147,18 +1128,18 @@ var Form = {
1147
1128
 
1148
1129
  // src/components/Form/fields/ArrayField.tsx
1149
1130
  var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
1150
- const { t } = useTranslation3(translationKey);
1131
+ const { t } = useTranslation3(translationKey3);
1151
1132
  const elementType = getArrayElementType2(type);
1152
1133
  const { onValueChange } = inputProps;
1153
1134
  const values = useFormValues(ArrayField.displayName, path, () => []);
1154
1135
  const getDefaultObjectValue = (typeNode) => {
1155
1136
  const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
1156
- const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST3.isTypeLiteral);
1137
+ const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
1157
1138
  if (!typeLiteral) {
1158
1139
  return {};
1159
1140
  }
1160
1141
  return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
1161
- const defaultValue = SchemaAST3.getDefaultAnnotation(prop.type).pipe((annotation) => Option3.getOrUndefined(annotation));
1142
+ const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
1162
1143
  return [
1163
1144
  prop.name,
1164
1145
  defaultValue
@@ -1192,13 +1173,11 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1192
1173
  label,
1193
1174
  asChild: true
1194
1175
  }), /* @__PURE__ */ React5.createElement("div", {
1195
- role: "none",
1196
1176
  className: "flex flex-col gap-form-gap"
1197
1177
  }, values?.map((_, index) => {
1198
1178
  return /* @__PURE__ */ React5.createElement("div", {
1199
- role: "none",
1200
1179
  key: index,
1201
- className: "flex gap-form-gap last:mb-form-gap"
1180
+ className: "grid grid-cols-[1fr_min-content] gap-form-gap last:mb-form-gap items-center"
1202
1181
  }, /* @__PURE__ */ React5.createElement(FormField, {
1203
1182
  autoFocus: index === values.length - 1,
1204
1183
  type: elementType,
@@ -1210,10 +1189,8 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1210
1189
  layout: "inline",
1211
1190
  ...props
1212
1191
  }), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement("div", {
1213
- role: "none",
1214
1192
  className: "flex flex-col h-full justify-end"
1215
1193
  }, /* @__PURE__ */ React5.createElement("div", {
1216
- role: "none",
1217
1194
  className: "flex items-center h-[2rem]"
1218
1195
  }, /* @__PURE__ */ React5.createElement(IconButton2, {
1219
1196
  icon: "ph--x--regular",
@@ -1225,7 +1202,7 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1225
1202
  })), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
1226
1203
  classNames: "flex w-full",
1227
1204
  icon: "ph--plus--regular",
1228
- label: t("add-field.button"),
1205
+ label: t("add-item.button"),
1229
1206
  onClick: handleAdd
1230
1207
  }));
1231
1208
  };
@@ -1277,8 +1254,9 @@ import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo a
1277
1254
  import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
1278
1255
  import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
1279
1256
  import { safeParseFloat } from "@dxos/util";
1257
+ import { translationKey as translationKey4 } from "#translations";
1280
1258
  var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
1281
- const { t } = useTranslation4(translationKey);
1259
+ const { t } = useTranslation4(translationKey4);
1282
1260
  const { status, error } = getStatus();
1283
1261
  const geoPoint = useMemo5(() => getValue() ?? [
1284
1262
  0,
@@ -1332,7 +1310,6 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
1332
1310
  label,
1333
1311
  asChild: true
1334
1312
  }), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
1335
- role: "none",
1336
1313
  className: "grid grid-cols-2 gap-form-gap"
1337
1314
  }, /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("latitude.label")), /* @__PURE__ */ React7.createElement(Input3.TextInput, {
1338
1315
  type: "number",
@@ -1369,56 +1346,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
1369
1346
  };
1370
1347
 
1371
1348
  // src/components/Form/fields/MarkdownField.tsx
1372
- import React8, { useCallback as useCallback6, useEffect as useEffect4, useRef as useRef2 } from "react";
1373
- import { Input as Input4 } from "@dxos/react-ui";
1374
- var MarkdownField = ({ type, readonly, label, placeholder, layout, getStatus, getValue, onValueChange, onBlur }) => {
1349
+ import { useAtomValue } from "@effect-atom/atom-react";
1350
+ import React8, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
1351
+ import { Obj, Ref as Ref2 } from "@dxos/echo";
1352
+ import { AtomRef } from "@dxos/echo-atom";
1353
+ import { createDocAccessor } from "@dxos/echo-db";
1354
+ import { Button, Icon as Icon2, Input as Input4, useTranslation as useTranslation5 } from "@dxos/react-ui";
1355
+ import { Editor, useBasicMarkdownExtensions } from "@dxos/react-ui-editor";
1356
+ import { Text } from "@dxos/schema";
1357
+ import { createDataExtensions } from "@dxos/ui-editor";
1358
+ import { translationKey as translationKey5 } from "#translations";
1359
+ var editorClassNames = "transition-colors bg-input-surface focus-within:bg-focus-surface border border-separator rounded-xs p-1 px-2";
1360
+ var MarkdownField = ({ type, readonly, label, placeholder, layout, db, getStatus, getValue, onValueChange }) => {
1375
1361
  const { status, error } = getStatus();
1376
- const textareaRef = useRef2(null);
1377
- const adjustHeight = useCallback6(() => {
1378
- const textarea = textareaRef.current;
1379
- if (textarea) {
1380
- textarea.style.blockSize = "auto";
1381
- textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
1382
- }
1383
- }, []);
1384
- useEffect4(() => {
1385
- adjustHeight();
1386
- }, [
1387
- adjustHeight
1388
- ]);
1389
- useEffect4(() => {
1390
- adjustHeight();
1391
- }, [
1392
- getValue(),
1393
- adjustHeight
1394
- ]);
1395
- const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
1396
- type,
1397
- onValueChange
1398
- ]);
1362
+ const isRef = Ref2.isRefType(type);
1399
1363
  const value3 = getValue();
1400
- if ((readonly || layout === "static") && !value3) {
1364
+ if ((readonly || layout === "static") && value3 == null) {
1401
1365
  return null;
1402
1366
  }
1367
+ const renderEditor = () => {
1368
+ if (isRef) {
1369
+ const reference = value3;
1370
+ if (reference) {
1371
+ return /* @__PURE__ */ React8.createElement(RefMarkdownEditor, {
1372
+ reference,
1373
+ placeholder
1374
+ });
1375
+ }
1376
+ if (readonly) {
1377
+ return null;
1378
+ }
1379
+ return /* @__PURE__ */ React8.createElement(CreateTextButton, {
1380
+ db,
1381
+ disabled: !db,
1382
+ onCreate: (ref) => onValueChange(type, ref)
1383
+ });
1384
+ }
1385
+ return /* @__PURE__ */ React8.createElement(StringMarkdownEditor, {
1386
+ value: value3 ?? "",
1387
+ placeholder,
1388
+ readonly: !!readonly,
1389
+ onChange: (next) => onValueChange(type, next)
1390
+ });
1391
+ };
1392
+ const renderStatic = () => {
1393
+ if (isRef) {
1394
+ const reference = value3;
1395
+ return reference ? /* @__PURE__ */ React8.createElement(RefStaticText, {
1396
+ reference
1397
+ }) : null;
1398
+ }
1399
+ return /* @__PURE__ */ React8.createElement("p", {
1400
+ className: "whitespace-pre-wrap"
1401
+ }, value3 ?? "");
1402
+ };
1403
1403
  return /* @__PURE__ */ React8.createElement(Input4.Root, {
1404
1404
  validationValence: status
1405
1405
  }, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
1406
1406
  error,
1407
1407
  readonly,
1408
1408
  label
1409
- }), layout === "static" ? /* @__PURE__ */ React8.createElement("p", null, value3) : /* @__PURE__ */ React8.createElement(Input4.TextArea, {
1410
- ref: textareaRef,
1411
- disabled: !!readonly,
1409
+ }), layout === "static" ? renderStatic() : renderEditor(), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
1410
+ };
1411
+ var RefStaticText = ({ reference }) => {
1412
+ const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
1413
+ reference
1414
+ ]));
1415
+ if (!text?.content) {
1416
+ return null;
1417
+ }
1418
+ return /* @__PURE__ */ React8.createElement("p", {
1419
+ className: "whitespace-pre-wrap"
1420
+ }, text.content);
1421
+ };
1422
+ var RefMarkdownEditor = ({ reference, placeholder }) => {
1423
+ const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
1424
+ reference
1425
+ ]));
1426
+ const dataExtensions = useMemo6(() => text ? [
1427
+ createDataExtensions({
1428
+ id: reference.dxn.toString(),
1429
+ text: createDocAccessor(text, [
1430
+ "content"
1431
+ ])
1432
+ })
1433
+ ] : [], [
1434
+ text,
1435
+ reference
1436
+ ]);
1437
+ const extensions = useBasicMarkdownExtensions({
1412
1438
  placeholder,
1413
- value: value3 ?? "",
1414
- classNames: "min-h-auto max-h-40 overflow-auto",
1415
- onChange: handleChange,
1416
- onBlur,
1417
- style: {
1418
- resize: "none"
1419
- },
1420
- spellCheck: false
1421
- }), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
1439
+ extensions: dataExtensions
1440
+ });
1441
+ if (!text) {
1442
+ return null;
1443
+ }
1444
+ return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
1445
+ classNames: editorClassNames,
1446
+ extensions
1447
+ }));
1448
+ };
1449
+ var StringMarkdownEditor = ({ value: value3, placeholder, readonly, onChange }) => {
1450
+ const extensions = useBasicMarkdownExtensions({
1451
+ placeholder
1452
+ });
1453
+ const handleChange = useCallback6((next) => onChange(next), [
1454
+ onChange
1455
+ ]);
1456
+ return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
1457
+ classNames: editorClassNames,
1458
+ extensions,
1459
+ value: value3,
1460
+ onChange: readonly ? void 0 : handleChange
1461
+ }));
1462
+ };
1463
+ var CreateTextButton = ({ db, disabled, onCreate }) => {
1464
+ const { t } = useTranslation5(translationKey5);
1465
+ const handleClick = useCallback6(() => {
1466
+ if (!db) {
1467
+ return;
1468
+ }
1469
+ const text = db.add(Obj.make(Text.Text, {
1470
+ content: ""
1471
+ }));
1472
+ onCreate(Ref2.make(text));
1473
+ }, [
1474
+ db,
1475
+ onCreate
1476
+ ]);
1477
+ return /* @__PURE__ */ React8.createElement(Button, {
1478
+ onClick: handleClick,
1479
+ disabled
1480
+ }, /* @__PURE__ */ React8.createElement(Icon2, {
1481
+ icon: "ph--plus--regular",
1482
+ size: 4
1483
+ }), /* @__PURE__ */ React8.createElement("span", null, t("create-text.label")));
1422
1484
  };
1423
1485
 
1424
1486
  // src/components/Form/fields/NumberField.tsx
@@ -1444,31 +1506,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
1444
1506
  };
1445
1507
 
1446
1508
  // src/components/Form/fields/RefField.tsx
1447
- import React11, { useCallback as useCallback9, useMemo as useMemo6 } from "react";
1509
+ import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
1448
1510
  import "@dxos/lit-ui/dx-tag-picker.pcss";
1449
- import { Entity, Filter, Obj, Ref as Ref2, Type } from "@dxos/echo";
1450
- import { useQuery, useSchema as useSchema$ } from "@dxos/echo-react";
1511
+ import { Entity, Filter, Obj as Obj2, Ref as Ref3, Type } from "@dxos/echo";
1512
+ import { useQuery, useSchema as defaultUseSchema } from "@dxos/echo-react";
1451
1513
  import { ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo/internal";
1452
1514
  import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1453
1515
  import { DXN } from "@dxos/keys";
1454
1516
  import { DxAnchor } from "@dxos/lit-ui/react";
1455
- import { Button, Icon as Icon2, Input as Input6, useTranslation as useTranslation6 } from "@dxos/react-ui";
1517
+ import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
1456
1518
  import { ParentLabelAnnotationId } from "@dxos/schema";
1457
- import { mx as mx2 } from "@dxos/ui-theme";
1519
+ import { translationKey as translationKey7 } from "#translations";
1458
1520
 
1459
1521
  // src/components/ObjectPicker/ObjectPicker.tsx
1460
1522
  import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
1461
- import { Popover, useTranslation as useTranslation5 } from "@dxos/react-ui";
1462
- import { Combobox, useSearchListInput, useSearchListResults } from "@dxos/react-ui-search";
1463
- var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap, onSelect, onCreate, ...props }, forwardedRef) => {
1464
- const { t } = useTranslation5(translationKey);
1523
+ import { Popover, useTranslation as useTranslation6 } from "@dxos/react-ui";
1524
+ import { Combobox } from "@dxos/react-ui-list";
1525
+ import { useSearchListResults } from "@dxos/react-ui-search";
1526
+ import { translationKey as translationKey6 } from "#translations";
1527
+ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
1528
+ const { t } = useTranslation6(translationKey6);
1465
1529
  const [showForm, setShowForm] = useState3(false);
1466
1530
  const [formInitialValue, setFormInitialValue] = useState3("");
1467
- const { results, handleSearch } = useSearchListResults({
1531
+ const { results, query, handleSearch } = useSearchListResults({
1468
1532
  items: options
1469
1533
  });
1470
- const handleFormSave = useCallback8((values) => {
1471
- onCreate?.(values);
1534
+ const handleFormSave = useCallback8(async (values) => {
1535
+ await onCreate?.(values);
1472
1536
  setShowForm(false);
1473
1537
  setFormInitialValue("");
1474
1538
  }, [
@@ -1493,7 +1557,6 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1493
1557
  if (showForm && createSchema) {
1494
1558
  return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1495
1559
  ...props,
1496
- onSearch: handleSearch,
1497
1560
  onKeyDownCapture: handleKeyDown,
1498
1561
  ref: forwardedRef
1499
1562
  }, /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
@@ -1502,19 +1565,20 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1502
1565
  defaultValues: createInitialValuePath ? {
1503
1566
  [createInitialValuePath]: formInitialValue
1504
1567
  } : {},
1505
- fieldMap: createFieldMap,
1568
+ fieldMap: createFieldMap3,
1506
1569
  onSave: handleFormSave,
1507
1570
  onCancel: handleFormCancel
1508
1571
  }, /* @__PURE__ */ React10.createElement(Form.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Content, null, /* @__PURE__ */ React10.createElement(Form.FieldSet, null), /* @__PURE__ */ React10.createElement(Form.Actions, null))))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1509
1572
  }
1510
1573
  return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1511
1574
  ...props,
1512
- onSearch: handleSearch,
1513
1575
  onKeyDownCapture: handleKeyDown,
1514
1576
  ref: forwardedRef
1515
1577
  }, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1516
1578
  placeholder: t("ref-field-combobox-input.placeholder"),
1517
- autoFocus: true
1579
+ autoFocus: true,
1580
+ value: query,
1581
+ onValueChange: handleSearch
1518
1582
  }), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1519
1583
  key: option.id,
1520
1584
  value: option.id,
@@ -1523,17 +1587,17 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
1523
1587
  onSelect: () => onSelect(option.id),
1524
1588
  classNames: "flex items-center gap-2"
1525
1589
  })), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
1590
+ query,
1526
1591
  createOptionLabel,
1527
1592
  createOptionIcon: createOptionIcon ?? "ph--plus--regular",
1528
- onCreateItemSelect: (query) => {
1529
- setFormInitialValue(query);
1593
+ onCreateItemSelect: (currentQuery) => {
1594
+ setFormInitialValue(currentQuery);
1530
1595
  setShowForm(true);
1531
1596
  }
1532
1597
  })), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1533
1598
  });
1534
- var CreateItem = ({ createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1535
- const { t } = useTranslation5(translationKey);
1536
- const { query } = useSearchListInput();
1599
+ var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1600
+ const { t } = useTranslation6(translationKey6);
1537
1601
  const label = createOptionLabel ? t(createOptionLabel[0], {
1538
1602
  ns: createOptionLabel[1].ns,
1539
1603
  text: query
@@ -1564,39 +1628,41 @@ var isRefSnapshot = (val) => {
1564
1628
  };
1565
1629
  var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
1566
1630
  const id = Entity.getDXN(result).toString();
1567
- const parent = parentLabel ? Obj.getParent(result) : void 0;
1631
+ const parent = parentLabel ? Obj2.getParent(result) : void 0;
1568
1632
  const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
1569
1633
  return {
1570
1634
  id,
1571
1635
  label: label ?? id
1572
1636
  };
1573
1637
  });
1574
- var defaultResultsHook = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
1638
+ var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
1575
1639
  var RefField = (props) => {
1576
- const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap, db, resultsHook: useResults = defaultResultsHook, schemaHook: useSchema = useSchema$, getOptions: getOptions2 = defaultGetOptions, onCreate, onValueChange } = props;
1577
- const { t } = useTranslation6(translationKey);
1640
+ const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useSchema = defaultUseSchema, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
1641
+ const { t } = useTranslation7(translationKey7);
1578
1642
  const { status, error } = getStatus();
1579
- const typename = useMemo6(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
1643
+ const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
1580
1644
  type
1581
1645
  ]);
1582
1646
  const results = useResults(db, typename);
1583
- const options = useMemo6(() => {
1647
+ const options = useMemo7(() => {
1584
1648
  const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
1585
- return getOptions2(results, {
1649
+ return getOptions(results, {
1586
1650
  parentLabel
1587
1651
  });
1588
1652
  }, [
1589
1653
  results,
1590
- getOptions2,
1654
+ getOptions,
1591
1655
  type
1592
1656
  ]);
1593
1657
  const handleGetValue = useCallback9(() => {
1594
1658
  const formValue = getValue();
1659
+ const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
1595
1660
  const unknownToRefOption = (value3) => {
1596
- const isRef = Ref2.isRef(value3);
1661
+ const isRef = Ref3.isRef(value3);
1597
1662
  if (isRef || isRefSnapshot(value3)) {
1598
1663
  const dxnString = isRef ? value3.dxn.toString() : value3["/"];
1599
- const matchingOption = options.find((option) => option.id === dxnString);
1664
+ const objectId = dxnToObjectId(dxnString);
1665
+ const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
1600
1666
  if (matchingOption) {
1601
1667
  return matchingOption;
1602
1668
  }
@@ -1608,29 +1674,37 @@ var RefField = (props) => {
1608
1674
  options,
1609
1675
  getValue
1610
1676
  ]);
1611
- const handleUpdate = useCallback9((id) => {
1612
- const item2 = options.find((option) => option.id === id);
1613
- const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
1614
- onValueChange(type, ref);
1615
- }, [
1616
- options,
1617
- type,
1618
- onValueChange
1619
- ]);
1620
1677
  const item = handleGetValue();
1621
- const selectedIds = useMemo6(() => item ? [
1678
+ const selectedIds = useMemo7(() => item ? [
1622
1679
  item.id
1623
1680
  ] : [], [
1624
1681
  item
1625
1682
  ]);
1626
1683
  const createSchema = useSchema(db, typename);
1627
- const handleCreate = useCallback9((values) => {
1628
- if (createSchema && onCreate) {
1629
- onCreate(createSchema, values);
1684
+ const [open, setOpen] = useState4(false);
1685
+ const handleCreate = useCallback9(async (values) => {
1686
+ if (!createSchema || !onCreate) {
1687
+ return;
1630
1688
  }
1689
+ const newObject = await onCreate(createSchema, values);
1690
+ if (newObject) {
1691
+ onValueChange(type, Ref3.make(newObject));
1692
+ }
1693
+ setOpen(false);
1631
1694
  }, [
1632
1695
  createSchema,
1633
- onCreate
1696
+ onCreate,
1697
+ type,
1698
+ onValueChange
1699
+ ]);
1700
+ const handleUpdate = useCallback9((id) => {
1701
+ const item2 = options.find((option) => option.id === id);
1702
+ const ref = item2 ? Ref3.fromDXN(DXN.parse(item2.id)) : void 0;
1703
+ onValueChange(type, ref);
1704
+ }, [
1705
+ options,
1706
+ type,
1707
+ onValueChange
1634
1708
  ]);
1635
1709
  const handleSelect = useCallback9((id) => {
1636
1710
  if (item?.id === id) {
@@ -1652,12 +1726,15 @@ var RefField = (props) => {
1652
1726
  readonly,
1653
1727
  label
1654
1728
  }), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
1655
- className: mx2("text-description", "mb-2")
1729
+ className: "text-description mb-2"
1656
1730
  }, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
1657
1731
  key: item.id,
1658
1732
  dxn: item.id,
1659
1733
  rootclassname: "me-1"
1660
- }, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1734
+ }, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, {
1735
+ open,
1736
+ onOpenChange: setOpen
1737
+ }, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1661
1738
  asChild: true,
1662
1739
  classNames: "p-0"
1663
1740
  }, item ? /* @__PURE__ */ React11.createElement("div", {
@@ -1668,25 +1745,27 @@ var RefField = (props) => {
1668
1745
  value: item.label,
1669
1746
  readOnly: true,
1670
1747
  classNames: "w-full"
1671
- }))) : /* @__PURE__ */ React11.createElement(Button, {
1748
+ }))) : /* @__PURE__ */ React11.createElement(Button2, {
1672
1749
  classNames: "w-full text-start gap-form-gap"
1673
1750
  }, /* @__PURE__ */ React11.createElement("div", {
1674
- role: "none",
1675
1751
  className: "grow overflow-hidden"
1676
1752
  }, /* @__PURE__ */ React11.createElement("span", {
1677
- className: "flex truncate text-description"
1678
- }, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon2, {
1753
+ className: "truncate text-description"
1754
+ }, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
1679
1755
  size: 3,
1680
1756
  icon: "ph--caret-down--bold"
1681
1757
  }))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
1682
1758
  classNames: "dx-card-popover-width",
1683
1759
  options,
1684
1760
  selectedIds,
1685
- createSchema: createSchema && omitId(createSchema),
1761
+ // Strip hidden (`FormInputAnnotation.set(false)`) fields so the
1762
+ // form's validator doesn't reject required-but-hidden fields
1763
+ // such as backing-object refs supplied by a `FactoryAnnotation`.
1764
+ createSchema: createSchema && omitHiddenFormFields(omitId(createSchema)),
1686
1765
  createOptionLabel,
1687
1766
  createOptionIcon,
1688
1767
  createInitialValuePath,
1689
- createFieldMap,
1768
+ createFieldMap: createFieldMap3,
1690
1769
  onCreate: handleCreate,
1691
1770
  onSelect: handleSelect
1692
1771
  })))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
@@ -1728,20 +1807,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
1728
1807
  };
1729
1808
 
1730
1809
  // src/components/Form/fields/SelectOptionField.tsx
1731
- import React13, { useCallback as useCallback11, useEffect as useEffect5, useRef as useRef3, useState as useState4 } from "react";
1810
+ import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
1732
1811
  import { PublicKey } from "@dxos/keys";
1733
- import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation7 } from "@dxos/react-ui";
1812
+ import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
1734
1813
  import { List } from "@dxos/react-ui-list";
1735
1814
  import { HuePicker } from "@dxos/react-ui-pickers";
1736
- import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
1815
+ import { hues, osTranslations } from "@dxos/ui-theme";
1816
+ import { translationKey as translationKey8 } from "#translations";
1737
1817
  var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
1738
- const { t } = useTranslation7(translationKey);
1818
+ const { t } = useTranslation8(translationKey8);
1739
1819
  const { status, error } = getStatus();
1740
- const [selected, setSelectedId] = useState4(null);
1741
- const [isNewOption, setIsNewOption] = useState4(false);
1742
- const inputRef = useRef3(null);
1820
+ const [selected, setSelectedId] = useState5(null);
1821
+ const [isNewOption, setIsNewOption] = useState5(false);
1822
+ const inputRef = useRef2(null);
1743
1823
  const options = getValue();
1744
- useEffect5(() => {
1824
+ useEffect4(() => {
1745
1825
  if (options === void 0) {
1746
1826
  onValueChange(type, []);
1747
1827
  }
@@ -1832,7 +1912,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1832
1912
  type,
1833
1913
  onValueChange
1834
1914
  ]);
1835
- useEffect5(() => {
1915
+ useEffect4(() => {
1836
1916
  if (selected && isNewOption && inputRef.current) {
1837
1917
  inputRef.current.focus();
1838
1918
  setIsNewOption(false);
@@ -1847,9 +1927,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1847
1927
  error,
1848
1928
  readonly,
1849
1929
  label
1850
- }), /* @__PURE__ */ React13.createElement("div", {
1851
- role: "none"
1852
- }, options && /* @__PURE__ */ React13.createElement(List.Root, {
1930
+ }), /* @__PURE__ */ React13.createElement("div", null, options && /* @__PURE__ */ React13.createElement(List.Root, {
1853
1931
  items: options,
1854
1932
  isItem: (_item) => true,
1855
1933
  onMove: readonly ? void 0 : handleMove,
@@ -1862,10 +1940,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1862
1940
  }, /* @__PURE__ */ React13.createElement(List.Item, {
1863
1941
  role: "button",
1864
1942
  item,
1865
- classNames: [
1866
- subtleHover,
1867
- "flex flex-col cursor-pointer rounded-xs"
1868
- ],
1943
+ classNames: "flex flex-col cursor-pointer rounded-xs dx-hover",
1869
1944
  "aria-expanded": selected === item.id
1870
1945
  }, /* @__PURE__ */ React13.createElement("div", {
1871
1946
  className: "flex items-center"
@@ -1879,7 +1954,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1879
1954
  }, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
1880
1955
  iconOnly: true,
1881
1956
  variant: "ghost",
1882
- label: t(selected === item.id ? "collapse label" : "expand label", {
1957
+ label: t(selected === item.id ? "collapse.label" : "expand.label", {
1883
1958
  ns: osTranslations
1884
1959
  }),
1885
1960
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
@@ -1921,7 +1996,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1921
1996
  // src/components/Form/fields/TextField.tsx
1922
1997
  import React14, { useCallback as useCallback12 } from "react";
1923
1998
  import { Input as Input9 } from "@dxos/react-ui";
1924
- var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
1999
+ var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
1925
2000
  const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
1926
2001
  type,
1927
2002
  onValueChange
@@ -1934,8 +2009,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
1934
2009
  disabled: !!readonly,
1935
2010
  placeholder,
1936
2011
  value: value3,
1937
- onChange: handleChange,
1938
- onBlur
2012
+ onBlur,
2013
+ onChange: handleChange
1939
2014
  }));
1940
2015
  };
1941
2016
 
@@ -1963,7 +2038,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
1963
2038
  // src/components/Form/fields/TupleField.tsx
1964
2039
  import React16 from "react";
1965
2040
  import { Input as Input11 } from "@dxos/react-ui";
1966
- import { mx as mx3 } from "@dxos/ui-theme";
2041
+ import { mx as mx2 } from "@dxos/ui-theme";
1967
2042
  import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
1968
2043
  var gridCols = [
1969
2044
  "grid-cols-1",
@@ -1981,7 +2056,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
1981
2056
  readonly,
1982
2057
  label
1983
2058
  }), /* @__PURE__ */ React16.createElement("div", {
1984
- className: mx3("grid gap-form-gap", gridCols[binding.length - 1])
2059
+ className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
1985
2060
  }, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
1986
2061
  key: prop,
1987
2062
  type: "number",
@@ -2000,13 +2075,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
2000
2075
  // src/components/FieldEditor/FieldEditor.tsx
2001
2076
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
2002
2077
  var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
2003
- const { t } = useTranslation8(translationKey);
2004
- const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
2005
- useEffect6(() => setProps(projection.getFieldProjection(field.id).props), [
2078
+ const { t } = useTranslation9(translationKey9);
2079
+ const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
2080
+ useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
2006
2081
  field,
2007
2082
  projection
2008
2083
  ]);
2009
- const [schemas, setSchemas] = useState5([]);
2084
+ const [schemas, setSchemas] = useState6([]);
2010
2085
  useAsyncEffect(async () => {
2011
2086
  if (!registry) {
2012
2087
  return;
@@ -2020,17 +2095,17 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2020
2095
  }, [
2021
2096
  registry
2022
2097
  ]);
2023
- const [referenceSchema, setReferenceSchema] = useState5();
2024
- useEffect6(() => {
2098
+ const [referenceSchema, setReferenceSchema] = useState6();
2099
+ useEffect5(() => {
2025
2100
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
2026
2101
  }, [
2027
2102
  schemas,
2028
2103
  props?.referenceSchema
2029
2104
  ]);
2030
- const [{ fieldSchema }, setFieldSchema] = useState5({
2105
+ const [{ fieldSchema }, setFieldSchema] = useState6({
2031
2106
  fieldSchema: getFormatSchema(props?.format)
2032
2107
  });
2033
- const fieldMap = useMemo7(() => ({
2108
+ const fieldMap = useMemo8(() => ({
2034
2109
  ["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
2035
2110
  ...props2,
2036
2111
  options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
@@ -2109,7 +2184,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2109
2184
  ]);
2110
2185
  const handleSave = useCallback14((props2) => {
2111
2186
  if (view) {
2112
- Obj2.change(view, () => {
2187
+ Obj3.update(view, () => {
2113
2188
  projection.setFieldProjection({
2114
2189
  field,
2115
2190
  props: props2
@@ -2137,12 +2212,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2137
2212
  if (!fieldSchema) {
2138
2213
  log2.warn("invalid format", {
2139
2214
  props
2140
- }, {
2141
- F: __dxlog_file2,
2142
- L: 172,
2143
- S: void 0,
2144
- C: (f, a) => f(...a)
2145
- });
2215
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
2146
2216
  return null;
2147
2217
  }
2148
2218
  return /* @__PURE__ */ React17.createElement(Form.Root, {
@@ -2164,99 +2234,487 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2164
2234
  }, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
2165
2235
  };
2166
2236
 
2237
+ // src/components/ObjectForm/ObjectForm.tsx
2238
+ import * as Schema3 from "effect/Schema";
2239
+ import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
2240
+ import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
2241
+ import { splitJsonPath } from "@dxos/echo/internal";
2242
+ import { invariant } from "@dxos/invariant";
2243
+ import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
2244
+ import { isNonNullable } from "@dxos/util";
2245
+ import { translationKey as translationKey10 } from "#translations";
2246
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
2247
+ var createFieldMap = {
2248
+ hue: ({ type, label, layout, getValue, onValueChange }) => {
2249
+ const handleChange = useCallback15((nextHue) => onValueChange(type, nextHue), [
2250
+ onValueChange,
2251
+ type
2252
+ ]);
2253
+ const handleReset = useCallback15(() => onValueChange(type, void 0), [
2254
+ onValueChange,
2255
+ type
2256
+ ]);
2257
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, layout !== "inline" && /* @__PURE__ */ React18.createElement(Form.Label, {
2258
+ label
2259
+ }), /* @__PURE__ */ React18.createElement(HuePicker2, {
2260
+ value: getValue(),
2261
+ onChange: handleChange,
2262
+ onReset: handleReset
2263
+ }));
2264
+ }
2265
+ };
2266
+ var ObjectForm = ({ object, schema }) => {
2267
+ const db = Obj4.getDatabase(object);
2268
+ const meta = Obj4.getMeta(object);
2269
+ const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
2270
+ const values = useMemo9(() => ({
2271
+ tags,
2272
+ ...object
2273
+ }), [
2274
+ object,
2275
+ tags
2276
+ ]);
2277
+ const formSchema = useMemo9(() => omitId(Schema3.Struct({
2278
+ tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
2279
+ }).pipe(Schema3.extend(schema))), [
2280
+ schema
2281
+ ]);
2282
+ const handleCreate = useCallback15((schema2, values2) => {
2283
+ invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
2284
+ invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
2285
+ const newObject = db.add(Obj4.make(schema2, values2));
2286
+ if (Obj4.instanceOf(Tag2.Tag, newObject)) {
2287
+ Obj4.update(object, (object2) => {
2288
+ Obj4.getMeta(object2).tags = [
2289
+ ...Obj4.getMeta(object2).tags ?? [],
2290
+ Obj4.getDXN(newObject).toString()
2291
+ ];
2292
+ });
2293
+ }
2294
+ }, []);
2295
+ const handleChange = useCallback15(({ tags: tags2, ...values2 }, { isValid, changed }) => {
2296
+ if (!isValid) {
2297
+ return;
2298
+ }
2299
+ const changedPaths = Object.keys(changed).filter((path) => changed[path]);
2300
+ const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
2301
+ if (hasTagsChange) {
2302
+ Obj4.update(object, (object2) => {
2303
+ Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2304
+ });
2305
+ }
2306
+ const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
2307
+ if (nonTagPaths.length > 0) {
2308
+ Obj4.update(object, () => {
2309
+ for (const path of nonTagPaths) {
2310
+ const parts = splitJsonPath(path);
2311
+ const value3 = Obj4.getValue(values2, parts);
2312
+ Obj4.setValue(object, parts, value3);
2313
+ }
2314
+ });
2315
+ }
2316
+ }, [
2317
+ object
2318
+ ]);
2319
+ return /* @__PURE__ */ React18.createElement(Form.Root, {
2320
+ schema: formSchema,
2321
+ defaultValues: values,
2322
+ createTypename: Type2.getTypename(Tag2.Tag),
2323
+ createOptionIcon: "ph--plus--regular",
2324
+ createOptionLabel: [
2325
+ "add-tag.label",
2326
+ {
2327
+ ns: translationKey10
2328
+ }
2329
+ ],
2330
+ createInitialValuePath: "label",
2331
+ createFieldMap,
2332
+ db,
2333
+ onValuesChanged: handleChange,
2334
+ onCreate: handleCreate
2335
+ }, /* @__PURE__ */ React18.createElement(Form.Viewport, null, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null))));
2336
+ };
2337
+
2338
+ // src/components/ObjectProperties/ObjectProperties.tsx
2339
+ import * as Function from "effect/Function";
2340
+ import * as Option5 from "effect/Option";
2341
+ import * as Schema4 from "effect/Schema";
2342
+ import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
2343
+ import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
2344
+ import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
2345
+ import { invariant as invariant2 } from "@dxos/invariant";
2346
+ import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
2347
+ import { FactoryAnnotation } from "@dxos/schema";
2348
+ import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
2349
+ import { isNonNullable as isNonNullable2 } from "@dxos/util";
2350
+ import { translationKey as translationKey11 } from "#translations";
2351
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
2352
+ var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
2353
+ const db = Obj5.getDatabase(object);
2354
+ const meta = Obj5.getMeta(object);
2355
+ const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
2356
+ const values = useMemo10(() => ({
2357
+ tags,
2358
+ ...object
2359
+ }), [
2360
+ object,
2361
+ tags
2362
+ ]);
2363
+ const formSchema = useMemo10(() => {
2364
+ return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
2365
+ }, [
2366
+ object
2367
+ ]);
2368
+ const handleCreate = useCallback16((schema, values2) => {
2369
+ invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
2370
+ invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
2371
+ const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
2372
+ const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
2373
+ return db.add(newObject);
2374
+ }, [
2375
+ db
2376
+ ]);
2377
+ const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
2378
+ if (!isValid) {
2379
+ return;
2380
+ }
2381
+ const changedPaths = Object.keys(changed).filter((path) => changed[path]);
2382
+ const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
2383
+ if (hasTagsChange) {
2384
+ Obj5.update(object, (object2) => {
2385
+ Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2386
+ });
2387
+ }
2388
+ const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
2389
+ if (nonTagPaths.length > 0) {
2390
+ Obj5.update(object, () => {
2391
+ for (const path of nonTagPaths) {
2392
+ const parts = splitJsonPath2(path);
2393
+ const value3 = Obj5.getValue(values2, parts);
2394
+ Obj5.setValue(object, parts, value3);
2395
+ }
2396
+ });
2397
+ }
2398
+ }, [
2399
+ object
2400
+ ]);
2401
+ if (!formSchema) {
2402
+ return null;
2403
+ }
2404
+ return /* @__PURE__ */ React19.createElement(Form.Root, {
2405
+ schema: formSchema,
2406
+ defaultValues: values,
2407
+ createTypename: Type3.getTypename(Tag3.Tag),
2408
+ createOptionIcon: "ph--plus--regular",
2409
+ createOptionLabel: [
2410
+ "add-tag.label",
2411
+ {
2412
+ ns: translationKey11
2413
+ }
2414
+ ],
2415
+ createInitialValuePath: "label",
2416
+ createFieldMap: createFieldMap2,
2417
+ db,
2418
+ onValuesChanged: handleChange,
2419
+ onCreate: handleCreate
2420
+ }, /* @__PURE__ */ React19.createElement(Form.Viewport, {
2421
+ ...composableProps2(props),
2422
+ ref: forwardedRef
2423
+ }, /* @__PURE__ */ React19.createElement(Form.Content, null, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), children)));
2424
+ });
2425
+ var createFieldMap2 = {
2426
+ hue: ({ type, label, layout, getValue, onValueChange }) => {
2427
+ const handleChange = useCallback16((nextHue) => onValueChange(type, nextHue), [
2428
+ onValueChange,
2429
+ type
2430
+ ]);
2431
+ const handleReset = useCallback16(() => onValueChange(type, void 0), [
2432
+ onValueChange,
2433
+ type
2434
+ ]);
2435
+ return /* @__PURE__ */ React19.createElement(React19.Fragment, null, layout !== "inline" && /* @__PURE__ */ React19.createElement(Form.Label, {
2436
+ label
2437
+ }), /* @__PURE__ */ React19.createElement(HuePicker3, {
2438
+ value: getValue(),
2439
+ onChange: handleChange,
2440
+ onReset: handleReset
2441
+ }));
2442
+ }
2443
+ };
2444
+ var BaseSchema = Schema4.Struct({
2445
+ tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
2446
+ });
2447
+
2448
+ // src/components/Settings/Settings.tsx
2449
+ import React22 from "react";
2450
+ import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
2451
+ import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
2452
+ import { translationKey as translationKey13 } from "#translations";
2453
+
2454
+ // src/components/Settings/SettingsFieldSet.tsx
2455
+ import * as SchemaAST5 from "effect/SchemaAST";
2456
+ import * as String3 from "effect/String";
2457
+ import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
2458
+ import { getAnnotation as getAnnotation3 } from "@dxos/effect";
2459
+ import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
2460
+
2461
+ // src/components/Settings/SettingsItem.tsx
2462
+ import React20 from "react";
2463
+ import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
2464
+ import { mx as mx3 } from "@dxos/ui-theme";
2465
+ import { translationKey as translationKey12 } from "#translations";
2466
+ var SETTINGS_PANEL_NAME = "Settings.Panel";
2467
+ var SETTINGS_ITEM_NAME = "Settings.Item";
2468
+ var SettingsPanel = ({ classNames, children }) => {
2469
+ return /* @__PURE__ */ React20.createElement("div", {
2470
+ className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
2471
+ }, children);
2472
+ };
2473
+ SettingsPanel.displayName = SETTINGS_PANEL_NAME;
2474
+ var SettingsItem = ({ title, description = "", children }) => {
2475
+ const { t } = useTranslation10(translationKey12);
2476
+ return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
2477
+ classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
2478
+ }, /* @__PURE__ */ React20.createElement(Input12.Label, {
2479
+ classNames: "pb-trim-md text-base-foreground text-lg md:col-span-2"
2480
+ }, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
2481
+ classNames: "text-base text-description"
2482
+ }, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
2483
+ className: "text-end py-1"
2484
+ }, children)));
2485
+ };
2486
+ SettingsItem.displayName = SETTINGS_ITEM_NAME;
2487
+
2488
+ // src/components/Settings/SettingsFieldSet.tsx
2489
+ var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
2490
+ const properties = useMemo11(() => {
2491
+ const props = getFormProperties(schema.ast);
2492
+ if (!sort) {
2493
+ return props;
2494
+ }
2495
+ const rank = (name) => {
2496
+ const idx = sort.indexOf(name);
2497
+ return idx === -1 ? Number.POSITIVE_INFINITY : idx;
2498
+ };
2499
+ return [
2500
+ ...props
2501
+ ].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
2502
+ }, [
2503
+ schema,
2504
+ sort
2505
+ ]);
2506
+ const handleChange = useCallback17((name, value3) => {
2507
+ onValuesChanged?.({
2508
+ ...values,
2509
+ [name]: value3
2510
+ });
2511
+ }, [
2512
+ values,
2513
+ onValuesChanged
2514
+ ]);
2515
+ return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
2516
+ const name = property.name.toString();
2517
+ const path = pathPrefix ? `${pathPrefix}.${name}` : name;
2518
+ if (visible && !visible(path, values)) {
2519
+ return null;
2520
+ }
2521
+ const entry = fieldMap?.[name];
2522
+ return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
2523
+ key: name,
2524
+ path,
2525
+ property,
2526
+ value: values[name],
2527
+ onChange: (value3) => handleChange(name, value3),
2528
+ readonly,
2529
+ customField: typeof entry === "function" ? entry : void 0,
2530
+ nestedFieldMap: typeof entry === "object" ? entry : void 0,
2531
+ visible,
2532
+ sort
2533
+ });
2534
+ }));
2535
+ };
2536
+ SettingsFieldSet.displayName = "Settings.FieldSet";
2537
+ var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
2538
+ const { type } = property;
2539
+ const name = property.name.toString();
2540
+ const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
2541
+ const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
2542
+ if (customField) {
2543
+ const CustomField = customField;
2544
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2545
+ title,
2546
+ description
2547
+ }, /* @__PURE__ */ React21.createElement(CustomField, {
2548
+ value: value3,
2549
+ onChange,
2550
+ readonly
2551
+ }));
2552
+ }
2553
+ const fieldType = detectFieldType(type);
2554
+ switch (fieldType) {
2555
+ case "struct":
2556
+ return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
2557
+ schema: {
2558
+ ast: type
2559
+ },
2560
+ values: value3 ?? {},
2561
+ onValuesChanged: onChange,
2562
+ readonly,
2563
+ fieldMap: nestedFieldMap,
2564
+ visible,
2565
+ sort,
2566
+ pathPrefix: path
2567
+ });
2568
+ case "boolean":
2569
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2570
+ title,
2571
+ description
2572
+ }, /* @__PURE__ */ React21.createElement(Input13.Switch, {
2573
+ disabled: readonly,
2574
+ checked: !!value3,
2575
+ onCheckedChange: (checked) => onChange(!!checked)
2576
+ }));
2577
+ case "select": {
2578
+ const options = getSelectOptionsFromAst(type) ?? [];
2579
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2580
+ title,
2581
+ description
2582
+ }, /* @__PURE__ */ React21.createElement(Select2.Root, {
2583
+ disabled: readonly,
2584
+ value: value3 == null ? "" : globalThis.String(value3),
2585
+ onValueChange: (selected) => {
2586
+ const matched = options.find((option) => globalThis.String(option.value) === selected);
2587
+ onChange(matched?.value ?? selected);
2588
+ }
2589
+ }, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
2590
+ disabled: readonly
2591
+ }), /* @__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, {
2592
+ key: globalThis.String(option.value),
2593
+ value: globalThis.String(option.value)
2594
+ }, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
2595
+ }
2596
+ case "string":
2597
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2598
+ title,
2599
+ description
2600
+ }, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
2601
+ disabled: readonly,
2602
+ value: value3 ?? "",
2603
+ onChange: (event) => onChange(event.target.value)
2604
+ }));
2605
+ case "number":
2606
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2607
+ title,
2608
+ description
2609
+ }, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
2610
+ disabled: readonly,
2611
+ type: "number",
2612
+ value: value3 ?? "",
2613
+ onChange: (event) => {
2614
+ if (event.target.value === "") {
2615
+ onChange(void 0);
2616
+ return;
2617
+ }
2618
+ const parsed = Number(event.target.value);
2619
+ onChange(Number.isNaN(parsed) ? void 0 : parsed);
2620
+ }
2621
+ }));
2622
+ default:
2623
+ return null;
2624
+ }
2625
+ };
2626
+
2167
2627
  // src/components/Settings/Settings.tsx
2168
- import React18 from "react";
2169
- import { Input as Input12, ScrollArea as ScrollArea2, toLocalizedString, useTranslation as useTranslation9 } from "@dxos/react-ui";
2170
- import { composable as composable2, composableProps as composableProps2, mx as mx4 } from "@dxos/ui-theme";
2171
2628
  var SETTINGS_ROOT_NAME = "Settings.Root";
2172
2629
  var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
2173
2630
  var SETTINGS_SECTION_NAME = "Settings.Section";
2174
- var SETTINGS_PANEL_NAME = "Settings.Panel";
2175
- var SETTINGS_ITEM_NAME = "Settings.Item";
2176
2631
  var SettingsRoot = ({ children, classNames }) => {
2177
- return /* @__PURE__ */ React18.createElement("div", {
2632
+ return /* @__PURE__ */ React22.createElement("div", {
2178
2633
  className: mx4("flex flex-col gap-2", classNames)
2179
2634
  }, children);
2180
2635
  };
2181
2636
  SettingsRoot.displayName = SETTINGS_ROOT_NAME;
2182
- var SettingsViewport = composable2(({ children, ...props }, forwardedRef) => {
2183
- return /* @__PURE__ */ React18.createElement(ScrollArea2.Root, {
2184
- ...composableProps2(props),
2637
+ var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
2638
+ return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
2639
+ ...composableProps3(props),
2185
2640
  orientation: "vertical",
2186
2641
  centered: true,
2187
2642
  thin: true,
2188
2643
  ref: forwardedRef
2189
- }, /* @__PURE__ */ React18.createElement(ScrollArea2.Viewport, {
2644
+ }, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
2190
2645
  classNames: "px-4 pointer-coarse:px-2"
2191
- }, /* @__PURE__ */ React18.createElement("div", {
2192
- role: "none",
2646
+ }, /* @__PURE__ */ React22.createElement("div", {
2193
2647
  className: "dx-document flex flex-col gap-2 py-4"
2194
2648
  }, children)));
2195
2649
  });
2196
2650
  SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
2197
2651
  var SettingsSection = ({ title, description, children }) => {
2198
- const { t } = useTranslation9(translationKey);
2199
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("h2", {
2652
+ const { t } = useTranslation11(translationKey13);
2653
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
2200
2654
  className: "px-trim-md mt-trim-md text-xl"
2201
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
2655
+ }, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
2202
2656
  className: "px-trim-md text-description"
2203
- }, toLocalizedString(description, t)), /* @__PURE__ */ React18.createElement("div", {
2657
+ }, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
2204
2658
  className: "w-full pt-trim-md space-y-trim-md"
2205
2659
  }, children));
2206
2660
  };
2207
2661
  SettingsSection.displayName = SETTINGS_SECTION_NAME;
2208
- var SettingsPanel = ({ classNames, children }) => {
2209
- return /* @__PURE__ */ React18.createElement("div", {
2210
- role: "none",
2211
- className: mx4("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
2212
- }, children);
2213
- };
2214
- SettingsPanel.displayName = SETTINGS_PANEL_NAME;
2215
- var SettingsItem = ({ title, description = "", children }) => {
2216
- const { t } = useTranslation9(translationKey);
2217
- return /* @__PURE__ */ React18.createElement(Input12.Root, null, /* @__PURE__ */ React18.createElement(SettingsPanel, {
2218
- classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
2219
- }, /* @__PURE__ */ React18.createElement(Input12.Label, {
2220
- classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
2221
- }, toLocalizedString(title, t)), /* @__PURE__ */ React18.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React18.createElement(Input12.Description, {
2222
- classNames: "text-base text-description"
2223
- }, toLocalizedString(description, t))), /* @__PURE__ */ React18.createElement("div", {
2224
- role: "none",
2225
- className: "text-end py-1"
2226
- }, children)));
2227
- };
2228
- SettingsItem.displayName = SETTINGS_ITEM_NAME;
2229
2662
  var Settings = {
2230
2663
  Root: SettingsRoot,
2231
2664
  Viewport: SettingsViewport,
2232
2665
  Section: SettingsSection,
2233
2666
  Panel: SettingsPanel,
2234
- Item: SettingsItem
2667
+ Item: SettingsItem,
2668
+ FieldSet: SettingsFieldSet
2669
+ };
2670
+
2671
+ // src/components/Settings/SettingsSelectField.tsx
2672
+ import React23 from "react";
2673
+ import { Select as Select3 } from "@dxos/react-ui";
2674
+ var createSelectField = ({ options, defaultLabel = "Default" }) => {
2675
+ const normalized = options.map((option) => typeof option === "string" ? {
2676
+ value: option,
2677
+ label: option
2678
+ } : option);
2679
+ const hasDefault = defaultLabel !== null;
2680
+ const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
2681
+ return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
2682
+ disabled: readonly,
2683
+ value: value3 ?? sentinel,
2684
+ onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
2685
+ }, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
2686
+ disabled: readonly
2687
+ }), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
2688
+ value: sentinel
2689
+ }, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
2690
+ key: option.value,
2691
+ value: option.value
2692
+ }, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
2235
2693
  };
2236
2694
 
2237
2695
  // src/components/ViewEditor/ViewEditor.tsx
2238
2696
  import { RegistryContext } from "@effect-atom/atom-react";
2239
- import * as Array2 from "effect/Array";
2697
+ import * as Array4 from "effect/Array";
2240
2698
  import * as Match2 from "effect/Match";
2241
- import * as Option4 from "effect/Option";
2242
- import * as Schema3 from "effect/Schema";
2243
- import React19, { forwardRef as forwardRef2, useCallback as useCallback15, useContext, useImperativeHandle, useMemo as useMemo8, useState as useState6 } from "react";
2244
- import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj3, Query, QueryAST, Ref as Ref3 } from "@dxos/echo";
2245
- import { View } from "@dxos/echo";
2699
+ import * as Option6 from "effect/Option";
2700
+ import * as Schema5 from "effect/Schema";
2701
+ import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
2702
+ import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6, View } from "@dxos/echo";
2246
2703
  import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
2247
- import { invariant } from "@dxos/invariant";
2704
+ import { invariant as invariant3 } from "@dxos/invariant";
2248
2705
  import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
2249
- import { IconButton as IconButton4, Input as Input13, Message, useTranslation as useTranslation10 } from "@dxos/react-ui";
2706
+ import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
2250
2707
  import { QueryForm } from "@dxos/react-ui-components";
2251
2708
  import { List as List2 } from "@dxos/react-ui-list";
2252
2709
  import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
2253
- import { mx as mx5, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
2254
- var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2710
+ import { mx as mx5, osTranslations as osTranslations2 } from "@dxos/ui-theme";
2711
+ import { translationKey as translationKey14 } from "#translations";
2712
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2255
2713
  var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
2256
2714
  const atomRegistry = useContext(RegistryContext);
2257
2715
  const schemaReadonly = !isMutable(schema);
2258
- const { t } = useTranslation10(translationKey);
2259
- const projectionModel = useMemo8(() => {
2716
+ const { t } = useTranslation12(translationKey14);
2717
+ const projectionModel = useMemo12(() => {
2260
2718
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2261
2719
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2262
2720
  const model = new ProjectionModel({
@@ -2280,21 +2738,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2280
2738
  if (from._tag !== "scope") {
2281
2739
  return void 0;
2282
2740
  }
2283
- return Option4.fromNullable(from.scope.queues).pipe(Option4.flatMap((queues) => Array2.head(queues)), Option4.map(String), Option4.getOrUndefined);
2741
+ return Option6.fromNullable(from.scope.feeds).pipe(Option6.flatMap((feeds2) => Array4.head(feeds2)), Option6.map(String), Option6.getOrUndefined);
2284
2742
  }), Match2.orElse(() => void 0));
2285
2743
  const feeds = useQuery2(db, Filter2.type(Feed.Feed));
2286
- const targetRef = useMemo8(() => {
2744
+ const targetRef = useMemo12(() => {
2287
2745
  if (!queueTarget) {
2288
2746
  return void 0;
2289
2747
  }
2290
2748
  const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
2291
- return feed ? Ref3.fromDXN(Entity2.getDXN(feed)) : void 0;
2749
+ return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
2292
2750
  }, [
2293
2751
  queueTarget,
2294
2752
  feeds
2295
2753
  ]);
2296
- const viewSchema = useMemo8(() => {
2297
- const base = Schema3.Struct({
2754
+ const viewSchema = useMemo12(() => {
2755
+ const base = Schema5.Struct({
2298
2756
  query: mode === "schema" ? Format5.URL.annotations({
2299
2757
  title: "Record type"
2300
2758
  }) : QueryAST.Query.annotations({
@@ -2302,19 +2760,19 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2302
2760
  })
2303
2761
  });
2304
2762
  if (mode === "tag") {
2305
- return Schema3.Struct({
2763
+ return Schema5.Struct({
2306
2764
  ...base.fields,
2307
2765
  // TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
2308
- target: Ref3.Ref(Feed.Feed).pipe(Schema3.annotations({
2766
+ target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
2309
2767
  title: "Target Feed"
2310
- }), ParentLabelAnnotation.set(true), Schema3.optional)
2311
- }).pipe(Schema3.mutable);
2768
+ }), ParentLabelAnnotation.set(true), Schema5.optional)
2769
+ }).pipe(Schema5.mutable);
2312
2770
  }
2313
- return base.pipe(Schema3.mutable);
2771
+ return base.pipe(Schema5.mutable);
2314
2772
  }, [
2315
2773
  mode
2316
2774
  ]);
2317
- const viewValues = useMemo8(() => ({
2775
+ const viewValues = useMemo12(() => ({
2318
2776
  query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2319
2777
  target: targetRef
2320
2778
  }), [
@@ -2322,7 +2780,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2322
2780
  view.query.ast,
2323
2781
  targetRef
2324
2782
  ]);
2325
- const fieldMap = useMemo8(() => mode === "tag" ? customFields({
2783
+ const fieldMap = useMemo12(() => mode === "tag" ? customFields({
2326
2784
  types,
2327
2785
  tags
2328
2786
  }) : void 0, [
@@ -2330,54 +2788,45 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2330
2788
  types,
2331
2789
  tags
2332
2790
  ]);
2333
- const handleUpdate = useCallback15((values) => {
2791
+ const handleUpdate = useCallback18((values) => {
2334
2792
  const targetValue = values.target;
2335
- let queueDxn;
2336
- if (Ref3.isRef(targetValue)) {
2337
- const feedDxn = targetValue.dxn.toString();
2338
- const feed = feeds.find((feed2) => Obj3.getDXN(feed2).toString() === feedDxn);
2793
+ let feedDXN;
2794
+ if (Ref6.isRef(targetValue)) {
2795
+ const targetDXN = targetValue.dxn.toString();
2796
+ const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === targetDXN);
2339
2797
  if (feed) {
2340
- queueDxn = Feed.getQueueDxn(feed)?.toString();
2798
+ feedDXN = Feed.getQueueDxn(feed)?.toString();
2341
2799
  }
2342
2800
  }
2343
2801
  const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
2344
- onQueryChanged?.(query, queueDxn);
2802
+ onQueryChanged?.(query, feedDXN);
2345
2803
  }, [
2346
2804
  onQueryChanged,
2347
2805
  mode,
2348
2806
  feeds
2349
2807
  ]);
2350
- const handleDelete = useCallback15((fieldId) => {
2351
- invariant(!readonly, void 0, {
2352
- F: __dxlog_file3,
2353
- L: 185,
2354
- S: void 0,
2355
- A: [
2356
- "!readonly",
2357
- ""
2358
- ]
2359
- });
2808
+ const handleDelete = useCallback18((fieldId) => {
2809
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 126, S: void 0, A: ["!readonly", ""] });
2360
2810
  onDelete?.(fieldId);
2361
2811
  }, [
2362
2812
  onDelete,
2363
2813
  readonly
2364
2814
  ]);
2365
- return /* @__PURE__ */ React19.createElement("div", {
2366
- role: "none",
2815
+ return /* @__PURE__ */ React24.createElement("div", {
2367
2816
  className: mx5(classNames)
2368
- }, schemaReadonly && !readonly && /* @__PURE__ */ React19.createElement(Message.Root, {
2817
+ }, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
2369
2818
  valence: "info",
2370
2819
  classNames: "my-form-padding"
2371
- }, /* @__PURE__ */ React19.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React19.createElement(Form.Root, {
2820
+ }, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
2372
2821
  schema: viewSchema,
2373
2822
  values: viewValues,
2374
2823
  fieldMap,
2375
2824
  db,
2376
2825
  onValuesChanged: handleUpdate
2377
- }, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), /* @__PURE__ */ React19.createElement(FormFieldLabel, {
2826
+ }, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2378
2827
  label: t("fields.label"),
2379
2828
  asChild: true
2380
- }), /* @__PURE__ */ React19.createElement(FieldList, {
2829
+ }), /* @__PURE__ */ React24.createElement(FieldList, {
2381
2830
  schema,
2382
2831
  view,
2383
2832
  registry,
@@ -2389,9 +2838,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
2389
2838
  var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
2390
2839
  const atomRegistry = useContext(RegistryContext);
2391
2840
  const schemaReadonly = !isMutable(schema);
2392
- const { t } = useTranslation10(translationKey);
2841
+ const { t } = useTranslation12(translationKey14);
2393
2842
  const [viewSnapshot] = useObject(view);
2394
- const projectionModel = useMemo8(() => {
2843
+ const projectionModel = useMemo12(() => {
2395
2844
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2396
2845
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2397
2846
  const model = new ProjectionModel({
@@ -2406,38 +2855,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2406
2855
  schema,
2407
2856
  view
2408
2857
  ]);
2409
- const [expandedField, setExpandedField] = useState6();
2410
- const handleAdd = useCallback15(() => {
2411
- invariant(!readonly, void 0, {
2412
- F: __dxlog_file3,
2413
- L: 250,
2414
- S: void 0,
2415
- A: [
2416
- "!readonly",
2417
- ""
2418
- ]
2419
- });
2858
+ const [expandedField, setExpandedField] = useState7();
2859
+ const handleAdd = useCallback18(() => {
2860
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 181, S: void 0, A: ["!readonly", ""] });
2420
2861
  const field = projectionModel.createFieldProjection();
2421
2862
  setExpandedField(field.id);
2422
2863
  }, [
2423
2864
  projectionModel,
2424
2865
  readonly
2425
2866
  ]);
2426
- const handleToggleField = useCallback15((field) => {
2867
+ const handleToggleField = useCallback18((field) => {
2427
2868
  setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2428
2869
  }, [
2429
2870
  readonly
2430
2871
  ]);
2431
- const handleDelete = useCallback15((fieldId) => {
2432
- invariant(!readonly, void 0, {
2433
- F: __dxlog_file3,
2434
- L: 264,
2435
- S: void 0,
2436
- A: [
2437
- "!readonly",
2438
- ""
2439
- ]
2440
- });
2872
+ const handleDelete = useCallback18((fieldId) => {
2873
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 194, S: void 0, A: ["!readonly", ""] });
2441
2874
  if (fieldId === expandedField) {
2442
2875
  setExpandedField(void 0);
2443
2876
  }
@@ -2447,36 +2880,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2447
2880
  onDelete,
2448
2881
  readonly
2449
2882
  ]);
2450
- const handleMove = useCallback15((fromIndex, toIndex) => {
2451
- invariant(!readonly, void 0, {
2452
- F: __dxlog_file3,
2453
- L: 276,
2454
- S: void 0,
2455
- A: [
2456
- "!readonly",
2457
- ""
2458
- ]
2459
- });
2460
- Obj3.change(view, (obj) => {
2883
+ const handleMove = useCallback18((fromIndex, toIndex) => {
2884
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 205, S: void 0, A: ["!readonly", ""] });
2885
+ Obj6.update(view, (view2) => {
2461
2886
  const fields = [
2462
- ...obj.projection.fields
2887
+ ...view2.projection.fields
2463
2888
  ];
2464
2889
  const [moved] = fields.splice(fromIndex, 1);
2465
2890
  fields.splice(toIndex, 0, moved);
2466
- obj.projection.fields = fields;
2891
+ view2.projection.fields = fields;
2467
2892
  });
2468
2893
  }, [
2469
2894
  view,
2470
2895
  readonly
2471
2896
  ]);
2472
- const handleClose = useCallback15(() => setExpandedField(void 0), []);
2473
- const handleHide = useCallback15((fieldId) => {
2897
+ const handleClose = useCallback18(() => setExpandedField(void 0), []);
2898
+ const handleHide = useCallback18((fieldId) => {
2474
2899
  setExpandedField(void 0);
2475
2900
  projectionModel.hideFieldProjection(fieldId);
2476
2901
  }, [
2477
2902
  projectionModel
2478
2903
  ]);
2479
- const handleShow = useCallback15((property) => {
2904
+ const handleShow = useCallback18((property) => {
2480
2905
  setExpandedField(void 0);
2481
2906
  projectionModel.showFieldProjection(property);
2482
2907
  }, [
@@ -2485,46 +2910,45 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2485
2910
  if (!viewSnapshot) {
2486
2911
  return null;
2487
2912
  }
2488
- return /* @__PURE__ */ React19.createElement(List2.Root, {
2913
+ return /* @__PURE__ */ React24.createElement(List2.Root, {
2489
2914
  items: viewSnapshot.projection.fields,
2490
- isItem: Schema3.is(View.FieldSchema),
2915
+ isItem: Schema5.is(View.FieldSchema),
2491
2916
  getId: (field) => field.id,
2492
2917
  onMove: readonly ? void 0 : handleMove,
2493
2918
  readonly
2494
- }, ({ items: fields }) => /* @__PURE__ */ React19.createElement(React19.Fragment, null, showHeading && /* @__PURE__ */ React19.createElement("h3", {
2919
+ }, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
2495
2920
  className: "text-sm"
2496
- }, t("field-path.label")), /* @__PURE__ */ React19.createElement("div", {
2921
+ }, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
2497
2922
  role: "list",
2498
2923
  className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
2499
2924
  }, fields?.map((field) => {
2500
2925
  const hidden = field.visible === false;
2501
- return /* @__PURE__ */ React19.createElement(List2.Item, {
2926
+ return /* @__PURE__ */ React24.createElement(List2.Item, {
2502
2927
  key: field.id,
2503
2928
  item: field,
2504
2929
  classNames: "grid grid-cols-subgrid col-span-5",
2505
2930
  "aria-expanded": expandedField === field.id
2506
- }, /* @__PURE__ */ React19.createElement("div", {
2507
- role: "none",
2508
- className: mx5(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
2509
- }, /* @__PURE__ */ React19.createElement(List2.ItemDragHandle, {
2931
+ }, /* @__PURE__ */ React24.createElement("div", {
2932
+ className: "grid grid-cols-subgrid col-span-5 rounded-xs cursor-pointer min-h-10 dx-hover"
2933
+ }, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
2510
2934
  disabled: readonly || schemaReadonly
2511
- }), /* @__PURE__ */ React19.createElement(List2.ItemTitle, {
2935
+ }), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
2512
2936
  classNames: hidden && "text-subdued",
2513
2937
  onClick: () => handleToggleField(field)
2514
- }, field.path), /* @__PURE__ */ React19.createElement(List2.ItemIconButton, {
2515
- label: t(hidden ? "show field label" : "hide field label"),
2938
+ }, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
2939
+ label: t(hidden ? "show-field.label" : "hide-field.label"),
2516
2940
  "data-testid": hidden ? "show-field-button" : "hide-field-button",
2517
2941
  icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2518
2942
  autoHide: false,
2519
2943
  disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
2520
2944
  onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2521
- }), !readonly && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(List2.ItemDeleteButton, {
2945
+ }), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
2522
2946
  label: t("delete-field.label"),
2523
2947
  autoHide: false,
2524
2948
  disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
2525
2949
  onClick: () => handleDelete(field.id),
2526
2950
  "data-testid": "field.delete"
2527
- }), /* @__PURE__ */ React19.createElement(List2.ItemIconButton, {
2951
+ }), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
2528
2952
  iconOnly: true,
2529
2953
  variant: "ghost",
2530
2954
  label: t("toggle-expand.label", {
@@ -2533,20 +2957,18 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2533
2957
  icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2534
2958
  onClick: () => handleToggleField(field),
2535
2959
  "data-testid": "field.toggle"
2536
- }))), expandedField === field.id && !readonly && /* @__PURE__ */ React19.createElement("div", {
2537
- role: "none",
2538
- className: "col-span-5 mt-1 mb-1 border border-separator rounded-md"
2539
- }, /* @__PURE__ */ React19.createElement(FieldEditor, {
2960
+ }))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
2961
+ className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
2962
+ }, /* @__PURE__ */ React24.createElement(FieldEditor, {
2540
2963
  readonly: readonly || schemaReadonly,
2541
2964
  registry,
2542
2965
  projection: projectionModel,
2543
2966
  field,
2544
2967
  onSave: handleClose
2545
2968
  })));
2546
- })), !readonly && !expandedField && /* @__PURE__ */ React19.createElement("div", {
2547
- role: "none",
2969
+ })), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
2548
2970
  className: "my-form-padding"
2549
- }, /* @__PURE__ */ React19.createElement(IconButton4, {
2971
+ }, /* @__PURE__ */ React24.createElement(IconButton4, {
2550
2972
  icon: "ph--plus--regular",
2551
2973
  label: t("add-property-button.label"),
2552
2974
  onClick: handleAdd,
@@ -2556,13 +2978,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2556
2978
  };
2557
2979
  var customFields = ({ types, tags }) => ({
2558
2980
  query: ({ type, readonly, label, getValue, onValueChange }) => {
2559
- const handleChange = useCallback15((query) => onValueChange(type, query.ast), [
2981
+ const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
2560
2982
  onValueChange
2561
2983
  ]);
2562
- return /* @__PURE__ */ React19.createElement(Input13.Root, null, /* @__PURE__ */ React19.createElement(FormFieldLabel, {
2984
+ return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2563
2985
  readonly,
2564
2986
  label
2565
- }), /* @__PURE__ */ React19.createElement(QueryForm, {
2987
+ }), /* @__PURE__ */ React24.createElement(QueryForm, {
2566
2988
  initialQuery: getValue(),
2567
2989
  types,
2568
2990
  tags,
@@ -2581,7 +3003,9 @@ export {
2581
3003
  GeoPointField,
2582
3004
  MarkdownField,
2583
3005
  NumberField,
3006
+ ObjectForm,
2584
3007
  ObjectPicker,
3008
+ ObjectProperties,
2585
3009
  RefField,
2586
3010
  SelectField,
2587
3011
  SelectOptionField,
@@ -2591,15 +3015,18 @@ export {
2591
3015
  TupleField,
2592
3016
  ViewEditor,
2593
3017
  cellClassesForFieldType,
3018
+ createSelectField,
3019
+ detectFieldType,
2594
3020
  formatForDisplay,
2595
3021
  formatForEditing,
2596
3022
  getDefaultValue,
2597
3023
  getFormProperties,
2598
3024
  getRefProps,
3025
+ getSelectOptionsFromAst,
3026
+ omitHiddenFormFields,
2599
3027
  omitId,
2600
3028
  parseValue,
2601
3029
  pathNotUniqueError,
2602
- translations,
2603
3030
  useFormContext,
2604
3031
  useFormFieldState,
2605
3032
  useFormHandler,