@dxos/react-ui-form 0.8.4-main.1068cf700f → 0.8.4-main.1c7ec43d41

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 (153) hide show
  1. package/README.md +0 -1
  2. package/dist/lib/browser/index.mjs +1135 -663
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/translations.mjs +82 -0
  6. package/dist/lib/browser/translations.mjs.map +7 -0
  7. package/dist/lib/node-esm/index.mjs +1135 -663
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/lib/node-esm/translations.mjs +84 -0
  11. package/dist/lib/node-esm/translations.mjs.map +7 -0
  12. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +3 -3
  13. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  14. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -61
  15. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  16. package/dist/types/src/components/Form/Form.d.ts +44 -16
  17. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  18. package/dist/types/src/components/Form/Form.stories.d.ts +75 -73
  19. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  20. package/dist/types/src/components/Form/FormField.d.ts +11 -5
  21. package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -7
  23. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts +2 -2
  25. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/FormFieldSet.d.ts +6 -10
  27. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
  29. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
  31. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
  33. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
  34. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
  35. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
  36. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
  37. package/dist/types/src/components/Form/fields/RefField.d.ts +15 -7
  38. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
  39. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
  40. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
  41. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
  42. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
  43. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
  44. package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
  45. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
  46. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
  47. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
  48. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
  49. package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
  50. package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
  51. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +26 -4
  52. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  53. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
  54. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  55. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
  56. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
  57. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
  58. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
  59. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
  60. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
  61. package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
  62. package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
  63. package/dist/types/src/components/Settings/Settings.d.ts +28 -33
  64. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
  65. package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
  66. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
  67. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
  68. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  69. package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
  70. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  71. package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
  72. package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
  73. package/dist/types/src/components/Settings/index.d.ts +2 -0
  74. package/dist/types/src/components/Settings/index.d.ts.map +1 -1
  75. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +6 -6
  76. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  77. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +67 -64
  78. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  79. package/dist/types/src/components/index.d.ts +2 -0
  80. package/dist/types/src/components/index.d.ts.map +1 -1
  81. package/dist/types/src/components/testing.d.ts +4 -4
  82. package/dist/types/src/components/testing.d.ts.map +1 -1
  83. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
  84. package/dist/types/src/hooks/useKeyHandler.d.ts +2 -1
  85. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -1
  86. package/dist/types/src/index.d.ts +0 -2
  87. package/dist/types/src/index.d.ts.map +1 -1
  88. package/dist/types/src/translations.d.ts +63 -61
  89. package/dist/types/src/translations.d.ts.map +1 -1
  90. package/dist/types/src/util/field-type.d.ts +19 -0
  91. package/dist/types/src/util/field-type.d.ts.map +1 -0
  92. package/dist/types/src/util/field.d.ts.map +1 -1
  93. package/dist/types/src/util/formatting.d.ts.map +1 -1
  94. package/dist/types/src/util/index.d.ts +1 -1
  95. package/dist/types/src/util/index.d.ts.map +1 -1
  96. package/dist/types/src/util/properties.d.ts.map +1 -1
  97. package/dist/types/src/util/refs.d.ts +1 -0
  98. package/dist/types/src/util/refs.d.ts.map +1 -1
  99. package/dist/types/tsconfig.tsbuildinfo +1 -1
  100. package/package.json +42 -42
  101. package/src/components/FieldEditor/FieldEditor.stories.tsx +6 -8
  102. package/src/components/FieldEditor/FieldEditor.test.tsx +0 -1
  103. package/src/components/FieldEditor/FieldEditor.tsx +6 -6
  104. package/src/components/Form/AUDIT.md +17 -0
  105. package/src/components/Form/Form.stories.tsx +29 -44
  106. package/src/components/Form/Form.tsx +102 -54
  107. package/src/components/Form/FormField.tsx +39 -19
  108. package/src/components/Form/FormFieldComponent.stories.tsx +4 -4
  109. package/src/components/Form/FormFieldComponent.tsx +10 -10
  110. package/src/components/Form/FormFieldSet.tsx +121 -104
  111. package/src/components/Form/fields/ArrayField.tsx +14 -9
  112. package/src/components/Form/fields/GeoPointField.tsx +8 -7
  113. package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
  114. package/src/components/Form/fields/MarkdownField.tsx +135 -45
  115. package/src/components/Form/fields/RefField.tsx +84 -44
  116. package/src/components/Form/fields/SelectField.tsx +1 -1
  117. package/src/components/Form/fields/SelectOptionField.stories.tsx +10 -8
  118. package/src/components/Form/fields/SelectOptionField.tsx +12 -12
  119. package/src/components/Form/fields/TextField.tsx +2 -2
  120. package/src/components/Form/fields/TupleField.tsx +1 -1
  121. package/src/components/ObjectForm/ObjectForm.tsx +114 -0
  122. package/src/components/ObjectForm/index.ts +5 -0
  123. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +16 -18
  124. package/src/components/ObjectPicker/ObjectPicker.tsx +92 -65
  125. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +362 -0
  126. package/src/components/ObjectProperties/ObjectProperties.test.tsx +101 -0
  127. package/src/components/ObjectProperties/ObjectProperties.tsx +141 -0
  128. package/src/components/ObjectProperties/index.ts +5 -0
  129. package/src/components/Settings/AUDIT.md +52 -0
  130. package/src/components/Settings/Settings.stories.tsx +69 -21
  131. package/src/components/Settings/Settings.tsx +35 -187
  132. package/src/components/Settings/SettingsFieldSet.tsx +257 -0
  133. package/src/components/Settings/SettingsItem.tsx +62 -0
  134. package/src/components/Settings/SettingsSelectField.tsx +59 -0
  135. package/src/components/Settings/index.ts +2 -0
  136. package/src/components/ViewEditor/ViewEditor.stories.tsx +21 -19
  137. package/src/components/ViewEditor/ViewEditor.test.tsx +2 -2
  138. package/src/components/ViewEditor/ViewEditor.tsx +87 -49
  139. package/src/components/index.ts +2 -0
  140. package/src/components/testing.tsx +23 -12
  141. package/src/hooks/useFormHandler.ts +42 -24
  142. package/src/hooks/useKeyHandler.tsx +7 -7
  143. package/src/index.ts +0 -4
  144. package/src/translations.ts +66 -63
  145. package/src/util/field-type.ts +60 -0
  146. package/src/util/index.ts +1 -1
  147. package/src/util/refs.ts +7 -3
  148. package/dist/types/src/components/Form/Form-old.stories.d.ts +0 -131
  149. package/dist/types/src/components/Form/Form-old.stories.d.ts.map +0 -1
  150. package/dist/types/src/util/echo.d.ts +0 -6
  151. package/dist/types/src/util/echo.d.ts.map +0 -1
  152. package/src/components/Form/Form-old.stories.tsx +0 -314
  153. package/src/util/echo.ts +0 -25
@@ -1,102 +1,13 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
- // src/translations.ts
4
- var translationKey = "@dxos/react-ui-form";
5
- var translations = [
6
- {
7
- "en-US": {
8
- [translationKey]: {
9
- "fields label": "Fields",
10
- "hidden fields label": "Hidden Fields",
11
- "empty readonly ref field label": "(none)",
12
- // TODO(burdon): Standardize field/property.
13
- "add property button label": "Add property",
14
- "field property label": "Property",
15
- "field property placeholder": "Property name",
16
- "field format label": "Type",
17
- "field path label": "Field path",
18
- "add field": "Add field",
19
- "delete field": "Delete field",
20
- "field limit reached": "Maximum number of fields reached",
21
- "boolean input true value": "Yes",
22
- "boolean input false value": "No",
23
- "show field label": "Show field",
24
- "hide field label": "Hide field",
25
- "delete field label": "Delete field",
26
- "ref field combobox input placeholder": "Search\u2026",
27
- "ref field placeholder_one": "Select\u2026",
28
- "ref field placeholder_other": "Select items\u2026",
29
- "example placeholder": "Example",
30
- "latitude placeholder": "Latitude (e.g., 40.7128)",
31
- "longitude placeholder": "Longitude (e.g., -74.0060)",
32
- "cancel button label": "Cancel",
33
- "save button label": "Save",
34
- // FormatEnum
35
- "format boolean": "Boolean",
36
- "format currency": "Currency",
37
- "format date": "Date",
38
- "format date-time": "DateTime",
39
- "format did": "DID",
40
- "format duration": "Duration",
41
- "format dxn": "DXN",
42
- "format email": "Email",
43
- "format formula": "Formula",
44
- "format hostname": "Hostname",
45
- "format integer": "Integer",
46
- "format json": "JSON",
47
- "format lnglat": "Geopoint",
48
- "format markdown": "Markdown",
49
- "format percent": "Percent",
50
- "format ref": "Reference",
51
- "format regex": "RegExp",
52
- "format string": "String",
53
- "format single-select": "Select",
54
- "format multi-select": "Multi-select",
55
- "format text": "Long text",
56
- "format time": "Time",
57
- "format timestamp": "Timestamp",
58
- "format user": "User",
59
- "format number": "Number",
60
- "format uri": "URI",
61
- "format url": "URL",
62
- "format uuid": "UUID",
63
- // GeoPointField.
64
- "latitude label": "Latitude",
65
- "longitude label": "Longitude",
66
- // SelectOptionsField.
67
- "select option label": "Label",
68
- "select option label placeholder": "Option label",
69
- "select option color": "Color",
70
- "select option delete": "Delete",
71
- "select option add": "Add option",
72
- // System schema message.
73
- "system schema title": "System type",
74
- "system schema description": "System type: cannot add or remove fields."
75
- }
76
- }
77
- }
78
- ];
79
-
80
3
  // src/components/FieldEditor/FieldEditor.tsx
81
- import React17, { useCallback as useCallback14, useEffect as useEffect7, useMemo as useMemo7, useState as useState5 } from "react";
4
+ import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
82
5
  import { Obj as Obj3 } from "@dxos/echo";
83
6
  import { Format as Format4, FormatEnums, formatToType } from "@dxos/echo/internal";
84
7
  import { log as log2 } from "@dxos/log";
85
- import { useAsyncEffect, useTranslation as useTranslation8 } from "@dxos/react-ui";
8
+ import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
86
9
  import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
87
-
88
- // src/util/echo.ts
89
- import { Obj } from "@dxos/echo";
90
- import { setValue as setValuePlain, splitJsonPath } from "@dxos/effect";
91
- var setValueEchoAware = (obj, path, value3) => {
92
- if (Obj.isObject(obj)) {
93
- Obj.change(obj, (mutableObj) => {
94
- Obj.setValue(mutableObj, splitJsonPath(path), value3);
95
- });
96
- return obj;
97
- }
98
- return setValuePlain(obj, path, value3);
99
- };
10
+ import { translationKey as translationKey9 } from "#translations";
100
11
 
101
12
  // src/util/field.ts
102
13
  import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
@@ -219,6 +130,46 @@ var pathNotUniqueError = (path) => ({
219
130
  message: `'${path}' is already present`
220
131
  });
221
132
 
133
+ // src/util/field-type.ts
134
+ import * as SchemaAST from "effect/SchemaAST";
135
+ import { getAnnotation, isLiteralUnion } from "@dxos/effect";
136
+ var detectFieldType = (ast) => {
137
+ if (isLiteralUnion(ast)) {
138
+ return "select";
139
+ }
140
+ if (SchemaAST.isTypeLiteral(ast)) {
141
+ return "struct";
142
+ }
143
+ switch (ast._tag) {
144
+ case "BooleanKeyword":
145
+ return "boolean";
146
+ case "StringKeyword":
147
+ return "string";
148
+ case "NumberKeyword":
149
+ return "number";
150
+ }
151
+ return void 0;
152
+ };
153
+ var getSelectOptionsFromAst = (ast) => {
154
+ if (!isLiteralUnion(ast)) {
155
+ return void 0;
156
+ }
157
+ return ast.types.flatMap((literalNode) => {
158
+ const value3 = literalNode.literal;
159
+ if (typeof value3 !== "string" && typeof value3 !== "number") {
160
+ return [];
161
+ }
162
+ const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
163
+ const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
164
+ return [
165
+ {
166
+ value: value3,
167
+ label
168
+ }
169
+ ];
170
+ });
171
+ };
172
+
222
173
  // src/util/formatting.ts
223
174
  import { format as formatDate } from "date-fns/format";
224
175
  import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
@@ -367,48 +318,57 @@ var getFormProperties = (ast) => {
367
318
 
368
319
  // src/util/refs.ts
369
320
  import { Ref } from "@dxos/echo";
370
- import { getArrayElementType, isArrayType } from "@dxos/effect";
321
+ import { ReferenceAnnotationId } from "@dxos/echo/internal";
322
+ import { findAnnotation, getArrayElementType, isArrayType } from "@dxos/effect";
371
323
  var getRefProps = (ast) => {
372
324
  if (isArrayType(ast)) {
373
325
  const elementType = getArrayElementType(ast);
374
326
  if (elementType) {
375
327
  if (Ref.isRefType(elementType)) {
328
+ const typename = findAnnotation(elementType, ReferenceAnnotationId)?.typename;
376
329
  return {
377
330
  ast: elementType,
378
- isArray: true
331
+ isArray: true,
332
+ typename
379
333
  };
380
334
  }
381
335
  }
382
336
  }
383
337
  if (Ref.isRefType(ast)) {
338
+ const typename = findAnnotation(ast, ReferenceAnnotationId)?.typename;
384
339
  return {
385
340
  ast,
386
- isArray: false
341
+ isArray: false,
342
+ typename
387
343
  };
388
344
  }
389
345
  return void 0;
390
346
  };
391
347
 
392
348
  // src/components/Form/fields/ArrayField.tsx
393
- import * as Option3 from "effect/Option";
394
- import * as SchemaAST2 from "effect/SchemaAST";
349
+ import * as Option4 from "effect/Option";
350
+ import * as SchemaAST4 from "effect/SchemaAST";
395
351
  import React5, { useCallback as useCallback3 } from "react";
396
352
  import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
397
353
  import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
354
+ import { translationKey as translationKey3 } from "#translations";
398
355
 
399
356
  // src/components/Form/Form.tsx
400
357
  import { createContext } from "@radix-ui/react-context";
358
+ import * as Option3 from "effect/Option";
401
359
  import * as Schema2 from "effect/Schema";
402
- import React4, { useEffect as useEffect3, useMemo as useMemo4, useRef } from "react";
360
+ import * as SchemaAST3 from "effect/SchemaAST";
361
+ import React4, { useEffect as useEffect2, useMemo as useMemo4, useRef } from "react";
362
+ import { Annotation as EchoAnnotation } from "@dxos/echo";
403
363
  import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
404
- import { IconButton, ScrollArea, useTranslation as useTranslation2 } from "@dxos/react-ui";
405
- import { mx as mx2 } from "@dxos/ui-theme";
364
+ import { IconButton, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
365
+ import { composable, composableProps, mx, withColumn } from "@dxos/ui-theme";
366
+ import { translationKey as translationKey2 } from "#translations";
406
367
 
407
368
  // src/hooks/useFormHandler.ts
408
369
  import { useControllableState } from "@radix-ui/react-use-controllable-state";
409
370
  import { useCallback, useEffect, useMemo, useState } from "react";
410
- import { Obj as Obj2 } from "@dxos/echo";
411
- import { createJsonPath, fromEffectValidationPath, getValue as getValue$, setValue as setValue$ } from "@dxos/effect";
371
+ import { createJsonPath, fromEffectValidationPath, getValue as getValue$ } from "@dxos/effect";
412
372
  import { log } from "@dxos/log";
413
373
  import { useDefaultValue } from "@dxos/react-ui";
414
374
  import { validateSchema } from "@dxos/schema";
@@ -423,11 +383,13 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
423
383
  prop: valuesProp,
424
384
  defaultProp: defaultValues,
425
385
  onChange: () => {
426
- setValues(valuesProp ?? defaultValues);
427
- setChanged({});
428
- setTouched({});
429
- setErrors({});
430
- setSaving(false);
386
+ if (valuesProp !== void 0) {
387
+ setValues(valuesProp ?? defaultValues);
388
+ setChanged({});
389
+ setTouched({});
390
+ setErrors({});
391
+ setSaving(false);
392
+ }
431
393
  }
432
394
  });
