@dxos/react-ui-form 0.8.4-main.4a85c3132b → 0.8.4-main.4f23b4e393

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 (141) hide show
  1. package/dist/lib/browser/index.mjs +1020 -623
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/browser/translations.mjs +82 -0
  5. package/dist/lib/browser/translations.mjs.map +7 -0
  6. package/dist/lib/node-esm/index.mjs +1020 -623
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/lib/node-esm/translations.mjs +84 -0
  10. package/dist/lib/node-esm/translations.mjs.map +7 -0
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  12. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -61
  13. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/Form/Form.d.ts +40 -12
  15. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.stories.d.ts +76 -74
  17. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/FormField.d.ts +11 -5
  19. package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -7
  21. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/FormFieldSet.d.ts +5 -9
  24. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
  25. package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
  26. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
  27. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
  29. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
  30. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
  31. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
  32. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
  33. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
  34. package/dist/types/src/components/Form/fields/RefField.d.ts +15 -7
  35. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
  37. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
  39. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
  41. package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
  42. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
  43. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
  44. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
  45. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
  46. package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
  47. package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
  48. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +26 -4
  49. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  50. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
  51. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
  53. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
  54. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
  55. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
  56. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
  57. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
  58. package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
  59. package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
  60. package/dist/types/src/components/Settings/Settings.d.ts +28 -33
  61. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
  62. package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
  63. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
  64. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
  65. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  66. package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
  67. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  68. package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
  69. package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
  70. package/dist/types/src/components/Settings/index.d.ts +2 -0
  71. package/dist/types/src/components/Settings/index.d.ts.map +1 -1
  72. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +3 -4
  73. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  74. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +65 -63
  75. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  76. package/dist/types/src/components/index.d.ts +2 -0
  77. package/dist/types/src/components/index.d.ts.map +1 -1
  78. package/dist/types/src/components/testing.d.ts +4 -4
  79. package/dist/types/src/components/testing.d.ts.map +1 -1
  80. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
  81. package/dist/types/src/hooks/useKeyHandler.d.ts +2 -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 +1 -0
  95. package/dist/types/src/util/refs.d.ts.map +1 -1
  96. package/dist/types/tsconfig.tsbuildinfo +1 -1
  97. package/package.json +42 -40
  98. package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
  99. package/src/components/FieldEditor/FieldEditor.test.tsx +0 -1
  100. package/src/components/FieldEditor/FieldEditor.tsx +4 -3
  101. package/src/components/Form/AUDIT.md +17 -0
  102. package/src/components/Form/Form.stories.tsx +25 -38
  103. package/src/components/Form/Form.tsx +77 -48
  104. package/src/components/Form/FormField.tsx +27 -15
  105. package/src/components/Form/FormFieldComponent.tsx +6 -4
  106. package/src/components/Form/FormFieldSet.tsx +98 -77
  107. package/src/components/Form/fields/ArrayField.tsx +14 -8
  108. package/src/components/Form/fields/GeoPointField.tsx +8 -7
  109. package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
  110. package/src/components/Form/fields/MarkdownField.tsx +135 -45
  111. package/src/components/Form/fields/RefField.tsx +79 -39
  112. package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -6
  113. package/src/components/Form/fields/SelectOptionField.tsx +12 -12
  114. package/src/components/Form/fields/TextField.tsx +2 -2
  115. package/src/components/Form/fields/TupleField.tsx +1 -1
  116. package/src/components/ObjectForm/ObjectForm.tsx +114 -0
  117. package/src/components/ObjectForm/index.ts +5 -0
  118. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +11 -9
  119. package/src/components/ObjectPicker/ObjectPicker.tsx +92 -65
  120. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +362 -0
  121. package/src/components/ObjectProperties/ObjectProperties.test.tsx +101 -0
  122. package/src/components/ObjectProperties/ObjectProperties.tsx +141 -0
  123. package/src/components/ObjectProperties/index.ts +5 -0
  124. package/src/components/Settings/AUDIT.md +52 -0
  125. package/src/components/Settings/Settings.stories.tsx +69 -21
  126. package/src/components/Settings/Settings.tsx +33 -183
  127. package/src/components/Settings/SettingsFieldSet.tsx +257 -0
  128. package/src/components/Settings/SettingsItem.tsx +58 -0
  129. package/src/components/Settings/SettingsSelectField.tsx +59 -0
  130. package/src/components/Settings/index.ts +2 -0
  131. package/src/components/ViewEditor/ViewEditor.stories.tsx +14 -15
  132. package/src/components/ViewEditor/ViewEditor.test.tsx +0 -1
  133. package/src/components/ViewEditor/ViewEditor.tsx +40 -36
  134. package/src/components/index.ts +2 -0
  135. package/src/components/testing.tsx +19 -11
  136. package/src/hooks/useKeyHandler.tsx +7 -7
  137. package/src/index.ts +0 -4
  138. package/src/translations.ts +66 -63
  139. package/src/util/field-type.ts +60 -0
  140. package/src/util/index.ts +1 -0
  141. package/src/util/refs.ts +7 -3
@@ -1,87 +1,11 @@
1
- // src/translations.ts
2
- var translationKey = "@dxos/react-ui-form";
3
- var translations = [
4
- {
5
- "en-US": {
6
- [translationKey]: {
7
- "fields label": "Fields",
8
- "hidden fields label": "Hidden Fields",
9
- "empty readonly ref field label": "(none)",
10
- // TODO(burdon): Standardize field/property.
11
- "add property button label": "Add property",
12
- "field property label": "Property",
13
- "field property placeholder": "Property name",
14
- "field format label": "Type",
15
- "field path label": "Field path",
16
- "add field": "Add field",
17
- "delete field": "Delete field",
18
- "field limit reached": "Maximum number of fields reached",
19
- "boolean input true value": "Yes",
20
- "boolean input false value": "No",
21
- "show field label": "Show field",
22
- "hide field label": "Hide field",
23
- "delete field label": "Delete field",
24
- "ref field combobox input placeholder": "Search\u2026",
25
- "ref field placeholder_one": "Select\u2026",
26
- "ref field placeholder_other": "Select items\u2026",
27
- "example placeholder": "Example",
28
- "latitude placeholder": "Latitude (e.g., 40.7128)",
29
- "longitude placeholder": "Longitude (e.g., -74.0060)",
30
- "cancel button label": "Cancel",
31
- "save button label": "Save",
32
- // FormatEnum
33
- "format boolean": "Boolean",
34
- "format currency": "Currency",
35
- "format date": "Date",
36
- "format date-time": "DateTime",
37
- "format did": "DID",
38
- "format duration": "Duration",
39
- "format dxn": "DXN",
40
- "format email": "Email",
41
- "format formula": "Formula",
42
- "format hostname": "Hostname",
43
- "format integer": "Integer",
44
- "format json": "JSON",
45
- "format lnglat": "Geopoint",
46
- "format markdown": "Markdown",
47
- "format percent": "Percent",
48
- "format ref": "Reference",
49
- "format regex": "RegExp",
50
- "format string": "String",
51
- "format single-select": "Select",
52
- "format multi-select": "Multi-select",
53
- "format text": "Long text",
54
- "format time": "Time",
55
- "format timestamp": "Timestamp",
56
- "format user": "User",
57
- "format number": "Number",
58
- "format uri": "URI",
59
- "format url": "URL",
60
- "format uuid": "UUID",
61
- // GeoPointField.
62
- "latitude label": "Latitude",
63
- "longitude label": "Longitude",
64
- // SelectOptionsField.
65
- "select option label": "Label",
66
- "select option label placeholder": "Option label",
67
- "select option color": "Color",
68
- "select option delete": "Delete",
69
- "select option add": "Add option",
70
- // System schema message.
71
- "system schema title": "System type",
72
- "system schema description": "System type: cannot add or remove fields."
73
- }
74
- }
75
- }
76
- ];
77
-
78
1
  // src/components/FieldEditor/FieldEditor.tsx
79
- import React17, { useCallback as useCallback14, useEffect as useEffect7, useMemo as useMemo7, useState as useState5 } from "react";
80
- import { Obj as Obj2 } from "@dxos/echo";
2
+ import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
3
+ import { Obj as Obj3 } from "@dxos/echo";
81
4
  import { Format as Format4, FormatEnums, formatToType } from "@dxos/echo/internal";
82
5
  import { log as log2 } from "@dxos/log";
83
- import { useAsyncEffect, useTranslation as useTranslation8 } from "@dxos/react-ui";
6
+ import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
84
7
  import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
8
+ import { translationKey as translationKey9 } from "#translations";
85
9
 
86
10
  // src/util/field.ts
87
11
  import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
@@ -204,6 +128,46 @@ var pathNotUniqueError = (path) => ({
204
128
  message: `'${path}' is already present`
205
129
  });
206
130
 
131
+ // src/util/field-type.ts
132
+ import * as SchemaAST from "effect/SchemaAST";
133
+ import { getAnnotation, isLiteralUnion } from "@dxos/effect";
134
+ var detectFieldType = (ast) => {
135
+ if (isLiteralUnion(ast)) {
136
+ return "select";
137
+ }
138
+ if (SchemaAST.isTypeLiteral(ast)) {
139
+ return "struct";
140
+ }
141
+ switch (ast._tag) {
142
+ case "BooleanKeyword":
143
+ return "boolean";
144
+ case "StringKeyword":
145
+ return "string";
146
+ case "NumberKeyword":
147
+ return "number";
148
+ }
149
+ return void 0;
150
+ };
151
+ var getSelectOptionsFromAst = (ast) => {
152
+ if (!isLiteralUnion(ast)) {
153
+ return void 0;
154
+ }
155
+ return ast.types.flatMap((literalNode) => {
156
+ const value3 = literalNode.literal;
157
+ if (typeof value3 !== "string" && typeof value3 !== "number") {
158
+ return [];
159
+ }
160
+ const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
161
+ const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
162
+ return [
163
+ {
164
+ value: value3,
165
+ label
166
+ }
167
+ ];
168
+ });
169
+ };
170
+
207
171
  // src/util/formatting.ts
208
172
  import { format as formatDate } from "date-fns/format";
209
173
  import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
