@dxos/react-ui-form 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b

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