433
395
  const values = values$;
@@ -439,12 +401,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
439
401
  log("validate", {
440
402
  values: values2,
441
403
  errors: errors2
442
- }, {
443
- F: __dxlog_file,
444
- L: 160,
445
- S: void 0,
446
- C: (f, a) => f(...a)
447
- });
404
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
448
405
  if (errors2.length === 0 && onValidate) {
449
406
  const validatedValues = values2;
450
407
  errors2 = onValidate(validatedValues) ?? [];
@@ -532,48 +489,39 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
532
489
  log("onValueChange", {
533
490
  path,
534
491
  value: value3
535
- }, {
536
- F: __dxlog_file,
537
- L: 259,
538
- S: void 0,
539
- C: (f, a) => f(...a)
540
- });
492
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
541
493
  const jsonPath = createJsonPath(path);
494
+ const pathArray = path;
542
495
  let parsedValue = value3;
543
496
  try {
544
497
  if (type._tag === "NumberKeyword") {
545
498
  parsedValue = parseFloat(value3) || 0;
546
499
  }
547
500
  } catch (err) {
548
- log.catch(err, void 0, {
549
- F: __dxlog_file,
550
- L: 268,
551
- S: void 0,
552
- C: (f, a) => f(...a)
553
- });
501
+ log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
554
502
  parsedValue = void 0;
555
503
  }
556
- const newValues = Obj2.isObject(values) ? (setValueEchoAware(values, jsonPath, parsedValue), values) : {
557
- ...setValue$(values, jsonPath, parsedValue)
558
- };
559
- setValues(newValues);
504
+ const newValues = mergeAtPath(values, pathArray, parsedValue);
560
505
  const newChanged = {
561
506
  [jsonPath]: true
562
507
  };
563
- setChanged({
564
- ...changed,
508
+ setChanged((prev) => ({
509
+ ...prev,
565
510
  ...newChanged
566
- });
511
+ }));
567
512
  const isValid2 = validate(newValues);
568
513
  onValuesChanged?.(newValues, {
569
514
  isValid: isValid2,
570
515
  changed: newChanged
571
516
  });
517
+ if (valuesProp === void 0) {
518
+ setValues(newValues);
519
+ }
572
520
  }, [
573
521
  values,
574
- changed,
575
522
  validate,
576
- onValuesChanged
523
+ onValuesChanged,
524
+ valuesProp
577
525
  ]);
578
526
  const onBlur = useCallback(async (path) => {
579
527
  const jsonPath = createJsonPath(path);
@@ -630,6 +578,24 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
630
578
  onCancel
631
579
  ]);
632
580
  };