@@ -352,43 +316,52 @@ var getFormProperties = (ast) => {
352
316
 
353
317
  // src/util/refs.ts
354
318
  import { Ref } from "@dxos/echo";
355
- import { getArrayElementType, isArrayType } from "@dxos/effect";
319
+ import { ReferenceAnnotationId } from "@dxos/echo/internal";
320
+ import { findAnnotation, getArrayElementType, isArrayType } from "@dxos/effect";
356
321
  var getRefProps = (ast) => {
357
322
  if (isArrayType(ast)) {
358
323
  const elementType = getArrayElementType(ast);
359
324
  if (elementType) {
360
325
  if (Ref.isRefType(elementType)) {
326
+ const typename = findAnnotation(elementType, ReferenceAnnotationId)?.typename;
361
327
  return {
362
328
  ast: elementType,
363
- isArray: true
329
+ isArray: true,
330
+ typename
364
331
  };
365
332
  }
366
333
  }
367
334
  }
368
335
  if (Ref.isRefType(ast)) {
336
+ const typename = findAnnotation(ast, ReferenceAnnotationId)?.typename;
369
337
  return {
370
338
  ast,
371
- isArray: false
339
+ isArray: false,
340
+ typename
372
341
  };
373
342
  }
374
343
  return void 0;
375
344
  };
376
345
 
377
346
  // src/components/Form/fields/ArrayField.tsx
378
- import * as Option3 from "effect/Option";
379
- import * as SchemaAST3 from "effect/SchemaAST";
347
+ import * as Option4 from "effect/Option";
348
+ import * as SchemaAST4 from "effect/SchemaAST";
380
349
  import React5, { useCallback as useCallback3 } from "react";
381
350
  import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
382
351
  import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
352
+ import { translationKey as translationKey3 } from "#translations";
383
353
 
384
354
  // src/components/Form/Form.tsx
385
355
  import { createContext } from "@radix-ui/react-context";
356
+ import * as Option3 from "effect/Option";
386
357
  import * as Schema2 from "effect/Schema";
387
- import * as SchemaAST2 from "effect/SchemaAST";
388
- import React4, { useEffect as useEffect3, useMemo as useMemo4, useRef } from "react";
358
+ import * as SchemaAST3 from "effect/SchemaAST";
359
+ import React4, { useEffect as useEffect2, useMemo as useMemo4, useRef } from "react";
360
+ import { Annotation as EchoAnnotation } from "@dxos/echo";
389
361
  import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
390
- import { IconButton, ScrollArea, useTranslation as useTranslation2 } from "@dxos/react-ui";
391
- import { mx as mx2 } from "@dxos/ui-theme";
362
+ import { IconButton, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
363
+ import { composable, composableProps, mx, withColumn } from "@dxos/ui-theme";
364
+ import { translationKey as translationKey2 } from "#translations";
392
365
 
393
366
  // src/hooks/useFormHandler.ts
394
367
  import { useControllableState } from "@radix-ui/react-use-controllable-state";
@@ -426,12 +399,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
426
399
  log("validate", {
427
400
  values: values2,
428
401
  errors: errors2
429
- }, {
430
- F: __dxlog_file,
431
- L: 155,
432
- S: void 0,
433
- C: (f, a) => f(...a)
434
- });
402
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
435
403
  if (errors2.length === 0 && onValidate) {
436
404
  const validatedValues = values2;
437
405
  errors2 = onValidate(validatedValues) ?? [];
@@ -519,12 +487,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
519
487
  log("onValueChange", {
520
488
  path,
521
489
  value: value3
522
- }, {
523
- F: __dxlog_file,
524
- L: 254,
525
- S: void 0,
526
- C: (f, a) => f(...a)
527
- });
490
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
528
491
  const jsonPath = createJsonPath(path);
529
492
  const pathArray = path;
530
493
  let parsedValue = value3;
@@ -533,12 +496,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
533
496
  parsedValue = parseFloat(value3) || 0;
534
497
  }
535
498
  } catch (err) {
536
- log.catch(err, void 0, {
537
- F: __dxlog_file,
538
- L: 264,
539
- S: void 0,
540
- C: (f, a) => f(...a)
541
- });
499
+ log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
542
500
  parsedValue = void 0;
543
501
  }
544
502
  const newValues = mergeAtPath(values, pathArray, parsedValue);
@@ -647,9 +605,9 @@ var flatMap = (errors) => {
647
605
  };
648
606
 
649
607
  // src/hooks/useKeyHandler.tsx
650
- import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
608
+ import { useCallback as useCallback2, useLayoutEffect } from "react";
651
609
  import { addEventListener } from "@dxos/async";
652
- var useKeyHandler = (formElement, form) => {
610
+ var useKeyHandler = (elRef, form) => {
653
611
  const handleKeyDown = useCallback2((event) => {
654
612
  switch (event.key) {
655
613
  case "Enter": {
@@ -665,13 +623,14 @@ var useKeyHandler = (formElement, form) => {
665
623
  form.onSave,
666
624
  form.autoSave
667
625
  ]);
668
- useEffect2(() => {
669
- if (!formElement) {
626
+ useLayoutEffect(() => {
627
+ const el = elRef.current;
628
+ if (!el) {
670
629
  return;
671
630
  }
672
- return addEventListener(formElement, "keydown", handleKeyDown);
631
+ return addEventListener(el, "keydown", handleKeyDown);
673
632
  }, [
674
- formElement,
633
+ elRef,
675
634
  handleKeyDown
676
635
  ]);
677
636
  };
@@ -683,7 +642,6 @@ import { inputTextLabel } from "@dxos/ui-theme";
683
642
  var FormFieldLabel = ({ label, error, readonly, asChild }) => {
684
643
  const Label = readonly || asChild ? "span" : Input.Label;
685
644
  return /* @__PURE__ */ React.createElement("div", {
686
- role: "none",
687
645
  className: "flex items-center justify-between"
688
646
  }, /* @__PURE__ */ React.createElement(Label, {
689
647
  className: inputTextLabel
@@ -707,7 +665,6 @@ var FormFieldWrapper = (props) => {
707
665
  }
708
666
  const str = String(value3 ?? "");
709
667
  return /* @__PURE__ */ React.createElement("div", {
710
- role: "none",
711
668
  className: "contents"
712
669
  }, /* @__PURE__ */ React.createElement(Input.Root, {
713
670
  validationValence: status
@@ -738,7 +695,7 @@ var FormFieldErrorBoundary = class extends Component {
738
695
  return /* @__PURE__ */ React.createElement("div", {
739
696
  className: "flex gap-2 border border-rose-fill font-mono text-sm"
740
697
  }, /* @__PURE__ */ React.createElement("span", {
741
- className: "bg-rose-fill text-surface-text px-1 font-thin"
698
+ className: "bg-rose-fill text-base-foreground px-1 font-thin"
742
699
  }, "ERROR"), String(this.props.path?.join(".")));
743
700
  }
744
701
  return this.props.children;
@@ -751,20 +708,19 @@ var FormFieldErrorBoundary = class extends Component {
751
708
  };
752
709
 
753
710
  // src/components/Form/FormFieldSet.tsx
754
- import React3, { forwardRef, useMemo as useMemo3 } from "react";
755
- import { mx } from "@dxos/ui-theme";
756
- import { isTruthy } from "@dxos/util";
711
+ import React3, { useMemo as useMemo3 } from "react";
757
712
 
758
713
  // src/components/Form/FormField.tsx
759
714
  import * as Match from "effect/Match";
760
715
  import * as Option2 from "effect/Option";
761
716
  import * as Schema from "effect/Schema";
762
- import * as SchemaAST from "effect/SchemaAST";
717
+ import * as SchemaAST2 from "effect/SchemaAST";
763
718
  import * as String2 from "effect/String";
764
719
  import React2, { useMemo as useMemo2 } from "react";
765
720
  import { Format as Format3 } from "@dxos/echo";
766
- 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";
767
722
  import { useTranslation } from "@dxos/react-ui";
723
+ import { translationKey } from "#translations";
768
724
  var FormField = (props) => {
769
725
  const {
770
726
  type,
@@ -776,23 +732,25 @@ var FormField = (props) => {
776
732
  readonly,
777
733
  layout,
778
734
  // RefFieldProps
735
+ createTypename,
779
736
  createOptionLabel,
780
737
  createOptionIcon,
781
738
  createInitialValuePath,
739
+ createFieldMap: createFieldMap3,
782
740
  db,
783
- schemaHook,
784
- getOptions: getRefOptions,
741
+ useSchema: schemaHook,
742
+ getOptions,
785
743
  onCreate
786
744
  } = props;
787
745
  const { t } = useTranslation(translationKey);
788
- const title = getAnnotation(SchemaAST.TitleAnnotationId)(type);
789
- const description = getAnnotation(SchemaAST.DescriptionAnnotationId)(type);
790
- 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);
791
749
  const label = useMemo2(() => title ?? String2.capitalize(name), [
792
750
  title,
793
751
  name
794
752
  ]);
795
- const placeholder = useMemo2(() => examples?.length ? `${t("example placeholder")}: ${examples[0]}` : description ?? label, [
753
+ const placeholder = useMemo2(() => examples?.length ? `${t("example.placeholder")}: ${examples[0]}` : description ?? label, [
796
754
  examples,
797
755
  description,
798
756
  label
@@ -805,6 +763,7 @@ var FormField = (props) => {
805
763
  label,
806
764
  placeholder,
807
765
  layout,
766
+ db,
808
767
  ...fieldState
809
768
  };
810
769
  const jsonPath = createJsonPath2(path ?? []);
@@ -831,7 +790,7 @@ var FormField = (props) => {
831
790
  if (Field) {
832
791
  return /* @__PURE__ */ React2.createElement(Field, fieldProps);
833
792
  }
834
- const options = getOptions(type);
793
+ const options = getSelectOptions(type);
835
794
  if (options) {
836
795
  const fieldProjections = projection?.getFieldProjections();
837
796
  const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
@@ -849,21 +808,23 @@ var FormField = (props) => {
849
808
  }
850
809
  const refProps = getRefProps(type);
851
810
  if (refProps) {
811
+ const isCreateTarget = !createTypename || refProps.typename === createTypename;
852
812
  return /* @__PURE__ */ React2.createElement(RefField, {
853
813
  ...fieldProps,
854
814
  ...refProps,
855
- createOptionLabel,
856
- createOptionIcon,
857
- createInitialValuePath,
815
+ createOptionLabel: isCreateTarget ? createOptionLabel : void 0,
816
+ createOptionIcon: isCreateTarget ? createOptionIcon : void 0,
817
+ createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
818
+ createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
858
819
  db,
859
- schemaHook,
860
- getOptions: getRefOptions,
820
+ useSchema: schemaHook,
821
+ getOptions,
861
822
  onCreate
862
823
  });
863
824
  }
864
825
  if (isNestedType(type)) {
865
826
  const baseNode = findNode(type, isDiscriminatedUnion);
866
- const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST.isTypeLiteral);
827
+ const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
867
828
  if (typeLiteral) {
868
829
  const schema = Schema.make(typeLiteral);
869
830
  return /* @__PURE__ */ React2.createElement(FormFieldSet, {
@@ -879,8 +840,8 @@ var FormField = (props) => {
879
840
  createOptionIcon,
880
841
  createInitialValuePath,
881
842
  db,
882
- schemaHook,
883
- getOptions: getRefOptions,
843
+ useSchema: schemaHook,
844
+ getOptions,
884
845
  onCreate
885
846
  });
886
847
  }
@@ -904,8 +865,8 @@ var getFormField = ({ type, format }) => {
904
865
  return BooleanField;
905
866
  }
906
867
  };
907
- var getOptions = (ast) => {
908
- if (isLiteralUnion(ast)) {
868
+ var getSelectOptions = (ast) => {
869
+ if (isLiteralUnion2(ast)) {
909
870
  return ast.types.map((type) => type.literal).filter((v) => v !== null);
910
871
  }
911
872
  return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
@@ -913,47 +874,19 @@ var getOptions = (ast) => {
913
874
 
914
875
  // src/components/Form/FormFieldSet.tsx
915
876
  var FORM_FIELDSET_NAME = "Form.FieldSet";
916
- var FormFieldSet = /* @__PURE__ */ forwardRef(({ label, schema, readonly, path, exclude, sort, projection, layout, ...props }, forwardRef4) => {
877
+ var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
917
878
  const values = useFormValues(FORM_FIELDSET_NAME, path);
918
- const properties = useMemo3(() => {
919
- if (!schema) {
920
- return [];
921
- }
922
- const props2 = getFormProperties(schema.ast);
923
- if (projection) {
924
- const fieldProjections = projection.getFieldProjections();
925
- const hiddenProperties = new Set(projection.getHiddenProperties());
926
- const visibleProps = props2.filter((prop) => !hiddenProperties.has(prop.name.toString()));
927
- const orderedProps = [];
928
- for (const fieldProjection of fieldProjections) {
929
- const fieldPath = String(fieldProjection.field.path);
930
- const prop = visibleProps.find((p) => p.name === fieldPath);
931
- if (prop) {
932
- orderedProps.push(prop);
933
- }
934
- }
935
- const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
936
- const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
937
- orderedProps.push(...remainingProps);
938
- return orderedProps;
939
- }
940
- const filtered = exclude ? exclude(props2) : props2;
941
- return sort ? filtered.sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filtered;
942
- }, [
879
+ const properties = useFormFieldSetProperties({
943
880
  schema,
944
881
  values,
945
882
  exclude,
946
883
  sort,
947
- projection?.fields
948
- ]);
884
+ projection
885
+ });
949
886
  if ((readonly || layout === "static") && values == null) {
950
887
  return null;
951
888
  }
952
- return /* @__PURE__ */ React3.createElement("div", {
953
- role: "form",
954
- className: mx("w-full", layout === "inline" && "flex flex-col gap-2"),
955
- ref: forwardRef4
956
- }, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
889
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
957
890
  label,
958
891
  asChild: true
959
892
  }), properties.map((property) => {
@@ -976,12 +909,52 @@ var FormFieldSet = /* @__PURE__ */ forwardRef(({ label, schema, readonly, path,
976
909
  projection,
977
910
  ...props
978
911
  }));
979
- }).filter(isTruthy));
980
- });
912
+ }));
913
+ };
981
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
+ };
982
950
 
983
951
  // src/components/Form/Form.tsx
984
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
+ };
985
958
  var [FormContextProvider, useFormContext] = createContext("Form");
986
959
  var useFormValues = (componentName, path, defaultValue) => {
987
960
  const stablePath = useMemo4(() => path ?? [], [
@@ -991,10 +964,10 @@ var useFormValues = (componentName, path, defaultValue) => {
991
964
  const { form: { values, onValueChange } } = useFormContext(componentName);
992
965
  const value3 = getValue$2(values, jsonPath);
993
966
  const lastAppliedPathRef = useRef(null);
994
- useEffect3(() => {
967
+ useEffect2(() => {
995
968
  if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
996
969
  lastAppliedPathRef.current = jsonPath;
997
- onValueChange(stablePath, SchemaAST2.stringKeyword, defaultValue());
970
+ onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
998
971
  }
999
972
  }, [
1000
973
  value3,
@@ -1038,29 +1011,35 @@ var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
1038
1011
  };
1039
1012
  FormRoot.displayName = "Form.Root";
1040
1013
  var FORM_VIEWPORT_NAME = "Form.Viewport";
1041
- var FormViewport = ({ children, classNames, margin = true, padding = true, thin = true, ...props }) => {
1014
+ var FormViewport = composable(({ children, ...props }, forwardedRef) => {
1042
1015
  return /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
1016
+ ...composableProps(props),
1043
1017
  orientation: "vertical",
1044
- classNames,
1045
- margin,
1046
- padding,
1047
- thin,
1048
- ...props
1018
+ centered: true,
1019
+ padding: true,
1020
+ thin: true,
1021
+ ref: forwardedRef
1049
1022
  }, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, children));
1050
- };
1023
+ });
1051
1024
  FormViewport.displayName = FORM_VIEWPORT_NAME;
1052
1025
  var FORM_CONTENT_NAME = "Form.Content";
1053
- var FormContent = ({ classNames, children }) => {
1026
+ var FormContent = composable(({ children, ...props }, forwardedRef) => {
1054
1027
  const { form, testId } = useFormContext(FORM_CONTENT_NAME);
1055
- const ref = useRef(null);
1056
- useKeyHandler(ref.current, form);
1028
+ const localRef = useRef(null);
1029
+ const mergedRef = useMergeRefs([
1030
+ forwardedRef,
1031
+ localRef
1032
+ ]);
1033
+ useKeyHandler(localRef, form);
1057
1034
  return /* @__PURE__ */ React4.createElement("div", {
1058
- ref,
1059
- role: "form",
1060
- className: mx2("w-full flex flex-col gap-form-padding", classNames),
1061
- "data-testid": testId
1035
+ ...composableProps(props, {
1036
+ role: "form",
1037
+ classNames: mx(withColumn.center(), "flex flex-col w-full pb-form-gap")
1038
+ }),
1039
+ "data-testid": testId,
1040
+ ref: mergedRef
1062
1041
  }, children);
1063
- };
1042
+ });
1064
1043
  FormContent.displayName = FORM_CONTENT_NAME;
1065
1044
  var FORM_FIELDSET_NAME2 = "Form.FieldSet";
1066
1045
  var FormFieldSet2 = (props) => {
@@ -1074,18 +1053,17 @@ var FormFieldSet2 = (props) => {
1074
1053
  FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
1075
1054
  var FORM_ACTIONS_NAME = "Form.Actions";
1076
1055
  var FormActions = ({ classNames }) => {
1077
- const { t } = useTranslation2(translationKey);
1056
+ const { t } = useTranslation2(translationKey2);
1078
1057
  const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
1079
1058
  if (readonly || layout === "static") {
1080
1059
  return null;
1081
1060
  }
1082
1061
  return /* @__PURE__ */ React4.createElement("div", {
1083
- role: "none",
1084
- className: mx2("grid grid-flow-col gap-2 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)
1085
1063
  }, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
1086
1064
  icon: "ph--x--regular",
1087
1065
  iconEnd: true,
1088
- label: t("cancel button label"),
1066
+ label: t("cancel-button.label"),
1089
1067
  onClick: onCancel,
1090
1068
  "data-testid": "cancel-button"
1091
1069
  }), onSave && /* @__PURE__ */ React4.createElement(IconButton, {
@@ -1094,29 +1072,42 @@ var FormActions = ({ classNames }) => {
1094
1072
  disabled: !canSave,
1095
1073
  icon: "ph--check--regular",
1096
1074
  iconEnd: true,
1097
- label: t("save button label"),
1075
+ label: t("save-button.label"),
1098
1076
  onClick: onSave,
1099
1077
  "data-testid": "save-button"
1100
1078
  }));
1101
1079
  };
1102
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;
1103
1095
  var FORM_SUBMIT_NAME = "Form.Submit";
1104
1096
  var FormSubmit = ({ classNames, label, icon, disabled }) => {
1105
- const { t } = useTranslation2(translationKey);
1097
+ const { t } = useTranslation2(translationKey2);
1106
1098
  const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
1107
1099
  if (readonly || layout === "static") {
1108
1100
  return null;
1109
1101
  }
1110
1102
  return /* @__PURE__ */ React4.createElement("div", {
1111
- role: "none",
1112
- className: mx2("flex w-full pt-form-padding", classNames)
1103
+ className: mx("flex w-full pt-form-padding", classNames)
1113
1104
  }, /* @__PURE__ */ React4.createElement(IconButton, {
1114
1105
  classNames: "w-full",
1115
1106
  type: "submit",
1116
1107
  variant: "primary",
1117
1108
  disabled: disabled ?? !canSave,
1118
1109
  icon: icon ?? "ph--check--regular",
1119
- label: label ?? t("save button label"),
1110
+ label: label ?? t("save-button.label"),
1120
1111
  onClick: onSave,
1121
1112
  "data-testid": "save-button"
1122
1113
  }));
@@ -1126,6 +1117,7 @@ var Form = {
1126
1117
  Root: FormRoot,
1127
1118
  Viewport: FormViewport,
1128
1119
  Content: FormContent,
1120
+ Section: FormSection,
1129
1121
  FieldSet: FormFieldSet2,
1130
1122
  Label: FormFieldLabel,
1131
1123
  Actions: FormActions,
@@ -1134,18 +1126,18 @@ var Form = {
1134
1126
 
1135
1127
  // src/components/Form/fields/ArrayField.tsx
1136
1128
  var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
1137
- const { t } = useTranslation3(translationKey);
1129
+ const { t } = useTranslation3(translationKey3);
1138
1130
  const elementType = getArrayElementType2(type);
1139
1131
  const { onValueChange } = inputProps;
1140
1132
  const values = useFormValues(ArrayField.displayName, path, () => []);
1141
1133
  const getDefaultObjectValue = (typeNode) => {
1142
1134
  const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
1143
- const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST3.isTypeLiteral);
1135
+ const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
1144
1136
  if (!typeLiteral) {
1145
1137
  return {};
1146
1138
  }
1147
1139
  return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
1148
- const defaultValue = SchemaAST3.getDefaultAnnotation(prop.type).pipe((annotation) => Option3.getOrUndefined(annotation));
1140
+ const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
1149
1141
  return [
1150
1142
  prop.name,
1151
1143
  defaultValue
@@ -1179,13 +1171,11 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1179
1171
  label,
1180
1172
  asChild: true
1181
1173
  }), /* @__PURE__ */ React5.createElement("div", {
1182
- role: "none",
1183
- className: "flex flex-col gap-2"
1174
+ className: "flex flex-col gap-form-gap"
1184
1175
  }, values?.map((_, index) => {
1185
1176
  return /* @__PURE__ */ React5.createElement("div", {
1186
- role: "none",
1187
1177
  key: index,
1188
- className: "grid grid-cols-[1fr_min-content] gap-2 last:mb-3"
1178
+ className: "grid grid-cols-[1fr_min-content] gap-form-gap last:mb-form-gap items-center"
1189
1179
  }, /* @__PURE__ */ React5.createElement(FormField, {
1190
1180
  autoFocus: index === values.length - 1,
1191
1181
  type: elementType,
@@ -1197,22 +1187,20 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1197
1187
  layout: "inline",
1198
1188
  ...props
1199
1189
  }), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement("div", {
1200
- role: "none",
1201
1190
  className: "flex flex-col h-full justify-end"
1202
1191
  }, /* @__PURE__ */ React5.createElement("div", {
1203
- role: "none",
1204
1192
  className: "flex items-center h-[2rem]"
1205
1193
  }, /* @__PURE__ */ React5.createElement(IconButton2, {
1206
1194
  icon: "ph--x--regular",
1207
1195
  iconOnly: true,
1208
- label: t("button remove"),
1196
+ label: t("remove.button"),
1209
1197
  onClick: () => handleDelete(index),
1210
1198
  classNames: "self-center"
1211
1199
  }))));
1212
1200
  })), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
1213
1201
  classNames: "flex w-full",
1214
1202
  icon: "ph--plus--regular",
1215
- label: t("add field"),
1203
+ label: t("add-item.button"),
1216
1204
  onClick: handleAdd
1217
1205
  }));
1218
1206
  };
@@ -1260,12 +1248,13 @@ var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
1260
1248
  };
1261
1249
 
1262
1250
  // src/components/Form/fields/GeoPointField.tsx
1263
- import React7, { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo5, useState as useState2 } from "react";
1251
+ import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo as useMemo5, useState as useState2 } from "react";
1264
1252
  import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
1265
1253
  import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
1266
1254
  import { safeParseFloat } from "@dxos/util";
1255
+ import { translationKey as translationKey4 } from "#translations";
1267
1256
  var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
1268
- const { t } = useTranslation4(translationKey);
1257
+ const { t } = useTranslation4(translationKey4);
1269
1258
  const { status, error } = getStatus();
1270
1259
  const geoPoint = useMemo5(() => getValue() ?? [
1271
1260
  0,
@@ -1278,7 +1267,7 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
1278
1267
  ]);
1279
1268
  const [longitudeText, setLongitudeText] = useState2(value3.longitude?.toString());
1280
1269
  const [latitudeText, setLatitudeText] = useState2(value3.latitude?.toString());
1281
- useEffect4(() => {
1270
+ useEffect3(() => {
1282
1271
  const location = GeoLocation3.fromGeoPoint(geoPoint);
1283
1272
  setLongitudeText(location.longitude?.toString());
1284
1273
  setLatitudeText(location.latitude?.toString());
@@ -1319,25 +1308,24 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
1319
1308
  label,
1320
1309
  asChild: true
1321
1310
  }), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
1322
- role: "none",
1323
- className: "grid grid-cols-2 gap-2"
1324
- }, /* @__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, {
1311
+ className: "grid grid-cols-2 gap-form-gap"
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, {
1325
1313
  type: "number",
1326
1314
  step: "0.00001",
1327
1315
  min: "-90",
1328
1316
  max: "90",
1329
1317
  disabled: !!readonly,
1330
- placeholder: t("latitude placeholder"),
1318
+ placeholder: t("latitude.placeholder"),
1331
1319
  value: latitudeText ?? "",
1332
1320
  onChange: handleChange("latitude", setLatitudeText),
1333
1321
  onBlur
1334
- }))), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("longitude label")), /* @__PURE__ */ React7.createElement(Input3.TextInput, {
1322
+ }))), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("longitude.label")), /* @__PURE__ */ React7.createElement(Input3.TextInput, {
1335
1323
  type: "number",
1336
1324
  step: "0.00001",
1337
1325
  min: "-180",
1338
1326
  max: "180",
1339
1327
  disabled: !!readonly,
1340
- placeholder: t("longitude placeholder"),
1328
+ placeholder: t("longitude.placeholder"),
1341
1329
  value: longitudeText ?? "",
1342
1330
  onChange: handleChange("longitude", setLongitudeText),
1343
1331
  onBlur
@@ -1347,7 +1335,7 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
1347
1335
  const latHem = latitude >= 0 ? "N" : "S";
1348
1336
  const lngHem = longitude >= 0 ? "E" : "W";
1349
1337
  return /* @__PURE__ */ React7.createElement("span", {
1350
- className: "inline-flex items-center gap-1"
1338
+ className: "inline-flex items-center gap-form-gap"
1351
1339
  }, /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
1352
1340
  className: "text-subdued"
1353
1341
  }, "\xB0", latHem)), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
@@ -1356,56 +1344,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
1356
1344
  };
1357
1345
 
1358
1346
  // src/components/Form/fields/MarkdownField.tsx
1359
- import React8, { useCallback as useCallback6, useEffect as useEffect5, useRef as useRef2 } from "react";
1360
- import { Input as Input4 } from "@dxos/react-ui";
1361
- 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 }) => {
1362
1359
  const { status, error } = getStatus();
1363
- const textareaRef = useRef2(null);
1364
- const adjustHeight = useCallback6(() => {
1365
- const textarea = textareaRef.current;
1366
- if (textarea) {
1367
- textarea.style.blockSize = "auto";
1368
- textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
1369
- }
1370
- }, []);
1371
- useEffect5(() => {
1372
- adjustHeight();
1373
- }, [
1374
- adjustHeight
1375
- ]);
1376
- useEffect5(() => {
1377
- adjustHeight();
1378
- }, [
1379
- getValue(),
1380
- adjustHeight
1381
- ]);
1382
- const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
1383
- type,
1384
- onValueChange
1385
- ]);
1360
+ const isRef = Ref2.isRefType(type);
1386
1361
  const value3 = getValue();
1387
- if ((readonly || layout === "static") && !value3) {
1362
+ if ((readonly || layout === "static") && value3 == null) {
1388
1363
  return null;
1389
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
+ };
1390
1401
  return /* @__PURE__ */ React8.createElement(Input4.Root, {
1391
1402
  validationValence: status
1392
1403
  }, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
1393
1404
  error,
1394
1405
  readonly,
1395
1406
  label
1396
- }), layout === "static" ? /* @__PURE__ */ React8.createElement("p", null, value3) : /* @__PURE__ */ React8.createElement(Input4.TextArea, {
1397
- ref: textareaRef,
1398
- 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({
1399
1436
  placeholder,
1400
- value: value3 ?? "",
1401
- classNames: "min-h-auto max-h-40 overflow-auto",
1402
- onChange: handleChange,
1403
- onBlur,
1404
- style: {
1405
- resize: "none"
1406
- },
1407
- spellCheck: false
1408
- }), 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")));
1409
1482
  };
1410
1483
 
1411
1484
  // src/components/Form/fields/NumberField.tsx
@@ -1431,47 +1504,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
1431
1504
  };
1432
1505
 
1433
1506
  // src/components/Form/fields/RefField.tsx
1507
+ import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
1434
1508
  import "@dxos/lit-ui/dx-tag-picker.pcss";
1435
- import React11, { useCallback as useCallback9, useMemo as useMemo6 } from "react";
1436
- import { Entity, Filter, Obj, Ref as Ref2, Type } from "@dxos/echo";
1437
- import { ReferenceAnnotationId } from "@dxos/echo/internal";
1438
- import { useQuery, useSchema as useSchema$ } from "@dxos/echo-react";
1439
- import { findAnnotation } from "@dxos/effect";
1509
+ import { Entity, Filter, Obj as Obj2, Ref as Ref3, Type } from "@dxos/echo";
1510
+ import { useQuery, useSchema as defaultUseSchema } from "@dxos/echo-react";
1511
+ import { ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo/internal";
1512
+ import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1440
1513
  import { DXN } from "@dxos/keys";
1441
1514
  import { DxAnchor } from "@dxos/lit-ui/react";
1442
- import { Button, Icon as Icon2, Input as Input6, useTranslation as useTranslation6 } from "@dxos/react-ui";
1443
- import { mx as mx3 } from "@dxos/ui-theme";
1515
+ import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
1516
+ import { ParentLabelAnnotationId } from "@dxos/schema";
1517
+ import { translationKey as translationKey7 } from "#translations";
1444
1518
 
1445
1519
  // src/components/ObjectPicker/ObjectPicker.tsx
1446
- import React10, { forwardRef as forwardRef2, useCallback as useCallback8, useState as useState3 } from "react";
1447
- import { Popover, useTranslation as useTranslation5 } from "@dxos/react-ui";
1448
- import { Combobox, useSearchListInput, useSearchListResults } from "@dxos/react-ui-searchlist";
1449
- var CreateItem = ({ createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1450
- const { t } = useTranslation5(translationKey);
1451
- const { query } = useSearchListInput();
1452
- return /* @__PURE__ */ React10.createElement(Combobox.Item, {
1453
- value: "__create__",
1454
- label: t(createOptionLabel[0], {
1455
- ns: createOptionLabel[1].ns,
1456
- text: query
1457
- }),
1458
- icon: createOptionIcon,
1459
- classNames: "flex items-center gap-2",
1460
- closeOnSelect: false,
1461
- onSelect: () => {
1462
- onCreateItemSelect(query);
1463
- }
1464
- });
1465
- };
1466
- var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
1467
- const { t } = useTranslation5(translationKey);
1520
+ import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
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);
1468
1527
  const [showForm, setShowForm] = useState3(false);
1469
1528
  const [formInitialValue, setFormInitialValue] = useState3("");
1470
- const { results, handleSearch } = useSearchListResults({
1529
+ const { results, query, handleSearch } = useSearchListResults({
1471
1530
  items: options
1472
1531
  });
1473
- const handleFormSave = useCallback8((values) => {
1474
- onCreate?.(values);
1532
+ const handleFormSave = useCallback8(async (values) => {
1533
+ await onCreate?.(values);
1475
1534
  setShowForm(false);
1476
1535
  setFormInitialValue("");
1477
1536
  }, [
@@ -1493,22 +1552,31 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
1493
1552
  }, [
1494
1553
  createSchema
1495
1554
  ]);
1555
+ if (showForm && createSchema) {
1556
+ return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1557
+ ...props,
1558
+ onKeyDownCapture: handleKeyDown,
1559
+ ref: forwardedRef
1560
+ }, /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
1561
+ testId: "create-referenced-object-form",
1562
+ schema: createSchema,
1563
+ defaultValues: createInitialValuePath ? {
1564
+ [createInitialValuePath]: formInitialValue
1565
+ } : {},
1566
+ fieldMap: createFieldMap3,
1567
+ onSave: handleFormSave,
1568
+ onCancel: handleFormCancel
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));
1570
+ }
1496
1571
  return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1497
1572
  ...props,
1498
- ref,
1499
- onSearch: handleSearch,
1500
- onKeyDownCapture: handleKeyDown
1501
- }, showForm && createSchema ? /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
1502
- testId: "create-referenced-object-form",
1503
- schema: createSchema,
1504
- values: createInitialValuePath ? {
1505
- [createInitialValuePath]: formInitialValue
1506
- } : {},
1507
- onSave: handleFormSave,
1508
- onCancel: handleFormCancel
1509
- }, /* @__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(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1510
- placeholder: t("ref field combobox input placeholder"),
1511
- autoFocus: true
1573
+ onKeyDownCapture: handleKeyDown,
1574
+ ref: forwardedRef
1575
+ }, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1576
+ placeholder: t("ref-field-combobox-input.placeholder"),
1577
+ autoFocus: true,
1578
+ value: query,
1579
+ onValueChange: handleSearch
1512
1580
  }), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1513
1581
  key: option.id,
1514
1582
  value: option.id,
@@ -1516,16 +1584,34 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
1516
1584
  checked: selectedIds?.includes(option.id),
1517
1585
  onSelect: () => onSelect(option.id),
1518
1586
  classNames: "flex items-center gap-2"
1519
- })), createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
1587
+ })), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
1588
+ query,
1520
1589
  createOptionLabel,
1521
- createOptionIcon,
1522
- onCreateItemSelect: (query) => {
1523
- setFormInitialValue(query);
1590
+ createOptionIcon: createOptionIcon ?? "ph--plus--regular",
1591
+ onCreateItemSelect: (currentQuery) => {
1592
+ setFormInitialValue(currentQuery);
1524
1593
  setShowForm(true);
1525
1594
  }
1526
- }))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1595
+ })), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1527
1596
  });
1528
- ObjectPickerContent.displayName = "ObjectPickerContent";
1597
+ var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1598
+ const { t } = useTranslation6(translationKey6);
1599
+ const label = createOptionLabel ? t(createOptionLabel[0], {
1600
+ ns: createOptionLabel[1].ns,
1601
+ text: query
1602
+ }) : t("create-option.label");
1603
+ return /* @__PURE__ */ React10.createElement(Combobox.Item, {
1604
+ value: "__create__",
1605
+ label,
1606
+ icon: createOptionIcon,
1607
+ classNames: "flex items-center gap-2",
1608
+ closeOnSelect: false,
1609
+ onSelect: () => {
1610
+ onCreateItemSelect(query);
1611
+ }
1612
+ });
1613
+ };
1614
+ ObjectPickerContent.displayName = "ObjectPicker.Content";
1529
1615
  var ObjectPicker = {
1530
1616
  Root: Combobox.Root,
1531
1617
  Portal: Combobox.Portal,
@@ -1538,34 +1624,43 @@ var ObjectPicker = {
1538
1624
  var isRefSnapshot = (val) => {
1539
1625
  return typeof val === "object" && typeof val?.["/"] === "string";
1540
1626
  };
1541
- var defaultGetOptions = (results) => results.map((result) => {
1627
+ var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
1542
1628
  const id = Entity.getDXN(result).toString();
1543
- const label = Entity.getLabel(result);
1629
+ const parent = parentLabel ? Obj2.getParent(result) : void 0;
1630
+ const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
1544
1631
  return {
1545
1632
  id,
1546
1633
  label: label ?? id
1547
1634
  };
1548
1635
  });
1549
- 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());
1550
1637
  var RefField = (props) => {
1551
- const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db, resultsHook: useResults = defaultResultsHook, schemaHook: useSchema = useSchema$, getOptions: getOptions2 = defaultGetOptions, onCreate, onValueChange } = props;
1552
- 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);
1553
1640
  const { status, error } = getStatus();
1554
- const typename = useMemo6(() => type ? findAnnotation(type, ReferenceAnnotationId)?.typename : void 0, [
1641
+ const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
1555
1642
  type
1556
1643
  ]);
1557
1644
  const results = useResults(db, typename);
1558
- const options = useMemo6(() => getOptions2(results), [
1645
+ const options = useMemo7(() => {
1646
+ const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
1647
+ return getOptions(results, {
1648
+ parentLabel
1649
+ });
1650
+ }, [
1559
1651
  results,
1560
- getOptions2
1652
+ getOptions,
1653
+ type
1561
1654
  ]);
1562
1655
  const handleGetValue = useCallback9(() => {
1563
1656
  const formValue = getValue();
1657
+ const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
1564
1658
  const unknownToRefOption = (value3) => {
1565
- const isRef = Ref2.isRef(value3);
1659
+ const isRef = Ref3.isRef(value3);
1566
1660
  if (isRef || isRefSnapshot(value3)) {
1567
1661
  const dxnString = isRef ? value3.dxn.toString() : value3["/"];
1568
- const matchingOption = options.find((option) => option.id === dxnString);
1662
+ const objectId = dxnToObjectId(dxnString);
1663
+ const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
1569
1664
  if (matchingOption) {
1570
1665
  return matchingOption;
1571
1666
  }
@@ -1577,29 +1672,37 @@ var RefField = (props) => {
1577
1672
  options,
1578
1673
  getValue
1579
1674
  ]);
1580
- const handleUpdate = useCallback9((id) => {
1581
- const item2 = options.find((option) => option.id === id);
1582
- const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
1583
- onValueChange(type, ref);
1584
- }, [
1585
- options,
1586
- type,
1587
- onValueChange
1588
- ]);
1589
1675
  const item = handleGetValue();
1590
- const selectedIds = useMemo6(() => item ? [
1676
+ const selectedIds = useMemo7(() => item ? [
1591
1677
  item.id
1592
1678
  ] : [], [
1593
1679
  item
1594
1680
  ]);
1595
1681
  const createSchema = useSchema(db, typename);
1596
- const handleCreate = useCallback9((values) => {
1597
- if (createSchema && onCreate) {
1598
- onCreate(createSchema, values);
1682
+ const [open, setOpen] = useState4(false);
1683
+ const handleCreate = useCallback9(async (values) => {
1684
+ if (!createSchema || !onCreate) {
1685
+ return;
1686
+ }
1687
+ const newObject = await onCreate(createSchema, values);
1688
+ if (newObject) {
1689
+ onValueChange(type, Ref3.make(newObject));
1599
1690
  }
1691
+ setOpen(false);
1600
1692
  }, [
1601
1693
  createSchema,
1602
- 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
1603
1706
  ]);
1604
1707
  const handleSelect = useCallback9((id) => {
1605
1708
  if (item?.id === id) {
@@ -1621,40 +1724,46 @@ var RefField = (props) => {
1621
1724
  readonly,
1622
1725
  label
1623
1726
  }), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
1624
- className: mx3("text-description", "mb-2")
1625
- }, t("empty readonly ref field label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
1727
+ className: "text-description mb-2"
1728
+ }, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
1626
1729
  key: item.id,
1627
1730
  dxn: item.id,
1628
1731
  rootclassname: "me-1"
1629
- }, 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, {
1630
1736
  asChild: true,
1631
1737
  classNames: "p-0"
1632
1738
  }, item ? /* @__PURE__ */ React11.createElement("div", {
1633
- className: "flex gap-2 w-full"
1739
+ className: "flex gap-form-gap w-full"
1634
1740
  }, /* @__PURE__ */ React11.createElement(Input6.Root, {
1635
1741
  key: item.id
1636
1742
  }, /* @__PURE__ */ React11.createElement(Input6.TextInput, {
1637
1743
  value: item.label,
1638
1744
  readOnly: true,
1639
1745
  classNames: "w-full"
1640
- }))) : /* @__PURE__ */ React11.createElement(Button, {
1641
- classNames: "w-full text-start gap-2"
1746
+ }))) : /* @__PURE__ */ React11.createElement(Button2, {
1747
+ classNames: "w-full text-start gap-form-gap"
1642
1748
  }, /* @__PURE__ */ React11.createElement("div", {
1643
- role: "none",
1644
1749
  className: "grow overflow-hidden"
1645
1750
  }, /* @__PURE__ */ React11.createElement("span", {
1646
- className: "flex truncate text-description"
1647
- }, placeholder ?? t("ref field placeholder"))), /* @__PURE__ */ React11.createElement(Icon2, {
1751
+ className: "truncate text-description"
1752
+ }, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
1648
1753
  size: 3,
1649
1754
  icon: "ph--caret-down--bold"
1650
1755
  }))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
1651
1756
  classNames: "dx-card-popover-width",
1652
1757
  options,
1653
1758
  selectedIds,
1654
- 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)),
1655
1763
  createOptionLabel,
1656
1764
  createOptionIcon,
1657
1765
  createInitialValuePath,
1766
+ createFieldMap: createFieldMap3,
1658
1767
  onCreate: handleCreate,
1659
1768
  onSelect: handleSelect
1660
1769
  })))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
@@ -1696,20 +1805,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
1696
1805
  };
1697
1806
 
1698
1807
  // src/components/Form/fields/SelectOptionField.tsx
1699
- import React13, { useCallback as useCallback11, useEffect as useEffect6, 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";
1700
1809
  import { PublicKey } from "@dxos/keys";
1701
- 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";
1702
1811
  import { List } from "@dxos/react-ui-list";
1703
1812
  import { HuePicker } from "@dxos/react-ui-pickers";
1704
- import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
1813
+ import { hues, osTranslations } from "@dxos/ui-theme";
1814
+ import { translationKey as translationKey8 } from "#translations";
1705
1815
  var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
1706
- const { t } = useTranslation7(translationKey);
1816
+ const { t } = useTranslation8(translationKey8);
1707
1817
  const { status, error } = getStatus();
1708
- const [selected, setSelectedId] = useState4(null);
1709
- const [isNewOption, setIsNewOption] = useState4(false);
1710
- const inputRef = useRef3(null);
1818
+ const [selected, setSelectedId] = useState5(null);
1819
+ const [isNewOption, setIsNewOption] = useState5(false);
1820
+ const inputRef = useRef2(null);
1711
1821
  const options = getValue();
1712
- useEffect6(() => {
1822
+ useEffect4(() => {
1713
1823
  if (options === void 0) {
1714
1824
  onValueChange(type, []);
1715
1825
  }
@@ -1800,7 +1910,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1800
1910
  type,
1801
1911
  onValueChange
1802
1912
  ]);
1803
- useEffect6(() => {
1913
+ useEffect4(() => {
1804
1914
  if (selected && isNewOption && inputRef.current) {
1805
1915
  inputRef.current.focus();
1806
1916
  setIsNewOption(false);
@@ -1815,9 +1925,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1815
1925
  error,
1816
1926
  readonly,
1817
1927
  label
1818
- }), /* @__PURE__ */ React13.createElement("div", {
1819
- role: "none"
1820
- }, options && /* @__PURE__ */ React13.createElement(List.Root, {
1928
+ }), /* @__PURE__ */ React13.createElement("div", null, options && /* @__PURE__ */ React13.createElement(List.Root, {
1821
1929
  items: options,
1822
1930
  isItem: (_item) => true,
1823
1931
  onMove: readonly ? void 0 : handleMove,
@@ -1830,10 +1938,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1830
1938
  }, /* @__PURE__ */ React13.createElement(List.Item, {
1831
1939
  role: "button",
1832
1940
  item,
1833
- classNames: [
1834
- subtleHover,
1835
- "flex flex-col cursor-pointer rounded-xs"
1836
- ],
1941
+ classNames: "flex flex-col cursor-pointer rounded-xs dx-hover",
1837
1942
  "aria-expanded": selected === item.id
1838
1943
  }, /* @__PURE__ */ React13.createElement("div", {
1839
1944
  className: "flex items-center"
@@ -1847,20 +1952,20 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1847
1952
  }, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
1848
1953
  iconOnly: true,
1849
1954
  variant: "ghost",
1850
- label: t(selected === item.id ? "collapse label" : "expand label", {
1955
+ label: t(selected === item.id ? "collapse.label" : "expand.label", {
1851
1956
  ns: osTranslations
1852
1957
  }),
1853
1958
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
1854
1959
  onClick: () => handleClick(item.id)
1855
1960
  })), selected === item.id && /* @__PURE__ */ React13.createElement("div", {
1856
- className: "flex flex-col p-form-padding gap-1 dx-density-fine"
1961
+ className: "flex flex-col p-form-padding gap-form-gap dx-density-fine"
1857
1962
  }, /* @__PURE__ */ React13.createElement(Input8.Label, {
1858
1963
  classNames: "text-xs"
1859
- }, t("select option label")), /* @__PURE__ */ React13.createElement("div", {
1860
- className: "grid grid-cols-[1fr_min-content_min-content] gap-1"
1964
+ }, t("select-option.label")), /* @__PURE__ */ React13.createElement("div", {
1965
+ className: "grid grid-cols-[1fr_min-content_min-content] gap-form-gap"
1861
1966
  }, /* @__PURE__ */ React13.createElement(Input8.TextInput, {
1862
1967
  disabled: !!readonly,
1863
- placeholder: t("select option label placeholder"),
1968
+ placeholder: t("select-option-label.placeholder"),
1864
1969
  ref: selected === item.id ? inputRef : void 0,
1865
1970
  value: item.title,
1866
1971
  onChange: handleTitleChange(item.id),
@@ -1874,12 +1979,12 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1874
1979
  disabled: !!readonly,
1875
1980
  icon: "ph--trash--fill",
1876
1981
  iconOnly: true,
1877
- label: t("select option delete"),
1982
+ label: t("select-option-delete.button"),
1878
1983
  onClick: () => handleDelete(item.id)
1879
1984
  })))))), /* @__PURE__ */ React13.createElement(IconButton3, {
1880
1985
  variant: "ghost",
1881
1986
  icon: "ph--plus--regular",
1882
- label: t("select option add"),
1987
+ label: t("select-option-add.button"),
1883
1988
  onClick: handleAdd,
1884
1989
  disabled: !!readonly,
1885
1990
  classNames: "w-full"
@@ -1889,7 +1994,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1889
1994
  // src/components/Form/fields/TextField.tsx
1890
1995
  import React14, { useCallback as useCallback12 } from "react";
1891
1996
  import { Input as Input9 } from "@dxos/react-ui";
1892
- var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
1997
+ var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
1893
1998
  const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
1894
1999
  type,
1895
2000
  onValueChange
@@ -1902,8 +2007,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
1902
2007
  disabled: !!readonly,
1903
2008
  placeholder,
1904
2009
  value: value3,
1905
- onChange: handleChange,
1906
- onBlur
2010
+ onBlur,
2011
+ onChange: handleChange
1907
2012
  }));
1908
2013
  };
1909
2014
 
@@ -1931,7 +2036,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
1931
2036
  // src/components/Form/fields/TupleField.tsx
1932
2037
  import React16 from "react";
1933
2038
  import { Input as Input11 } from "@dxos/react-ui";
1934
- import { mx as mx4 } from "@dxos/ui-theme";
2039
+ import { mx as mx2 } from "@dxos/ui-theme";
1935
2040
  import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
1936
2041
  var gridCols = [
1937
2042
  "grid-cols-1",
@@ -1949,7 +2054,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
1949
2054
  readonly,
1950
2055
  label
1951
2056
  }), /* @__PURE__ */ React16.createElement("div", {
1952
- className: mx4("grid gap-2", gridCols[binding.length - 1])
2057
+ className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
1953
2058
  }, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
1954
2059
  key: prop,
1955
2060
  type: "number",
@@ -1968,13 +2073,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
1968
2073
  // src/components/FieldEditor/FieldEditor.tsx
1969
2074
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1970
2075
  var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
1971
- const { t } = useTranslation8(translationKey);
1972
- const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
1973
- useEffect7(() => 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), [
1974
2079
  field,
1975
2080
  projection
1976
2081
  ]);
1977
- const [schemas, setSchemas] = useState5([]);
2082
+ const [schemas, setSchemas] = useState6([]);
1978
2083
  useAsyncEffect(async () => {
1979
2084
  if (!registry) {
1980
2085
  return;
@@ -1988,22 +2093,22 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
1988
2093
  }, [
1989
2094
  registry
1990
2095
  ]);
1991
- const [referenceSchema, setReferenceSchema] = useState5();
1992
- useEffect7(() => {
2096
+ const [referenceSchema, setReferenceSchema] = useState6();
2097
+ useEffect5(() => {
1993
2098
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
1994
2099
  }, [
1995
2100
  schemas,
1996
2101
  props?.referenceSchema
1997
2102
  ]);
1998
- const [{ fieldSchema }, setFieldSchema] = useState5({
2103
+ const [{ fieldSchema }, setFieldSchema] = useState6({
1999
2104
  fieldSchema: getFormatSchema(props?.format)
2000
2105
  });
2001
- const fieldMap = useMemo7(() => ({
2106
+ const fieldMap = useMemo8(() => ({
2002
2107
  ["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
2003
2108
  ...props2,
2004
2109
  options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
2005
2110
  value: value3,
2006
- label: t(`format ${value3}`)
2111
+ label: t(`format.${value3}.label`)
2007
2112
  }))
2008
2113
  }),
2009
2114
  ["referenceSchema"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
@@ -2077,7 +2182,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2077
2182
  ]);
2078
2183
  const handleSave = useCallback14((props2) => {
2079
2184
  if (view) {
2080
- Obj2.change(view, () => {
2185
+ Obj3.update(view, () => {
2081
2186
  projection.setFieldProjection({
2082
2187
  field,
2083
2188
  props: props2
@@ -2105,12 +2210,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2105
2210
  if (!fieldSchema) {
2106
2211
  log2.warn("invalid format", {
2107
2212
  props
2108
- }, {
2109
- F: __dxlog_file2,
2110
- L: 172,
2111
- S: void 0,
2112
- C: (f, a) => f(...a)
2113
- });
2213
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
2114
2214
  return null;
2115
2215
  }
2116
2216
  return /* @__PURE__ */ React17.createElement(Form.Root, {
@@ -2132,160 +2232,487 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2132
2232
  }, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
2133
2233
  };
2134
2234
 
2135
- // src/components/Settings/Settings.tsx
2136
- import React18 from "react";
2137
- import { Button as Button2, Input as Input12, ScrollArea as ScrollArea2, toLocalizedString, useTranslation as useTranslation9 } from "@dxos/react-ui";
2138
- import { mx as mx5 } from "@dxos/ui-theme";
2139
- var SETTINGS_ROOT_NAME = "Settings.Root";
2140
- var SETTINGS_SECTION_NAME = "Settings.Section";
2141
- var SETTINGS_SECTION_HEADING_NAME = "Settings.SectionHeading";
2142
- var SETTINGS_GROUP_NAME = "Settings.Group";
2143
- var SETTINGS_GROUP_BUTTON_NAME = "Settings.GroupButton";
2144
- var SETTINGS_CONTAINER_NAME = "Settings.Container";
2145
- var SETTINGS_FRAME_NAME = "Settings.Frame";
2146
- var SETTINGS_FRAME_ITEM_NAME = "Settings.FrameItem";
2147
- var SETTINGS_ITEM_NAME = "Settings.Item";
2148
- var SETTINGS_ITEM_INPUT_NAME = "Settings.ItemInput";
2149
- var styles = {
2150
- title: "pb-trim-md text-base-surface-text text-lg",
2151
- description: "text-base text-description",
2152
- grid: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg"
2153
- };
2154
- var SettingsRoot = ({ children }) => {
2155
- return /* @__PURE__ */ React18.createElement(ScrollArea2.Root, {
2156
- orientation: "vertical",
2157
- className: "dx-article"
2158
- }, /* @__PURE__ */ React18.createElement(ScrollArea2.Viewport, {
2159
- classNames: "p-trim-md"
2160
- }, children));
2161
- };
2162
- SettingsRoot.displayName = SETTINGS_ROOT_NAME;
2163
- var SettingsSection = ({ title, description, children }) => {
2164
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SettingsSectionHeading, {
2165
- title,
2166
- description
2167
- }), /* @__PURE__ */ React18.createElement("div", {
2168
- className: "w-full pt-trim-md space-y-trim-md"
2169
- }, children));
2170
- };
2171
- SettingsSection.displayName = SETTINGS_SECTION_NAME;
2172
- var SettingsSectionHeading = ({ title, description }) => {
2173
- const { t } = useTranslation9(translationKey);
2174
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("h2", {
2175
- className: "px-trim-md mt-trim-md mb-trim-md text-xl"
2176
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
2177
- className: "px-trim-md my-trim-md text-description"
2178
- }, toLocalizedString(description, t)));
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
+ }
2179
2263
  };
2180
- SettingsSectionHeading.displayName = SETTINGS_SECTION_HEADING_NAME;
2181
- var SettingsGroupButton = ({ classNames, ...props }) => {
2182
- return /* @__PURE__ */ React18.createElement(Button2, {
2183
- ...props,
2184
- classNames: [
2185
- "md:col-span-2",
2186
- classNames
2187
- ]
2188
- });
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))));
2189
2334
  };
2190
- SettingsGroupButton.displayName = SETTINGS_GROUP_BUTTON_NAME;
2191
- var SettingsGroup = ({ children, classNames }) => /* @__PURE__ */ React18.createElement("div", {
2192
- role: "none",
2193
- className: mx5("group space-y-trim-md", classNames)
2194
- }, children);
2195
- SettingsGroup.displayName = SETTINGS_GROUP_NAME;
2196
- var SettingsFrame = ({ children }) => /* @__PURE__ */ React18.createElement("div", {
2197
- role: "none",
2198
- className: "p-trim-md border border-separator rounded-md"
2199
- }, children);
2200
- SettingsFrame.displayName = SETTINGS_FRAME_NAME;
2201
- var SettingsFrameItem = ({ title, description, children }) => {
2202
- const { t } = useTranslation9(translationKey);
2203
- return /* @__PURE__ */ React18.createElement("div", {
2204
- role: "group",
2205
- className: "min-w-0"
2206
- }, /* @__PURE__ */ React18.createElement("h3", {
2207
- className: "text-lg mb-2"
2208
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
2209
- className: "my-trim-sm md:mb-0 text-description"
2210
- }, toLocalizedString(description, t)), children);
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
+ }
2211
2441
  };
2212
- SettingsFrameItem.displayName = SETTINGS_FRAME_ITEM_NAME;
2213
- var SettingsContainer = ({ classNames, children }) => {
2214
- return /* @__PURE__ */ React18.createElement("div", {
2215
- role: "none",
2216
- className: mx5([
2217
- "dx-article",
2218
- "*:first:mt-0! *:last:mb-0! px-trim-md py-trim-md",
2219
- "border border-separator rounded-md",
2220
- classNames
2221
- ])
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)
2222
2469
  }, children);
2223
2470
  };
2224
- SettingsContainer.displayName = SETTINGS_CONTAINER_NAME;
2471
+ SettingsPanel.displayName = SETTINGS_PANEL_NAME;
2225
2472
  var SettingsItem = ({ title, description = "", children }) => {
2226
- const { t } = useTranslation9(translationKey);
2227
- return /* @__PURE__ */ React18.createElement(SettingsContainer, {
2228
- classNames: styles.grid
2229
- }, /* @__PURE__ */ React18.createElement("h3", {
2230
- className: mx5(styles.title, "md:col-span-2")
2231
- }, toLocalizedString(title, t)), /* @__PURE__ */ React18.createElement("p", {
2232
- className: styles.description
2233
- }, toLocalizedString(description, t)), /* @__PURE__ */ React18.createElement("div", {
2234
- role: "none",
2235
- className: "overflow-hidden text-end py-1"
2236
- }, 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)));
2237
2483
  };
2238
2484
  SettingsItem.displayName = SETTINGS_ITEM_NAME;
2239
- var SettingsItemInput = ({ title, description = "", children }) => {
2240
- const { t } = useTranslation9(translationKey);
2241
- return /* @__PURE__ */ React18.createElement(Input12.Root, null, /* @__PURE__ */ React18.createElement(SettingsContainer, {
2242
- classNames: styles.grid
2243
- }, /* @__PURE__ */ React18.createElement(Input12.Label, {
2244
- classNames: mx5(styles.title, "md:col-span-2")
2245
- }, toLocalizedString(title, t)), /* @__PURE__ */ React18.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React18.createElement(Input12.Description, {
2246
- classNames: styles.description
2247
- }, toLocalizedString(description, t))), /* @__PURE__ */ React18.createElement("div", {
2248
- role: "none",
2249
- className: "text-end py-1"
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
+
2625
+ // src/components/Settings/Settings.tsx
2626
+ var SETTINGS_ROOT_NAME = "Settings.Root";
2627
+ var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
2628
+ var SETTINGS_SECTION_NAME = "Settings.Section";
2629
+ var SettingsRoot = ({ children, classNames }) => {
2630
+ return /* @__PURE__ */ React22.createElement("div", {
2631
+ className: mx4("flex flex-col gap-2", classNames)
2632
+ }, children);
2633
+ };
2634
+ SettingsRoot.displayName = SETTINGS_ROOT_NAME;
2635
+ var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
2636
+ return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
2637
+ ...composableProps3(props),
2638
+ orientation: "vertical",
2639
+ centered: true,
2640
+ thin: true,
2641
+ ref: forwardedRef
2642
+ }, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
2643
+ classNames: "px-4 pointer-coarse:px-2"
2644
+ }, /* @__PURE__ */ React22.createElement("div", {
2645
+ className: "dx-document flex flex-col gap-2 py-4"
2250
2646
  }, children)));
2647
+ });
2648
+ SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
2649
+ var SettingsSection = ({ title, description, children }) => {
2650
+ const { t } = useTranslation11(translationKey13);
2651
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
2652
+ className: "px-trim-md mt-trim-md text-xl"
2653
+ }, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
2654
+ className: "px-trim-md text-description"
2655
+ }, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
2656
+ className: "w-full pt-trim-md space-y-trim-md"
2657
+ }, children));
2251
2658
  };
2252
- SettingsItemInput.displayName = SETTINGS_ITEM_INPUT_NAME;
2659
+ SettingsSection.displayName = SETTINGS_SECTION_NAME;
2253
2660
  var Settings = {
2254
2661
  Root: SettingsRoot,
2662
+ Viewport: SettingsViewport,
2255
2663
  Section: SettingsSection,
2256
- SectionHeading: SettingsSectionHeading,
2257
- Group: SettingsGroup,
2258
- GroupButton: SettingsGroupButton,
2259
- Container: SettingsContainer,
2260
- Frame: SettingsFrame,
2261
- FrameItem: SettingsFrameItem,
2664
+ Panel: SettingsPanel,
2262
2665
  Item: SettingsItem,
2263
- ItemInput: SettingsItemInput
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))));
2264
2691
  };
2265
2692
 
2266
2693
  // src/components/ViewEditor/ViewEditor.tsx
2267
2694
  import { RegistryContext } from "@effect-atom/atom-react";
2268
- import * as Array2 from "effect/Array";
2695
+ import * as Array4 from "effect/Array";
2269
2696
  import * as Match2 from "effect/Match";
2270
- import * as Option4 from "effect/Option";
2271
- import * as Schema3 from "effect/Schema";
2272
- import React19, { forwardRef as forwardRef3, useCallback as useCallback15, useContext, useImperativeHandle, useMemo as useMemo8, useState as useState6 } from "react";
2273
- import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj3, Query, QueryAST, Ref as Ref3 } from "@dxos/echo";
2274
- 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";
2275
2701
  import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
2276
- import { invariant } from "@dxos/invariant";
2702
+ import { invariant as invariant3 } from "@dxos/invariant";
2277
2703
  import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
2278
- 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";
2279
2705
  import { QueryForm } from "@dxos/react-ui-components";
2280
2706
  import { List as List2 } from "@dxos/react-ui-list";
2281
- import { ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
2282
- import { mx as mx6, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
2283
- var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2284
- var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
2707
+ import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
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";
2711
+ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
2285
2712
  const atomRegistry = useContext(RegistryContext);
2286
2713
  const schemaReadonly = !isMutable(schema);
2287
- const { t } = useTranslation10(translationKey);
2288
- const projectionModel = useMemo8(() => {
2714
+ const { t } = useTranslation12(translationKey14);
2715
+ const projectionModel = useMemo12(() => {
2289
2716
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2290
2717
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2291
2718
  const model = new ProjectionModel({
@@ -2309,21 +2736,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2309
2736
  if (from._tag !== "scope") {
2310
2737
  return void 0;
2311
2738
  }
2312
- 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);
2313
2740
  }), Match2.orElse(() => void 0));
2314
2741
  const feeds = useQuery2(db, Filter2.type(Feed.Feed));
2315
- const targetRef = useMemo8(() => {
2742
+ const targetRef = useMemo12(() => {
2316
2743
  if (!queueTarget) {
2317
2744
  return void 0;
2318
2745
  }
2319
2746
  const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
2320
- return feed ? Ref3.fromDXN(Entity2.getDXN(feed)) : void 0;
2747
+ return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
2321
2748
  }, [
2322
2749
  queueTarget,
2323
2750
  feeds
2324
2751
  ]);
2325
- const viewSchema = useMemo8(() => {
2326
- const base = Schema3.Struct({
2752
+ const viewSchema = useMemo12(() => {
2753
+ const base = Schema5.Struct({
2327
2754
  query: mode === "schema" ? Format5.URL.annotations({
2328
2755
  title: "Record type"
2329
2756
  }) : QueryAST.Query.annotations({
@@ -2331,18 +2758,19 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2331
2758
  })
2332
2759
  });
2333
2760
  if (mode === "tag") {
2334
- return Schema3.Struct({
2761
+ return Schema5.Struct({
2335
2762
  ...base.fields,
2336
- target: Schema3.optional(Ref3.Ref(Feed.Feed).annotations({
2763
+ // TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
2764
+ target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
2337
2765
  title: "Target Feed"
2338
- }))
2339
- }).pipe(Schema3.mutable);
2766
+ }), ParentLabelAnnotation.set(true), Schema5.optional)
2767
+ }).pipe(Schema5.mutable);
2340
2768
  }
2341
- return base.pipe(Schema3.mutable);
2769
+ return base.pipe(Schema5.mutable);
2342
2770
  }, [
2343
2771
  mode
2344
2772
  ]);
2345
- const viewValues = useMemo8(() => ({
2773
+ const viewValues = useMemo12(() => ({
2346
2774
  query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2347
2775
  target: targetRef
2348
2776
  }), [
@@ -2350,7 +2778,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2350
2778
  view.query.ast,
2351
2779
  targetRef
2352
2780
  ]);
2353
- const fieldMap = useMemo8(() => mode === "tag" ? customFields({
2781
+ const fieldMap = useMemo12(() => mode === "tag" ? customFields({
2354
2782
  types,
2355
2783
  tags
2356
2784
  }) : void 0, [
@@ -2358,54 +2786,45 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2358
2786
  types,
2359
2787
  tags
2360
2788
  ]);
2361
- const handleUpdate = useCallback15((values) => {
2789
+ const handleUpdate = useCallback18((values) => {
2362
2790
  const targetValue = values.target;
2363
- let queueDxn;
2364
- if (Ref3.isRef(targetValue)) {
2365
- const feedDxn = targetValue.dxn.toString();
2366
- 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);
2367
2795
  if (feed) {
2368
- queueDxn = Feed.getQueueDxn(feed)?.toString();
2796
+ feedDXN = Feed.getQueueDxn(feed)?.toString();
2369
2797
  }
2370
2798
  }
2371
2799
  const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
2372
- onQueryChanged?.(query, queueDxn);
2800
+ onQueryChanged?.(query, feedDXN);
2373
2801
  }, [
2374
2802
  onQueryChanged,
2375
2803
  mode,
2376
2804
  feeds
2377
2805
  ]);
2378
- const handleDelete = useCallback15((fieldId) => {
2379
- invariant(!readonly, void 0, {
2380
- F: __dxlog_file3,
2381
- L: 174,
2382
- S: void 0,
2383
- A: [
2384
- "!readonly",
2385
- ""
2386
- ]
2387
- });
2806
+ const handleDelete = useCallback18((fieldId) => {
2807
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 126, S: void 0, A: ["!readonly", ""] });
2388
2808
  onDelete?.(fieldId);
2389
2809
  }, [
2390
2810
  onDelete,
2391
2811
  readonly
2392
2812
  ]);
2393
- return /* @__PURE__ */ React19.createElement("div", {
2394
- role: "none",
2395
- className: mx6(classNames)
2396
- }, schemaReadonly && !readonly && /* @__PURE__ */ React19.createElement(Message.Root, {
2813
+ return /* @__PURE__ */ React24.createElement("div", {
2814
+ className: mx5(classNames)
2815
+ }, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
2397
2816
  valence: "info",
2398
2817
  classNames: "my-form-padding"
2399
- }, /* @__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, {
2400
2819
  schema: viewSchema,
2401
2820
  values: viewValues,
2402
2821
  fieldMap,
2403
2822
  db,
2404
2823
  onValuesChanged: handleUpdate
2405
- }, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), /* @__PURE__ */ React19.createElement(FormFieldLabel, {
2406
- label: t("fields label"),
2824
+ }, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2825
+ label: t("fields.label"),
2407
2826
  asChild: true
2408
- }), /* @__PURE__ */ React19.createElement(FieldList, {
2827
+ }), /* @__PURE__ */ React24.createElement(FieldList, {
2409
2828
  schema,
2410
2829
  view,
2411
2830
  registry,
@@ -2417,9 +2836,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2417
2836
  var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
2418
2837
  const atomRegistry = useContext(RegistryContext);
2419
2838
  const schemaReadonly = !isMutable(schema);
2420
- const { t } = useTranslation10(translationKey);
2839
+ const { t } = useTranslation12(translationKey14);
2421
2840
  const [viewSnapshot] = useObject(view);
2422
- const projectionModel = useMemo8(() => {
2841
+ const projectionModel = useMemo12(() => {
2423
2842
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2424
2843
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2425
2844
  const model = new ProjectionModel({
@@ -2434,38 +2853,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2434
2853
  schema,
2435
2854
  view
2436
2855
  ]);
2437
- const [expandedField, setExpandedField] = useState6();
2438
- const handleAdd = useCallback15(() => {
2439
- invariant(!readonly, void 0, {
2440
- F: __dxlog_file3,
2441
- L: 239,
2442
- S: void 0,
2443
- A: [
2444
- "!readonly",
2445
- ""
2446
- ]
2447
- });
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", ""] });
2448
2859
  const field = projectionModel.createFieldProjection();
2449
2860
  setExpandedField(field.id);
2450
2861
  }, [
2451
2862
  projectionModel,
2452
2863
  readonly
2453
2864
  ]);
2454
- const handleToggleField = useCallback15((field) => {
2865
+ const handleToggleField = useCallback18((field) => {
2455
2866
  setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2456
2867
  }, [
2457
2868
  readonly
2458
2869
  ]);
2459
- const handleDelete = useCallback15((fieldId) => {
2460
- invariant(!readonly, void 0, {
2461
- F: __dxlog_file3,
2462
- L: 253,
2463
- S: void 0,
2464
- A: [
2465
- "!readonly",
2466
- ""
2467
- ]
2468
- });
2870
+ const handleDelete = useCallback18((fieldId) => {
2871
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 194, S: void 0, A: ["!readonly", ""] });
2469
2872
  if (fieldId === expandedField) {
2470
2873
  setExpandedField(void 0);
2471
2874
  }
@@ -2475,36 +2878,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2475
2878
  onDelete,
2476
2879
  readonly
2477
2880
  ]);
2478
- const handleMove = useCallback15((fromIndex, toIndex) => {
2479
- invariant(!readonly, void 0, {
2480
- F: __dxlog_file3,
2481
- L: 265,
2482
- S: void 0,
2483
- A: [
2484
- "!readonly",
2485
- ""
2486
- ]
2487
- });
2488
- Obj3.change(view, (v) => {
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) => {
2489
2884
  const fields = [
2490
- ...v.projection.fields
2885
+ ...view2.projection.fields
2491
2886
  ];
2492
2887
  const [moved] = fields.splice(fromIndex, 1);
2493
2888
  fields.splice(toIndex, 0, moved);
2494
- v.projection.fields = fields;
2889
+ view2.projection.fields = fields;
2495
2890
  });
2496
2891
  }, [
2497
2892
  view,
2498
2893
  readonly
2499
2894
  ]);
2500
- const handleClose = useCallback15(() => setExpandedField(void 0), []);
2501
- const handleHide = useCallback15((fieldId) => {
2895
+ const handleClose = useCallback18(() => setExpandedField(void 0), []);
2896
+ const handleHide = useCallback18((fieldId) => {
2502
2897
  setExpandedField(void 0);
2503
2898
  projectionModel.hideFieldProjection(fieldId);
2504
2899
  }, [
2505
2900
  projectionModel
2506
2901
  ]);
2507
- const handleShow = useCallback15((property) => {
2902
+ const handleShow = useCallback18((property) => {
2508
2903
  setExpandedField(void 0);
2509
2904
  projectionModel.showFieldProjection(property);
2510
2905
  }, [
@@ -2513,70 +2908,67 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2513
2908
  if (!viewSnapshot) {
2514
2909
  return null;
2515
2910
  }
2516
- return /* @__PURE__ */ React19.createElement(List2.Root, {
2911
+ return /* @__PURE__ */ React24.createElement(List2.Root, {
2517
2912
  items: viewSnapshot.projection.fields,
2518
- isItem: Schema3.is(View.FieldSchema),
2913
+ isItem: Schema5.is(View.FieldSchema),
2519
2914
  getId: (field) => field.id,
2520
2915
  onMove: readonly ? void 0 : handleMove,
2521
2916
  readonly
2522
- }, ({ 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", {
2523
2918
  className: "text-sm"
2524
- }, t("field path label")), /* @__PURE__ */ React19.createElement("div", {
2919
+ }, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
2525
2920
  role: "list",
2526
2921
  className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
2527
2922
  }, fields?.map((field) => {
2528
2923
  const hidden = field.visible === false;
2529
- return /* @__PURE__ */ React19.createElement(List2.Item, {
2924
+ return /* @__PURE__ */ React24.createElement(List2.Item, {
2530
2925
  key: field.id,
2531
2926
  item: field,
2532
2927
  classNames: "grid grid-cols-subgrid col-span-5",
2533
2928
  "aria-expanded": expandedField === field.id
2534
- }, /* @__PURE__ */ React19.createElement("div", {
2535
- role: "none",
2536
- className: mx6(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
2537
- }, /* @__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, {
2538
2932
  disabled: readonly || schemaReadonly
2539
- }), /* @__PURE__ */ React19.createElement(List2.ItemTitle, {
2933
+ }), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
2540
2934
  classNames: hidden && "text-subdued",
2541
2935
  onClick: () => handleToggleField(field)
2542
- }, field.path), /* @__PURE__ */ React19.createElement(List2.ItemButton, {
2543
- 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"),
2544
2938
  "data-testid": hidden ? "show-field-button" : "hide-field-button",
2545
2939
  icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2546
2940
  autoHide: false,
2547
2941
  disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
2548
2942
  onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2549
- }), !readonly && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(List2.ItemDeleteButton, {
2550
- label: t("delete field label"),
2943
+ }), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
2944
+ label: t("delete-field.label"),
2551
2945
  autoHide: false,
2552
2946
  disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
2553
2947
  onClick: () => handleDelete(field.id),
2554
2948
  "data-testid": "field.delete"
2555
- }), /* @__PURE__ */ React19.createElement(IconButton4, {
2949
+ }), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
2556
2950
  iconOnly: true,
2557
2951
  variant: "ghost",
2558
- label: t("toggle expand label", {
2952
+ label: t("toggle-expand.label", {
2559
2953
  ns: osTranslations2
2560
2954
  }),
2561
2955
  icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2562
2956
  onClick: () => handleToggleField(field),
2563
2957
  "data-testid": "field.toggle"
2564
- }))), expandedField === field.id && !readonly && /* @__PURE__ */ React19.createElement("div", {
2565
- role: "none",
2566
- className: "col-span-5 mt-1 mb-1 border border-separator rounded-md"
2567
- }, /* @__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, {
2568
2961
  readonly: readonly || schemaReadonly,
2569
2962
  registry,
2570
2963
  projection: projectionModel,
2571
2964
  field,
2572
2965
  onSave: handleClose
2573
2966
  })));
2574
- })), !readonly && !expandedField && /* @__PURE__ */ React19.createElement("div", {
2575
- role: "none",
2967
+ })), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
2576
2968
  className: "my-form-padding"
2577
- }, /* @__PURE__ */ React19.createElement(IconButton4, {
2969
+ }, /* @__PURE__ */ React24.createElement(IconButton4, {
2578
2970
  icon: "ph--plus--regular",
2579
- label: t("add property button label"),
2971
+ label: t("add-property-button.label"),
2580
2972
  onClick: handleAdd,
2581
2973
  disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
2582
2974
  classNames: "w-full"
@@ -2584,13 +2976,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2584
2976
  };
2585
2977
  var customFields = ({ types, tags }) => ({
2586
2978
  query: ({ type, readonly, label, getValue, onValueChange }) => {
2587
- const handleChange = useCallback15((query) => onValueChange(type, query.ast), [
2979
+ const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
2588
2980
  onValueChange
2589
2981
  ]);
2590
- return /* @__PURE__ */ React19.createElement(Input13.Root, null, /* @__PURE__ */ React19.createElement(FormFieldLabel, {
2982
+ return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2591
2983
  readonly,
2592
2984
  label
2593
- }), /* @__PURE__ */ React19.createElement(QueryForm, {
2985
+ }), /* @__PURE__ */ React24.createElement(QueryForm, {
2594
2986
  initialQuery: getValue(),
2595
2987
  types,
2596
2988
  tags,
@@ -2609,7 +3001,9 @@ export {
2609
3001
  GeoPointField,
2610
3002
  MarkdownField,
2611
3003
  NumberField,
3004
+ ObjectForm,
2612
3005
  ObjectPicker,
3006
+ ObjectProperties,
2613
3007
  RefField,
2614
3008
  SelectField,
2615
3009
  SelectOptionField,
@@ -2619,15 +3013,18 @@ export {
2619
3013
  TupleField,
2620
3014
  ViewEditor,
2621
3015
  cellClassesForFieldType,
3016
+ createSelectField,
3017
+ detectFieldType,
2622
3018
  formatForDisplay,
2623
3019
  formatForEditing,
2624
3020
  getDefaultValue,
2625
3021
  getFormProperties,
2626
3022
  getRefProps,
3023
+ getSelectOptionsFromAst,
3024
+ omitHiddenFormFields,
2627
3025
  omitId,
2628
3026
  parseValue,
2629
3027
  pathNotUniqueError,
2630
- translations,
2631
3028
  useFormContext,
2632
3029
  useFormFieldState,
2633
3030
  useFormHandler,