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