581
+ var mergeAtPath = (obj, path, value3) => {
582
+ if (path.length === 0) {
583
+ return value3;
584
+ }
585
+ const [head2, ...rest] = path;
586
+ const child = rest.length === 0 ? value3 : mergeAtPath(obj?.[head2], rest, value3);
587
+ if (Array.isArray(obj)) {
588
+ const copy = [
589
+ ...obj
590
+ ];
591
+ copy[head2] = child;
592
+ return copy;
593
+ }
594
+ return {
595
+ ...obj,
596
+ [head2]: child
597
+ };
598
+ };
633
599
  var flatMap = (errors) => {
634
600
  return errors.reduce((result, { path, message }) => {
635
601
  const jsonPath = fromEffectValidationPath(path);
@@ -641,9 +607,9 @@ var flatMap = (errors) => {
641
607
  };
642
608
 
643
609
  // src/hooks/useKeyHandler.tsx
644
- import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
610
+ import { useCallback as useCallback2, useLayoutEffect } from "react";
645
611
  import { addEventListener } from "@dxos/async";
646
- var useKeyHandler = (formElement, form) => {
612
+ var useKeyHandler = (elRef, form) => {
647
613
  const handleKeyDown = useCallback2((event) => {
648
614
  switch (event.key) {
649
615
  case "Enter": {
@@ -659,13 +625,14 @@ var useKeyHandler = (formElement, form) => {
659
625
  form.onSave,
660
626
  form.autoSave
661
627
  ]);
662
- useEffect2(() => {
663
- if (!formElement) {
628
+ useLayoutEffect(() => {
629
+ const el = elRef.current;
630
+ if (!el) {
664
631
  return;
665
632
  }
666
- return addEventListener(formElement, "keydown", handleKeyDown);
633
+ return addEventListener(el, "keydown", handleKeyDown);
667
634
  }, [
668
- formElement,
635
+ elRef,
669
636
  handleKeyDown
670
637
  ]);
671
638
  };
@@ -673,17 +640,22 @@ var useKeyHandler = (formElement, form) => {
673
640
  // src/components/Form/FormFieldComponent.tsx
674
641
  import React, { Component } from "react";
675
642
  import { Icon, Input, Tooltip } from "@dxos/react-ui";
676
- import { errorText } from "@dxos/ui-theme";
643
+ import { inputTextLabel } from "@dxos/ui-theme";
677
644
  var FormFieldLabel = ({ label, error, readonly, asChild }) => {
678
645
  const Label = readonly || asChild ? "span" : Input.Label;
679
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Label, null, label), error && /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
646
+ return /* @__PURE__ */ React.createElement("div", {
647
+ role: "none",
648
+ className: "flex items-center justify-between"
649
+ }, /* @__PURE__ */ React.createElement(Label, {
650
+ className: inputTextLabel
651
+ }, label), error && /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
680
652
  asChild: true,
681
653
  content: error,
682
654
  side: "bottom"
683
655
  }, /* @__PURE__ */ React.createElement(Icon, {
684
656
  icon: "ph--warning--regular",
685
657
  size: 4,
686
- classNames: errorText
658
+ classNames: "text-error-text"
687
659
  })));
688
660
  };
689
661
  FormFieldLabel.displayName = "Form.FieldLabel";
@@ -725,9 +697,9 @@ var FormFieldErrorBoundary = class extends Component {
725
697
  render() {
726
698
  if (this.state.error) {
727
699
  return /* @__PURE__ */ React.createElement("div", {
728
- className: "flex gap-2 border border-roseFill font-mono text-sm"
700
+ className: "flex gap-2 border border-rose-fill font-mono text-sm"
729
701
  }, /* @__PURE__ */ React.createElement("span", {
730
- className: "bg-roseFill text-surfaceText pli-1 font-thin"
702
+ className: "bg-rose-fill text-surface-text px-1 font-thin"
731
703
  }, "ERROR"), String(this.props.path?.join(".")));
732
704
  }
733
705
  return this.props.children;
@@ -740,20 +712,19 @@ var FormFieldErrorBoundary = class extends Component {
740
712
  };
741
713
 
742
714
  // src/components/Form/FormFieldSet.tsx
743
- import React3, { forwardRef, useMemo as useMemo3 } from "react";
744
- import { mx } from "@dxos/ui-theme";
745
- import { isTruthy } from "@dxos/util";
715
+ import React3, { useMemo as useMemo3 } from "react";
746
716
 
747
717
  // src/components/Form/FormField.tsx
748
718
  import * as Match from "effect/Match";
749
719
  import * as Option2 from "effect/Option";
750
720
  import * as Schema from "effect/Schema";
751
- import * as SchemaAST from "effect/SchemaAST";
721
+ import * as SchemaAST2 from "effect/SchemaAST";
752
722
  import * as String2 from "effect/String";
753
723
  import React2, { useMemo as useMemo2 } from "react";
754
724
  import { Format as Format3 } from "@dxos/echo";
755
- import { createJsonPath as createJsonPath2, findNode, getAnnotation, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion, isNestedType } from "@dxos/effect";
725
+ import { createJsonPath as createJsonPath2, findNode, getAnnotation as getAnnotation2, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion as isLiteralUnion2, isNestedType } from "@dxos/effect";
756
726
  import { useTranslation } from "@dxos/react-ui";
727
+ import { translationKey } from "#translations";
757
728
  var FormField = (props) => {
758
729
  const {
759
730
  type,
@@ -765,23 +736,25 @@ var FormField = (props) => {
765
736
  readonly,
766
737
  layout,
767
738
  // RefFieldProps
739
+ createTypename,
768
740
  createOptionLabel,
769
741
  createOptionIcon,
770
742
  createInitialValuePath,
743
+ createFieldMap: createFieldMap3,
771
744
  db,
772
- schemaHook,
773
- getOptions: getRefOptions,
745
+ useSchema: schemaHook,
746
+ getOptions,
774
747
  onCreate
775
748
  } = props;
776
749
  const { t } = useTranslation(translationKey);
777
- const title = getAnnotation(SchemaAST.TitleAnnotationId)(type);
778
- const description = getAnnotation(SchemaAST.DescriptionAnnotationId)(type);
779
- const examples = getAnnotation(SchemaAST.ExamplesAnnotationId)(type);
750
+ const title = getAnnotation2(SchemaAST2.TitleAnnotationId)(type);
751
+ const description = getAnnotation2(SchemaAST2.DescriptionAnnotationId)(type);
752
+ const examples = getAnnotation2(SchemaAST2.ExamplesAnnotationId)(type);
780
753
  const label = useMemo2(() => title ?? String2.capitalize(name), [
781
754
  title,
782
755
  name
783
756
  ]);
784
- const placeholder = useMemo2(() => examples?.length ? `${t("example placeholder")}: ${examples[0]}` : description ?? label, [
757
+ const placeholder = useMemo2(() => examples?.length ? `${t("example.placeholder")}: ${examples[0]}` : description ?? label, [
785
758
  examples,
786
759
  description,
787
760
  label
@@ -794,6 +767,7 @@ var FormField = (props) => {
794
767
  label,
795
768
  placeholder,
796
769
  layout,
770
+ db,
797
771
  ...fieldState
798
772
  };
799
773
  const jsonPath = createJsonPath2(path ?? []);
@@ -820,33 +794,41 @@ var FormField = (props) => {
820
794
  if (Field) {
821
795
  return /* @__PURE__ */ React2.createElement(Field, fieldProps);
822
796
  }
823
- const options = getOptions(type);
797
+ const options = getSelectOptions(type);
824
798
  if (options) {
799
+ const fieldProjections = projection?.getFieldProjections();
800
+ const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
801
+ const selectOptions = fieldProjection?.props.options;
825
802
  return /* @__PURE__ */ React2.createElement(SelectField, {
826
803
  ...fieldProps,
827
- options: options.map((option) => ({
828
- value: option,
829
- label: option.toString()
830
- }))
804
+ options: options.map((option) => {
805
+ const selectOption = selectOptions?.find((so) => so.id === globalThis.String(option));
806
+ return {
807
+ value: option,
808
+ label: selectOption?.title ?? option.toString()
809
+ };
810
+ })
831
811
  });
832
812
  }
833
813
  const refProps = getRefProps(type);
834
814
  if (refProps) {
815
+ const isCreateTarget = !createTypename || refProps.typename === createTypename;
835
816
  return /* @__PURE__ */ React2.createElement(RefField, {
836
817
  ...fieldProps,
837
818
  ...refProps,
838
- createOptionLabel,
839
- createOptionIcon,
840
- createInitialValuePath,
819
+ createOptionLabel: isCreateTarget ? createOptionLabel : void 0,
820
+ createOptionIcon: isCreateTarget ? createOptionIcon : void 0,
821
+ createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
822
+ createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
841
823
  db,
842
- schemaHook,
843
- getOptions: getRefOptions,
824
+ useSchema: schemaHook,
825
+ getOptions,
844
826
  onCreate
845
827
  });
846
828
  }
847
829
  if (isNestedType(type)) {
848
830
  const baseNode = findNode(type, isDiscriminatedUnion);
849
- const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST.isTypeLiteral);
831
+ const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
850
832
  if (typeLiteral) {
851
833
  const schema = Schema.make(typeLiteral);
852
834
  return /* @__PURE__ */ React2.createElement(FormFieldSet, {
@@ -862,8 +844,8 @@ var FormField = (props) => {
862
844
  createOptionIcon,
863
845
  createInitialValuePath,
864
846
  db,
865
- schemaHook,
866
- getOptions: getRefOptions,
847
+ useSchema: schemaHook,
848
+ getOptions,
867
849
  onCreate
868
850
  });
869
851
  }
@@ -887,8 +869,8 @@ var getFormField = ({ type, format }) => {
887
869
  return BooleanField;
888
870
  }
889
871
  };
890
- var getOptions = (ast) => {
891
- if (isLiteralUnion(ast)) {
872
+ var getSelectOptions = (ast) => {
873
+ if (isLiteralUnion2(ast)) {
892
874
  return ast.types.map((type) => type.literal).filter((v) => v !== null);
893
875
  }
894
876
  return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
@@ -896,47 +878,19 @@ var getOptions = (ast) => {
896
878
 
897
879
  // src/components/Form/FormFieldSet.tsx
898
880
  var FORM_FIELDSET_NAME = "Form.FieldSet";
899
- var FormFieldSet = /* @__PURE__ */ forwardRef(({ classNames, label, schema, readonly, path, exclude, sort, projection, layout, ...props }, forwardRef4) => {
881
+ var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
900
882
  const values = useFormValues(FORM_FIELDSET_NAME, path);
901
- const properties = useMemo3(() => {
902
- if (!schema) {
903
- return [];
904
- }
905
- const props2 = getFormProperties(schema.ast);
906
- if (projection) {
907
- const fieldProjections = projection.getFieldProjections();
908
- const hiddenProperties = new Set(projection.getHiddenProperties());
909
- const visibleProps = props2.filter((prop) => !hiddenProperties.has(prop.name.toString()));
910
- const orderedProps = [];
911
- for (const fieldProjection of fieldProjections) {
912
- const fieldPath = String(fieldProjection.field.path);
913
- const prop = visibleProps.find((p) => p.name === fieldPath);
914
- if (prop) {
915
- orderedProps.push(prop);
916
- }
917
- }
918
- const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
919
- const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
920
- orderedProps.push(...remainingProps);
921
- return orderedProps;
922
- }
923
- const filtered = exclude ? exclude(props2) : props2;
924
- return sort ? filtered.sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filtered;
925
- }, [
883
+ const properties = useFormFieldSetProperties({
926
884
  schema,
927
885
  values,
928
886
  exclude,
929
887
  sort,
930
- projection?.fields
931
- ]);
888
+ projection
889
+ });
932
890
  if ((readonly || layout === "static") && values == null) {
933
891
  return null;
934
892
  }
935
- return /* @__PURE__ */ React3.createElement("div", {
936
- role: "form",
937
- className: mx("is-full", layout === "inline" && "flex flex-col gap-2", classNames),
938
- ref: forwardRef4
939
- }, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
893
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
940
894
  label,
941
895
  asChild: true
942
896
  }), properties.map((property) => {
@@ -959,24 +913,72 @@ var FormFieldSet = /* @__PURE__ */ forwardRef(({ classNames, label, schema, read
959
913
  projection,
960
914
  ...props
961
915
  }));
962
- }).filter(isTruthy));
963
- });
916
+ }));
917
+ };
964
918
  FormFieldSet.displayName = FORM_FIELDSET_NAME;
919
+ var useFormFieldSetProperties = ({ schema, exclude, projection, values, sort }) => {
920
+ return useMemo3(() => {
921
+ if (!schema) {
922
+ return [];
923
+ }
924
+ const schemaProps = getFormProperties(schema.ast);
925
+ const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
926
+ if (projection) {
927
+ const fieldProjections = projection.getFieldProjections();
928
+ const hiddenProperties = new Set(projection.getHiddenProperties());
929
+ const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
930
+ const orderedProps = [];
931
+ for (const fieldProjection of fieldProjections) {
932
+ const fieldPath = String(fieldProjection.field.path);
933
+ const prop = visibleProps.find((prop2) => prop2.name === fieldPath);
934
+ if (prop) {
935
+ orderedProps.push(prop);
936
+ }
937
+ }
938
+ const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
939
+ const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
940
+ orderedProps.push(...remainingProps);
941
+ return orderedProps;
942
+ }
943
+ return sort ? [
944
+ ...filteredProps
945
+ ].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
946
+ }, [
947
+ schema,
948
+ values,
949
+ exclude,
950
+ sort,
951
+ projection
952
+ ]);
953
+ };
965
954
 
966
955
  // src/components/Form/Form.tsx
967
956
  var omitId = (schema) => schema.pipe(Schema2.omit("id"));
957
+ var omitHiddenFormFields = (schema) => {
958
+ const properties = SchemaAST3.getPropertySignatures(schema.ast);
959
+ const hidden = properties.filter((prop) => Option3.getOrElse(EchoAnnotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false).map((prop) => prop.name);
960
+ return hidden.length === 0 ? schema : schema.pipe(Schema2.omit(...hidden));
961
+ };
968
962
  var [FormContextProvider, useFormContext] = createContext("Form");
969
- var useFormValues = (componentName, path = [], defaultValue) => {
970
- const jsonPath = createJsonPath3(path);
971
- const { form: { values } } = useFormContext(componentName);
963
+ var useFormValues = (componentName, path, defaultValue) => {
964
+ const stablePath = useMemo4(() => path ?? [], [
965
+ path ? path.join(".") : void 0
966
+ ]);
967
+ const jsonPath = createJsonPath3(stablePath);
968
+ const { form: { values, onValueChange } } = useFormContext(componentName);
972
969
  const value3 = getValue$2(values, jsonPath);
973
- useEffect3(() => {
974
- if (!value3 && defaultValue) {
975
- setValueEchoAware(values, jsonPath, defaultValue());
970
+ const lastAppliedPathRef = useRef(null);
971
+ useEffect2(() => {
972
+ if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
973
+ lastAppliedPathRef.current = jsonPath;
974
+ onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
976
975
  }
977
976
  }, [
978
977
  value3,
979
- defaultValue
978
+ defaultValue,
979
+ onValueChange,
980
+ stablePath,
981
+ jsonPath
980
982
  ]);
981
983
  return value3;
982
984
  };
@@ -1013,49 +1015,60 @@ var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
1013
1015
  };
1014
1016
  FormRoot.displayName = "Form.Root";
1015
1017
  var FORM_VIEWPORT_NAME = "Form.Viewport";
1016
- var FormViewport = ({ children }) => {
1018
+ var FormViewport = composable(({ children, ...props }, forwardedRef) => {
1017
1019
  return /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
1018
- orientation: "vertical"
1020
+ ...composableProps(props),
1021
+ orientation: "vertical",
1022
+ centered: true,
1023
+ padding: true,
1024
+ thin: true,
1025
+ ref: forwardedRef
1019
1026
  }, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, children));
1020
- };
1027
+ });
1021
1028
  FormViewport.displayName = FORM_VIEWPORT_NAME;
1022
1029
  var FORM_CONTENT_NAME = "Form.Content";
1023
- var FormContent = ({ classNames, children }) => {
1030
+ var FormContent = composable(({ children, ...props }, forwardedRef) => {
1024
1031
  const { form, testId } = useFormContext(FORM_CONTENT_NAME);
1025
- const ref = useRef(null);
1026
- useKeyHandler(ref.current, form);
1032
+ const localRef = useRef(null);
1033
+ const mergedRef = useMergeRefs([
1034
+ forwardedRef,
1035
+ localRef
1036
+ ]);
1037
+ useKeyHandler(localRef, form);
1027
1038
  return /* @__PURE__ */ React4.createElement("div", {
1028
- ref,
1029
- role: "form",
1030
- className: mx2("flex flex-col is-full pli-cardSpacingInline density-fine", classNames),
1031
- "data-testid": testId
1039
+ ...composableProps(props, {
1040
+ role: "form",
1041
+ classNames: mx(withColumn.center(), "flex flex-col w-full pb-form-gap")
1042
+ }),
1043
+ "data-testid": testId,
1044
+ ref: mergedRef
1032
1045
  }, children);
1033
- };
1046
+ });
1034
1047
  FormContent.displayName = FORM_CONTENT_NAME;
1035
1048
  var FORM_FIELDSET_NAME2 = "Form.FieldSet";
1036
- var FormFieldSet2 = ({ classNames }) => {
1037
- const { form, ...props } = useFormContext(FORM_FIELDSET_NAME2);
1049
+ var FormFieldSet2 = (props) => {
1050
+ const { form, ...contextProps } = useFormContext(FORM_FIELDSET_NAME2);
1038
1051
  return /* @__PURE__ */ React4.createElement(FormFieldSet, {
1039
- classNames,
1040
1052
  schema: form.schema,
1053
+ ...contextProps,
1041
1054
  ...props
1042
1055
  });
1043
1056
  };
1044
1057
  FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
1045
1058
  var FORM_ACTIONS_NAME = "Form.Actions";
1046
1059
  var FormActions = ({ classNames }) => {
1047
- const { t } = useTranslation2(translationKey);
1060
+ const { t } = useTranslation2(translationKey2);
1048
1061
  const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
1049
1062
  if (readonly || layout === "static") {
1050
1063
  return null;
1051
1064
  }
1052
1065
  return /* @__PURE__ */ React4.createElement("div", {
1053
1066
  role: "none",
1054
- className: mx2("grid grid-flow-col auto-cols-fr gap-2 pbs-cardSpacingBlock", classNames)
1067
+ className: mx(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
1055
1068
  }, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
1056
1069
  icon: "ph--x--regular",
1057
1070
  iconEnd: true,
1058
- label: t("cancel button label"),
1071
+ label: t("cancel-button.label"),
1059
1072
  onClick: onCancel,
1060
1073
  "data-testid": "cancel-button"
1061
1074
  }), onSave && /* @__PURE__ */ React4.createElement(IconButton, {
@@ -1064,29 +1077,43 @@ var FormActions = ({ classNames }) => {
1064
1077
  disabled: !canSave,
1065
1078
  icon: "ph--check--regular",
1066
1079
  iconEnd: true,
1067
- label: t("save button label"),
1080
+ label: t("save-button.label"),
1068
1081
  onClick: onSave,
1069
1082
  "data-testid": "save-button"
1070
1083
  }));
1071
1084
  };
1072
1085
  FormActions.displayName = FORM_ACTIONS_NAME;
1086
+ var FORM_SECTION_NAME = "Form.Section";
1087
+ var FormSection = composable(({ children, label, description, ...props }, forwardedRef) => {
1088
+ return /* @__PURE__ */ React4.createElement("div", {
1089
+ ...composableProps(props, {
1090
+ classNames: "flex flex-col pt-form-section-gap first:pt-0"
1091
+ }),
1092
+ ref: forwardedRef
1093
+ }, /* @__PURE__ */ React4.createElement("h2", {
1094
+ className: "text-lg"
1095
+ }, label), description && /* @__PURE__ */ React4.createElement("p", {
1096
+ className: "text-description"
1097
+ }, description), children);
1098
+ });
1099
+ FormSection.displayName = FORM_SECTION_NAME;
1073
1100
  var FORM_SUBMIT_NAME = "Form.Submit";
1074
1101
  var FormSubmit = ({ classNames, label, icon, disabled }) => {
1075
- const { t } = useTranslation2(translationKey);
1102
+ const { t } = useTranslation2(translationKey2);
1076
1103
  const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
1077
1104
  if (readonly || layout === "static") {
1078
1105
  return null;
1079
1106
  }
1080
1107
  return /* @__PURE__ */ React4.createElement("div", {
1081
1108
  role: "none",
1082
- className: mx2("flex is-full pbs-cardSpacingBlock", classNames)
1109
+ className: mx("flex w-full pt-form-padding", classNames)
1083
1110
  }, /* @__PURE__ */ React4.createElement(IconButton, {
1084
- classNames: "is-full",
1111
+ classNames: "w-full",
1085
1112
  type: "submit",
1086
1113
  variant: "primary",
1087
1114
  disabled: disabled ?? !canSave,
1088
1115
  icon: icon ?? "ph--check--regular",
1089
- label: label ?? t("save button label"),
1116
+ label: label ?? t("save-button.label"),
1090
1117
  onClick: onSave,
1091
1118
  "data-testid": "save-button"
1092
1119
  }));
@@ -1096,26 +1123,27 @@ var Form = {
1096
1123
  Root: FormRoot,
1097
1124
  Viewport: FormViewport,
1098
1125
  Content: FormContent,
1126
+ Section: FormSection,
1099
1127
  FieldSet: FormFieldSet2,
1128
+ Label: FormFieldLabel,
1100
1129
  Actions: FormActions,
1101
- Submit: FormSubmit,
1102
- Label: FormFieldLabel
1130
+ Submit: FormSubmit
1103
1131
  };
1104
1132
 
1105
1133
  // src/components/Form/fields/ArrayField.tsx
1106
1134
  var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
1107
- const { t } = useTranslation3(translationKey);
1135
+ const { t } = useTranslation3(translationKey3);
1108
1136
  const elementType = getArrayElementType2(type);
1109
1137
  const { onValueChange } = inputProps;
1110
1138
  const values = useFormValues(ArrayField.displayName, path, () => []);
1111
1139
  const getDefaultObjectValue = (typeNode) => {
1112
1140
  const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
1113
- const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST2.isTypeLiteral);
1141
+ const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
1114
1142
  if (!typeLiteral) {
1115
1143
  return {};
1116
1144
  }
1117
1145
  return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
1118
- const defaultValue = SchemaAST2.getDefaultAnnotation(prop.type).pipe((annotation) => Option3.getOrUndefined(annotation));
1146
+ const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
1119
1147
  return [
1120
1148
  prop.name,
1121
1149
  defaultValue
@@ -1150,12 +1178,12 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1150
1178
  asChild: true
1151
1179
  }), /* @__PURE__ */ React5.createElement("div", {
1152
1180
  role: "none",
1153
- className: "flex flex-col gap-2"
1181
+ className: "flex flex-col gap-form-gap"
1154
1182
  }, values?.map((_, index) => {
1155
1183
  return /* @__PURE__ */ React5.createElement("div", {
1156
1184
  role: "none",
1157
1185
  key: index,
1158
- className: "grid grid-cols-[1fr_min-content] gap-2 last:mb-3"
1186
+ className: "grid grid-cols-[1fr_min-content] gap-form-gap last:mb-form-gap items-center"
1159
1187
  }, /* @__PURE__ */ React5.createElement(FormField, {
1160
1188
  autoFocus: index === values.length - 1,
1161
1189
  type: elementType,
@@ -1168,21 +1196,21 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
1168
1196
  ...props
1169
1197
  }), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement("div", {
1170
1198
  role: "none",
1171
- className: "flex flex-col bs-full justify-end"
1199
+ className: "flex flex-col h-full justify-end"
1172
1200
  }, /* @__PURE__ */ React5.createElement("div", {
1173
1201
  role: "none",
1174
- className: "flex items-center bs-[var(--line-height)]"
1202
+ className: "flex items-center h-[2rem]"
1175
1203
  }, /* @__PURE__ */ React5.createElement(IconButton2, {
1176
1204
  icon: "ph--x--regular",
1177
1205
  iconOnly: true,
1178
- label: t("button remove"),
1206
+ label: t("remove.button"),
1179
1207
  onClick: () => handleDelete(index),
1180
1208
  classNames: "self-center"
1181
1209
  }))));
1182
1210
  })), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
1183
- classNames: "flex is-full _mlb-cardSpacingBlock",
1211
+ classNames: "flex w-full",
1184
1212
  icon: "ph--plus--regular",
1185
- label: t("add field"),
1213
+ label: t("add-item.button"),
1186
1214
  onClick: handleAdd
1187
1215
  }));
1188
1216
  };
@@ -1230,12 +1258,13 @@ var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
1230
1258
  };
1231
1259
 
1232
1260
  // src/components/Form/fields/GeoPointField.tsx
1233
- import React7, { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo5, useState as useState2 } from "react";
1261
+ import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo as useMemo5, useState as useState2 } from "react";
1234
1262
  import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
1235
1263
  import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
1236
1264
  import { safeParseFloat } from "@dxos/util";
1265
+ import { translationKey as translationKey4 } from "#translations";
1237
1266
  var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
1238
- const { t } = useTranslation4(translationKey);
1267
+ const { t } = useTranslation4(translationKey4);
1239
1268
  const { status, error } = getStatus();
1240
1269
  const geoPoint = useMemo5(() => getValue() ?? [
1241
1270
  0,
@@ -1248,7 +1277,7 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
1248
1277
  ]);
1249
1278
  const [longitudeText, setLongitudeText] = useState2(value3.longitude?.toString());
1250
1279
  const [latitudeText, setLatitudeText] = useState2(value3.latitude?.toString());
1251
- useEffect4(() => {
1280
+ useEffect3(() => {
1252
1281
  const location = GeoLocation3.fromGeoPoint(geoPoint);
1253
1282
  setLongitudeText(location.longitude?.toString());
1254
1283
  setLatitudeText(location.latitude?.toString());
@@ -1290,24 +1319,24 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
1290
1319
  asChild: true
1291
1320
  }), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
1292
1321
  role: "none",
1293
- className: "grid grid-cols-2 gap-2"
1294
- }, /* @__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, {
1322
+ className: "grid grid-cols-2 gap-form-gap"
1323
+ }, /* @__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, {
1295
1324
  type: "number",
1296
1325
  step: "0.00001",
1297
1326
  min: "-90",
1298
1327
  max: "90",
1299
1328
  disabled: !!readonly,
1300
- placeholder: t("latitude placeholder"),
1329
+ placeholder: t("latitude.placeholder"),
1301
1330
  value: latitudeText ?? "",
1302
1331
  onChange: handleChange("latitude", setLatitudeText),
1303
1332
  onBlur
1304
- }))), /* @__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, {
1333
+ }))), /* @__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, {
1305
1334
  type: "number",
1306
1335
  step: "0.00001",
1307
1336
  min: "-180",
1308
1337
  max: "180",
1309
1338
  disabled: !!readonly,
1310
- placeholder: t("longitude placeholder"),
1339
+ placeholder: t("longitude.placeholder"),
1311
1340
  value: longitudeText ?? "",
1312
1341
  onChange: handleChange("longitude", setLongitudeText),
1313
1342
  onBlur
@@ -1317,7 +1346,7 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
1317
1346
  const latHem = latitude >= 0 ? "N" : "S";
1318
1347
  const lngHem = longitude >= 0 ? "E" : "W";
1319
1348
  return /* @__PURE__ */ React7.createElement("span", {
1320
- className: "inline-flex items-center gap-1"
1349
+ className: "inline-flex items-center gap-form-gap"
1321
1350
  }, /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
1322
1351
  className: "text-subdued"
1323
1352
  }, "\xB0", latHem)), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
@@ -1326,56 +1355,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
1326
1355
  };
1327
1356
 
1328
1357
  // src/components/Form/fields/MarkdownField.tsx
1329
- import React8, { useCallback as useCallback6, useEffect as useEffect5, useRef as useRef2 } from "react";
1330
- import { Input as Input4 } from "@dxos/react-ui";
1331
- var MarkdownField = ({ type, readonly, label, placeholder, layout, getStatus, getValue, onValueChange, onBlur }) => {
1358
+ import { useAtomValue } from "@effect-atom/atom-react";
1359
+ import React8, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
1360
+ import { Obj, Ref as Ref2 } from "@dxos/echo";
1361
+ import { AtomRef } from "@dxos/echo-atom";
1362
+ import { createDocAccessor } from "@dxos/echo-db";
1363
+ import { Button, Icon as Icon2, Input as Input4, useTranslation as useTranslation5 } from "@dxos/react-ui";
1364
+ import { Editor, useBasicMarkdownExtensions } from "@dxos/react-ui-editor";
1365
+ import { Text } from "@dxos/schema";
1366
+ import { createDataExtensions } from "@dxos/ui-editor";
1367
+ import { translationKey as translationKey5 } from "#translations";
1368
+ var editorClassNames = "transition-colors bg-input-surface focus-within:bg-focus-surface border border-separator rounded-xs p-1 px-2";
1369
+ var MarkdownField = ({ type, readonly, label, placeholder, layout, db, getStatus, getValue, onValueChange }) => {
1332
1370
  const { status, error } = getStatus();
1333
- const textareaRef = useRef2(null);
1334
- const adjustHeight = useCallback6(() => {
1335
- const textarea = textareaRef.current;
1336
- if (textarea) {
1337
- textarea.style.blockSize = "auto";
1338
- textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
1339
- }
1340
- }, []);
1341
- useEffect5(() => {
1342
- adjustHeight();
1343
- }, [
1344
- adjustHeight
1345
- ]);
1346
- useEffect5(() => {
1347
- adjustHeight();
1348
- }, [
1349
- getValue(),
1350
- adjustHeight
1351
- ]);
1352
- const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
1353
- type,
1354
- onValueChange
1355
- ]);
1371
+ const isRef = Ref2.isRefType(type);
1356
1372
  const value3 = getValue();
1357
- if ((readonly || layout === "static") && !value3) {
1373
+ if ((readonly || layout === "static") && value3 == null) {
1358
1374
  return null;
1359
1375
  }
1376
+ const renderEditor = () => {
1377
+ if (isRef) {
1378
+ const reference = value3;
1379
+ if (reference) {
1380
+ return /* @__PURE__ */ React8.createElement(RefMarkdownEditor, {
1381
+ reference,
1382
+ placeholder
1383
+ });
1384
+ }
1385
+ if (readonly) {
1386
+ return null;
1387
+ }
1388
+ return /* @__PURE__ */ React8.createElement(CreateTextButton, {
1389
+ db,
1390
+ disabled: !db,
1391
+ onCreate: (ref) => onValueChange(type, ref)
1392
+ });
1393
+ }
1394
+ return /* @__PURE__ */ React8.createElement(StringMarkdownEditor, {
1395
+ value: value3 ?? "",
1396
+ placeholder,
1397
+ readonly: !!readonly,
1398
+ onChange: (next) => onValueChange(type, next)
1399
+ });
1400
+ };
1401
+ const renderStatic = () => {
1402
+ if (isRef) {
1403
+ const reference = value3;
1404
+ return reference ? /* @__PURE__ */ React8.createElement(RefStaticText, {
1405
+ reference
1406
+ }) : null;
1407
+ }
1408
+ return /* @__PURE__ */ React8.createElement("p", {
1409
+ className: "whitespace-pre-wrap"
1410
+ }, value3 ?? "");
1411
+ };
1360
1412
  return /* @__PURE__ */ React8.createElement(Input4.Root, {
1361
1413
  validationValence: status
1362
1414
  }, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
1363
1415
  error,
1364
1416
  readonly,
1365
1417
  label
1366
- }), layout === "static" ? /* @__PURE__ */ React8.createElement("p", null, value3) : /* @__PURE__ */ React8.createElement(Input4.TextArea, {
1367
- ref: textareaRef,
1368
- disabled: !!readonly,
1418
+ }), layout === "static" ? renderStatic() : renderEditor(), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
1419
+ };
1420
+ var RefStaticText = ({ reference }) => {
1421
+ const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
1422
+ reference
1423
+ ]));
1424
+ if (!text?.content) {
1425
+ return null;
1426
+ }
1427
+ return /* @__PURE__ */ React8.createElement("p", {
1428
+ className: "whitespace-pre-wrap"
1429
+ }, text.content);
1430
+ };
1431
+ var RefMarkdownEditor = ({ reference, placeholder }) => {
1432
+ const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
1433
+ reference
1434
+ ]));
1435
+ const dataExtensions = useMemo6(() => text ? [
1436
+ createDataExtensions({
1437
+ id: reference.dxn.toString(),
1438
+ text: createDocAccessor(text, [
1439
+ "content"
1440
+ ])
1441
+ })
1442
+ ] : [], [
1443
+ text,
1444
+ reference
1445
+ ]);
1446
+ const extensions = useBasicMarkdownExtensions({
1369
1447
  placeholder,
1370
- value: value3 ?? "",
1371
- classNames: "min-bs-auto max-bs-40 overflow-auto",
1372
- onChange: handleChange,
1373
- onBlur,
1374
- style: {
1375
- resize: "none"
1376
- },
1377
- spellCheck: false
1378
- }), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
1448
+ extensions: dataExtensions
1449
+ });
1450
+ if (!text) {
1451
+ return null;
1452
+ }
1453
+ return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
1454
+ classNames: editorClassNames,
1455
+ extensions
1456
+ }));
1457
+ };
1458
+ var StringMarkdownEditor = ({ value: value3, placeholder, readonly, onChange }) => {
1459
+ const extensions = useBasicMarkdownExtensions({
1460
+ placeholder
1461
+ });
1462
+ const handleChange = useCallback6((next) => onChange(next), [
1463
+ onChange
1464
+ ]);
1465
+ return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
1466
+ classNames: editorClassNames,
1467
+ extensions,
1468
+ value: value3,
1469
+ onChange: readonly ? void 0 : handleChange
1470
+ }));
1471
+ };
1472
+ var CreateTextButton = ({ db, disabled, onCreate }) => {
1473
+ const { t } = useTranslation5(translationKey5);
1474
+ const handleClick = useCallback6(() => {
1475
+ if (!db) {
1476
+ return;
1477
+ }
1478
+ const text = db.add(Obj.make(Text.Text, {
1479
+ content: ""
1480
+ }));
1481
+ onCreate(Ref2.make(text));
1482
+ }, [
1483
+ db,
1484
+ onCreate
1485
+ ]);
1486
+ return /* @__PURE__ */ React8.createElement(Button, {
1487
+ onClick: handleClick,
1488
+ disabled
1489
+ }, /* @__PURE__ */ React8.createElement(Icon2, {
1490
+ icon: "ph--plus--regular",
1491
+ size: 4
1492
+ }), /* @__PURE__ */ React8.createElement("span", null, t("create-text.label")));
1379
1493
  };
