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