1380
1494
 
1381
1495
  // src/components/Form/fields/NumberField.tsx
@@ -1401,47 +1515,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
1401
1515
  };
1402
1516
 
1403
1517
  // src/components/Form/fields/RefField.tsx
1518
+ import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
1404
1519
  import "@dxos/lit-ui/dx-tag-picker.pcss";
1405
- import React11, { useCallback as useCallback9, useMemo as useMemo6 } from "react";
1406
- import { Entity, Filter, Ref as Ref2, Type } from "@dxos/echo";
1407
- import { ReferenceAnnotationId } from "@dxos/echo/internal";
1408
- import { useQuery, useSchema as useSchema$ } from "@dxos/echo-react";
1409
- import { findAnnotation } from "@dxos/effect";
1520
+ import { Entity, Filter, Obj as Obj2, Ref as Ref3, Type } from "@dxos/echo";
1521
+ import { useQuery, useSchema as defaultUseSchema } from "@dxos/echo-react";
1522
+ import { ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo/internal";
1523
+ import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1410
1524
  import { DXN } from "@dxos/keys";
1411
1525
  import { DxAnchor } from "@dxos/lit-ui/react";
1412
- import { Button, Icon as Icon2, Input as Input6, useTranslation as useTranslation6 } from "@dxos/react-ui";
1413
- import { descriptionText, mx as mx3 } from "@dxos/ui-theme";
1526
+ import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
1527
+ import { ParentLabelAnnotationId } from "@dxos/schema";
1528
+ import { translationKey as translationKey7 } from "#translations";
1414
1529
 
1415
1530
  // src/components/ObjectPicker/ObjectPicker.tsx
1416
- import React10, { forwardRef as forwardRef2, useCallback as useCallback8, useState as useState3 } from "react";
1417
- import { Popover, useTranslation as useTranslation5 } from "@dxos/react-ui";
1418
- import { Combobox, useSearchListInput, useSearchListResults } from "@dxos/react-ui-searchlist";
1419
- var CreateItem = ({ createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1420
- const { t } = useTranslation5(translationKey);
1421
- const { query } = useSearchListInput();
1422
- return /* @__PURE__ */ React10.createElement(Combobox.Item, {
1423
- value: "__create__",
1424
- label: t(createOptionLabel[0], {
1425
- ns: createOptionLabel[1].ns,
1426
- text: query
1427
- }),
1428
- icon: createOptionIcon,
1429
- classNames: "flex items-center gap-2",
1430
- closeOnSelect: false,
1431
- onSelect: () => {
1432
- onCreateItemSelect(query);
1433
- }
1434
- });
1435
- };
1436
- var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
1437
- const { t } = useTranslation5(translationKey);
1531
+ import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
1532
+ import { Popover, useTranslation as useTranslation6 } from "@dxos/react-ui";
1533
+ import { Combobox } from "@dxos/react-ui-list";
1534
+ import { useSearchListResults } from "@dxos/react-ui-search";
1535
+ import { translationKey as translationKey6 } from "#translations";
1536
+ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
1537
+ const { t } = useTranslation6(translationKey6);
1438
1538
  const [showForm, setShowForm] = useState3(false);
1439
1539
  const [formInitialValue, setFormInitialValue] = useState3("");
1440
- const { results, handleSearch } = useSearchListResults({
1540
+ const { results, query, handleSearch } = useSearchListResults({
1441
1541
  items: options
1442
1542
  });
1443
- const handleFormSave = useCallback8((values) => {
1444
- onCreate?.(values);
1543
+ const handleFormSave = useCallback8(async (values) => {
1544
+ await onCreate?.(values);
1445
1545
  setShowForm(false);
1446
1546
  setFormInitialValue("");
1447
1547
  }, [
@@ -1463,22 +1563,31 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
1463
1563
  }, [
1464
1564
  createSchema
1465
1565
  ]);
1566
+ if (showForm && createSchema) {
1567
+ return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1568
+ ...props,
1569
+ onKeyDownCapture: handleKeyDown,
1570
+ ref: forwardedRef
1571
+ }, /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
1572
+ testId: "create-referenced-object-form",
1573
+ schema: createSchema,
1574
+ defaultValues: createInitialValuePath ? {
1575
+ [createInitialValuePath]: formInitialValue
1576
+ } : {},
1577
+ fieldMap: createFieldMap3,
1578
+ onSave: handleFormSave,
1579
+ onCancel: handleFormCancel
1580
+ }, /* @__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));
1581
+ }
1466
1582
  return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1467
1583
  ...props,
1468
- ref,
1469
- onSearch: handleSearch,
1470
- onKeyDownCapture: handleKeyDown
1471
- }, showForm && createSchema ? /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
1472
- testId: "create-referenced-object-form",
1473
- schema: createSchema,
1474
- values: createInitialValuePath ? {
1475
- [createInitialValuePath]: formInitialValue
1476
- } : {},
1477
- onSave: handleFormSave,
1478
- onCancel: handleFormCancel
1479
- }, /* @__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, {
1480
- placeholder: t("ref field combobox input placeholder"),
1481
- autoFocus: true
1584
+ onKeyDownCapture: handleKeyDown,
1585
+ ref: forwardedRef
1586
+ }, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1587
+ placeholder: t("ref-field-combobox-input.placeholder"),
1588
+ autoFocus: true,
1589
+ value: query,
1590
+ onValueChange: handleSearch
1482
1591
  }), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1483
1592
  key: option.id,
1484
1593
  value: option.id,
@@ -1486,16 +1595,34 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
1486
1595
  checked: selectedIds?.includes(option.id),
1487
1596
  onSelect: () => onSelect(option.id),
1488
1597
  classNames: "flex items-center gap-2"
1489
- })), createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
1598
+ })), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
1599
+ query,
1490
1600
  createOptionLabel,
1491
- createOptionIcon,
1492
- onCreateItemSelect: (query) => {
1493
- setFormInitialValue(query);
1601
+ createOptionIcon: createOptionIcon ?? "ph--plus--regular",
1602
+ onCreateItemSelect: (currentQuery) => {
1603
+ setFormInitialValue(currentQuery);
1494
1604
  setShowForm(true);
1495
1605
  }
1496
- }))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1606
+ })), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1497
1607
  });
1498
- ObjectPickerContent.displayName = "ObjectPickerContent";
1608
+ var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
1609
+ const { t } = useTranslation6(translationKey6);
1610
+ const label = createOptionLabel ? t(createOptionLabel[0], {
1611
+ ns: createOptionLabel[1].ns,
1612
+ text: query
1613
+ }) : t("create-option.label");
1614
+ return /* @__PURE__ */ React10.createElement(Combobox.Item, {
1615
+ value: "__create__",
1616
+ label,
1617
+ icon: createOptionIcon,
1618
+ classNames: "flex items-center gap-2",
1619
+ closeOnSelect: false,
1620
+ onSelect: () => {
1621
+ onCreateItemSelect(query);
1622
+ }
1623
+ });
1624
+ };
1625
+ ObjectPickerContent.displayName = "ObjectPicker.Content";
1499
1626
  var ObjectPicker = {
1500
1627
  Root: Combobox.Root,
1501
1628
  Portal: Combobox.Portal,
@@ -1508,34 +1635,43 @@ var ObjectPicker = {
1508
1635
  var isRefSnapshot = (val) => {
1509
1636
  return typeof val === "object" && typeof val?.["/"] === "string";
1510
1637
  };
1511
- var defaultGetOptions = (results) => results.map((result) => {
1638
+ var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
1512
1639
  const id = Entity.getDXN(result).toString();
1513
- const label = Entity.getLabel(result);
1640
+ const parent = parentLabel ? Obj2.getParent(result) : void 0;
1641
+ const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
1514
1642
  return {
1515
1643
  id,
1516
1644
  label: label ?? id
1517
1645
  };
1518
1646
  });
1519
- var defaultResultsHook = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Type.Obj) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
1647
+ var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
1520
1648
  var RefField = (props) => {
1521
- const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db, resultsHook: useResults = defaultResultsHook, schemaHook: useSchema = useSchema$, getOptions: getOptions2 = defaultGetOptions, onCreate, onValueChange } = props;
1522
- const { t } = useTranslation6(translationKey);
1649
+ const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useSchema = defaultUseSchema, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
1650
+ const { t } = useTranslation7(translationKey7);
1523
1651
  const { status, error } = getStatus();
1524
- const typename = useMemo6(() => type ? findAnnotation(type, ReferenceAnnotationId)?.typename : void 0, [
1652
+ const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
1525
1653
  type
1526
1654
  ]);
1527
1655
  const results = useResults(db, typename);
1528
- const options = useMemo6(() => getOptions2(results), [
1656
+ const options = useMemo7(() => {
1657
+ const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
1658
+ return getOptions(results, {
1659
+ parentLabel
1660
+ });
1661
+ }, [
1529
1662
  results,
1530
- getOptions2
1663
+ getOptions,
1664
+ type
1531
1665
  ]);
1532
1666
  const handleGetValue = useCallback9(() => {
1533
1667
  const formValue = getValue();
1668
+ const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
1534
1669
  const unknownToRefOption = (value3) => {
1535
- const isRef = Ref2.isRef(value3);
1670
+ const isRef = Ref3.isRef(value3);
1536
1671
  if (isRef || isRefSnapshot(value3)) {
1537
1672
  const dxnString = isRef ? value3.dxn.toString() : value3["/"];
1538
- const matchingOption = options.find((option) => option.id === dxnString);
1673
+ const objectId = dxnToObjectId(dxnString);
1674
+ const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
1539
1675
  if (matchingOption) {
1540
1676
  return matchingOption;
1541
1677
  }
@@ -1547,29 +1683,37 @@ var RefField = (props) => {
1547
1683
  options,
1548
1684
  getValue
1549
1685
  ]);
1550
- const handleUpdate = useCallback9((id) => {
1551
- const item2 = options.find((option) => option.id === id);
1552
- const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
1553
- onValueChange(type, ref);
1554
- }, [
1555
- options,
1556
- type,
1557
- onValueChange
1558
- ]);
1559
1686
  const item = handleGetValue();
1560
- const selectedIds = useMemo6(() => item ? [
1687
+ const selectedIds = useMemo7(() => item ? [
1561
1688
  item.id
1562
1689
  ] : [], [
1563
1690
  item
1564
1691
  ]);
1565
1692
  const createSchema = useSchema(db, typename);
1566
- const handleCreate = useCallback9((values) => {
1567
- if (createSchema && onCreate) {
1568
- onCreate(createSchema, values);
1693
+ const [open, setOpen] = useState4(false);
1694
+ const handleCreate = useCallback9(async (values) => {
1695
+ if (!createSchema || !onCreate) {
1696
+ return;
1697
+ }
1698
+ const newObject = await onCreate(createSchema, values);
1699
+ if (newObject) {
1700
+ onValueChange(type, Ref3.make(newObject));
1569
1701
  }
1702
+ setOpen(false);
1570
1703
  }, [
1571
1704
  createSchema,
1572
- onCreate
1705
+ onCreate,
1706
+ type,
1707
+ onValueChange
1708
+ ]);
1709
+ const handleUpdate = useCallback9((id) => {
1710
+ const item2 = options.find((option) => option.id === id);
1711
+ const ref = item2 ? Ref3.fromDXN(DXN.parse(item2.id)) : void 0;
1712
+ onValueChange(type, ref);
1713
+ }, [
1714
+ options,
1715
+ type,
1716
+ onValueChange
1573
1717
  ]);
1574
1718
  const handleSelect = useCallback9((id) => {
1575
1719
  if (item?.id === id) {
@@ -1591,40 +1735,48 @@ var RefField = (props) => {
1591
1735
  readonly,
1592
1736
  label
1593
1737
  }), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
1594
- className: mx3(descriptionText, "mbe-2")
1595
- }, t("empty readonly ref field label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
1738
+ className: "text-description mb-2"
1739
+ }, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
1596
1740
  key: item.id,
1597
1741
  dxn: item.id,
1598
- rootclassname: "mie-1"
1599
- }, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1742
+ rootclassname: "me-1"
1743
+ }, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, {
1744
+ open,
1745
+ onOpenChange: setOpen
1746
+ }, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1600
1747
  asChild: true,
1601
1748
  classNames: "p-0"
1602
1749
  }, item ? /* @__PURE__ */ React11.createElement("div", {
1603
- className: "flex gap-2 is-full"
1750
+ role: "none",
1751
+ className: "flex gap-form-gap w-full"
1604
1752
  }, /* @__PURE__ */ React11.createElement(Input6.Root, {
1605
1753
  key: item.id
1606
1754
  }, /* @__PURE__ */ React11.createElement(Input6.TextInput, {
1607
1755
  value: item.label,
1608
1756
  readOnly: true,
1609
- classNames: "is-full"
1610
- }))) : /* @__PURE__ */ React11.createElement(Button, {
1611
- classNames: "is-full text-start gap-2"
1757
+ classNames: "w-full"
1758
+ }))) : /* @__PURE__ */ React11.createElement(Button2, {
1759
+ classNames: "w-full text-start gap-form-gap"
1612
1760
  }, /* @__PURE__ */ React11.createElement("div", {
1613
1761
  role: "none",
1614
1762
  className: "grow overflow-hidden"
1615
1763
  }, /* @__PURE__ */ React11.createElement("span", {
1616
- className: "flex truncate text-description"
1617
- }, placeholder ?? t("ref field placeholder"))), /* @__PURE__ */ React11.createElement(Icon2, {
1764
+ className: "truncate text-description"
1765
+ }, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
1618
1766
  size: 3,
1619
1767
  icon: "ph--caret-down--bold"
1620
1768
  }))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
1621
- classNames: "popover-card-width",
1769
+ classNames: "dx-card-popover-width",
1622
1770
  options,
1623
1771
  selectedIds,
1624
- createSchema: createSchema && omitId(createSchema),
1772
+ // Strip hidden (`FormInputAnnotation.set(false)`) fields so the
1773
+ // form's validator doesn't reject required-but-hidden fields
1774
+ // such as backing-object refs supplied by a `FactoryAnnotation`.
1775
+ createSchema: createSchema && omitHiddenFormFields(omitId(createSchema)),
1625
1776
  createOptionLabel,
1626
1777
  createOptionIcon,
1627
1778
  createInitialValuePath,
1779
+ createFieldMap: createFieldMap3,
1628
1780
  onCreate: handleCreate,
1629
1781
  onSelect: handleSelect
1630
1782
  })))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
@@ -1653,7 +1805,7 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
1653
1805
  value: value3,
1654
1806
  onValueChange: handleValueChange
1655
1807
  }, /* @__PURE__ */ React12.createElement(Select.TriggerButton, {
1656
- classNames: "is-full",
1808
+ classNames: "w-full",
1657
1809
  disabled: !!readonly,
1658
1810
  placeholder
1659
1811
  }), /* @__PURE__ */ React12.createElement(Select.Portal, null, /* @__PURE__ */ React12.createElement(Select.Content, null, /* @__PURE__ */ React12.createElement(Select.Viewport, null, options?.map(({ value: value4, label: label2 }) => (
@@ -1666,20 +1818,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
1666
1818
  };
1667
1819
 
1668
1820
  // src/components/Form/fields/SelectOptionField.tsx
1669
- import React13, { useCallback as useCallback11, useEffect as useEffect6, useRef as useRef3, useState as useState4 } from "react";
1821
+ import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
1670
1822
  import { PublicKey } from "@dxos/keys";
1671
- import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation7 } from "@dxos/react-ui";
1823
+ import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
1672
1824
  import { List } from "@dxos/react-ui-list";
1673
1825
  import { HuePicker } from "@dxos/react-ui-pickers";
1674
1826
  import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
1827
+ import { translationKey as translationKey8 } from "#translations";
1675
1828
  var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
1676
- const { t } = useTranslation7(translationKey);
1829
+ const { t } = useTranslation8(translationKey8);
1677
1830
  const { status, error } = getStatus();
1678
- const [selected, setSelectedId] = useState4(null);
1679
- const [isNewOption, setIsNewOption] = useState4(false);
1680
- const inputRef = useRef3(null);
1831
+ const [selected, setSelectedId] = useState5(null);
1832
+ const [isNewOption, setIsNewOption] = useState5(false);
1833
+ const inputRef = useRef2(null);
1681
1834
  const options = getValue();
1682
- useEffect6(() => {
1835
+ useEffect4(() => {
1683
1836
  if (options === void 0) {
1684
1837
  onValueChange(type, []);
1685
1838
  }
@@ -1770,7 +1923,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1770
1923
  type,
1771
1924
  onValueChange
1772
1925
  ]);
1773
- useEffect6(() => {
1926
+ useEffect4(() => {
1774
1927
  if (selected && isNewOption && inputRef.current) {
1775
1928
  inputRef.current.focus();
1776
1929
  setIsNewOption(false);
@@ -1794,7 +1947,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1794
1947
  readonly: !!readonly
1795
1948
  }, ({ items }) => /* @__PURE__ */ React13.createElement("div", {
1796
1949
  role: "list",
1797
- className: "is-full overflow-auto"
1950
+ className: "w-full overflow-auto"
1798
1951
  }, items?.map((item) => /* @__PURE__ */ React13.createElement("div", {
1799
1952
  key: item.id
1800
1953
  }, /* @__PURE__ */ React13.createElement(List.Item, {
@@ -1802,7 +1955,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1802
1955
  item,
1803
1956
  classNames: [
1804
1957
  subtleHover,
1805
- "flex flex-col cursor-pointer rounded-sm"
1958
+ "flex flex-col cursor-pointer rounded-xs"
1806
1959
  ],
1807
1960
  "aria-expanded": selected === item.id
1808
1961
  }, /* @__PURE__ */ React13.createElement("div", {
@@ -1817,20 +1970,20 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1817
1970
  }, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
1818
1971
  iconOnly: true,
1819
1972
  variant: "ghost",
1820
- label: t(selected === item.id ? "collapse label" : "expand label", {
1973
+ label: t(selected === item.id ? "collapse.label" : "expand.label", {
1821
1974
  ns: osTranslations
1822
1975
  }),
1823
1976
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
1824
1977
  onClick: () => handleClick(item.id)
1825
1978
  })), selected === item.id && /* @__PURE__ */ React13.createElement("div", {
1826
- className: "pli-cardSpacingInline plb-cardSpacingBlock flex flex-col gap-1 density-fine"
1979
+ className: "flex flex-col p-form-padding gap-form-gap dx-density-fine"
1827
1980
  }, /* @__PURE__ */ React13.createElement(Input8.Label, {
1828
1981
  classNames: "text-xs"
1829
- }, t("select option label")), /* @__PURE__ */ React13.createElement("div", {
1830
- className: "grid grid-cols-[1fr_min-content_min-content] gap-1"
1982
+ }, t("select-option.label")), /* @__PURE__ */ React13.createElement("div", {
1983
+ className: "grid grid-cols-[1fr_min-content_min-content] gap-form-gap"
1831
1984
  }, /* @__PURE__ */ React13.createElement(Input8.TextInput, {
1832
1985
  disabled: !!readonly,
1833
- placeholder: t("select option label placeholder"),
1986
+ placeholder: t("select-option-label.placeholder"),
1834
1987
  ref: selected === item.id ? inputRef : void 0,
1835
1988
  value: item.title,
1836
1989
  onChange: handleTitleChange(item.id),
@@ -1844,22 +1997,22 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
1844
1997
  disabled: !!readonly,
1845
1998
  icon: "ph--trash--fill",
1846
1999
  iconOnly: true,
1847
- label: t("select option delete"),
2000
+ label: t("select-option-delete.button"),
1848
2001
  onClick: () => handleDelete(item.id)
1849
2002
  })))))), /* @__PURE__ */ React13.createElement(IconButton3, {
1850
2003
  variant: "ghost",
1851
2004
  icon: "ph--plus--regular",
1852
- label: t("select option add"),
2005
+ label: t("select-option-add.button"),
1853
2006
  onClick: handleAdd,
1854
2007
  disabled: !!readonly,
1855
- classNames: "is-full"
2008
+ classNames: "w-full"
1856
2009
  })))));
1857
2010
  };
1858
2011
 
1859
2012
  // src/components/Form/fields/TextField.tsx
1860
2013
  import React14, { useCallback as useCallback12 } from "react";
1861
2014
  import { Input as Input9 } from "@dxos/react-ui";
1862
- var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
2015
+ var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
1863
2016
  const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
1864
2017
  type,
1865
2018
  onValueChange
@@ -1872,8 +2025,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
1872
2025
  disabled: !!readonly,
1873
2026
  placeholder,
1874
2027
  value: value3,
1875
- onChange: handleChange,
1876
- onBlur
2028
+ onBlur,
2029
+ onChange: handleChange
1877
2030
  }));
1878
2031
  };
1879
2032
 
@@ -1901,7 +2054,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
1901
2054
  // src/components/Form/fields/TupleField.tsx
1902
2055
  import React16 from "react";
1903
2056
  import { Input as Input11 } from "@dxos/react-ui";
1904
- import { mx as mx4 } from "@dxos/ui-theme";
2057
+ import { mx as mx2 } from "@dxos/ui-theme";
1905
2058
  import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
1906
2059
  var gridCols = [
1907
2060
  "grid-cols-1",
@@ -1919,7 +2072,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
1919
2072
  readonly,
1920
2073
  label
1921
2074
  }), /* @__PURE__ */ React16.createElement("div", {
1922
- className: mx4("grid gap-2", gridCols[binding.length - 1])
2075
+ className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
1923
2076
  }, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
1924
2077
  key: prop,
1925
2078
  type: "number",
@@ -1938,13 +2091,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
1938
2091
  // src/components/FieldEditor/FieldEditor.tsx
1939
2092
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1940
2093
  var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
1941
- const { t } = useTranslation8(translationKey);
1942
- const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
1943
- useEffect7(() => setProps(projection.getFieldProjection(field.id).props), [
2094
+ const { t } = useTranslation9(translationKey9);
2095
+ const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
2096
+ useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
1944
2097
  field,
1945
2098
  projection
1946
2099
  ]);
1947
- const [schemas, setSchemas] = useState5([]);
2100
+ const [schemas, setSchemas] = useState6([]);
1948
2101
  useAsyncEffect(async () => {
1949
2102
  if (!registry) {
1950
2103
  return;
@@ -1958,22 +2111,22 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
1958
2111
  }, [
1959
2112
  registry
1960
2113
  ]);
1961
- const [referenceSchema, setReferenceSchema] = useState5();
1962
- useEffect7(() => {
2114
+ const [referenceSchema, setReferenceSchema] = useState6();
2115
+ useEffect5(() => {
1963
2116
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
1964
2117
  }, [
1965
2118
  schemas,
1966
2119
  props?.referenceSchema
1967
2120
  ]);
1968
- const [{ fieldSchema }, setFieldSchema] = useState5({
2121
+ const [{ fieldSchema }, setFieldSchema] = useState6({
1969
2122
  fieldSchema: getFormatSchema(props?.format)
1970
2123
  });
1971
- const fieldMap = useMemo7(() => ({
2124
+ const fieldMap = useMemo8(() => ({
1972
2125
  ["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
1973
2126
  ...props2,
1974
2127
  options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
1975
2128
  value: value3,
1976
- label: t(`format ${value3}`)
2129
+ label: t(`format.${value3}.label`)
1977
2130
  }))
1978
2131
  }),
1979
2132
  ["referenceSchema"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
@@ -2047,7 +2200,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2047
2200
  ]);
2048
2201
  const handleSave = useCallback14((props2) => {
2049
2202
  if (view) {
2050
- Obj3.change(view, () => {
2203
+ Obj3.update(view, () => {
2051
2204
  projection.setFieldProjection({
2052
2205
  field,
2053
2206
  props: props2
@@ -2075,12 +2228,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2075
2228
  if (!fieldSchema) {
2076
2229
  log2.warn("invalid format", {
2077
2230
  props
2078
- }, {
2079
- F: __dxlog_file2,
2080
- L: 173,
2081
- S: void 0,
2082
- C: (f, a) => f(...a)
2083
- });
2231
+ }, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
2084
2232
  return null;
2085
2233
  }
2086
2234
  return /* @__PURE__ */ React17.createElement(Form.Root, {
@@ -2102,160 +2250,491 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
2102
2250
  }, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
2103
2251
  };
2104
2252
 
2105
- // src/components/Settings/Settings.tsx
2106
- import React18 from "react";
2107
- import { Button as Button2, Input as Input12, ScrollArea as ScrollArea2, toLocalizedString, useTranslation as useTranslation9 } from "@dxos/react-ui";
2108
- import { mx as mx5 } from "@dxos/ui-theme";
2109
- var SETTINGS_ROOT_NAME = "Settings.Root";
2110
- var SETTINGS_SECTION_NAME = "Settings.Section";
2111
- var SETTINGS_SECTION_HEADING_NAME = "Settings.SectionHeading";
2112
- var SETTINGS_GROUP_NAME = "Settings.Group";
2113
- var SETTINGS_GROUP_BUTTON_NAME = "Settings.GroupButton";
2114
- var SETTINGS_CONTAINER_NAME = "Settings.Container";
2115
- var SETTINGS_FRAME_NAME = "Settings.Frame";
2116
- var SETTINGS_FRAME_ITEM_NAME = "Settings.FrameItem";
2117
- var SETTINGS_ITEM_NAME = "Settings.Item";
2118
- var SETTINGS_ITEM_INPUT_NAME = "Settings.ItemInput";
2119
- var styles = {
2120
- title: "pbe-trimMd text-baseText text-lg",
2121
- description: "text-base text-description",
2122
- grid: "grid grid-cols-1 md:grid-cols-[3fr_2fr] gap-x-trimLg"
2123
- };
2124
- var SettingsRoot = ({ children }) => {
2125
- return /* @__PURE__ */ React18.createElement(ScrollArea2.Root, {
2126
- orientation: "vertical"
2127
- }, /* @__PURE__ */ React18.createElement(ScrollArea2.Viewport, {
2128
- classNames: "p-trimMd"
2129
- }, children));
2130
- };
2131
- SettingsRoot.displayName = SETTINGS_ROOT_NAME;
2132
- var SettingsSection = ({ title, description, children }) => {
2133
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SettingsSectionHeading, {
2134
- title,
2135
- description
2136
- }), /* @__PURE__ */ React18.createElement("div", {
2137
- className: "is-full pbs-trimMd space-y-trimMd"
2138
- }, children));
2139
- };
2140
- SettingsSection.displayName = SETTINGS_SECTION_NAME;
2141
- var SettingsSectionHeading = ({ title, description }) => {
2142
- const { t } = useTranslation9(translationKey);
2143
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("h2", {
2144
- className: "pli-trimMd container-max-width text-xl mbs-trimMd mbe-trimMd"
2145
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
2146
- className: "pli-trimMd mlb-trimMd container-max-width text-description"
2147
- }, toLocalizedString(description, t)));
2253
+ // src/components/ObjectForm/ObjectForm.tsx
2254
+ import * as Schema3 from "effect/Schema";
2255
+ import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
2256
+ import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
2257
+ import { splitJsonPath } from "@dxos/echo/internal";
2258
+ import { invariant } from "@dxos/invariant";
2259
+ import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
2260
+ import { isNonNullable } from "@dxos/util";
2261
+ import { translationKey as translationKey10 } from "#translations";
2262
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
2263
+ var createFieldMap = {
2264
+ hue: ({ type, label, layout, getValue, onValueChange }) => {
2265
+ const handleChange = useCallback15((nextHue) => onValueChange(type, nextHue), [
2266
+ onValueChange,
2267
+ type
2268
+ ]);
2269
+ const handleReset = useCallback15(() => onValueChange(type, void 0), [
2270
+ onValueChange,
2271
+ type
2272
+ ]);
2273
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, layout !== "inline" && /* @__PURE__ */ React18.createElement(Form.Label, {
2274
+ label
2275
+ }), /* @__PURE__ */ React18.createElement(HuePicker2, {
2276
+ value: getValue(),
2277
+ onChange: handleChange,
2278
+ onReset: handleReset
2279
+ }));
2280
+ }
2148
2281
  };
2149
- SettingsSectionHeading.displayName = SETTINGS_SECTION_HEADING_NAME;
2150
- var SettingsGroupButton = ({ classNames, ...props }) => {
2151
- return /* @__PURE__ */ React18.createElement(Button2, {
2152
- ...props,
2153
- classNames: [
2154
- "md:col-span-2",
2155
- classNames
2156
- ]
2157
- });
2282
+ var ObjectForm = ({ object, schema }) => {
2283
+ const db = Obj4.getDatabase(object);
2284
+ const meta = Obj4.getMeta(object);
2285
+ const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
2286
+ const values = useMemo9(() => ({
2287
+ tags,
2288
+ ...object
2289
+ }), [
2290
+ object,
2291
+ tags
2292
+ ]);
2293
+ const formSchema = useMemo9(() => omitId(Schema3.Struct({
2294
+ tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
2295
+ }).pipe(Schema3.extend(schema))), [
2296
+ schema
2297
+ ]);
2298
+ const handleCreate = useCallback15((schema2, values2) => {
2299
+ invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
2300
+ invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
2301
+ const newObject = db.add(Obj4.make(schema2, values2));
2302
+ if (Obj4.instanceOf(Tag2.Tag, newObject)) {
2303
+ Obj4.update(object, (object2) => {
2304
+ Obj4.getMeta(object2).tags = [
2305
+ ...Obj4.getMeta(object2).tags ?? [],
2306
+ Obj4.getDXN(newObject).toString()
2307
+ ];
2308
+ });
2309
+ }
2310
+ }, []);
2311
+ const handleChange = useCallback15(({ tags: tags2, ...values2 }, { isValid, changed }) => {
2312
+ if (!isValid) {
2313
+ return;
2314
+ }
2315
+ const changedPaths = Object.keys(changed).filter((path) => changed[path]);
2316
+ const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
2317
+ if (hasTagsChange) {
2318
+ Obj4.update(object, (object2) => {
2319
+ Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2320
+ });
2321
+ }
2322
+ const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
2323
+ if (nonTagPaths.length > 0) {
2324
+ Obj4.update(object, () => {
2325
+ for (const path of nonTagPaths) {
2326
+ const parts = splitJsonPath(path);
2327
+ const value3 = Obj4.getValue(values2, parts);
2328
+ Obj4.setValue(object, parts, value3);
2329
+ }
2330
+ });
2331
+ }
2332
+ }, [
2333
+ object
2334
+ ]);
2335
+ return /* @__PURE__ */ React18.createElement(Form.Root, {
2336
+ schema: formSchema,
2337
+ defaultValues: values,
2338
+ createTypename: Type2.getTypename(Tag2.Tag),
2339
+ createOptionIcon: "ph--plus--regular",
2340
+ createOptionLabel: [
2341
+ "add-tag.label",
2342
+ {
2343
+ ns: translationKey10
2344
+ }
2345
+ ],
2346
+ createInitialValuePath: "label",
2347
+ createFieldMap,
2348
+ db,
2349
+ onValuesChanged: handleChange,
2350
+ onCreate: handleCreate
2351
+ }, /* @__PURE__ */ React18.createElement(Form.Viewport, null, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null))));
2158
2352
  };
2159
- SettingsGroupButton.displayName = SETTINGS_GROUP_BUTTON_NAME;
2160
- var SettingsGroup = ({ children, classNames }) => /* @__PURE__ */ React18.createElement("div", {
2161
- role: "none",
2162
- className: mx5("group container-max-width space-y-trimMd", classNames)
2163
- }, children);
2164
- SettingsGroup.displayName = SETTINGS_GROUP_NAME;
2165
- var SettingsFrame = ({ children }) => /* @__PURE__ */ React18.createElement("div", {
2166
- role: "none",
2167
- className: mx5("container-max-width p-trimMd", "border border-separator rounded-md")
2168
- }, children);
2169
- SettingsFrame.displayName = SETTINGS_FRAME_NAME;
2170
- var SettingsFrameItem = ({ title, description, children }) => {
2171
- const { t } = useTranslation9(translationKey);
2172
- return /* @__PURE__ */ React18.createElement("div", {
2173
- role: "group",
2174
- className: "min-is-0"
2175
- }, /* @__PURE__ */ React18.createElement("h3", {
2176
- className: "text-lg mbe-2"
2177
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
2178
- className: "mlb-trimSm md:mbe-0 text-description"
2179
- }, toLocalizedString(description, t)), children);
2353
+
2354
+ // src/components/ObjectProperties/ObjectProperties.tsx
2355
+ import * as Function from "effect/Function";
2356
+ import * as Option5 from "effect/Option";
2357
+ import * as Schema4 from "effect/Schema";
2358
+ import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
2359
+ import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
2360
+ import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
2361
+ import { invariant as invariant2 } from "@dxos/invariant";
2362
+ import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
2363
+ import { FactoryAnnotation } from "@dxos/schema";
2364
+ import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
2365
+ import { isNonNullable as isNonNullable2 } from "@dxos/util";
2366
+ import { translationKey as translationKey11 } from "#translations";
2367
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
2368
+ var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
2369
+ const db = Obj5.getDatabase(object);
2370
+ const meta = Obj5.getMeta(object);
2371
+ const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
2372
+ const values = useMemo10(() => ({
2373
+ tags,
2374
+ ...object
2375
+ }), [
2376
+ object,
2377
+ tags
2378
+ ]);
2379
+ const formSchema = useMemo10(() => {
2380
+ return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
2381
+ }, [
2382
+ object
2383
+ ]);
2384
+ const handleCreate = useCallback16((schema, values2) => {
2385
+ invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
2386
+ invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
2387
+ const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
2388
+ const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
2389
+ return db.add(newObject);
2390
+ }, [
2391
+ db
2392
+ ]);
2393
+ const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
2394
+ if (!isValid) {
2395
+ return;
2396
+ }
2397
+ const changedPaths = Object.keys(changed).filter((path) => changed[path]);
2398
+ const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
2399
+ if (hasTagsChange) {
2400
+ Obj5.update(object, (object2) => {
2401
+ Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
2402
+ });
2403
+ }
2404
+ const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
2405
+ if (nonTagPaths.length > 0) {
2406
+ Obj5.update(object, () => {
2407
+ for (const path of nonTagPaths) {
2408
+ const parts = splitJsonPath2(path);
2409
+ const value3 = Obj5.getValue(values2, parts);
2410
+ Obj5.setValue(object, parts, value3);
2411
+ }
2412
+ });
2413
+ }
2414
+ }, [
2415
+ object
2416
+ ]);
2417
+ if (!formSchema) {
2418
+ return null;
2419
+ }
2420
+ return /* @__PURE__ */ React19.createElement(Form.Root, {
2421
+ schema: formSchema,
2422
+ defaultValues: values,
2423
+ createTypename: Type3.getTypename(Tag3.Tag),
2424
+ createOptionIcon: "ph--plus--regular",
2425
+ createOptionLabel: [
2426
+ "add-tag.label",
2427
+ {
2428
+ ns: translationKey11
2429
+ }
2430
+ ],
2431
+ createInitialValuePath: "label",
2432
+ createFieldMap: createFieldMap2,
2433
+ db,
2434
+ onValuesChanged: handleChange,
2435
+ onCreate: handleCreate
2436
+ }, /* @__PURE__ */ React19.createElement(Form.Viewport, {
2437
+ ...composableProps2(props),
2438
+ ref: forwardedRef
2439
+ }, /* @__PURE__ */ React19.createElement(Form.Content, null, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), children)));
2440
+ });
2441
+ var createFieldMap2 = {
2442
+ hue: ({ type, label, layout, getValue, onValueChange }) => {
2443
+ const handleChange = useCallback16((nextHue) => onValueChange(type, nextHue), [
2444
+ onValueChange,
2445
+ type
2446
+ ]);
2447
+ const handleReset = useCallback16(() => onValueChange(type, void 0), [
2448
+ onValueChange,
2449
+ type
2450
+ ]);
2451
+ return /* @__PURE__ */ React19.createElement(React19.Fragment, null, layout !== "inline" && /* @__PURE__ */ React19.createElement(Form.Label, {
2452
+ label
2453
+ }), /* @__PURE__ */ React19.createElement(HuePicker3, {
2454
+ value: getValue(),
2455
+ onChange: handleChange,
2456
+ onReset: handleReset
2457
+ }));
2458
+ }
2180
2459
  };
2181
- SettingsFrameItem.displayName = SETTINGS_FRAME_ITEM_NAME;
2182
- var SettingsContainer = ({ classNames, children }) => {
2183
- return /* @__PURE__ */ React18.createElement("div", {
2460
+ var BaseSchema = Schema4.Struct({
2461
+ tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
2462
+ });
2463
+
2464
+ // src/components/Settings/Settings.tsx
2465
+ import React22 from "react";
2466
+ import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
2467
+ import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
2468
+ import { translationKey as translationKey13 } from "#translations";
2469
+
2470
+ // src/components/Settings/SettingsFieldSet.tsx
2471
+ import * as SchemaAST5 from "effect/SchemaAST";
2472
+ import * as String3 from "effect/String";
2473
+ import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
2474
+ import { getAnnotation as getAnnotation3 } from "@dxos/effect";
2475
+ import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
2476
+
2477
+ // src/components/Settings/SettingsItem.tsx
2478
+ import React20 from "react";
2479
+ import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
2480
+ import { mx as mx3 } from "@dxos/ui-theme";
2481
+ import { translationKey as translationKey12 } from "#translations";
2482
+ var SETTINGS_PANEL_NAME = "Settings.Panel";
2483
+ var SETTINGS_ITEM_NAME = "Settings.Item";
2484
+ var SettingsPanel = ({ classNames, children }) => {
2485
+ return /* @__PURE__ */ React20.createElement("div", {
2184
2486
  role: "none",
2185
- className: mx5([
2186
- "container-max-width",
2187
- "*:first:!mbs-0 *:last:!mbe-0 pli-trimMd plb-trimMd",
2188
- "border border-separator rounded-md",
2189
- classNames
2190
- ])
2487
+ className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
2191
2488
  }, children);
2192
2489
  };
2193
- SettingsContainer.displayName = SETTINGS_CONTAINER_NAME;
2490
+ SettingsPanel.displayName = SETTINGS_PANEL_NAME;
2194
2491
  var SettingsItem = ({ title, description = "", children }) => {
2195
- const { t } = useTranslation9(translationKey);
2196
- return /* @__PURE__ */ React18.createElement(SettingsContainer, {
2197
- classNames: styles.grid
2198
- }, /* @__PURE__ */ React18.createElement("h3", {
2199
- className: mx5(styles.title, "md:col-span-2")
2200
- }, toLocalizedString(title, t)), /* @__PURE__ */ React18.createElement("p", {
2201
- className: styles.description
2202
- }, toLocalizedString(description, t)), /* @__PURE__ */ React18.createElement("div", {
2492
+ const { t } = useTranslation10(translationKey12);
2493
+ return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
2494
+ classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
2495
+ }, /* @__PURE__ */ React20.createElement(Input12.Label, {
2496
+ classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
2497
+ }, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
2498
+ classNames: "text-base text-description"
2499
+ }, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
2203
2500
  role: "none",
2204
- className: "text-end plb-1"
2205
- }, children));
2501
+ className: "text-end py-1"
2502
+ }, children)));
2206
2503
  };
2207
2504
  SettingsItem.displayName = SETTINGS_ITEM_NAME;
2208
- var SettingsItemInput = ({ title, description = "", children }) => {
2209
- const { t } = useTranslation9(translationKey);
2210
- return /* @__PURE__ */ React18.createElement(Input12.Root, null, /* @__PURE__ */ React18.createElement(SettingsContainer, {
2211
- classNames: styles.grid
2212
- }, /* @__PURE__ */ React18.createElement(Input12.Label, {
2213
- classNames: mx5(styles.title, "md:col-span-2")
2214
- }, toLocalizedString(title, t)), /* @__PURE__ */ React18.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React18.createElement(Input12.Description, {
2215
- classNames: styles.description
2216
- }, toLocalizedString(description, t))), /* @__PURE__ */ React18.createElement("div", {
2505
+
2506
+ // src/components/Settings/SettingsFieldSet.tsx
2507
+ var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
2508
+ const properties = useMemo11(() => {
2509
+ const props = getFormProperties(schema.ast);
2510
+ if (!sort) {
2511
+ return props;
2512
+ }
2513
+ const rank = (name) => {
2514
+ const idx = sort.indexOf(name);
2515
+ return idx === -1 ? Number.POSITIVE_INFINITY : idx;
2516
+ };
2517
+ return [
2518
+ ...props
2519
+ ].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
2520
+ }, [
2521
+ schema,
2522
+ sort
2523
+ ]);
2524
+ const handleChange = useCallback17((name, value3) => {
2525
+ onValuesChanged?.({
2526
+ ...values,
2527
+ [name]: value3
2528
+ });
2529
+ }, [
2530
+ values,
2531
+ onValuesChanged
2532
+ ]);
2533
+ return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
2534
+ const name = property.name.toString();
2535
+ const path = pathPrefix ? `${pathPrefix}.${name}` : name;
2536
+ if (visible && !visible(path, values)) {
2537
+ return null;
2538
+ }
2539
+ const entry = fieldMap?.[name];
2540
+ return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
2541
+ key: name,
2542
+ path,
2543
+ property,
2544
+ value: values[name],
2545
+ onChange: (value3) => handleChange(name, value3),
2546
+ readonly,
2547
+ customField: typeof entry === "function" ? entry : void 0,
2548
+ nestedFieldMap: typeof entry === "object" ? entry : void 0,
2549
+ visible,
2550
+ sort
2551
+ });
2552
+ }));
2553
+ };
2554
+ SettingsFieldSet.displayName = "Settings.FieldSet";
2555
+ var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
2556
+ const { type } = property;
2557
+ const name = property.name.toString();
2558
+ const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
2559
+ const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
2560
+ if (customField) {
2561
+ const CustomField = customField;
2562
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2563
+ title,
2564
+ description
2565
+ }, /* @__PURE__ */ React21.createElement(CustomField, {
2566
+ value: value3,
2567
+ onChange,
2568
+ readonly
2569
+ }));
2570
+ }
2571
+ const fieldType = detectFieldType(type);
2572
+ switch (fieldType) {
2573
+ case "struct":
2574
+ return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
2575
+ schema: {
2576
+ ast: type
2577
+ },
2578
+ values: value3 ?? {},
2579
+ onValuesChanged: onChange,
2580
+ readonly,
2581
+ fieldMap: nestedFieldMap,
2582
+ visible,
2583
+ sort,
2584
+ pathPrefix: path
2585
+ });
2586
+ case "boolean":
2587
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2588
+ title,
2589
+ description
2590
+ }, /* @__PURE__ */ React21.createElement(Input13.Switch, {
2591
+ disabled: readonly,
2592
+ checked: !!value3,
2593
+ onCheckedChange: (checked) => onChange(!!checked)
2594
+ }));
2595
+ case "select": {
2596
+ const options = getSelectOptionsFromAst(type) ?? [];
2597
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2598
+ title,
2599
+ description
2600
+ }, /* @__PURE__ */ React21.createElement(Select2.Root, {
2601
+ disabled: readonly,
2602
+ value: value3 == null ? "" : globalThis.String(value3),
2603
+ onValueChange: (selected) => {
2604
+ const matched = options.find((option) => globalThis.String(option.value) === selected);
2605
+ onChange(matched?.value ?? selected);
2606
+ }
2607
+ }, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
2608
+ disabled: readonly
2609
+ }), /* @__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, {
2610
+ key: globalThis.String(option.value),
2611
+ value: globalThis.String(option.value)
2612
+ }, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
2613
+ }
2614
+ case "string":
2615
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2616
+ title,
2617
+ description
2618
+ }, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
2619
+ disabled: readonly,
2620
+ value: value3 ?? "",
2621
+ onChange: (event) => onChange(event.target.value)
2622
+ }));
2623
+ case "number":
2624
+ return /* @__PURE__ */ React21.createElement(SettingsItem, {
2625
+ title,
2626
+ description
2627
+ }, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
2628
+ disabled: readonly,
2629
+ type: "number",
2630
+ value: value3 ?? "",
2631
+ onChange: (event) => {
2632
+ if (event.target.value === "") {
2633
+ onChange(void 0);
2634
+ return;
2635
+ }
2636
+ const parsed = Number(event.target.value);
2637
+ onChange(Number.isNaN(parsed) ? void 0 : parsed);
2638
+ }
2639
+ }));
2640
+ default:
2641
+ return null;
2642
+ }
2643
+ };
2644
+
2645
+ // src/components/Settings/Settings.tsx
2646
+ var SETTINGS_ROOT_NAME = "Settings.Root";
2647
+ var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
2648
+ var SETTINGS_SECTION_NAME = "Settings.Section";
2649
+ var SettingsRoot = ({ children, classNames }) => {
2650
+ return /* @__PURE__ */ React22.createElement("div", {
2651
+ className: mx4("flex flex-col gap-2", classNames)
2652
+ }, children);
2653
+ };
2654
+ SettingsRoot.displayName = SETTINGS_ROOT_NAME;
2655
+ var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
2656
+ return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
2657
+ ...composableProps3(props),
2658
+ orientation: "vertical",
2659
+ centered: true,
2660
+ thin: true,
2661
+ ref: forwardedRef
2662
+ }, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
2663
+ classNames: "px-4 pointer-coarse:px-2"
2664
+ }, /* @__PURE__ */ React22.createElement("div", {
2217
2665
  role: "none",
2218
- className: "text-end plb-1"
2666
+ className: "dx-document flex flex-col gap-2 py-4"
2219
2667
  }, children)));
2668
+ });
2669
+ SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
2670
+ var SettingsSection = ({ title, description, children }) => {
2671
+ const { t } = useTranslation11(translationKey13);
2672
+ return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
2673
+ className: "px-trim-md mt-trim-md text-xl"
2674
+ }, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
2675
+ className: "px-trim-md text-description"
2676
+ }, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
2677
+ className: "w-full pt-trim-md space-y-trim-md"
2678
+ }, children));
2220
2679
  };
2221
- SettingsItemInput.displayName = SETTINGS_ITEM_INPUT_NAME;
2680
+ SettingsSection.displayName = SETTINGS_SECTION_NAME;
2222
2681
  var Settings = {
2223
2682
  Root: SettingsRoot,
2683
+ Viewport: SettingsViewport,
2224
2684
  Section: SettingsSection,
2225
- SectionHeading: SettingsSectionHeading,
2226
- Group: SettingsGroup,
2227
- GroupButton: SettingsGroupButton,
2228
- Container: SettingsContainer,
2229
- Frame: SettingsFrame,
2230
- FrameItem: SettingsFrameItem,
2685
+ Panel: SettingsPanel,
2231
2686
  Item: SettingsItem,
2232
- ItemInput: SettingsItemInput
2687
+ FieldSet: SettingsFieldSet
2688
+ };
2689
+
2690
+ // src/components/Settings/SettingsSelectField.tsx
2691
+ import React23 from "react";
2692
+ import { Select as Select3 } from "@dxos/react-ui";
2693
+ var createSelectField = ({ options, defaultLabel = "Default" }) => {
2694
+ const normalized = options.map((option) => typeof option === "string" ? {
2695
+ value: option,
2696
+ label: option
2697
+ } : option);
2698
+ const hasDefault = defaultLabel !== null;
2699
+ const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
2700
+ return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
2701
+ disabled: readonly,
2702
+ value: value3 ?? sentinel,
2703
+ onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
2704
+ }, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
2705
+ disabled: readonly
2706
+ }), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
2707
+ value: sentinel
2708
+ }, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
2709
+ key: option.value,
2710
+ value: option.value
2711
+ }, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
2233
2712
  };
2234
2713
 
2235
2714
  // src/components/ViewEditor/ViewEditor.tsx
2236
2715
  import { RegistryContext } from "@effect-atom/atom-react";
2237
- import * as Array2 from "effect/Array";
2716
+ import * as Array4 from "effect/Array";
2238
2717
  import * as Match2 from "effect/Match";
2239
- import * as Option4 from "effect/Option";
2240
- import * as Schema3 from "effect/Schema";
2241
- import React19, { forwardRef as forwardRef3, useCallback as useCallback15, useContext, useImperativeHandle, useMemo as useMemo8, useState as useState6 } from "react";
2242
- import { Filter as Filter2, Format as Format5, Obj as Obj4, Query, QueryAST } from "@dxos/echo";
2718
+ import * as Option6 from "effect/Option";
2719
+ import * as Schema5 from "effect/Schema";
2720
+ import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
2721
+ import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6 } from "@dxos/echo";
2722
+ import { View } from "@dxos/echo";
2243
2723
  import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
2244
- import { invariant } from "@dxos/invariant";
2245
- import { useObject } from "@dxos/react-client/echo";
2246
- import { Callout, IconButton as IconButton4, Input as Input13, useTranslation as useTranslation10 } from "@dxos/react-ui";
2724
+ import { invariant as invariant3 } from "@dxos/invariant";
2725
+ import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
2726
+ import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
2247
2727
  import { QueryForm } from "@dxos/react-ui-components";
2248
2728
  import { List as List2 } from "@dxos/react-ui-list";
2249
- import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
2250
- import { mx as mx6, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
2251
- var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2252
- var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
2253
- var listItemGrid = "grid grid-cols-subgrid col-span-5";
2254
- var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
2729
+ import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
2730
+ import { mx as mx5, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
2731
+ import { translationKey as translationKey14 } from "#translations";
2732
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2733
+ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
2255
2734
  const atomRegistry = useContext(RegistryContext);
2256
2735
  const schemaReadonly = !isMutable(schema);
2257
- const { t } = useTranslation10(translationKey);
2258
- const projectionModel = useMemo8(() => {
2736
+ const { t } = useTranslation12(translationKey14);
2737
+ const projectionModel = useMemo12(() => {
2259
2738
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2260
2739
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2261
2740
  const model = new ProjectionModel({
@@ -2274,12 +2753,26 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2274
2753
  projectionModel
2275
2754
  ]);
2276
2755
  const queueTarget = Match2.value(view.query.ast).pipe(Match2.when({
2277
- type: "options"
2278
- }, ({ options }) => {
2279
- return Option4.fromNullable(options.queues).pipe(Option4.flatMap((queues) => Array2.head(queues)), Option4.getOrUndefined);
2756
+ type: "from"
2757
+ }, ({ from }) => {
2758
+ if (from._tag !== "scope") {
2759
+ return void 0;
2760
+ }
2761
+ return Option6.fromNullable(from.scope.queues).pipe(Option6.flatMap((queues) => Array4.head(queues)), Option6.map(String), Option6.getOrUndefined);
2280
2762
  }), Match2.orElse(() => void 0));
2281
- const viewSchema = useMemo8(() => {
2282
- const base = Schema3.Struct({
2763
+ const feeds = useQuery2(db, Filter2.type(Feed.Feed));
2764
+ const targetRef = useMemo12(() => {
2765
+ if (!queueTarget) {
2766
+ return void 0;
2767
+ }
2768
+ const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
2769
+ return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
2770
+ }, [
2771
+ queueTarget,
2772
+ feeds
2773
+ ]);
2774
+ const viewSchema = useMemo12(() => {
2775
+ const base = Schema5.Struct({
2283
2776
  query: mode === "schema" ? Format5.URL.annotations({
2284
2777
  title: "Record type"
2285
2778
  }) : QueryAST.Query.annotations({
@@ -2287,26 +2780,27 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2287
2780
  })
2288
2781
  });
2289
2782
  if (mode === "tag") {
2290
- return Schema3.Struct({
2783
+ return Schema5.Struct({
2291
2784
  ...base.fields,
2292
- target: Schema3.optional(Schema3.String.annotations({
2293
- title: "Target Queue"
2294
- }))
2295
- }).pipe(Schema3.mutable);
2785
+ // TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
2786
+ target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
2787
+ title: "Target Feed"
2788
+ }), ParentLabelAnnotation.set(true), Schema5.optional)
2789
+ }).pipe(Schema5.mutable);
2296
2790
  }
2297
- return base.pipe(Schema3.mutable);
2791
+ return base.pipe(Schema5.mutable);
2298
2792
  }, [
2299
2793
  mode
2300
2794
  ]);
2301
- const viewValues = useMemo8(() => ({
2795
+ const viewValues = useMemo12(() => ({
2302
2796
  query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2303
- target: queueTarget
2797
+ target: targetRef
2304
2798
  }), [
2305
2799
  mode,
2306
2800
  view.query.ast,
2307
- queueTarget
2801
+ targetRef
2308
2802
  ]);
2309
- const fieldMap = useMemo8(() => mode === "tag" ? customFields({
2803
+ const fieldMap = useMemo12(() => mode === "tag" ? customFields({
2310
2804
  types,
2311
2805
  tags
2312
2806
  }) : void 0, [
@@ -2314,48 +2808,46 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2314
2808
  types,
2315
2809
  tags
2316
2810
  ]);
2317
- const handleUpdate = useCallback15((values) => {
2318
- requestAnimationFrame(() => {
2319
- const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : values.query;
2320
- onQueryChanged?.(query, values.target);
2321
- });
2811
+ const handleUpdate = useCallback18((values) => {
2812
+ const targetValue = values.target;
2813
+ let queueDxn;
2814
+ if (Ref6.isRef(targetValue)) {
2815
+ const feedDxn = targetValue.dxn.toString();
2816
+ const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === feedDxn);
2817
+ if (feed) {
2818
+ queueDxn = Feed.getQueueDxn(feed)?.toString();
2819
+ }
2820
+ }
2821
+ const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
2822
+ onQueryChanged?.(query, queueDxn);
2322
2823
  }, [
2323
2824
  onQueryChanged,
2324
- view,
2325
- queueTarget,
2326
- mode
2825
+ mode,
2826
+ feeds
2327
2827
  ]);
2328
- const handleDelete = useCallback15((fieldId) => {
2329
- invariant(!readonly, void 0, {
2330
- F: __dxlog_file3,
2331
- L: 155,
2332
- S: void 0,
2333
- A: [
2334
- "!readonly",
2335
- ""
2336
- ]
2337
- });
2828
+ const handleDelete = useCallback18((fieldId) => {
2829
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 127, S: void 0, A: ["!readonly", ""] });
2338
2830
  onDelete?.(fieldId);
2339
2831
  }, [
2340
2832
  onDelete,
2341
2833
  readonly
2342
2834
  ]);
2343
- return /* @__PURE__ */ React19.createElement("div", {
2835
+ return /* @__PURE__ */ React24.createElement("div", {
2344
2836
  role: "none",
2345
- className: mx6(classNames)
2346
- }, schemaReadonly && !readonly && /* @__PURE__ */ React19.createElement(Callout.Root, {
2837
+ className: mx5(classNames)
2838
+ }, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
2347
2839
  valence: "info",
2348
- classNames: "mlb-cardSpacingBlock"
2349
- }, /* @__PURE__ */ React19.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React19.createElement(Form.Root, {
2840
+ classNames: "my-form-padding"
2841
+ }, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
2350
2842
  schema: viewSchema,
2351
2843
  values: viewValues,
2352
2844
  fieldMap,
2353
- autoSave: true,
2354
- onSave: handleUpdate
2355
- }, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), /* @__PURE__ */ React19.createElement(FormFieldLabel, {
2356
- label: t("fields label"),
2845
+ db,
2846
+ onValuesChanged: handleUpdate
2847
+ }, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2848
+ label: t("fields.label"),
2357
2849
  asChild: true
2358
- }), /* @__PURE__ */ React19.createElement(FieldList, {
2850
+ }), /* @__PURE__ */ React24.createElement(FieldList, {
2359
2851
  schema,
2360
2852
  view,
2361
2853
  registry,
@@ -2367,9 +2859,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
2367
2859
  var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
2368
2860
  const atomRegistry = useContext(RegistryContext);
2369
2861
  const schemaReadonly = !isMutable(schema);
2370
- const { t } = useTranslation10(translationKey);
2862
+ const { t } = useTranslation12(translationKey14);
2371
2863
  const [viewSnapshot] = useObject(view);
2372
- const projectionModel = useMemo8(() => {
2864
+ const projectionModel = useMemo12(() => {
2373
2865
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2374
2866
  const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
2375
2867
  const model = new ProjectionModel({
@@ -2384,38 +2876,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2384
2876
  schema,
2385
2877
  view
2386
2878
  ]);
2387
- const [expandedField, setExpandedField] = useState6();
2388
- const handleAdd = useCallback15(() => {
2389
- invariant(!readonly, void 0, {
2390
- F: __dxlog_file3,
2391
- L: 220,
2392
- S: void 0,
2393
- A: [
2394
- "!readonly",
2395
- ""
2396
- ]
2397
- });
2879
+ const [expandedField, setExpandedField] = useState7();
2880
+ const handleAdd = useCallback18(() => {
2881
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 183, S: void 0, A: ["!readonly", ""] });
2398
2882
  const field = projectionModel.createFieldProjection();
2399
2883
  setExpandedField(field.id);
2400
2884
  }, [
2401
2885
  projectionModel,
2402
2886
  readonly
2403
2887
  ]);
2404
- const handleToggleField = useCallback15((field) => {
2888
+ const handleToggleField = useCallback18((field) => {
2405
2889
  setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2406
2890
  }, [
2407
2891
  readonly
2408
2892
  ]);
2409
- const handleDelete = useCallback15((fieldId) => {
2410
- invariant(!readonly, void 0, {
2411
- F: __dxlog_file3,
2412
- L: 234,
2413
- S: void 0,
2414
- A: [
2415
- "!readonly",
2416
- ""
2417
- ]
2418
- });
2893
+ const handleDelete = useCallback18((fieldId) => {
2894
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 196, S: void 0, A: ["!readonly", ""] });
2419
2895
  if (fieldId === expandedField) {
2420
2896
  setExpandedField(void 0);
2421
2897
  }
@@ -2425,36 +2901,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2425
2901
  onDelete,
2426
2902
  readonly
2427
2903
  ]);
2428
- const handleMove = useCallback15((fromIndex, toIndex) => {
2429
- invariant(!readonly, void 0, {
2430
- F: __dxlog_file3,
2431
- L: 246,
2432
- S: void 0,
2433
- A: [
2434
- "!readonly",
2435
- ""
2436
- ]
2437
- });
2438
- Obj4.change(view, (v) => {
2904
+ const handleMove = useCallback18((fromIndex, toIndex) => {
2905
+ invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 207, S: void 0, A: ["!readonly", ""] });
2906
+ Obj6.update(view, (view2) => {
2439
2907
  const fields = [
2440
- ...v.projection.fields
2908
+ ...view2.projection.fields
2441
2909
  ];
2442
2910
  const [moved] = fields.splice(fromIndex, 1);
2443
2911
  fields.splice(toIndex, 0, moved);
2444
- v.projection.fields = fields;
2912
+ view2.projection.fields = fields;
2445
2913
  });
2446
2914
  }, [
2447
2915
  view,
2448
2916
  readonly
2449
2917
  ]);
2450
- const handleClose = useCallback15(() => setExpandedField(void 0), []);
2451
- const handleHide = useCallback15((fieldId) => {
2918
+ const handleClose = useCallback18(() => setExpandedField(void 0), []);
2919
+ const handleHide = useCallback18((fieldId) => {
2452
2920
  setExpandedField(void 0);
2453
2921
  projectionModel.hideFieldProjection(fieldId);
2454
2922
  }, [
2455
2923
  projectionModel
2456
2924
  ]);
2457
- const handleShow = useCallback15((property) => {
2925
+ const handleShow = useCallback18((property) => {
2458
2926
  setExpandedField(void 0);
2459
2927
  projectionModel.showFieldProjection(property);
2460
2928
  }, [
@@ -2463,84 +2931,84 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
2463
2931
  if (!viewSnapshot) {
2464
2932
  return null;
2465
2933
  }
2466
- return /* @__PURE__ */ React19.createElement(List2.Root, {
2934
+ return /* @__PURE__ */ React24.createElement(List2.Root, {
2467
2935
  items: viewSnapshot.projection.fields,
2468
- isItem: Schema3.is(FieldSchema),
2936
+ isItem: Schema5.is(View.FieldSchema),
2469
2937
  getId: (field) => field.id,
2470
2938
  onMove: readonly ? void 0 : handleMove,
2471
2939
  readonly
2472
- }, ({ items: fields }) => /* @__PURE__ */ React19.createElement(React19.Fragment, null, showHeading && /* @__PURE__ */ React19.createElement("h3", {
2940
+ }, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
2473
2941
  className: "text-sm"
2474
- }, t("field path label")), /* @__PURE__ */ React19.createElement("div", {
2942
+ }, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
2475
2943
  role: "list",
2476
- className: listGrid
2944
+ className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
2477
2945
  }, fields?.map((field) => {
2478
2946
  const hidden = field.visible === false;
2479
- return /* @__PURE__ */ React19.createElement(List2.Item, {
2947
+ return /* @__PURE__ */ React24.createElement(List2.Item, {
2480
2948
  key: field.id,
2481
2949
  item: field,
2482
- classNames: listItemGrid,
2950
+ classNames: "grid grid-cols-subgrid col-span-5",
2483
2951
  "aria-expanded": expandedField === field.id
2484
- }, /* @__PURE__ */ React19.createElement("div", {
2952
+ }, /* @__PURE__ */ React24.createElement("div", {
2485
2953
  role: "none",
2486
- className: mx6(subtleHover2, listItemGrid, "rounded-sm cursor-pointer min-bs-10")
2487
- }, /* @__PURE__ */ React19.createElement(List2.ItemDragHandle, {
2954
+ className: mx5(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
2955
+ }, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
2488
2956
  disabled: readonly || schemaReadonly
2489
- }), /* @__PURE__ */ React19.createElement(List2.ItemTitle, {
2957
+ }), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
2490
2958
  classNames: hidden && "text-subdued",
2491
2959
  onClick: () => handleToggleField(field)
2492
- }, field.path), /* @__PURE__ */ React19.createElement(List2.ItemButton, {
2493
- label: t(hidden ? "show field label" : "hide field label"),
2960
+ }, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
2961
+ label: t(hidden ? "show-field.label" : "hide-field.label"),
2494
2962
  "data-testid": hidden ? "show-field-button" : "hide-field-button",
2495
2963
  icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2496
2964
  autoHide: false,
2497
2965
  disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
2498
2966
  onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2499
- }), !readonly && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(List2.ItemDeleteButton, {
2500
- label: t("delete field label"),
2967
+ }), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
2968
+ label: t("delete-field.label"),
2501
2969
  autoHide: false,
2502
2970
  disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
2503
2971
  onClick: () => handleDelete(field.id),
2504
2972
  "data-testid": "field.delete"
2505
- }), /* @__PURE__ */ React19.createElement(IconButton4, {
2973
+ }), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
2506
2974
  iconOnly: true,
2507
2975
  variant: "ghost",
2508
- label: t("toggle expand label", {
2976
+ label: t("toggle-expand.label", {
2509
2977
  ns: osTranslations2
2510
2978
  }),
2511
2979
  icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2512
2980
  onClick: () => handleToggleField(field),
2513
2981
  "data-testid": "field.toggle"
2514
- }))), expandedField === field.id && !readonly && /* @__PURE__ */ React19.createElement("div", {
2982
+ }))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
2515
2983
  role: "none",
2516
- className: "col-span-5 mbs-1 mbe-1 border border-separator rounded-md"
2517
- }, /* @__PURE__ */ React19.createElement(FieldEditor, {
2984
+ className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
2985
+ }, /* @__PURE__ */ React24.createElement(FieldEditor, {
2518
2986
  readonly: readonly || schemaReadonly,
2519
2987
  registry,
2520
2988
  projection: projectionModel,
2521
2989
  field,
2522
2990
  onSave: handleClose
2523
2991
  })));
2524
- })), !readonly && !expandedField && /* @__PURE__ */ React19.createElement("div", {
2992
+ })), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
2525
2993
  role: "none",
2526
- className: "mlb-cardSpacingBlock"
2527
- }, /* @__PURE__ */ React19.createElement(IconButton4, {
2994
+ className: "my-form-padding"
2995
+ }, /* @__PURE__ */ React24.createElement(IconButton4, {
2528
2996
  icon: "ph--plus--regular",
2529
- label: t("add property button label"),
2997
+ label: t("add-property-button.label"),
2530
2998
  onClick: handleAdd,
2531
2999
  disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
2532
- classNames: "is-full"
3000
+ classNames: "w-full"
2533
3001
  }))));
2534
3002
  };
2535
3003
  var customFields = ({ types, tags }) => ({
2536
3004
  query: ({ type, readonly, label, getValue, onValueChange }) => {
2537
- const handleChange = useCallback15((query) => onValueChange(type, query.ast), [
3005
+ const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
2538
3006
  onValueChange
2539
3007
  ]);
2540
- return /* @__PURE__ */ React19.createElement(Input13.Root, null, /* @__PURE__ */ React19.createElement(FormFieldLabel, {
3008
+ return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
2541
3009
  readonly,
2542
3010
  label
2543
- }), /* @__PURE__ */ React19.createElement(QueryForm, {
3011
+ }), /* @__PURE__ */ React24.createElement(QueryForm, {
2544
3012
  initialQuery: getValue(),
2545
3013
  types,
2546
3014
  tags,
@@ -2559,7 +3027,9 @@ export {
2559
3027
  GeoPointField,
2560
3028
  MarkdownField,
2561
3029
  NumberField,
3030
+ ObjectForm,
2562
3031
  ObjectPicker,
3032
+ ObjectProperties,
2563
3033
  RefField,
2564
3034
  SelectField,
2565
3035
  SelectOptionField,
@@ -2569,16 +3039,18 @@ export {
2569
3039
  TupleField,
2570
3040
  ViewEditor,
2571
3041
  cellClassesForFieldType,
3042
+ createSelectField,
3043
+ detectFieldType,
2572
3044
  formatForDisplay,
2573
3045
  formatForEditing,
2574
3046
  getDefaultValue,
2575
3047
  getFormProperties,
2576
3048
  getRefProps,
3049
+ getSelectOptionsFromAst,
3050
+ omitHiddenFormFields,
2577
3051
  omitId,
2578
3052
  parseValue,
2579
3053
  pathNotUniqueError,
2580
- setValueEchoAware,
2581
- translations,
2582
3054
  useFormContext,
2583
3055
  useFormFieldState,
2584
3056
  useFormHandler,