@dxos/react-ui-form 0.8.4-main.67995b8 → 0.8.4-main.70d3990

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 (118) hide show
  1. package/dist/lib/browser/index.mjs +909 -675
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +909 -675
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/ControlSection/ControlSection.d.ts +2 -2
  8. package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +1 -1
  9. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +81 -5
  10. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
  12. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  13. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +76 -5
  14. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/ArrayField.d.ts +2 -2
  16. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/Defaults.d.ts +5 -5
  18. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/Form.d.ts +10 -8
  20. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/Form.stories.d.ts +144 -33
  22. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/FormContent.d.ts +17 -11
  25. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/FormContext.d.ts +5 -5
  27. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/Input.d.ts +6 -3
  29. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/RefField.d.ts +15 -5
  31. package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -1
  33. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  34. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +1 -1
  35. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +76 -4
  37. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/custom/TupleInput.d.ts +1 -1
  39. package/dist/types/src/components/Form/factory.d.ts +2 -2
  40. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  41. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +41 -0
  42. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
  43. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +82 -0
  44. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
  45. package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
  46. package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
  47. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +20 -6
  48. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  49. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +80 -8
  50. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  51. package/dist/types/src/components/index.d.ts +1 -1
  52. package/dist/types/src/components/index.d.ts.map +1 -1
  53. package/dist/types/src/components/testing.d.ts +6 -3
  54. package/dist/types/src/components/testing.d.ts.map +1 -1
  55. package/dist/types/src/hooks/useForm.d.ts +6 -6
  56. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  57. package/dist/types/src/hooks/useQueryRefOptions.d.ts +9 -3
  58. package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -1
  59. package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +1 -1
  60. package/dist/types/src/translations.d.ts +14 -8
  61. package/dist/types/src/translations.d.ts.map +1 -1
  62. package/dist/types/src/util/field.d.ts +3 -3
  63. package/dist/types/src/util/field.d.ts.map +1 -1
  64. package/dist/types/src/util/formatting.d.ts +2 -2
  65. package/dist/types/src/util/formatting.d.ts.map +1 -1
  66. package/dist/types/src/util/refs.d.ts +1 -1
  67. package/dist/types/src/util/refs.d.ts.map +1 -1
  68. package/dist/types/src/util/schema.d.ts +1 -1
  69. package/dist/types/src/util/schema.d.ts.map +1 -1
  70. package/dist/types/tsconfig.tsbuildinfo +1 -1
  71. package/package.json +43 -38
  72. package/src/components/ControlSection/ControlSection.stories.tsx +11 -14
  73. package/src/components/ControlSection/ControlSection.tsx +26 -12
  74. package/src/components/FieldEditor/FieldEditor.stories.tsx +16 -16
  75. package/src/components/FieldEditor/FieldEditor.test.tsx +3 -2
  76. package/src/components/FieldEditor/FieldEditor.tsx +28 -20
  77. package/src/components/Form/ArrayField.tsx +15 -12
  78. package/src/components/Form/Defaults.tsx +23 -21
  79. package/src/components/Form/Form.stories.tsx +144 -108
  80. package/src/components/Form/Form.tsx +33 -19
  81. package/src/components/Form/FormActions.tsx +9 -3
  82. package/src/components/Form/FormContent.tsx +172 -50
  83. package/src/components/Form/FormContext.tsx +11 -11
  84. package/src/components/Form/Input.tsx +6 -3
  85. package/src/components/Form/RefField.tsx +111 -41
  86. package/src/components/Form/custom/GeoPointInput.tsx +29 -21
  87. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +11 -11
  88. package/src/components/Form/custom/SelectOptionsInput.tsx +31 -32
  89. package/src/components/Form/custom/TupleInput.tsx +2 -2
  90. package/src/components/Form/factory.tsx +8 -5
  91. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +207 -0
  92. package/src/components/ObjectPicker/ObjectPicker.tsx +161 -0
  93. package/src/components/ObjectPicker/index.ts +5 -0
  94. package/src/components/ViewEditor/ViewEditor.stories.tsx +123 -51
  95. package/src/components/ViewEditor/ViewEditor.test.tsx +13 -15
  96. package/src/components/ViewEditor/ViewEditor.tsx +271 -219
  97. package/src/components/index.ts +1 -2
  98. package/src/components/testing.tsx +15 -9
  99. package/src/hooks/useForm.ts +15 -10
  100. package/src/hooks/useQueryRefOptions.ts +15 -6
  101. package/src/hooks/useRefQueryLookupHandler.ts +5 -5
  102. package/src/translations.ts +16 -9
  103. package/src/util/field.ts +33 -43
  104. package/src/util/formatting.ts +22 -22
  105. package/src/util/refs.ts +7 -7
  106. package/src/util/schema.ts +2 -4
  107. package/dist/types/src/components/deprecated/Form.d.ts +0 -15
  108. package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
  109. package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
  110. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
  111. package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
  112. package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
  113. package/dist/types/src/components/deprecated/index.d.ts +0 -2
  114. package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
  115. package/src/components/deprecated/Form.stories.tsx +0 -62
  116. package/src/components/deprecated/Form.tsx +0 -119
  117. package/src/components/deprecated/FormInput.tsx +0 -71
  118. package/src/components/deprecated/index.ts +0 -5
@@ -8,7 +8,7 @@ var translations = [
8
8
  "hidden fields label": "Hidden Fields",
9
9
  "empty readonly ref field label": "(none)",
10
10
  // TODO(burdon): Standardize field/property.
11
- "button add property": "Add property",
11
+ "add property button label": "Add property",
12
12
  "field property label": "Property",
13
13
  "field property placeholder": "Property name",
14
14
  "field format label": "Type",
@@ -18,9 +18,15 @@ var translations = [
18
18
  "field limit reached": "Maximum number of fields reached",
19
19
  "boolean input true value": "Yes",
20
20
  "boolean input false value": "No",
21
+ "show field label": "Show field",
22
+ "hide field label": "Hide field",
23
+ "delete field label": "Delete field",
24
+ "ref field combobox input placeholder": "Search\u2026",
25
+ "ref field placeholder_one": "Select\u2026",
26
+ "ref field placeholder_other": "Select items\u2026",
21
27
  // TODO(burdon): Factor out?
22
- "button cancel": "Cancel",
23
- "button save": "Save",
28
+ "cancel button label": "Cancel",
29
+ "save button label": "Save",
24
30
  // FormatEnum
25
31
  "format boolean": "Boolean",
26
32
  "format currency": "Currency",
@@ -34,7 +40,7 @@ var translations = [
34
40
  "format hostname": "Hostname",
35
41
  "format integer": "Integer",
36
42
  "format json": "JSON",
37
- "format latlng": "Geopoint",
43
+ "format lnglat": "Geopoint",
38
44
  "format markdown": "Markdown",
39
45
  "format percent": "Percent",
40
46
  "format ref": "Reference",
@@ -50,9 +56,9 @@ var translations = [
50
56
  "format uri": "URI",
51
57
  "format url": "URL",
52
58
  "format uuid": "UUID",
53
- // Placeholders.
54
- "placeholder latitude": "Latitude",
55
- "placeholder longitude": "Longitude",
59
+ // GeoPointInput.
60
+ "latitude label": "Latitude",
61
+ "longitude label": "Longitude",
56
62
  // SelectOptionsInput.
57
63
  "select option label": "Label",
58
64
  "select option label placeholder": "Option label",
@@ -60,86 +66,38 @@ var translations = [
60
66
  "select option delete": "Delete",
61
67
  "select option add": "Add option",
62
68
  // System schema message.
63
- "system schema title": "System Schema",
64
- "system schema description": "This is a system schema and cannot be modified."
69
+ "system schema title": "System type",
70
+ "system schema description": "This is a system type and cannot be modified, though the view can still be configured."
65
71
  }
66
72
  }
67
73
  }
68
74
  ];
69
75
 
70
- // src/components/deprecated/FormInput.tsx
76
+ // src/components/ControlSection/ControlSection.tsx
71
77
  import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
72
78
  import React from "react";
73
- import { Input } from "@dxos/react-ui";
74
- import { mx, textBlockWidth } from "@dxos/react-ui-theme";
75
- var DeprecatedFormContainer = ({ children, classNames }) => {
76
- var _effect = _useSignals();
77
- try {
78
- return /* @__PURE__ */ React.createElement("div", {
79
- role: "none",
80
- className: "container-max-width p-4 justify-center overflow-x-hidden overflow-y-auto"
81
- }, /* @__PURE__ */ React.createElement("div", {
82
- role: "form",
83
- className: mx("flex flex-col", textBlockWidth, classNames)
84
- }, children));
85
- } finally {
86
- _effect.f();
87
- }
88
- };
89
- var DeprecatedFormInput = ({ label, description, secondary, children }) => {
79
+ import { Button, Input, toLocalizedString, useTranslation } from "@dxos/react-ui";
80
+ import { StackItem } from "@dxos/react-ui-stack";
81
+ import { mx } from "@dxos/react-ui-theme";
82
+ var ControlPage = ({ children, classNames, ...props }) => {
90
83
  var _effect = _useSignals();
91
84
  try {
92
- const primary = /* @__PURE__ */ React.createElement("div", {
93
- role: "none",
94
- className: "flex w-full gap-4 py-1"
95
- }, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement("div", {
96
- role: "none",
97
- className: "flex flex-col w-full"
98
- }, /* @__PURE__ */ React.createElement(Input.Label, {
99
- classNames: "flex min-bs-[--rail-action] items-center",
100
- style: {
101
- fontSize: "unset"
102
- }
103
- }, label), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, {
104
- classNames: "mbs-0.5"
105
- }, /* @__PURE__ */ React.createElement(Input.Description, null, description))), /* @__PURE__ */ React.createElement("div", {
106
- role: "none"
85
+ return /* @__PURE__ */ React.createElement(StackItem.Content, {
86
+ scrollable: true,
87
+ classNames: "[--control-spacing:var(--dx-trimMd)]"
107
88
  }, /* @__PURE__ */ React.createElement("div", {
108
89
  role: "none",
109
- className: "flex min-bs-[--rail-action] items-center"
110
- }, children))));
111
- if (secondary) {
112
- return /* @__PURE__ */ React.createElement("div", {
113
- role: "none"
114
- }, primary, secondary);
115
- }
116
- return primary;
117
- } finally {
118
- _effect.f();
119
- }
120
- };
121
-
122
- // src/components/ControlSection/ControlSection.tsx
123
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
124
- import React2 from "react";
125
- import { Button, Input as Input2, toLocalizedString, useTranslation } from "@dxos/react-ui";
126
- import { mx as mx2 } from "@dxos/react-ui-theme";
127
- var ControlPage = ({ children, classNames, ...props }) => {
128
- var _effect = _useSignals2();
129
- try {
130
- return /* @__PURE__ */ React2.createElement("div", {
131
- role: "none",
132
- className: mx2("pli-cardSpacingInline", classNames),
90
+ className: mx("pli-cardSpacingInline pbe-trimLg", classNames),
133
91
  ...props
134
- }, children);
92
+ }, children));
135
93
  } finally {
136
94
  _effect.f();
137
95
  }
138
96
  };
139
97
  var ControlSection = ({ title, description, children }) => {
140
- var _effect = _useSignals2();
98
+ var _effect = _useSignals();
141
99
  try {
142
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ControlSectionHeading, {
100
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ControlSectionHeading, {
143
101
  title,
144
102
  description
145
103
  }), children);
@@ -148,12 +106,12 @@ var ControlSection = ({ title, description, children }) => {
148
106
  }
149
107
  };
150
108
  var ControlSectionHeading = ({ title, description }) => {
151
- var _effect = _useSignals2();
109
+ var _effect = _useSignals();
152
110
  try {
153
111
  const { t } = useTranslation(translationKey);
154
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("h2", {
112
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h2", {
155
113
  className: "pli-trimMd container-max-width text-xl mbs-trimLg mbe-trimMd"
156
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
114
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
157
115
  className: "pli-trimMd mlb-trimMd container-max-width text-description"
158
116
  }, toLocalizedString(description, t)));
159
117
  } finally {
@@ -161,9 +119,9 @@ var ControlSectionHeading = ({ title, description }) => {
161
119
  }
162
120
  };
163
121
  var ControlGroupButton = ({ classNames, ...props }) => {
164
- var _effect = _useSignals2();
122
+ var _effect = _useSignals();
165
123
  try {
166
- return /* @__PURE__ */ React2.createElement(Button, {
124
+ return /* @__PURE__ */ React.createElement(Button, {
167
125
  ...props,
168
126
  classNames: [
169
127
  "md:col-span-2",
@@ -175,41 +133,46 @@ var ControlGroupButton = ({ classNames, ...props }) => {
175
133
  }
176
134
  };
177
135
  var ControlGroup = ({ children, classNames }) => {
178
- var _effect = _useSignals2();
136
+ var _effect = _useSignals();
179
137
  try {
180
- return /* @__PURE__ */ React2.createElement("div", {
138
+ return /* @__PURE__ */ React.createElement("div", {
181
139
  role: "none",
182
- className: mx2("group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-trimMd", classNames)
140
+ className: mx("group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-trimMd", "[--control-spacing:0px] [&_input]:justify-self-end [&_button]:justify-self-end", classNames)
183
141
  }, children);
184
142
  } finally {
185
143
  _effect.f();
186
144
  }
187
145
  };
188
146
  var ControlFrame = ({ children }) => {
189
- var _effect = _useSignals2();
147
+ var _effect = _useSignals();
190
148
  try {
191
- return /* @__PURE__ */ React2.createElement("div", {
149
+ return /* @__PURE__ */ React.createElement("div", {
192
150
  role: "none",
193
- className: "p-trimMd container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-trimSm md:gap-trimMd border border-separator rounded-md"
151
+ className: mx("container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-trimSm md:gap-trimMd p-trimMd", "border border-separator rounded-md")
194
152
  }, children);
195
153
  } finally {
196
154
  _effect.f();
197
155
  }
198
156
  };
199
- var controlItemClasses = "pli-trimMd plb-trimMd container-max-width grid md:col-span-2 grid-cols-subgrid items-center gap-trimSm border border-separator rounded-md *:first:!mbs-0 *:last:!mbe-0";
200
- var controlItemTitleClasses = "text-lg font-normal";
201
- var controlItemDescriptionClasses = "text-base mlb-trimSm md:mbe-0 text-description";
157
+ var controlItemClasses = mx([
158
+ "container-max-width grid md:col-span-2 grid-cols-subgrid gap-trimSm items-center",
159
+ // TODO(burdon): Use grid gap consistently or apply margins consistently?
160
+ "mlb-[--control-spacing] *:first:!mbs-0 *:last:!mbe-0 pli-trimMd plb-trimMd",
161
+ "border border-separator rounded-md"
162
+ ]);
163
+ var controlItemTitleClasses = "mbe-0 text-lg text-baseText font-normal";
164
+ var controlItemDescriptionClasses = "mlb-trimSm md:mbe-0 text-base text-description";
202
165
  var ControlItem = ({ title, description, children }) => {
203
- var _effect = _useSignals2();
166
+ var _effect = _useSignals();
204
167
  try {
205
168
  const { t } = useTranslation(translationKey);
206
- return /* @__PURE__ */ React2.createElement("div", {
169
+ return /* @__PURE__ */ React.createElement("div", {
207
170
  className: controlItemClasses
208
- }, /* @__PURE__ */ React2.createElement("div", {
171
+ }, /* @__PURE__ */ React.createElement("div", {
209
172
  role: "none"
210
- }, /* @__PURE__ */ React2.createElement("h3", {
173
+ }, /* @__PURE__ */ React.createElement("h3", {
211
174
  className: controlItemTitleClasses
212
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
175
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
213
176
  className: controlItemDescriptionClasses
214
177
  }, toLocalizedString(description, t))), children);
215
178
  } finally {
@@ -217,16 +180,16 @@ var ControlItem = ({ title, description, children }) => {
217
180
  }
218
181
  };
219
182
  var ControlItemInput = ({ title, description, children }) => {
220
- var _effect = _useSignals2();
183
+ var _effect = _useSignals();
221
184
  try {
222
185
  const { t } = useTranslation(translationKey);
223
- return /* @__PURE__ */ React2.createElement(Input2.Root, null, /* @__PURE__ */ React2.createElement("div", {
186
+ return /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement("div", {
224
187
  className: controlItemClasses
225
- }, /* @__PURE__ */ React2.createElement("div", {
188
+ }, /* @__PURE__ */ React.createElement("div", {
226
189
  role: "none"
227
- }, /* @__PURE__ */ React2.createElement(Input2.Label, {
190
+ }, /* @__PURE__ */ React.createElement(Input.Label, {
228
191
  classNames: controlItemTitleClasses
229
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement(Input2.DescriptionAndValidation, null, /* @__PURE__ */ React2.createElement(Input2.Description, {
192
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, null, /* @__PURE__ */ React.createElement(Input.Description, {
230
193
  classNames: controlItemDescriptionClasses
231
194
  }, toLocalizedString(description, t)))), children));
232
195
  } finally {
@@ -234,15 +197,15 @@ var ControlItemInput = ({ title, description, children }) => {
234
197
  }
235
198
  };
236
199
  var ControlFrameItem = ({ title, description, children }) => {
237
- var _effect = _useSignals2();
200
+ var _effect = _useSignals();
238
201
  try {
239
202
  const { t } = useTranslation(translationKey);
240
- return /* @__PURE__ */ React2.createElement("div", {
203
+ return /* @__PURE__ */ React.createElement("div", {
241
204
  role: "group",
242
205
  className: "min-is-0"
243
- }, /* @__PURE__ */ React2.createElement("h3", {
206
+ }, /* @__PURE__ */ React.createElement("h3", {
244
207
  className: "text-lg mbe-2"
245
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
208
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
246
209
  className: "mlb-trimSm md:mbe-0 text-description"
247
210
  }, toLocalizedString(description, t)), children);
248
211
  } finally {
@@ -252,40 +215,40 @@ var ControlFrameItem = ({ title, description, children }) => {
252
215
 
253
216
  // src/components/FieldEditor/FieldEditor.tsx
254
217
  import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
255
- import React14, { useCallback as useCallback9, useEffect as useEffect8, useMemo as useMemo7, useState as useState5 } from "react";
256
- import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo-schema";
218
+ import React14, { useCallback as useCallback12, useEffect as useEffect8, useMemo as useMemo7, useState as useState6 } from "react";
219
+ import { Format as Format5, FormatEnums, formatToType } from "@dxos/echo/internal";
257
220
  import { log as log3 } from "@dxos/log";
258
- import { useTranslation as useTranslation8 } from "@dxos/react-ui";
259
- import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
221
+ import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
222
+ import { formatToAdditionalPropertyAttributes, getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
260
223
 
261
224
  // src/components/Form/custom/GeoPointInput.tsx
262
- import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
263
- import React4, { useCallback, useState, useEffect, useMemo } from "react";
264
- import { GeoLocation } from "@dxos/echo-schema";
265
- import { Input as Input4, useTranslation as useTranslation2 } from "@dxos/react-ui";
225
+ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
226
+ import React3, { useCallback, useEffect, useMemo, useState } from "react";
227
+ import { GeoLocation } from "@dxos/echo/internal";
228
+ import { Input as Input3, useTranslation as useTranslation2 } from "@dxos/react-ui";
266
229
  import { safeParseFloat } from "@dxos/util";
267
230
 
268
231
  // src/components/Form/Input.tsx
269
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
270
- import React3 from "react";
271
- import { Icon, Input as Input3, Tooltip } from "@dxos/react-ui";
232
+ import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
233
+ import React2 from "react";
234
+ import { Icon, Input as Input2, Tooltip } from "@dxos/react-ui";
272
235
  import { labelSpacing } from "@dxos/react-ui-stack";
273
- import { errorText, mx as mx3 } from "@dxos/react-ui-theme";
236
+ import { errorText, mx as mx2 } from "@dxos/react-ui-theme";
274
237
  var InputHeader = ({ error, label, readonly }) => {
275
- var _effect = _useSignals3();
238
+ var _effect = _useSignals2();
276
239
  try {
277
- const Label = readonly ? "span" : Input3.Label;
240
+ const Label = readonly ? "span" : Input2.Label;
278
241
  const labelProps = readonly ? {} : {
279
242
  classNames: "!mlb-0"
280
243
  };
281
- return /* @__PURE__ */ React3.createElement("div", {
244
+ return /* @__PURE__ */ React2.createElement("div", {
282
245
  role: "none",
283
- className: mx3("flex justify-between items-center", labelSpacing)
284
- }, /* @__PURE__ */ React3.createElement(Label, labelProps, label), error && /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
246
+ className: mx2("flex justify-between items-center", labelSpacing)
247
+ }, /* @__PURE__ */ React2.createElement(Label, labelProps, label), error && /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
285
248
  asChild: true,
286
249
  content: error,
287
250
  side: "bottom"
288
- }, /* @__PURE__ */ React3.createElement(Icon, {
251
+ }, /* @__PURE__ */ React2.createElement(Icon, {
289
252
  icon: "ph--warning--regular",
290
253
  size: 4,
291
254
  classNames: errorText
@@ -296,8 +259,8 @@ var InputHeader = ({ error, label, readonly }) => {
296
259
  };
297
260
 
298
261
  // src/components/Form/custom/GeoPointInput.tsx
299
- var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
300
- var _effect = _useSignals4();
262
+ var GeoPointInput = ({ type, label, readonly, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
263
+ var _effect = _useSignals3();
301
264
  try {
302
265
  const { t } = useTranslation2(translationKey);
303
266
  const { status, error } = getStatus();
@@ -342,46 +305,52 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
342
305
  onValueChange,
343
306
  type
344
307
  ]);
345
- return /* @__PURE__ */ React4.createElement(Input4.Root, {
308
+ return /* @__PURE__ */ React3.createElement(Input3.Root, {
346
309
  validationValence: status
347
- }, /* @__PURE__ */ React4.createElement(InputHeader, {
310
+ }, /* @__PURE__ */ React3.createElement(InputHeader, {
348
311
  error,
349
312
  label
350
- }), /* @__PURE__ */ React4.createElement("div", {
313
+ }), /* @__PURE__ */ React3.createElement("div", {
351
314
  role: "none",
352
315
  className: "grid grid-cols-2 gap-2"
353
- }, /* @__PURE__ */ React4.createElement(Input4.TextInput, {
354
- type: "text",
355
- pattern: "^-?[0-9]*\\.?[0-9]*$",
356
- disabled,
357
- placeholder: t("placeholder latitude"),
316
+ }, /* @__PURE__ */ React3.createElement("div", {
317
+ role: "none"
318
+ }, /* @__PURE__ */ React3.createElement(Input3.Label, null, t("latitude label")), /* @__PURE__ */ React3.createElement(Input3.TextInput, {
319
+ type: "number",
320
+ step: "0.00001",
321
+ min: "-90",
322
+ max: "90",
323
+ disabled: !!readonly,
358
324
  value: latitudeText,
359
325
  onChange: handleCoordinateChange("latitude", setLatitudeText),
360
326
  onBlur
361
- }), /* @__PURE__ */ React4.createElement(Input4.TextInput, {
362
- type: "text",
363
- pattern: "^-?[0-9]*\\.?[0-9]*$",
364
- disabled,
365
- placeholder: t("placeholder longitude"),
327
+ })), /* @__PURE__ */ React3.createElement("div", {
328
+ role: "none"
329
+ }, /* @__PURE__ */ React3.createElement(Input3.Label, null, t("longitude label")), /* @__PURE__ */ React3.createElement(Input3.TextInput, {
330
+ type: "number",
331
+ step: "0.00001",
332
+ min: "-180",
333
+ max: "180",
334
+ disabled: !!readonly,
366
335
  value: longitudeText,
367
336
  onChange: handleCoordinateChange("longitude", setLongitudeText),
368
337
  onBlur
369
- })));
338
+ }))));
370
339
  } finally {
371
340
  _effect.f();
372
341
  }
373
342
  };
374
343
 
375
344
  // src/components/Form/custom/SelectOptionsInput.tsx
376
- import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
377
- import React5, { useCallback as useCallback2, useEffect as useEffect2, useState as useState2, useRef } from "react";
345
+ import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
346
+ import React4, { useCallback as useCallback2, useEffect as useEffect2, useRef, useState as useState2 } from "react";
378
347
  import { PublicKey } from "@dxos/keys";
379
- import { Icon as Icon2, IconButton, Input as Input5, Tag, Toolbar, useTranslation as useTranslation3 } from "@dxos/react-ui";
348
+ import { IconButton, Input as Input4, Tag, useTranslation as useTranslation3 } from "@dxos/react-ui";
380
349
  import { List } from "@dxos/react-ui-list";
381
350
  import { HuePicker } from "@dxos/react-ui-pickers";
382
- import { hues, mx as mx4 } from "@dxos/react-ui-theme";
383
- var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
384
- var _effect = _useSignals5();
351
+ import { hues, subtleHover } from "@dxos/react-ui-theme";
352
+ var SelectOptionInput = ({ type, label, readonly, getStatus, getValue: getValue3, onValueChange }) => {
353
+ var _effect = _useSignals4();
385
354
  try {
386
355
  const [selected, setSelectedId] = useState2(null);
387
356
  const [isNewOption, setIsNewOption] = useState2(false);
@@ -489,49 +458,56 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
489
458
  selected,
490
459
  isNewOption
491
460
  ]);
492
- return /* @__PURE__ */ React5.createElement(Input5.Root, {
461
+ return /* @__PURE__ */ React4.createElement(Input4.Root, {
493
462
  validationValence: status
494
- }, /* @__PURE__ */ React5.createElement(InputHeader, {
463
+ }, /* @__PURE__ */ React4.createElement(InputHeader, {
495
464
  error,
496
465
  label
497
- }), /* @__PURE__ */ React5.createElement("div", {
466
+ }), /* @__PURE__ */ React4.createElement("div", {
498
467
  role: "none"
499
- }, options && /* @__PURE__ */ React5.createElement(List.Root, {
468
+ }, options && /* @__PURE__ */ React4.createElement(List.Root, {
500
469
  items: options,
501
470
  isItem: (item) => true,
502
- onMove: handleMove
503
- }, ({ items }) => /* @__PURE__ */ React5.createElement("div", {
471
+ onMove: readonly ? void 0 : handleMove,
472
+ readonly: !!readonly
473
+ }, ({ items }) => /* @__PURE__ */ React4.createElement("div", {
504
474
  role: "list",
505
- className: "w-full overflow-auto"
506
- }, items?.map((item) => /* @__PURE__ */ React5.createElement("div", {
475
+ className: "is-full overflow-auto"
476
+ }, items?.map((item) => /* @__PURE__ */ React4.createElement("div", {
507
477
  key: item.id
508
- }, /* @__PURE__ */ React5.createElement(List.Item, {
478
+ }, /* @__PURE__ */ React4.createElement(List.Item, {
509
479
  role: "button",
510
480
  item,
511
481
  classNames: [
512
- "p-1 plb-2",
513
- "flex flex-col",
514
- "cursor-pointer",
515
- "hover:bg-hoverOverlay"
482
+ subtleHover,
483
+ "flex flex-col cursor-pointer rounded-sm"
516
484
  ],
517
485
  "aria-expanded": selected === item.id
518
- }, /* @__PURE__ */ React5.createElement("div", {
486
+ }, /* @__PURE__ */ React4.createElement("div", {
519
487
  className: "flex items-center"
520
- }, /* @__PURE__ */ React5.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React5.createElement(List.ItemTitle, {
488
+ }, /* @__PURE__ */ React4.createElement(List.ItemDragHandle, {
489
+ disabled: !!readonly
490
+ }), /* @__PURE__ */ React4.createElement(List.ItemTitle, {
521
491
  onClick: () => handleClick(item.id),
522
492
  classNames: "flex-1"
523
- }, /* @__PURE__ */ React5.createElement(Tag, {
493
+ }, /* @__PURE__ */ React4.createElement(Tag, {
524
494
  palette: item.color
525
- }, item.title || "\u200B")), /* @__PURE__ */ React5.createElement(Icon2, {
495
+ }, item.title || "\u200B")), /* @__PURE__ */ React4.createElement(IconButton, {
496
+ iconOnly: true,
497
+ variant: "ghost",
498
+ label: t(selected === item.id ? "collapse label" : "expand label", {
499
+ ns: "os"
500
+ }),
526
501
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
527
502
  onClick: () => handleClick(item.id)
528
- })), selected === item.id && /* @__PURE__ */ React5.createElement("div", {
529
- className: "mis-4 mbs-2 flex flex-col gap-1"
530
- }, /* @__PURE__ */ React5.createElement(Input5.Label, {
503
+ })), selected === item.id && /* @__PURE__ */ React4.createElement("div", {
504
+ className: "pli-cardSpacingInline plb-cardSpacingBlock flex flex-col gap-1 density-fine"
505
+ }, /* @__PURE__ */ React4.createElement(Input4.Label, {
531
506
  classNames: "text-xs"
532
- }, t("select option label")), /* @__PURE__ */ React5.createElement("div", {
533
- className: "flex flex-row items-center gap-1"
534
- }, /* @__PURE__ */ React5.createElement(Input5.TextInput, {
507
+ }, t("select option label")), /* @__PURE__ */ React4.createElement("div", {
508
+ className: "grid grid-cols-[1fr_min-content_min-content] gap-1"
509
+ }, /* @__PURE__ */ React4.createElement(Input4.TextInput, {
510
+ disabled: !!readonly,
535
511
  placeholder: t("select option label placeholder"),
536
512
  ref: selected === item.id ? inputRef : void 0,
537
513
  value: item.title,
@@ -539,40 +515,34 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
539
515
  onKeyDown: handleKeyDown,
540
516
  classNames: "flex-1",
541
517
  "data-no-submit": true
542
- }), /* @__PURE__ */ React5.createElement(Toolbar.Root, {
543
- classNames: "p-0 m-0 !is-auto"
544
- }, /* @__PURE__ */ React5.createElement(HuePicker, {
518
+ }), /* @__PURE__ */ React4.createElement(HuePicker, {
519
+ disabled: !!readonly,
545
520
  value: item.color,
546
- onChange: handleColorChange(item.id),
547
- rootVariant: "toolbar-button"
548
- })), /* @__PURE__ */ React5.createElement(IconButton, {
521
+ onChange: handleColorChange(item.id)
522
+ }), /* @__PURE__ */ React4.createElement(IconButton, {
523
+ disabled: !!readonly,
549
524
  icon: "ph--trash--fill",
550
525
  iconOnly: true,
551
526
  label: t("select option delete"),
552
527
  onClick: () => handleDelete(item.id)
553
- })))))), /* @__PURE__ */ React5.createElement("div", {
554
- role: "listitem"
555
- }, /* @__PURE__ */ React5.createElement("div", {
556
- role: "button",
557
- className: mx4("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
558
- onClick: handleAdd
559
- }, /* @__PURE__ */ React5.createElement("div", {
560
- className: "flex items-center gap-1"
561
- }, /* @__PURE__ */ React5.createElement(Icon2, {
562
- icon: "ph--plus--regular"
563
- }), /* @__PURE__ */ React5.createElement("span", {
564
- className: "text-sm"
565
- }, t("select option add")))))))));
528
+ })))))), /* @__PURE__ */ React4.createElement(IconButton, {
529
+ variant: "ghost",
530
+ icon: "ph--plus--regular",
531
+ label: t("select option add"),
532
+ onClick: handleAdd,
533
+ disabled: !!readonly,
534
+ classNames: "is-full"
535
+ })))));
566
536
  } finally {
567
537
  _effect.f();
568
538
  }
569
539
  };
570
540
 
571
541
  // src/components/Form/custom/TupleInput.tsx
572
- import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
573
- import React6 from "react";
574
- import { Input as Input6 } from "@dxos/react-ui";
575
- import { mx as mx5 } from "@dxos/react-ui-theme";
542
+ import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
543
+ import React5 from "react";
544
+ import { Input as Input5 } from "@dxos/react-ui";
545
+ import { mx as mx3 } from "@dxos/react-ui-theme";
576
546
  import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
577
547
  var gridCols = [
578
548
  "grid-cols-1",
@@ -580,22 +550,22 @@ var gridCols = [
580
550
  "grid-cols-3",
581
551
  "grid-cols-4"
582
552
  ];
583
- var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
584
- var _effect = _useSignals6();
553
+ var TupleInput = ({ binding, type, label, readonly, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
554
+ var _effect = _useSignals5();
585
555
  try {
586
556
  const { status, error } = getStatus();
587
557
  const values = getValue3() ?? {};
588
- return /* @__PURE__ */ React6.createElement(Input6.Root, {
558
+ return /* @__PURE__ */ React5.createElement(Input5.Root, {
589
559
  validationValence: status
590
- }, /* @__PURE__ */ React6.createElement(InputHeader, {
560
+ }, /* @__PURE__ */ React5.createElement(InputHeader, {
591
561
  error,
592
562
  label
593
- }), /* @__PURE__ */ React6.createElement("div", {
594
- className: mx5("grid gap-2", gridCols[binding.length - 1])
595
- }, binding.map((prop) => /* @__PURE__ */ React6.createElement(Input6.TextInput, {
563
+ }), /* @__PURE__ */ React5.createElement("div", {
564
+ className: mx3("grid gap-2", gridCols[binding.length - 1])
565
+ }, binding.map((prop) => /* @__PURE__ */ React5.createElement(Input5.TextInput, {
596
566
  key: prop,
597
567
  type: "number",
598
- disabled,
568
+ disabled: !!readonly,
599
569
  value: values[prop],
600
570
  onChange: (event) => onValueChange(type, {
601
571
  ...values,
@@ -609,103 +579,104 @@ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValu
609
579
  };
610
580
 
611
581
  // src/components/Form/Defaults.tsx
612
- import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
613
- import React7, { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2 } from "react";
614
- import { Input as Input7, Select, useTranslation as useTranslation4 } from "@dxos/react-ui";
615
- var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
616
- var _effect = _useSignals7();
582
+ import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
583
+ import React6, { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2 } from "react";
584
+ import { Input as Input6, Select, useTranslation as useTranslation4 } from "@dxos/react-ui";
585
+ var TextInput = ({ type, label, inputOnly, readonly, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
586
+ var _effect = _useSignals6();
617
587
  try {
618
588
  const { status, error } = getStatus();
619
- return disabled && !getValue3() ? null : disabled && inputOnly ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.Root, {
589
+ return readonly && !getValue3() ? null : readonly === "static" && inputOnly ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.Root, {
620
590
  validationValence: status
621
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
591
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
622
592
  error,
623
593
  label
624
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextInput, {
625
- disabled,
594
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.TextInput, {
595
+ disabled: !!readonly,
626
596
  placeholder,
627
597
  value: getValue3() ?? "",
628
598
  onChange: (event) => onValueChange(type, event.target.value),
629
599
  onBlur
630
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.Validation, null, error));
600
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.Validation, null, error));
631
601
  } finally {
632
602
  _effect.f();
633
603
  }
634
604
  };
635
- var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
636
- var _effect = _useSignals7();
605
+ var NumberInput = ({ type, label, inputOnly, readonly, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
606
+ var _effect = _useSignals6();
637
607
  try {
638
608
  const { status, error } = getStatus();
639
- return disabled && !getValue3() ? null : disabled && inputOnly ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.Root, {
609
+ return readonly && !getValue3() ? null : readonly === "static" && inputOnly ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.Root, {
640
610
  validationValence: status
641
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
611
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
642
612
  error,
643
613
  label
644
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextInput, {
614
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.TextInput, {
645
615
  type: "number",
646
- disabled,
616
+ disabled: !!readonly,
647
617
  placeholder,
648
- value: getValue3() ?? 0,
618
+ value: getValue3(),
649
619
  onChange: (event) => onValueChange(type, event.target.value),
650
620
  onBlur
651
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
621
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
652
622
  } finally {
653
623
  _effect.f();
654
624
  }
655
625
  };
656
- var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange, disabled }) => {
657
- var _effect = _useSignals7();
626
+ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange, readonly }) => {
627
+ var _effect = _useSignals6();
658
628
  try {
659
629
  const { status, error } = getStatus();
660
630
  const checked = Boolean(getValue3());
661
631
  const { t } = useTranslation4(translationKey);
662
- return /* @__PURE__ */ React7.createElement(Input7.Root, {
632
+ return /* @__PURE__ */ React6.createElement(Input6.Root, {
663
633
  validationValence: status
664
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
634
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
665
635
  error,
666
636
  label
667
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, t(checked ? "boolean input true value" : "boolean input false value")) : /* @__PURE__ */ React7.createElement(Input7.Switch, {
637
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, t(checked ? "boolean input true value" : "boolean input false value")) : /* @__PURE__ */ React6.createElement(Input6.Switch, {
638
+ disabled: !!readonly,
668
639
  checked,
669
- onCheckedChange: (value) => onValueChange(type, value)
670
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
640
+ onCheckedChange: (value2) => onValueChange(type, value2)
641
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
671
642
  } finally {
672
643
  _effect.f();
673
644
  }
674
645
  };
675
- var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
676
- var _effect = _useSignals7();
646
+ var SelectInput = ({ type, label, inputOnly, readonly, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
647
+ var _effect = _useSignals6();
677
648
  try {
678
649
  const { status, error } = getStatus();
679
- const value = getValue3();
680
- const handleValueChange = useCallback3((value2) => onValueChange(type, value2), [
650
+ const value2 = getValue3();
651
+ const handleValueChange = useCallback3((value3) => onValueChange(type, value3), [
681
652
  type,
682
653
  onValueChange
683
654
  ]);
684
- return disabled && !value ? null : /* @__PURE__ */ React7.createElement(Input7.Root, {
655
+ return readonly && !value2 ? null : /* @__PURE__ */ React6.createElement(Input6.Root, {
685
656
  validationValence: status
686
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
657
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
687
658
  error,
688
659
  label
689
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value)?.label ?? String(value)) : /* @__PURE__ */ React7.createElement(Select.Root, {
690
- value,
660
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value2)?.label ?? String(value2)) : /* @__PURE__ */ React6.createElement(Select.Root, {
661
+ value: value2,
691
662
  onValueChange: handleValueChange
692
- }, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
663
+ }, /* @__PURE__ */ React6.createElement(Select.TriggerButton, {
693
664
  classNames: "is-full",
694
- disabled,
665
+ disabled: !!readonly,
695
666
  placeholder
696
- }), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value: value2, label: label2 }) => (
667
+ }), /* @__PURE__ */ React6.createElement(Select.Portal, null, /* @__PURE__ */ React6.createElement(Select.Content, null, /* @__PURE__ */ React6.createElement(Select.Viewport, null, options?.map(({ value: value3, label: label2 }) => (
697
668
  // NOTE: Numeric values are converted to and from strings.
698
- /* @__PURE__ */ React7.createElement(Select.Option, {
699
- key: String(value2),
700
- value: String(value2)
701
- }, label2 ?? String(value2))
702
- )))))), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
669
+ /* @__PURE__ */ React6.createElement(Select.Option, {
670
+ key: String(value3),
671
+ value: String(value3)
672
+ }, label2 ?? String(value3))
673
+ ))), /* @__PURE__ */ React6.createElement(Select.Arrow, null)))), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
703
674
  } finally {
704
675
  _effect.f();
705
676
  }
706
677
  };
707
- var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
708
- var _effect = _useSignals7();
678
+ var MarkdownInput = ({ type, label, inputOnly, readonly, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
679
+ var _effect = _useSignals6();
709
680
  try {
710
681
  const { status, error } = getStatus();
711
682
  const textareaRef = useRef2(null);
@@ -727,24 +698,24 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
727
698
  getValue3(),
728
699
  adjustHeight
729
700
  ]);
730
- return /* @__PURE__ */ React7.createElement(Input7.Root, {
701
+ return /* @__PURE__ */ React6.createElement(Input6.Root, {
731
702
  validationValence: status
732
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
703
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
733
704
  error,
734
705
  label
735
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextArea, {
706
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.TextArea, {
736
707
  ref: textareaRef,
737
- disabled,
708
+ disabled: !!readonly,
738
709
  placeholder,
739
710
  value: getValue3() ?? "",
740
- classNames: "min-bs-auto max-h-40 overflow-auto",
711
+ classNames: "min-bs-auto max-bs-40 overflow-auto",
741
712
  onChange: (event) => onValueChange(type, event.target.value),
742
713
  onBlur,
743
714
  style: {
744
715
  resize: "none"
745
716
  },
746
717
  spellCheck: false
747
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.Validation, null, error));
718
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.Validation, null, error));
748
719
  } finally {
749
720
  _effect.f();
750
721
  }
@@ -752,27 +723,28 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
752
723
 
753
724
  // src/components/Form/Form.tsx
754
725
  import { useSignals as _useSignals13 } from "@preact-signals/safe-react/tracking";
755
- import React13, { useEffect as useEffect7, useMemo as useMemo6, useRef as useRef3 } from "react";
726
+ import { useFocusFinders } from "@fluentui/react-tabster";
727
+ import React13, { useCallback as useCallback11, useEffect as useEffect7, useRef as useRef3 } from "react";
756
728
  import { cardDialogOverflow, cardSpacing as cardSpacing2 } from "@dxos/react-ui-stack";
757
729
 
758
730
  // src/components/Form/FormActions.tsx
759
- import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
760
- import React9 from "react";
731
+ import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
732
+ import React8 from "react";
761
733
  import { IconButton as IconButton2, useTranslation as useTranslation5 } from "@dxos/react-ui";
762
734
  import { cardSpacing } from "@dxos/react-ui-stack";
763
- import { mx as mx6 } from "@dxos/react-ui-theme";
735
+ import { mx as mx4 } from "@dxos/react-ui-theme";
764
736
 
765
737
  // src/components/Form/FormContext.tsx
766
- import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
767
- import React8, { createContext, useContext, useEffect as useEffect6, useMemo as useMemo3, useCallback as useCallback6 } from "react";
738
+ import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
739
+ import React7, { createContext, useCallback as useCallback7, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
768
740
  import { raise } from "@dxos/debug";
769
- import { getValue as getValue2 } from "@dxos/echo-schema";
741
+ import { getValue as getValue2 } from "@dxos/echo/internal";
770
742
  import { createJsonPath as createJsonPath2 } from "@dxos/effect";
771
743
 
772
744
  // src/hooks/useForm.ts
773
- import { SchemaAST } from "effect";
745
+ import * as SchemaAST from "effect/SchemaAST";
774
746
  import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo2, useState as useState3 } from "react";
775
- import { getValue, setValue } from "@dxos/echo-schema";
747
+ import { getValue, setValue } from "@dxos/echo/internal";
776
748
  import { createJsonPath, fromEffectValidationPath } from "@dxos/effect";
777
749
  import { invariant } from "@dxos/invariant";
778
750
  import { log } from "@dxos/log";
@@ -781,7 +753,7 @@ var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.t
781
753
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
782
754
  invariant(SchemaAST.isTypeLiteral(schema.ast), void 0, {
783
755
  F: __dxlog_file,
784
- L: 93,
756
+ L: 96,
785
757
  S: void 0,
786
758
  A: [
787
759
  "SchemaAST.isTypeLiteral(schema.ast)",
@@ -875,17 +847,17 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
875
847
  }, [
876
848
  values
877
849
  ]);
878
- const onValueChange = useCallback4((path, type, value) => {
850
+ const onValueChange = useCallback4((path, type, value2) => {
879
851
  const jsonPath = createJsonPath(path);
880
- let parsedValue = value;
852
+ let parsedValue = value2;
881
853
  try {
882
854
  if (type === "number") {
883
- parsedValue = parseFloat(value) || 0;
855
+ parsedValue = parseFloat(value2) || 0;
884
856
  }
885
857
  } catch (err) {
886
858
  log.catch(err, void 0, {
887
859
  F: __dxlog_file,
888
- L: 213,
860
+ L: 217,
889
861
  S: void 0,
890
862
  C: (f, a) => f(...a)
891
863
  });
@@ -895,15 +867,16 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
895
867
  ...setValue(values, jsonPath, parsedValue)
896
868
  };
897
869
  setValues(newValues);
898
- setChanged((prev) => ({
899
- ...prev,
870
+ const newChanged = {
871
+ ...changed,
900
872
  [jsonPath]: true
901
- }));
873
+ };
874
+ setChanged(newChanged);
902
875
  onValuesChanged?.(newValues);
903
876
  const isValid = validate(newValues);
904
877
  if (isValid && onValid) {
905
878
  onValid(newValues, {
906
- changed
879
+ changed: newChanged
907
880
  });
908
881
  }
909
882
  }, [
@@ -953,10 +926,10 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
953
926
  onTouched
954
927
  ]);
955
928
  };
956
- var createKeySet = (obj, value) => {
929
+ var createKeySet = (obj, value2) => {
957
930
  invariant(obj, void 0, {
958
931
  F: __dxlog_file,
959
- L: 275,
932
+ L: 280,
960
933
  S: void 0,
961
934
  A: [
962
935
  "obj",
@@ -965,7 +938,7 @@ var createKeySet = (obj, value) => {
965
938
  });
966
939
  return Object.keys(obj).reduce((acc, key) => ({
967
940
  ...acc,
968
- [key]: value
941
+ [key]: value2
969
942
  }), {});
970
943
  };
971
944
  var flatMap = (errors) => {
@@ -980,7 +953,7 @@ var flatMap = (errors) => {
980
953
 
981
954
  // src/hooks/useRefQueryLookupHandler.ts
982
955
  import { useCallback as useCallback5 } from "react";
983
- import { getObjectDXN } from "@dxos/echo-schema";
956
+ import { Obj } from "@dxos/echo";
984
957
  import { Filter } from "@dxos/react-client/echo";
985
958
  import { isNonNullable } from "@dxos/util";
986
959
  var useRefQueryLookupHandler = ({ space }) => {
@@ -991,13 +964,13 @@ var useRefQueryLookupHandler = ({ space }) => {
991
964
  const query = space.db.query(Filter.typename(typeInfo.typename));
992
965
  const { objects } = await query.run();
993
966
  return objects.map((object) => {
994
- const dxn = getObjectDXN(object);
967
+ const dxn = Obj.getDXN(object);
995
968
  if (!dxn) {
996
969
  return void 0;
997
970
  }
998
971
  const item = {
999
972
  dxn,
1000
- label: object?.name ?? object?.id ?? ""
973
+ label: Obj.getLabel(object) ?? object?.id ?? ""
1001
974
  };
1002
975
  return item;
1003
976
  }).filter(isNonNullable);
@@ -1007,12 +980,14 @@ var useRefQueryLookupHandler = ({ space }) => {
1007
980
  };
1008
981
 
1009
982
  // src/hooks/useQueryRefOptions.ts
1010
- import { useEffect as useEffect5, useState as useState4 } from "react";
983
+ import { useCallback as useCallback6, useEffect as useEffect5, useState as useState4 } from "react";
1011
984
  import { log as log2 } from "@dxos/log";
1012
985
  var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts";
1013
986
  var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1014
987
  const [options, setOptions] = useState4([]);
1015
988
  const [loading, setLoading] = useState4(false);
989
+ const [state, setState] = useState4({});
990
+ const update = useCallback6(() => setState({}), []);
1016
991
  useEffect5(() => {
1017
992
  if (!refTypeInfo || !onQueryRefOptions) {
1018
993
  return;
@@ -1032,7 +1007,7 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1032
1007
  } catch (error) {
1033
1008
  log2.error("Failed to fetch ref options:", error, {
1034
1009
  F: __dxlog_file2,
1035
- L: 42,
1010
+ L: 51,
1036
1011
  S: void 0,
1037
1012
  C: (f, a) => f(...a)
1038
1013
  });
@@ -1044,10 +1019,12 @@ var useQueryRefOptions = ({ refTypeInfo, onQueryRefOptions }) => {
1044
1019
  void fetchOptions();
1045
1020
  }, [
1046
1021
  refTypeInfo,
1047
- onQueryRefOptions
1022
+ onQueryRefOptions,
1023
+ state
1048
1024
  ]);
1049
1025
  return {
1050
1026
  options,
1027
+ update,
1051
1028
  loading
1052
1029
  };
1053
1030
  };
@@ -1070,7 +1047,7 @@ var useInputProps = (path = []) => {
1070
1047
  return useMemo3(() => ({
1071
1048
  getStatus: () => getStatus(stablePath),
1072
1049
  getValue: () => getFormValue(stablePath),
1073
- onValueChange: (type, value) => onValueChange(stablePath, type, value),
1050
+ onValueChange: (type, value2) => onValueChange(stablePath, type, value2),
1074
1051
  onBlur: () => onTouched(stablePath)
1075
1052
  }), [
1076
1053
  getStatus,
@@ -1081,10 +1058,10 @@ var useInputProps = (path = []) => {
1081
1058
  ]);
1082
1059
  };
1083
1060
  var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1084
- var _effect = _useSignals8();
1061
+ var _effect = _useSignals7();
1085
1062
  try {
1086
1063
  const form = useForm(formOptions);
1087
- const handleKeyDown = useCallback6((event) => {
1064
+ const handleKeyDown = useCallback7((event) => {
1088
1065
  const keyIsEnter = event.key === "Enter";
1089
1066
  const modifierUsed = event.ctrlKey || event.altKey || event.metaKey || event.shiftKey;
1090
1067
  const inputIsTextarea = event.target.tagName.toLowerCase() === "textarea";
@@ -1100,7 +1077,9 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1100
1077
  }
1101
1078
  }
1102
1079
  }, [
1103
- form,
1080
+ form.canSave,
1081
+ form.formIsValid,
1082
+ form.handleSave,
1104
1083
  autoSave
1105
1084
  ]);
1106
1085
  useEffect6(() => {
@@ -1117,7 +1096,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1117
1096
  form.handleSave,
1118
1097
  autoSave
1119
1098
  ]);
1120
- return /* @__PURE__ */ React8.createElement(FormContext.Provider, {
1099
+ return /* @__PURE__ */ React7.createElement(FormContext.Provider, {
1121
1100
  value: form
1122
1101
  }, children);
1123
1102
  } finally {
@@ -1127,24 +1106,24 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1127
1106
 
1128
1107
  // src/components/Form/FormActions.tsx
1129
1108
  var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1130
- var _effect = _useSignals9();
1109
+ var _effect = _useSignals8();
1131
1110
  try {
1132
1111
  const { t } = useTranslation5(translationKey);
1133
1112
  const { canSave, handleSave } = useFormContext();
1134
- return /* @__PURE__ */ React9.createElement("div", {
1113
+ return /* @__PURE__ */ React8.createElement("div", {
1135
1114
  role: "none",
1136
- className: mx6(outerSpacing === "scroll-fields" ? "pli-cardSpacingInline mbe-cardSpacingBlock" : outerSpacing ? cardSpacing : "mbs-cardSpacingBlock", "flex [&_button]:grow gap-1 first:mbs-0")
1137
- }, onCancel && !readonly && /* @__PURE__ */ React9.createElement(IconButton2, {
1115
+ className: mx4(outerSpacing === "scroll-fields" ? "pli-cardSpacingInline mbe-cardSpacingBlock" : outerSpacing ? cardSpacing : "mbs-cardSpacingBlock", "flex [&_button]:grow gap-1 first:mbs-0")
1116
+ }, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
1138
1117
  "data-testid": "cancel-button",
1139
1118
  icon: "ph--x--regular",
1140
- label: t("button cancel"),
1119
+ label: t("cancel button label"),
1141
1120
  onClick: onCancel
1142
- }), handleSave && /* @__PURE__ */ React9.createElement(IconButton2, {
1121
+ }), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
1143
1122
  type: "submit",
1144
1123
  "data-testid": "save-button",
1145
1124
  disabled: !canSave,
1146
1125
  icon: "ph--check--regular",
1147
- label: t("button save"),
1126
+ label: t("save button label"),
1148
1127
  onClick: handleSave
1149
1128
  }));
1150
1129
  } finally {
@@ -1154,53 +1133,45 @@ var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1154
1133
 
1155
1134
  // src/components/Form/FormContent.tsx
1156
1135
  import { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
1157
- import { Schema, SchemaAST as SchemaAST4, pipe as pipe2 } from "effect";
1158
- import { capitalize as capitalize2 } from "effect/String";
1159
- import React12, { forwardRef, useMemo as useMemo5 } from "react";
1136
+ import * as Function2 from "effect/Function";
1137
+ import * as Schema from "effect/Schema";
1138
+ import * as SchemaAST4 from "effect/SchemaAST";
1139
+ import * as StringEffect from "effect/String";
1140
+ import React12, { Component, forwardRef as forwardRef2, useMemo as useMemo6 } from "react";
1160
1141
  import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
1161
- import { mx as mx8 } from "@dxos/react-ui-theme";
1142
+ import { mx as mx6 } from "@dxos/react-ui-theme";
1162
1143
  import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
1163
- import { isNotFalsy } from "@dxos/util";
1164
-
1165
- // src/components/Form/ArrayField.tsx
1166
- import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1167
- import { SchemaAST as SchemaAST3, pipe } from "effect";
1168
- import { capitalize } from "effect/String";
1169
- import React10, { Fragment, useCallback as useCallback7 } from "react";
1170
- import { findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
1171
- import { invariant as invariant2 } from "@dxos/invariant";
1172
- import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
1173
- import { getSchemaProperties } from "@dxos/schema";
1144
+ import { isTruthy } from "@dxos/util";
1174
1145
 
1175
1146
  // src/util/field.ts
1176
- import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1177
- var parseValue = ({ type, format, value }) => {
1178
- if (value === void 0 || value === null || value === "") {
1147
+ import { Format, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo/internal";
1148
+ var parseValue = ({ type, format, value: value2 }) => {
1149
+ if (value2 === void 0 || value2 === null || value2 === "") {
1179
1150
  return void 0;
1180
1151
  }
1181
1152
  const parseScalar = (type2) => {
1182
1153
  switch (type2) {
1183
1154
  case TypeEnum.Boolean: {
1184
- if (typeof value === "string") {
1185
- const lowercaseValue = value.toLowerCase();
1155
+ if (typeof value2 === "string") {
1156
+ const lowercaseValue = value2.toLowerCase();
1186
1157
  if (lowercaseValue === "0" || lowercaseValue === "false") {
1187
1158
  return false;
1188
1159
  } else if (lowercaseValue === "1" || lowercaseValue === "true") {
1189
1160
  return true;
1190
1161
  }
1191
1162
  }
1192
- return Boolean(value);
1163
+ return Boolean(value2);
1193
1164
  }
1194
1165
  case TypeEnum.Number: {
1195
- const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
1166
+ const cleaned = typeof value2 === "string" ? value2.replace(/[^0-9.-]+/g, "") : value2;
1196
1167
  const num = Number(cleaned);
1197
1168
  return Number.isNaN(num) ? null : num;
1198
1169
  }
1199
1170
  case TypeEnum.String:
1200
1171
  case TypeEnum.Ref:
1201
- return String(value);
1172
+ return String(value2);
1202
1173
  default: {
1203
- return value;
1174
+ return value2;
1204
1175
  }
1205
1176
  }
1206
1177
  };
@@ -1208,28 +1179,28 @@ var parseValue = ({ type, format, value }) => {
1208
1179
  return parseScalar(type);
1209
1180
  }
1210
1181
  switch (format) {
1211
- case FormatEnum.Boolean:
1182
+ case Format.TypeFormat.Boolean:
1212
1183
  return parseScalar(TypeEnum.Boolean);
1213
- case FormatEnum.Number:
1214
- case FormatEnum.Percent:
1215
- case FormatEnum.Currency:
1184
+ case Format.TypeFormat.Number:
1185
+ case Format.TypeFormat.Percent:
1186
+ case Format.TypeFormat.Currency:
1216
1187
  return parseScalar(TypeEnum.Number);
1217
- case FormatEnum.String:
1218
- case FormatEnum.Markdown: {
1188
+ case Format.TypeFormat.String:
1189
+ case Format.TypeFormat.Markdown: {
1219
1190
  return parseScalar(TypeEnum.String);
1220
1191
  }
1221
- case FormatEnum.Ref:
1222
- throw new Error(`unexpected format: ${FormatEnum.Ref}`);
1223
- case FormatEnum.DateTime:
1224
- case FormatEnum.Date:
1225
- case FormatEnum.Time:
1226
- case FormatEnum.Timestamp: {
1227
- const date = new Date(value);
1192
+ case Format.TypeFormat.Ref:
1193
+ throw new Error(`unexpected format: ${Format.TypeFormat.Ref}`);
1194
+ case Format.TypeFormat.DateTime:
1195
+ case Format.TypeFormat.Date:
1196
+ case Format.TypeFormat.Time:
1197
+ case Format.TypeFormat.Timestamp: {
1198
+ const date = new Date(value2);
1228
1199
  return isNaN(date.getTime()) ? null : date;
1229
1200
  }
1230
- case FormatEnum.GeoPoint: {
1231
- if (typeof value === "string") {
1232
- const cleaned = value.replace(/[^0-9.,-]+/g, "");
1201
+ case Format.TypeFormat.GeoPoint: {
1202
+ if (typeof value2 === "string") {
1203
+ const cleaned = value2.replace(/[^0-9.,-]+/g, "");
1233
1204
  const parts = cleaned.split(",");
1234
1205
  if (parts.length === 2) {
1235
1206
  const lat = parseFloat(parts[0]);
@@ -1248,53 +1219,42 @@ var parseValue = ({ type, format, value }) => {
1248
1219
  ];
1249
1220
  }
1250
1221
  default: {
1251
- return value;
1222
+ return value2;
1252
1223
  }
1253
1224
  }
1254
1225
  };
1255
1226
  var cellClassesForFieldType = ({ type, format }) => {
1256
- if (!format) {
1257
- switch (type) {
1258
- case TypeEnum.Number:
1259
- return [
1260
- "text-right",
1261
- "font-mono"
1262
- ];
1263
- case TypeEnum.Boolean:
1264
- return [
1265
- "text-right",
1266
- "font-mono"
1267
- ];
1268
- case TypeEnum.String:
1269
- return void 0;
1270
- case TypeEnum.Ref:
1271
- return void 0;
1272
- default: {
1273
- return void 0;
1274
- }
1275
- }
1276
- }
1277
- switch (format) {
1278
- case FormatEnum.Markdown:
1227
+ switch (format || type) {
1228
+ case Format.TypeFormat.Markdown:
1279
1229
  return void 0;
1280
- case FormatEnum.Time:
1281
- case FormatEnum.Timestamp:
1282
- case FormatEnum.DateTime:
1283
- case FormatEnum.Date:
1284
- case FormatEnum.Duration:
1230
+ case Format.TypeFormat.Time:
1231
+ case Format.TypeFormat.Timestamp:
1232
+ case Format.TypeFormat.DateTime:
1233
+ case Format.TypeFormat.Date:
1234
+ case Format.TypeFormat.Duration:
1285
1235
  return [
1286
1236
  "font-mono",
1287
1237
  "text-right"
1288
1238
  ];
1289
- case FormatEnum.Currency:
1239
+ case Format.TypeFormat.Currency:
1290
1240
  return [
1291
1241
  "text-right"
1292
1242
  ];
1293
- case FormatEnum.JSON:
1294
- case FormatEnum.DID:
1243
+ case Format.TypeFormat.JSON:
1244
+ case Format.TypeFormat.DID:
1295
1245
  return [
1296
1246
  "font-mono"
1297
1247
  ];
1248
+ case TypeEnum.Number:
1249
+ case TypeEnum.Boolean:
1250
+ return [
1251
+ "text-right",
1252
+ "font-mono"
1253
+ ];
1254
+ case TypeEnum.String:
1255
+ return void 0;
1256
+ case TypeEnum.Ref:
1257
+ return void 0;
1298
1258
  default:
1299
1259
  return void 0;
1300
1260
  }
@@ -1306,19 +1266,19 @@ var pathNotUniqueError = (path) => ({
1306
1266
 
1307
1267
  // src/util/formatting.ts
1308
1268
  import { format as formatDate } from "date-fns/format";
1309
- import { FormatEnum as FormatEnum2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo-schema";
1310
- var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1269
+ import { Format as Format2, GeoLocation as GeoLocation3, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
1270
+ var formatForDisplay = ({ type, format, value: value2, locale = void 0 }) => {
1311
1271
  const formatScalar = (type2) => {
1312
1272
  switch (type2) {
1313
1273
  case TypeEnum2.Boolean:
1314
- return value.toLocaleString().toUpperCase();
1274
+ return value2.toLocaleString().toUpperCase();
1315
1275
  case TypeEnum2.Number:
1316
- return value.toLocaleString(locale);
1276
+ return value2.toLocaleString(locale);
1317
1277
  case TypeEnum2.String:
1318
1278
  case TypeEnum2.Ref:
1319
- return String(value);
1279
+ return String(value2);
1320
1280
  default: {
1321
- return String(value);
1281
+ return String(value2);
1322
1282
  }
1323
1283
  }
1324
1284
  };
@@ -1326,144 +1286,137 @@ var formatForDisplay = ({ type, format, value, locale = void 0 }) => {
1326
1286
  return formatScalar(type);
1327
1287
  }
1328
1288
  switch (format) {
1329
- case FormatEnum2.Boolean: {
1289
+ case Format2.TypeFormat.Boolean: {
1330
1290
  return formatScalar(TypeEnum2.Boolean);
1331
1291
  }
1332
- case FormatEnum2.Number: {
1292
+ case Format2.TypeFormat.Number: {
1333
1293
  return formatScalar(TypeEnum2.Number);
1334
1294
  }
1335
- case FormatEnum2.String:
1336
- case FormatEnum2.Ref: {
1295
+ case Format2.TypeFormat.String:
1296
+ case Format2.TypeFormat.Ref: {
1337
1297
  return formatScalar(TypeEnum2.String);
1338
1298
  }
1339
- case FormatEnum2.Percent: {
1340
- return `${value * 100}%`;
1299
+ case Format2.TypeFormat.Percent: {
1300
+ return `${value2 * 100}%`;
1341
1301
  }
1342
- case FormatEnum2.Currency: {
1343
- return value.toLocaleString(locale, {
1302
+ case Format2.TypeFormat.Currency: {
1303
+ return value2.toLocaleString(locale, {
1344
1304
  style: "currency",
1345
1305
  currency: "USD",
1346
1306
  minimumFractionDigits: 2,
1347
1307
  maximumFractionDigits: 2
1348
1308
  });
1349
1309
  }
1350
- case FormatEnum2.Date: {
1310
+ case Format2.TypeFormat.Date: {
1351
1311
  try {
1352
- return formatDate(new Date(value), "yyyy-MM-dd");
1312
+ return formatDate(new Date(value2), "yyyy-MM-dd");
1353
1313
  } catch (error) {
1354
1314
  return "Invalid Date";
1355
1315
  }
1356
1316
  }
1357
- case FormatEnum2.Time: {
1317
+ case Format2.TypeFormat.Time: {
1358
1318
  try {
1359
- return formatDate(new Date(value), "HH:mm:ss");
1319
+ return formatDate(new Date(value2), "HH:mm:ss");
1360
1320
  } catch (error) {
1361
1321
  return "Invalid Time";
1362
1322
  }
1363
1323
  }
1364
- case FormatEnum2.DateTime: {
1324
+ case Format2.TypeFormat.DateTime: {
1365
1325
  try {
1366
- return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
1326
+ return formatDate(new Date(value2), "yyyy-MM-dd HH:mm:ss");
1367
1327
  } catch (error) {
1368
1328
  return "Invalid DateTime";
1369
1329
  }
1370
1330
  }
1371
- case FormatEnum2.GeoPoint: {
1372
- if (value === null || value === void 0) {
1331
+ case Format2.TypeFormat.GeoPoint: {
1332
+ if (value2 === null || value2 === void 0) {
1373
1333
  return "";
1374
1334
  }
1375
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1376
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1335
+ if (Array.isArray(value2) && value2.length >= 2 && value2.every(Number.isFinite)) {
1336
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value2);
1377
1337
  return `${latitude},${longitude}`;
1378
1338
  }
1379
- return String(value);
1339
+ return String(value2);
1380
1340
  }
1381
1341
  default: {
1382
- if (value === null || value === "undefined") {
1342
+ if (value2 === null || value2 === "undefined") {
1383
1343
  return "";
1384
1344
  }
1385
- return String(value);
1345
+ return String(value2);
1386
1346
  }
1387
1347
  }
1388
1348
  };
1389
- var formatForEditing = ({ type, format, value, locale = void 0 }) => {
1349
+ var formatForEditing = ({ type, format, value: value2, locale = void 0 }) => {
1390
1350
  const formatScalar = (type2) => {
1391
1351
  switch (type2) {
1392
1352
  case TypeEnum2.Boolean:
1393
1353
  case TypeEnum2.Number:
1394
1354
  case TypeEnum2.String:
1395
1355
  case TypeEnum2.Ref:
1396
- return String(value);
1356
+ return String(value2);
1397
1357
  default:
1398
- return String(value);
1358
+ return String(value2);
1399
1359
  }
1400
1360
  };
1401
1361
  if (!format) {
1402
1362
  return formatScalar(type);
1403
1363
  }
1404
1364
  switch (format) {
1405
- case FormatEnum2.Boolean:
1406
- case FormatEnum2.Number:
1407
- case FormatEnum2.String:
1408
- case FormatEnum2.Ref: {
1365
+ case Format2.TypeFormat.Boolean:
1366
+ case Format2.TypeFormat.Number:
1367
+ case Format2.TypeFormat.String:
1368
+ case Format2.TypeFormat.Ref: {
1409
1369
  return formatScalar(type);
1410
1370
  }
1411
- case FormatEnum2.Percent: {
1412
- return String(value * 100);
1371
+ case Format2.TypeFormat.Percent: {
1372
+ return String(value2 * 100);
1413
1373
  }
1414
- case FormatEnum2.Currency: {
1415
- return String(value);
1374
+ case Format2.TypeFormat.Currency: {
1375
+ return String(value2);
1416
1376
  }
1417
- case FormatEnum2.DateTime: {
1418
- const date = new Date(value);
1377
+ case Format2.TypeFormat.DateTime: {
1378
+ const date = new Date(value2);
1419
1379
  return date.toISOString();
1420
1380
  }
1421
- case FormatEnum2.Date: {
1422
- const date = new Date(value);
1381
+ case Format2.TypeFormat.Date: {
1382
+ const date = new Date(value2);
1423
1383
  return date.toISOString().split("T")[0];
1424
1384
  }
1425
- case FormatEnum2.Time: {
1426
- const date = new Date(value);
1385
+ case Format2.TypeFormat.Time: {
1386
+ const date = new Date(value2);
1427
1387
  return date.toISOString().split("T")[1].split(".")[0];
1428
1388
  }
1429
- case FormatEnum2.GeoPoint: {
1430
- if (value === null || value === void 0) {
1389
+ case Format2.TypeFormat.GeoPoint: {
1390
+ if (value2 === null || value2 === void 0) {
1431
1391
  return "";
1432
1392
  }
1433
- if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
1434
- const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
1393
+ if (Array.isArray(value2) && value2.length >= 2 && value2.every(Number.isFinite)) {
1394
+ const { latitude, longitude } = GeoLocation3.fromGeoPoint(value2);
1435
1395
  return `${latitude},${longitude}`;
1436
1396
  }
1437
- return String(value);
1397
+ return String(value2);
1438
1398
  }
1439
1399
  default: {
1440
- return String(value);
1400
+ return String(value2);
1441
1401
  }
1442
1402
  }
1443
1403
  };
1444
1404
 
1445
1405
  // src/util/refs.ts
1446
- import { FormatEnum as FormatEnum3, ReferenceAnnotationId } from "@dxos/echo-schema";
1406
+ import { Format as Format3, ReferenceAnnotationId } from "@dxos/echo/internal";
1447
1407
  import { findAnnotation } from "@dxos/effect";
1448
1408
 
1449
1409
  // src/util/schema.ts
1450
- import { SchemaAST as SchemaAST2 } from "effect";
1410
+ import * as SchemaAST2 from "effect/SchemaAST";
1451
1411
  import { findNode } from "@dxos/effect";
1452
1412
  var findArrayElementType = (ast) => {
1453
1413
  const tupleType = findNode(ast, SchemaAST2.isTupleType);
1454
- const elementType = tupleType?.rest[0]?.type;
1455
- return elementType;
1414
+ return tupleType?.rest[0]?.type;
1456
1415
  };
1457
1416
 
1458
1417
  // src/util/refs.ts
1459
1418
  var getRefProps = (property) => {
1460
1419
  const { ast, format, array } = property;
1461
- if (format === FormatEnum3.Ref) {
1462
- return {
1463
- ast,
1464
- isArray: false
1465
- };
1466
- }
1467
1420
  if (array) {
1468
1421
  const elementType = findArrayElementType(ast);
1469
1422
  if (elementType) {
@@ -1476,27 +1429,42 @@ var getRefProps = (property) => {
1476
1429
  }
1477
1430
  }
1478
1431
  }
1432
+ if (format === Format3.TypeFormat.Ref) {
1433
+ return {
1434
+ ast,
1435
+ isArray: false
1436
+ };
1437
+ }
1479
1438
  return void 0;
1480
1439
  };
1481
1440
 
1482
1441
  // src/components/Form/ArrayField.tsx
1442
+ import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
1443
+ import * as Function from "effect/Function";
1444
+ import * as SchemaAST3 from "effect/SchemaAST";
1445
+ import * as String2 from "effect/String";
1446
+ import React9, { Fragment, useCallback as useCallback8 } from "react";
1447
+ import { SimpleType, findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion } from "@dxos/effect";
1448
+ import { invariant as invariant2 } from "@dxos/invariant";
1449
+ import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
1450
+ import { getSchemaProperties } from "@dxos/schema";
1483
1451
  var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
1484
1452
  var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
1485
- var _effect = _useSignals10();
1453
+ var _effect = _useSignals9();
1486
1454
  try {
1487
1455
  const { t } = useTranslation6(translationKey);
1488
1456
  const { ast, name, type, title } = property;
1489
1457
  const values = useFormValues(path ?? []) ?? [];
1490
1458
  invariant2(Array.isArray(values), `Values at path ${path?.join(".")} must be an array.`, {
1491
1459
  F: __dxlog_file3,
1492
- L: 36,
1460
+ L: 37,
1493
1461
  S: void 0,
1494
1462
  A: [
1495
1463
  "Array.isArray(values)",
1496
1464
  "`Values at path ${path?.join('.')} must be an array.`"
1497
1465
  ]
1498
1466
  });
1499
- const label = title ?? pipe(name, capitalize);
1467
+ const label = title ?? Function.pipe(name, String2.capitalize);
1500
1468
  const elementType = findArrayElementType(ast);
1501
1469
  const getDefaultObjectValue = (typeNode) => {
1502
1470
  const baseNode = findNode2(typeNode, isDiscriminatedUnion);
@@ -1504,13 +1472,15 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1504
1472
  if (!typeLiteral) {
1505
1473
  return {};
1506
1474
  }
1507
- return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
1475
+ return Object.fromEntries(getSchemaProperties(typeLiteral, {}, {
1476
+ form: true
1477
+ }).map((prop) => [
1508
1478
  prop.name,
1509
1479
  prop.defaultValue
1510
1480
  ]));
1511
1481
  };
1512
1482
  const getDefaultValue = () => type === "object" && elementType ? getDefaultObjectValue(elementType) : SimpleType.getDefaultValue(type);
1513
- const handleAdd = useCallback7(() => {
1483
+ const handleAdd = useCallback8(() => {
1514
1484
  inputProps.onValueChange(type, [
1515
1485
  ...values,
1516
1486
  getDefaultValue()
@@ -1521,7 +1491,7 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1521
1491
  inputProps,
1522
1492
  values
1523
1493
  ]);
1524
- const handleRemove = useCallback7((index) => {
1494
+ const handleRemove = useCallback8((index) => {
1525
1495
  const newValues = values.filter((_, i) => i !== index);
1526
1496
  inputProps.onValueChange(type, newValues);
1527
1497
  }, [
@@ -1532,14 +1502,14 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1532
1502
  if (!elementType) {
1533
1503
  return null;
1534
1504
  }
1535
- return readonly && values.length < 1 ? null : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(InputHeader, {
1505
+ return readonly && values.length < 1 ? null : /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(InputHeader, {
1536
1506
  readonly: true,
1537
1507
  label
1538
- }), /* @__PURE__ */ React10.createElement("div", {
1508
+ }), /* @__PURE__ */ React9.createElement("div", {
1539
1509
  role: "none",
1540
1510
  className: readonly ? "flex flex-wrap gap-1 mlb-1" : values.length > 0 ? "grid gap-1 grid-cols-[1fr_min-content] mlb-1" : "hidden"
1541
1511
  }, values.map((_value, index) => {
1542
- const field = /* @__PURE__ */ React10.createElement(FormField, {
1512
+ const field = /* @__PURE__ */ React9.createElement(FormField, {
1543
1513
  property: {
1544
1514
  ...property,
1545
1515
  array: false,
@@ -1554,18 +1524,18 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1554
1524
  Custom,
1555
1525
  lookupComponent
1556
1526
  });
1557
- return readonly ? field : /* @__PURE__ */ React10.createElement(Fragment, {
1527
+ return readonly ? field : /* @__PURE__ */ React9.createElement(Fragment, {
1558
1528
  key: index
1559
- }, /* @__PURE__ */ React10.createElement("div", {
1529
+ }, /* @__PURE__ */ React9.createElement("div", {
1560
1530
  role: "none"
1561
- }, field), /* @__PURE__ */ React10.createElement(IconButton3, {
1531
+ }, field), /* @__PURE__ */ React9.createElement(IconButton3, {
1562
1532
  icon: "ph--trash--regular",
1563
1533
  iconOnly: true,
1564
1534
  label: t("button remove"),
1565
1535
  onClick: () => handleRemove(index),
1566
1536
  classNames: "self-center"
1567
1537
  }));
1568
- })), !readonly && /* @__PURE__ */ React10.createElement(IconButton3, {
1538
+ })), !readonly && /* @__PURE__ */ React9.createElement(IconButton3, {
1569
1539
  classNames: "is-full mlb-cardSpacingBlock flex",
1570
1540
  icon: "ph--plus--regular",
1571
1541
  label: t("add field"),
@@ -1576,25 +1546,144 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1576
1546
  }
1577
1547
  };
1578
1548
 
1549
+ // src/components/Form/factory.tsx
1550
+ import { Format as Format4 } from "@dxos/echo/internal";
1551
+ var getInputComponent = (type, format) => {
1552
+ switch (format) {
1553
+ case Format4.TypeFormat.GeoPoint:
1554
+ return GeoPointInput;
1555
+ case Format4.TypeFormat.Markdown:
1556
+ return MarkdownInput;
1557
+ }
1558
+ switch (type) {
1559
+ case "string":
1560
+ return TextInput;
1561
+ case "number":
1562
+ return NumberInput;
1563
+ case "boolean":
1564
+ return BooleanInput;
1565
+ }
1566
+ };
1567
+
1579
1568
  // src/components/Form/RefField.tsx
1580
1569
  import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
1581
- import React11, { useCallback as useCallback8, useMemo as useMemo4 } from "react";
1582
- import { Expando, getTypeAnnotation, Ref, ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo-schema";
1570
+ import "@dxos/lit-ui/dx-tag-picker.pcss";
1571
+ import React11, { useCallback as useCallback10, useMemo as useMemo5 } from "react";
1572
+ import { Expando, Ref, ReferenceAnnotationId as ReferenceAnnotationId2, getTypeAnnotation } from "@dxos/echo/internal";
1583
1573
  import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1584
1574
  import { DXN } from "@dxos/keys";
1585
- import { DxRefTag } from "@dxos/lit-ui/react";
1586
- import { Input as Input8, useTranslation as useTranslation7 } from "@dxos/react-ui";
1587
- import { TagPicker } from "@dxos/react-ui-tag-picker";
1588
- import { descriptionText, mx as mx7 } from "@dxos/react-ui-theme";
1575
+ import { DxAnchor, DxTagPickerItem } from "@dxos/lit-ui/react";
1576
+ import { Button as Button2, Icon as Icon3, Input as Input7, useTranslation as useTranslation8 } from "@dxos/react-ui";
1577
+ import { descriptionText, mx as mx5 } from "@dxos/react-ui-theme";
1589
1578
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
1590
- var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, onValueChange, ...restInputProps }) => {
1591
- var _effect = _useSignals11();
1579
+
1580
+ // src/components/ObjectPicker/ObjectPicker.tsx
1581
+ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1582
+ import React10, { forwardRef, useCallback as useCallback9, useMemo as useMemo4, useState as useState5 } from "react";
1583
+ import { Icon as Icon2, Popover, useTranslation as useTranslation7 } from "@dxos/react-ui";
1584
+ import { Combobox } from "@dxos/react-ui-searchlist";
1585
+ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
1586
+ var _effect = _useSignals10();
1592
1587
  try {
1593
1588
  const { t } = useTranslation7(translationKey);
1594
- const refTypeInfo = useMemo4(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1589
+ const [searchString, setSearchString] = useState5("");
1590
+ const [showForm, setShowForm] = useState5(false);
1591
+ const handleFormSave = useCallback9((values) => {
1592
+ onCreate?.(values);
1593
+ setShowForm(false);
1594
+ setSearchString("");
1595
+ }, [
1596
+ onCreate
1597
+ ]);
1598
+ const handleFormCancel = useCallback9(() => {
1599
+ setShowForm(false);
1600
+ setSearchString("");
1601
+ }, []);
1602
+ const handleClick = useCallback9((event) => {
1603
+ if (createSchema && event.target.closest('[data-value="__create__"]')) {
1604
+ event.stopPropagation();
1605
+ event.preventDefault();
1606
+ setShowForm(true);
1607
+ }
1608
+ }, [
1609
+ createSchema
1610
+ ]);
1611
+ const handleKeyDown = useCallback9((event) => {
1612
+ if (event.key === "Enter" && createSchema && event.currentTarget.querySelector('[role="option"][aria-selected="true"][data-value="__create__"]')) {
1613
+ event.stopPropagation();
1614
+ event.preventDefault();
1615
+ setShowForm(true);
1616
+ }
1617
+ }, [
1618
+ createSchema
1619
+ ]);
1620
+ const labelById = useMemo4(() => options.reduce((acc, option) => {
1621
+ acc[option.id.toLowerCase()] = option.label.toLowerCase();
1622
+ return acc;
1623
+ }, {}), [
1624
+ options
1625
+ ]);
1626
+ return /* @__PURE__ */ React10.createElement(Combobox.Content, {
1627
+ ...props,
1628
+ ref,
1629
+ filter: (value2, search) => value2 === "__create__" || labelById[value2]?.includes(search.toLowerCase()) ? 1 : 0,
1630
+ onClickCapture: handleClick,
1631
+ onKeyDownCapture: handleKeyDown
1632
+ }, showForm && createSchema ? /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form, {
1633
+ schema: createSchema,
1634
+ values: createInitialValuePath ? {
1635
+ [createInitialValuePath]: searchString
1636
+ } : {},
1637
+ onSave: handleFormSave,
1638
+ onCancel: handleFormCancel,
1639
+ testId: "create-referenced-object-form"
1640
+ })) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Combobox.Input, {
1641
+ placeholder: t("ref field combobox input placeholder"),
1642
+ value: searchString,
1643
+ onValueChange: setSearchString,
1644
+ autoFocus: true
1645
+ }), /* @__PURE__ */ React10.createElement(Combobox.List, null, options.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
1646
+ key: option.id,
1647
+ value: option.id,
1648
+ onSelect: () => onSelect(option.id),
1649
+ classNames: "flex items-center gap-2"
1650
+ }, /* @__PURE__ */ React10.createElement("span", {
1651
+ className: "grow"
1652
+ }, option.label), selectedIds?.includes(option.id) && /* @__PURE__ */ React10.createElement(Icon2, {
1653
+ icon: "ph--check--regular"
1654
+ }))), searchString.length > 0 && createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React10.createElement(Combobox.Item, {
1655
+ value: "__create__",
1656
+ classNames: "flex items-center gap-2"
1657
+ }, /* @__PURE__ */ React10.createElement(Icon2, {
1658
+ icon: createOptionIcon
1659
+ }), t(createOptionLabel[0], {
1660
+ ns: createOptionLabel[1].ns,
1661
+ text: searchString
1662
+ })))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
1663
+ } finally {
1664
+ _effect.f();
1665
+ }
1666
+ });
1667
+ ObjectPickerContent.displayName = "ObjectPickerContent";
1668
+ var ObjectPicker = {
1669
+ Root: Combobox.Root,
1670
+ Trigger: Combobox.Trigger,
1671
+ VirtualTrigger: Combobox.VirtualTrigger,
1672
+ Content: ObjectPickerContent
1673
+ };
1674
+
1675
+ // src/components/Form/RefField.tsx
1676
+ var isRefSnapShot = (val) => {
1677
+ return typeof val === "object" && typeof val?.["/"] === "string";
1678
+ };
1679
+ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, getValue: getValue3, createOptionLabel, createOptionIcon, onBlur, onCreate, createSchema, createInitialValuePath, onQueryRefOptions, onValueChange, ...restInputProps }) => {
1680
+ var _effect = _useSignals11();
1681
+ try {
1682
+ const { t } = useTranslation8(translationKey);
1683
+ const refTypeInfo = useMemo5(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
1595
1684
  ast
1596
1685
  ]);
1597
- const { options: availableOptions, loading: _loading } = useQueryRefOptions({
1686
+ const { options: availableOptions, update: updateOptions, loading: _loading } = useQueryRefOptions({
1598
1687
  refTypeInfo,
1599
1688
  onQueryRefOptions
1600
1689
  });
@@ -1603,7 +1692,7 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1603
1692
  type,
1604
1693
  label,
1605
1694
  placeholder,
1606
- disabled,
1695
+ readonly,
1607
1696
  inputOnly,
1608
1697
  getValue: getValue3,
1609
1698
  onBlur,
@@ -1611,11 +1700,12 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1611
1700
  ...restInputProps
1612
1701
  });
1613
1702
  }
1614
- const handleGetValue = useCallback8(() => {
1703
+ const handleGetValue = useCallback10(() => {
1615
1704
  const formValue = getValue3();
1616
1705
  const unknownToRefOption = (val) => {
1617
- if (Ref.isRef(val)) {
1618
- const dxnString = val.dxn.toString();
1706
+ const isRef = Ref.isRef(val);
1707
+ if (isRef || isRefSnapShot(val)) {
1708
+ const dxnString = isRef ? val.dxn.toString() : val["/"];
1619
1709
  const matchingOption = availableOptions.find((option2) => option2.id === dxnString);
1620
1710
  if (matchingOption) {
1621
1711
  return matchingOption;
@@ -1638,14 +1728,7 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1638
1728
  availableOptions,
1639
1729
  array
1640
1730
  ]);
1641
- const handleSearch = useCallback8((text, ids) => availableOptions.filter((option) => !ids.includes(option.id)).filter((option) => option.label.toLowerCase().includes(text.toLowerCase())).map((option) => ({
1642
- id: option.id,
1643
- label: option.label,
1644
- hue: option.hue
1645
- })), [
1646
- availableOptions
1647
- ]);
1648
- const handleUpdate = useCallback8((ids) => {
1731
+ const handleUpdate = useCallback10((ids) => {
1649
1732
  if (ids.length === 0) {
1650
1733
  onValueChange("object", void 0);
1651
1734
  return;
@@ -1668,44 +1751,98 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1668
1751
  array,
1669
1752
  onValueChange
1670
1753
  ]);
1671
- const tagPickerMode = useMemo4(() => array ? "multi-select" : "single-select", [
1672
- array
1754
+ const handleCreate = useCallback10((values) => {
1755
+ onCreate?.(values);
1756
+ updateOptions();
1757
+ }, [
1758
+ onCreate,
1759
+ updateOptions
1673
1760
  ]);
1674
1761
  if (!refTypeInfo) {
1675
1762
  return null;
1676
1763
  }
1677
1764
  const { status, error } = restInputProps.getStatus();
1678
1765
  const items = handleGetValue();
1679
- return disabled && items.length < 1 ? null : /* @__PURE__ */ React11.createElement(Input8.Root, {
1766
+ const selectedIds = useMemo5(() => items.map((i) => i.id), [
1767
+ items
1768
+ ]);
1769
+ const toggleSelect = useCallback10((id) => {
1770
+ if (array) {
1771
+ const nextIds = selectedIds.includes(id) ? selectedIds.filter((x) => x !== id) : [
1772
+ ...selectedIds,
1773
+ id
1774
+ ];
1775
+ handleUpdate(nextIds);
1776
+ } else {
1777
+ if (selectedIds[0] === id) {
1778
+ handleUpdate([]);
1779
+ } else {
1780
+ handleUpdate([
1781
+ id
1782
+ ]);
1783
+ }
1784
+ }
1785
+ }, [
1786
+ array,
1787
+ selectedIds,
1788
+ handleUpdate
1789
+ ]);
1790
+ return readonly && items.length < 1 ? null : /* @__PURE__ */ React11.createElement(Input7.Root, {
1680
1791
  validationValence: status
1681
1792
  }, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
1682
1793
  error,
1683
1794
  label
1684
1795
  }), /* @__PURE__ */ React11.createElement("div", {
1685
1796
  "data-no-submit": true
1686
- }, disabled ? items.length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1687
- className: mx7(descriptionText, "mbe-2")
1688
- }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React11.createElement(DxRefTag, {
1797
+ }, readonly ? items.length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1798
+ className: mx5(descriptionText, "mbe-2")
1799
+ }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React11.createElement(DxAnchor, {
1689
1800
  key: item.id,
1690
1801
  refid: item.id,
1691
- rootclassname: "mie-1",
1692
- style: {
1693
- marginInlineEnd: ".25rem"
1802
+ rootclassname: "mie-1"
1803
+ }, item.label)) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
1804
+ asChild: true
1805
+ }, /* @__PURE__ */ React11.createElement(Button2, {
1806
+ variant: "ghost",
1807
+ classNames: "is-full text-start gap-2"
1808
+ }, /* @__PURE__ */ React11.createElement("div", {
1809
+ role: "none",
1810
+ className: "grow"
1811
+ }, items?.length ? items?.map((item) => /* @__PURE__ */ React11.createElement(DxTagPickerItem, {
1812
+ key: item.id,
1813
+ itemId: item.id,
1814
+ label: item.label,
1815
+ ...item.hue ? {
1816
+ hue: item.hue
1817
+ } : {},
1818
+ removeLabel: t("remove item label"),
1819
+ onItemClick: (event) => {
1820
+ if (event.action === "remove") {
1821
+ toggleSelect(item.id);
1822
+ }
1694
1823
  }
1695
- }, item.label)) : /* @__PURE__ */ React11.createElement(TagPicker, {
1696
- readonly: disabled,
1697
- items,
1698
- mode: tagPickerMode,
1699
- onBlur: (event) => onBlur(event),
1700
- onUpdate: handleUpdate,
1701
- onSearch: handleSearch,
1702
- classNames: "bg-inputSurface p-1.5 rounded-sm"
1703
- })), inputOnly && /* @__PURE__ */ React11.createElement(Input8.DescriptionAndValidation, null, error));
1824
+ })) : /* @__PURE__ */ React11.createElement("span", {
1825
+ className: "text-description"
1826
+ }, placeholder ?? t("ref field placeholder", {
1827
+ count: array ? 99 : 1
1828
+ }))), /* @__PURE__ */ React11.createElement(Icon3, {
1829
+ size: 3,
1830
+ icon: "ph--caret-down--bold"
1831
+ }))), /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
1832
+ options: availableOptions,
1833
+ selectedIds,
1834
+ onSelect: toggleSelect,
1835
+ createSchema,
1836
+ createOptionLabel,
1837
+ createOptionIcon,
1838
+ createInitialValuePath,
1839
+ onCreate: handleCreate
1840
+ }))), inputOnly && /* @__PURE__ */ React11.createElement(Input7.DescriptionAndValidation, null, error));
1704
1841
  } finally {
1705
1842
  _effect.f();
1706
1843
  }
1707
1844
  };
1708
- var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1845
+ var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1709
1846
  var _effect = _useSignals11();
1710
1847
  try {
1711
1848
  const handleOnValueChange = (_type, dxnString) => {
@@ -1731,7 +1868,7 @@ var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValu
1731
1868
  return /* @__PURE__ */ React11.createElement(TextInput, {
1732
1869
  type,
1733
1870
  label,
1734
- disabled,
1871
+ readonly,
1735
1872
  placeholder,
1736
1873
  inputOnly,
1737
1874
  getValue: handleGetValue,
@@ -1743,36 +1880,17 @@ var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValu
1743
1880
  }
1744
1881
  };
1745
1882
 
1746
- // src/components/Form/factory.tsx
1747
- import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
1748
- var getInputComponent = (type, format) => {
1749
- switch (format) {
1750
- case FormatEnum4.GeoPoint:
1751
- return GeoPointInput;
1752
- case FormatEnum4.Markdown:
1753
- return MarkdownInput;
1754
- }
1755
- switch (type) {
1756
- case "string":
1757
- return TextInput;
1758
- case "number":
1759
- return NumberInput;
1760
- case "boolean":
1761
- return BooleanInput;
1762
- }
1763
- };
1764
-
1765
1883
  // src/components/Form/FormContent.tsx
1766
- var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
1884
+ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreate, createSchema, createInitialValuePath, lookupComponent, Custom }) => {
1767
1885
  var _effect = _useSignals12();
1768
1886
  try {
1769
1887
  const { ast, name, type, format, title, description, options, examples, array } = property;
1770
1888
  const inputProps = useInputProps(path);
1771
- const label = useMemo5(() => title ?? pipe2(name, capitalize2), [
1889
+ const label = useMemo6(() => title ?? Function2.pipe(name, StringEffect.capitalize), [
1772
1890
  title,
1773
1891
  name
1774
1892
  ]);
1775
- const placeholder = useMemo5(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1893
+ const placeholder = useMemo6(() => examples?.length ? `Example: "${examples[0]}"` : description, [
1776
1894
  examples,
1777
1895
  description
1778
1896
  ]);
@@ -1783,7 +1901,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1783
1901
  type,
1784
1902
  format,
1785
1903
  label,
1786
- disabled: readonly,
1904
+ readonly,
1787
1905
  placeholder,
1788
1906
  ...inputProps
1789
1907
  }
@@ -1800,7 +1918,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1800
1918
  label,
1801
1919
  inputOnly: inline,
1802
1920
  placeholder,
1803
- disabled: readonly,
1921
+ readonly,
1804
1922
  ...inputProps
1805
1923
  });
1806
1924
  }
@@ -1813,9 +1931,14 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1813
1931
  format,
1814
1932
  label,
1815
1933
  placeholder,
1816
- disabled: readonly,
1934
+ readonly,
1817
1935
  inputOnly: inline,
1818
1936
  onQueryRefOptions,
1937
+ createOptionLabel,
1938
+ createOptionIcon,
1939
+ onCreate,
1940
+ createSchema,
1941
+ createInitialValuePath,
1819
1942
  ...inputProps
1820
1943
  });
1821
1944
  }
@@ -1836,7 +1959,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1836
1959
  label,
1837
1960
  inputOnly: inline,
1838
1961
  placeholder,
1839
- disabled: readonly,
1962
+ readonly,
1840
1963
  ...inputProps
1841
1964
  });
1842
1965
  }
@@ -1844,7 +1967,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1844
1967
  return /* @__PURE__ */ React12.createElement(SelectInput, {
1845
1968
  type,
1846
1969
  format,
1847
- disabled: readonly,
1970
+ readonly,
1848
1971
  inputOnly: inline,
1849
1972
  label,
1850
1973
  options: options.map((option) => ({
@@ -1860,12 +1983,16 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1860
1983
  const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
1861
1984
  if (typeLiteral) {
1862
1985
  return /* @__PURE__ */ React12.createElement(React12.Fragment, null, !inline && /* @__PURE__ */ React12.createElement("h3", {
1863
- className: mx8("text-lg mlb-inputSpacingBlock first:mbs-0")
1986
+ className: mx6("text-lg mlb-inputSpacingBlock first:mbs-0")
1864
1987
  }, label), /* @__PURE__ */ React12.createElement(FormFields, {
1865
1988
  schema: Schema.make(typeLiteral),
1866
1989
  path,
1867
1990
  readonly,
1991
+ projection,
1868
1992
  onQueryRefOptions,
1993
+ createOptionLabel,
1994
+ createOptionIcon,
1995
+ onCreate,
1869
1996
  Custom,
1870
1997
  lookupComponent
1871
1998
  }));
@@ -1876,62 +2003,124 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1876
2003
  _effect.f();
1877
2004
  }
1878
2005
  };
1879
- var FormFields = /* @__PURE__ */ forwardRef(({ classNames, testId, schema, path, filter, sort, readonly, lookupComponent, Custom, onQueryRefOptions }, forwardRef2) => {
2006
+ var FormFields = /* @__PURE__ */ forwardRef2(({ classNames, schema, path, filter, sort, projection, readonly, lookupComponent, Custom, onQueryRefOptions, ...props }, forwardRef4) => {
1880
2007
  var _effect = _useSignals12();
1881
2008
  try {
1882
2009
  const values = useFormValues(path);
1883
- const properties = useMemo5(() => {
1884
- const props = getSchemaProperties2(schema.ast, values);
1885
- const filtered = filter ? filter(props) : props;
2010
+ const properties = useMemo6(() => {
2011
+ const props2 = getSchemaProperties2(schema.ast, values, {
2012
+ form: true
2013
+ });
2014
+ if (projection) {
2015
+ const fieldProjections = projection.getFieldProjections();
2016
+ const hiddenProperties = new Set(projection.getHiddenProperties());
2017
+ const visibleProps = props2.filter((prop) => !hiddenProperties.has(prop.name));
2018
+ const orderedProps = [];
2019
+ for (const fieldProjection of fieldProjections) {
2020
+ const fieldPath = String(fieldProjection.field.path);
2021
+ const prop = visibleProps.find((p) => p.name === fieldPath);
2022
+ if (prop) {
2023
+ orderedProps.push(prop);
2024
+ }
2025
+ }
2026
+ const projectionPaths = new Set(fieldProjections.map((fp) => String(fp.field.path)));
2027
+ const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name));
2028
+ orderedProps.push(...remainingProps);
2029
+ return orderedProps;
2030
+ }
2031
+ const filtered = filter ? filter(props2) : props2;
1886
2032
  return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
1887
2033
  }, [
1888
2034
  schema,
1889
2035
  values,
1890
2036
  filter,
1891
- sort
2037
+ sort,
2038
+ projection?.fields
1892
2039
  ]);
1893
2040
  return /* @__PURE__ */ React12.createElement("div", {
1894
2041
  role: "form",
1895
- className: mx8("is-full", classNames),
1896
- ref: forwardRef2
2042
+ className: mx6("is-full", classNames),
2043
+ ref: forwardRef4
1897
2044
  }, properties.map((property) => {
1898
- return /* @__PURE__ */ React12.createElement(FormField, {
2045
+ return /* @__PURE__ */ React12.createElement(ErrorBoundary, {
1899
2046
  key: property.name,
2047
+ path: [
2048
+ ...path ?? [],
2049
+ property.name
2050
+ ]
2051
+ }, /* @__PURE__ */ React12.createElement(FormField, {
1900
2052
  property,
1901
2053
  path: [
1902
2054
  ...path ?? [],
1903
2055
  property.name
1904
2056
  ],
1905
2057
  readonly,
2058
+ projection,
1906
2059
  onQueryRefOptions,
1907
2060
  lookupComponent,
1908
- Custom
1909
- });
1910
- }).filter(isNotFalsy));
2061
+ Custom,
2062
+ ...props
2063
+ }));
2064
+ }).filter(isTruthy));
1911
2065
  } finally {
1912
2066
  _effect.f();
1913
2067
  }
1914
2068
  });
2069
+ var ErrorBoundary = class extends Component {
2070
+ static getDerivedStateFromError(error) {
2071
+ return {
2072
+ error
2073
+ };
2074
+ }
2075
+ state = {
2076
+ error: void 0
2077
+ };
2078
+ componentDidUpdate(prevProps) {
2079
+ if (prevProps.path !== this.props.path) {
2080
+ this.resetError();
2081
+ }
2082
+ }
2083
+ render() {
2084
+ if (this.state.error) {
2085
+ return /* @__PURE__ */ React12.createElement("div", {
2086
+ className: "flex gap-2 border border-roseFill font-mono text-sm"
2087
+ }, /* @__PURE__ */ React12.createElement("span", {
2088
+ className: "bg-roseFill text-surfaceText pli-1 font-thin"
2089
+ }, "ERROR"), String(this.props.path?.join(".")));
2090
+ }
2091
+ return this.props.children;
2092
+ }
2093
+ resetError() {
2094
+ this.setState({
2095
+ error: void 0
2096
+ });
2097
+ }
2098
+ };
1915
2099
 
1916
2100
  // src/components/Form/Form.tsx
1917
- var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, onCancel, schema, onValuesChanged, onValidate, onSave, ...props }) => {
2101
+ var Form = ({ classNames, id, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, schema, onCancel, onValuesChanged, onValidate, onSave, ...props }) => {
1918
2102
  var _effect = _useSignals13();
1919
2103
  try {
1920
2104
  const formRef = useRef3(null);
1921
- const handleValid = useMemo6(() => autoSave ? onSave : void 0, [
1922
- autoSave,
1923
- onSave
1924
- ]);
2105
+ const { findFirstFocusable } = useFocusFinders();
1925
2106
  useEffect7(() => {
1926
2107
  if (autoFocus && formRef.current) {
1927
- const input = formRef.current.querySelector("input");
1928
- if (input) {
1929
- input.focus();
2108
+ const firstFocusable = findFirstFocusable(formRef.current);
2109
+ if (firstFocusable) {
2110
+ firstFocusable.focus();
1930
2111
  }
1931
2112
  }
1932
2113
  }, [
1933
2114
  autoFocus
1934
2115
  ]);
2116
+ const handleValid = useCallback11(async (values, meta) => {
2117
+ if (autoSave) {
2118
+ await onSave?.(values, meta);
2119
+ }
2120
+ }, [
2121
+ autoSave,
2122
+ onSave
2123
+ ]);
1935
2124
  return /* @__PURE__ */ React13.createElement(FormProvider, {
1936
2125
  formRef,
1937
2126
  schema,
@@ -1944,6 +2133,9 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1944
2133
  }, /* @__PURE__ */ React13.createElement("div", {
1945
2134
  role: "none",
1946
2135
  className: "contents",
2136
+ ...id && {
2137
+ "data-object-id": id
2138
+ },
1947
2139
  "data-testid": testId
1948
2140
  }, /* @__PURE__ */ React13.createElement(FormFields, {
1949
2141
  ...props,
@@ -1955,7 +2147,7 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1955
2147
  ],
1956
2148
  readonly,
1957
2149
  schema
1958
- }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React13.createElement(FormActions, {
2150
+ }), (onCancel || onSave) && !autoSave && !readonly && /* @__PURE__ */ React13.createElement(FormActions, {
1959
2151
  readonly,
1960
2152
  onCancel,
1961
2153
  outerSpacing
@@ -1967,45 +2159,40 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1967
2159
 
1968
2160
  // src/components/FieldEditor/FieldEditor.tsx
1969
2161
  var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1970
- var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing }) => {
2162
+ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, outerSpacing }) => {
1971
2163
  var _effect = _useSignals14();
1972
2164
  try {
1973
- const { t } = useTranslation8(translationKey);
1974
- const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
2165
+ const { t } = useTranslation9(translationKey);
2166
+ const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
1975
2167
  useEffect8(() => setProps(projection.getFieldProjection(field.id).props), [
1976
2168
  field,
1977
2169
  projection
1978
2170
  ]);
1979
- const [schemas, setSchemas] = useState5([]);
1980
- useEffect8(() => {
2171
+ const [schemas, setSchemas] = useState6([]);
2172
+ useAsyncEffect(async () => {
1981
2173
  if (!registry) {
1982
2174
  return;
1983
2175
  }
1984
2176
  const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
1985
2177
  fire: true
1986
2178
  });
1987
- const t2 = setTimeout(async () => {
1988
- const schemas2 = await registry.query().run();
1989
- setSchemas(schemas2);
1990
- });
1991
- return () => {
1992
- clearTimeout(t2);
1993
- subscription?.();
1994
- };
2179
+ const schemas2 = await registry.query().run();
2180
+ setSchemas(schemas2);
2181
+ return () => subscription?.();
1995
2182
  }, [
1996
2183
  registry
1997
2184
  ]);
1998
- const [referenceSchema, setReferenceSchema] = useState5();
2185
+ const [referenceSchema, setReferenceSchema] = useState6();
1999
2186
  useEffect8(() => {
2000
2187
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
2001
2188
  }, [
2002
2189
  schemas,
2003
2190
  props?.referenceSchema
2004
2191
  ]);
2005
- const [{ fieldSchema }, setFieldSchema] = useState5({
2192
+ const [{ fieldSchema }, setFieldSchema] = useState6({
2006
2193
  fieldSchema: getFormatSchema(props?.format)
2007
2194
  });
2008
- const handleValuesChanged = useCallback9((_props) => {
2195
+ const handleValuesChanged = useCallback12((_props) => {
2009
2196
  setFieldSchema((prev) => {
2010
2197
  const fieldSchema2 = getFormatSchema(_props.format);
2011
2198
  if (prev.fieldSchema === fieldSchema2) {
@@ -2026,10 +2213,12 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2026
2213
  });
2027
2214
  setProps((props2) => {
2028
2215
  const type = formatToType[_props.format];
2216
+ const additionalProps = formatToAdditionalPropertyAttributes[_props.format];
2029
2217
  if (props2.type !== type) {
2030
2218
  return {
2031
2219
  ...props2,
2032
2220
  ..._props,
2221
+ ...additionalProps,
2033
2222
  type
2034
2223
  };
2035
2224
  }
@@ -2040,7 +2229,7 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2040
2229
  props.format,
2041
2230
  props.referenceSchema
2042
2231
  ]);
2043
- const handleValidate = useCallback9(({ property }) => {
2232
+ const handleValidate = useCallback12(({ property }) => {
2044
2233
  if (property && projection.fields.find((f) => f.path === property && f.path !== field.path)) {
2045
2234
  return [
2046
2235
  {
@@ -2053,7 +2242,7 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2053
2242
  projection.fields,
2054
2243
  field
2055
2244
  ]);
2056
- const handleSave = useCallback9((props2) => {
2245
+ const handleSave = useCallback12((props2) => {
2057
2246
  projection.setFieldProjection({
2058
2247
  field,
2059
2248
  props: props2
@@ -2064,7 +2253,7 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2064
2253
  field,
2065
2254
  onSave
2066
2255
  ]);
2067
- const handleCancel = useCallback9(() => {
2256
+ const handleCancel = useCallback12(() => {
2068
2257
  requestAnimationFrame(() => onCancel?.());
2069
2258
  onSave();
2070
2259
  }, [
@@ -2073,9 +2262,9 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2073
2262
  const custom = useMemo7(() => ({
2074
2263
  ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2075
2264
  ...props2,
2076
- options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
2077
- value,
2078
- label: t(`format ${value}`)
2265
+ options: FormatEnums.filter((value2) => value2 !== Format5.TypeFormat.None).map((value2) => ({
2266
+ value: value2,
2267
+ label: t(`format ${value2}`)
2079
2268
  }))
2080
2269
  }),
2081
2270
  ["referenceSchema"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
@@ -2086,7 +2275,9 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2086
2275
  }),
2087
2276
  ["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2088
2277
  ...props2,
2089
- options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
2278
+ options: referenceSchema ? getSchemaProperties3(referenceSchema.ast, {}, {
2279
+ form: true
2280
+ }).sort(sortProperties).map((p) => ({
2090
2281
  value: p.name
2091
2282
  })) : []
2092
2283
  }),
@@ -2096,13 +2287,13 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2096
2287
  schemas,
2097
2288
  referenceSchema
2098
2289
  ]);
2099
- const propIsNotType = useCallback9((props2) => props2.filter((p) => p.name !== "type"), []);
2290
+ const propIsNotType = useCallback12((props2) => props2.filter((p) => p.name !== "type"), []);
2100
2291
  if (!fieldSchema) {
2101
2292
  log3.warn("invalid format", {
2102
2293
  props
2103
2294
  }, {
2104
2295
  F: __dxlog_file4,
2105
- L: 173,
2296
+ L: 180,
2106
2297
  S: void 0,
2107
2298
  C: (f, a) => f(...a)
2108
2299
  });
@@ -2111,6 +2302,7 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2111
2302
  return /* @__PURE__ */ React14.createElement(Form, {
2112
2303
  key: field.id,
2113
2304
  autoFocus: true,
2305
+ readonly,
2114
2306
  values: props,
2115
2307
  schema: fieldSchema,
2116
2308
  filter: propIsNotType,
@@ -2132,112 +2324,129 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2132
2324
 
2133
2325
  // src/components/ViewEditor/ViewEditor.tsx
2134
2326
  import { useSignals as _useSignals15 } from "@preact-signals/safe-react/tracking";
2135
- import { Schema as Schema2 } from "effect";
2136
- import React15, { useCallback as useCallback10, useMemo as useMemo8, useState as useState6 } from "react";
2137
- import { EchoSchema, Format, isMutable, toJsonSchema } from "@dxos/echo-schema";
2327
+ import * as Array2 from "effect/Array";
2328
+ import * as Match from "effect/Match";
2329
+ import * as Option from "effect/Option";
2330
+ import * as Schema2 from "effect/Schema";
2331
+ import React15, { forwardRef as forwardRef3, useCallback as useCallback13, useImperativeHandle, useMemo as useMemo8, useState as useState7 } from "react";
2332
+ import { QueryAST } from "@dxos/echo";
2333
+ import { EchoSchema, Format as Format6, isMutable, toJsonSchema } from "@dxos/echo/internal";
2334
+ import { Filter as Filter2, Query } from "@dxos/echo-db";
2138
2335
  import { invariant as invariant3 } from "@dxos/invariant";
2139
- import { Callout, IconButton as IconButton4, useTranslation as useTranslation9 } from "@dxos/react-ui";
2336
+ import { Callout, IconButton as IconButton4, Input as Input8, useTranslation as useTranslation10 } from "@dxos/react-ui";
2337
+ import { QueryForm } from "@dxos/react-ui-components";
2140
2338
  import { List as List2 } from "@dxos/react-ui-list";
2141
2339
  import { cardSpacing as cardSpacing3 } from "@dxos/react-ui-stack";
2142
- import { ghostHover, inputTextLabel, mx as mx9 } from "@dxos/react-ui-theme";
2143
- import { FieldSchema, VIEW_FIELD_LIMIT, ProjectionModel } from "@dxos/schema";
2340
+ import { inputTextLabel, mx as mx7, subtleHover as subtleHover2 } from "@dxos/react-ui-theme";
2341
+ import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, getTypenameFromQuery } from "@dxos/schema";
2144
2342
  var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2145
- var grid = "grid grid-cols-[32px_1fr_32px_32px] min-bs-[2.5rem]";
2146
- var ViewMetaSchema = Schema2.Struct({
2147
- typename: Format.URL.annotations({
2148
- title: "Typename"
2149
- })
2150
- }).pipe(Schema2.mutable);
2151
- var ViewEditor = ({ classNames, schema, view, registry, readonly: _readonly, showHeading = false, onTypenameChanged, onDelete, outerSpacing = true }) => {
2343
+ var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
2344
+ var listItemGrid = "grid grid-cols-subgrid col-span-5";
2345
+ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, types, tags, onQueryChanged, onDelete, outerSpacing = true }, forwardedRef) => {
2152
2346
  var _effect = _useSignals15();
2153
2347
  try {
2154
- const { t } = useTranslation9(translationKey);
2155
- const projection = useMemo8(() => {
2348
+ const schemaReadonly = !isMutable(schema);
2349
+ const { t } = useTranslation10(translationKey);
2350
+ const projectionModel = useMemo8(() => {
2156
2351
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2157
2352
  return new ProjectionModel(jsonSchema, view.projection);
2158
2353
  }, [
2159
2354
  schema,
2160
- view.projection
2355
+ JSON.stringify(view.projection)
2161
2356
  ]);
2162
- const [field, setField] = useState6();
2163
- const readonly = _readonly || !isMutable(schema);
2164
- const viewValues = useMemo8(() => {
2165
- return {
2166
- // TODO(burdon): Need to warn user of possible consequences of editing.
2167
- // TODO(burdon): Settings should have domain name owned by user.
2168
- typename: view.query.typename
2169
- };
2170
- }, [
2171
- view.query.typename
2357
+ useImperativeHandle(forwardedRef, () => projectionModel, [
2358
+ projectionModel
2172
2359
  ]);
2173
- const handleSelect = useCallback10((field2) => {
2174
- if (readonly) {
2175
- return;
2360
+ const [expandedField, setExpandedField] = useState7();
2361
+ const queueTarget = Match.value(view.query.ast).pipe(Match.when({
2362
+ type: "options"
2363
+ }, ({ options }) => {
2364
+ return Option.fromNullable(options.queues).pipe(Option.flatMap((queues) => Array2.head(queues)), Option.getOrUndefined);
2365
+ }), Match.orElse(() => void 0));
2366
+ const viewSchema = useMemo8(() => {
2367
+ const base = Schema2.Struct({
2368
+ query: mode === "schema" ? Format6.URL.annotations({
2369
+ title: "Record type"
2370
+ }) : QueryAST.Query.annotations({
2371
+ title: "Query"
2372
+ })
2373
+ });
2374
+ if (mode === "tag") {
2375
+ return Schema2.Struct({
2376
+ ...base.fields,
2377
+ target: Schema2.optional(Schema2.String.annotations({
2378
+ title: "Target Queue"
2379
+ }))
2380
+ }).pipe(Schema2.mutable);
2176
2381
  }
2177
- setField((f) => f === field2 ? void 0 : field2);
2382
+ return base.pipe(Schema2.mutable);
2383
+ }, [
2384
+ mode
2385
+ ]);
2386
+ const viewValues = useMemo8(() => ({
2387
+ query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
2388
+ target: queueTarget
2389
+ }), [
2390
+ mode,
2391
+ view.query.ast,
2392
+ queueTarget
2393
+ ]);
2394
+ const handleToggleField = useCallback13((field) => {
2395
+ setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2178
2396
  }, [
2179
2397
  readonly
2180
2398
  ]);
2181
- const handleAdd = useCallback10(() => {
2399
+ const handleAdd = useCallback13(() => {
2182
2400
  invariant3(!readonly, void 0, {
2183
2401
  F: __dxlog_file5,
2184
- L: 88,
2402
+ L: 129,
2185
2403
  S: void 0,
2186
2404
  A: [
2187
2405
  "!readonly",
2188
2406
  ""
2189
2407
  ]
2190
2408
  });
2191
- const field2 = projection.createFieldProjection();
2192
- setField(field2);
2409
+ const field = projectionModel.createFieldProjection();
2410
+ setExpandedField(field.id);
2193
2411
  }, [
2194
2412
  schema,
2195
- projection,
2413
+ projectionModel,
2196
2414
  readonly
2197
2415
  ]);
2198
- const handleUpdate = useCallback10(({ typename }) => {
2199
- invariant3(!readonly, void 0, {
2200
- F: __dxlog_file5,
2201
- L: 95,
2202
- S: void 0,
2203
- A: [
2204
- "!readonly",
2205
- ""
2206
- ]
2207
- });
2416
+ const handleUpdate = useCallback13((values) => {
2208
2417
  requestAnimationFrame(() => {
2209
- if (view.query.typename !== typename && !readonly) {
2210
- onTypenameChanged?.(typename);
2211
- }
2418
+ const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : values.query;
2419
+ onQueryChanged?.(query, values.target);
2212
2420
  });
2213
2421
  }, [
2214
- view.query.typename,
2215
- onTypenameChanged,
2216
- readonly
2422
+ onQueryChanged,
2423
+ view,
2424
+ queueTarget,
2425
+ mode
2217
2426
  ]);
2218
- const handleDelete = useCallback10((fieldId) => {
2427
+ const handleDelete = useCallback13((fieldId) => {
2219
2428
  invariant3(!readonly, void 0, {
2220
2429
  F: __dxlog_file5,
2221
- L: 107,
2430
+ L: 146,
2222
2431
  S: void 0,
2223
2432
  A: [
2224
2433
  "!readonly",
2225
2434
  ""
2226
2435
  ]
2227
2436
  });
2228
- if (fieldId === field?.id) {
2229
- setField(void 0);
2437
+ if (fieldId === expandedField) {
2438
+ setExpandedField(void 0);
2230
2439
  }
2231
2440
  onDelete?.(fieldId);
2232
2441
  }, [
2233
- field,
2442
+ expandedField,
2234
2443
  onDelete,
2235
2444
  readonly
2236
2445
  ]);
2237
- const handleMove = useCallback10((fromIndex, toIndex) => {
2446
+ const handleMove = useCallback13((fromIndex, toIndex) => {
2238
2447
  invariant3(!readonly, void 0, {
2239
2448
  F: __dxlog_file5,
2240
- L: 119,
2449
+ L: 158,
2241
2450
  S: void 0,
2242
2451
  A: [
2243
2452
  "!readonly",
@@ -2254,109 +2463,135 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly: _readonly, sho
2254
2463
  view.projection.fields,
2255
2464
  readonly
2256
2465
  ]);
2257
- const handleClose = useCallback10(() => setField(void 0), []);
2258
- const hiddenProperties = projection.getHiddenProperties();
2259
- const handleHide = useCallback10((fieldId) => {
2260
- setField(void 0);
2261
- projection.hideFieldProjection(fieldId);
2466
+ const handleClose = useCallback13(() => setExpandedField(void 0), []);
2467
+ const handleHide = useCallback13((fieldId) => {
2468
+ setExpandedField(void 0);
2469
+ projectionModel.hideFieldProjection(fieldId);
2262
2470
  }, [
2263
- projection
2471
+ projectionModel
2264
2472
  ]);
2265
- const handleShow = useCallback10((property) => {
2266
- setField(void 0);
2267
- projection.showFieldProjection(property);
2473
+ const handleShow = useCallback13((property) => {
2474
+ setExpandedField(void 0);
2475
+ projectionModel.showFieldProjection(property);
2268
2476
  }, [
2269
- projection
2477
+ projectionModel
2478
+ ]);
2479
+ const custom = useMemo8(() => mode === "tag" ? customFields({
2480
+ types,
2481
+ tags
2482
+ }) : void 0, [
2483
+ types,
2484
+ tags,
2485
+ mode
2270
2486
  ]);
2271
2487
  return /* @__PURE__ */ React15.createElement("div", {
2272
2488
  role: "none",
2273
- className: mx9(classNames)
2274
- }, readonly && /* @__PURE__ */ React15.createElement("div", {
2275
- role: "none",
2276
- className: mx9("is-full", outerSpacing && "plb-cardSpacingBlock pli-cardSpacingInline")
2277
- }, /* @__PURE__ */ React15.createElement(Callout.Root, {
2278
- valence: "info"
2279
- }, /* @__PURE__ */ React15.createElement(Callout.Title, null, t("system schema description")))), /* @__PURE__ */ React15.createElement(Form, {
2489
+ className: mx7(classNames)
2490
+ }, schemaReadonly && !readonly && /* @__PURE__ */ React15.createElement(Callout.Root, {
2491
+ valence: "info",
2492
+ classNames: [
2493
+ "mlb-cardSpacingBlock",
2494
+ outerSpacing && "mli-cardSpacingInline"
2495
+ ]
2496
+ }, /* @__PURE__ */ React15.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React15.createElement(Form, {
2280
2497
  autoSave: true,
2281
- schema: ViewMetaSchema,
2498
+ schema: viewSchema,
2282
2499
  values: viewValues,
2283
- readonly,
2284
2500
  onSave: handleUpdate,
2285
- outerSpacing
2501
+ outerSpacing,
2502
+ Custom: custom
2286
2503
  }), /* @__PURE__ */ React15.createElement("div", {
2287
2504
  role: "none",
2288
2505
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2289
- }, /* @__PURE__ */ React15.createElement("label", {
2290
- className: mx9(inputTextLabel)
2506
+ }, /* @__PURE__ */ React15.createElement("h2", {
2507
+ className: mx7(inputTextLabel)
2291
2508
  }, t("fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
2292
2509
  items: view.projection.fields,
2293
2510
  isItem: Schema2.is(FieldSchema),
2294
- getId: (field2) => field2.id,
2295
- readonly,
2296
- onMove: readonly ? void 0 : handleMove
2297
- }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("div", {
2298
- role: "heading",
2299
- className: grid
2300
- }, /* @__PURE__ */ React15.createElement("div", null), /* @__PURE__ */ React15.createElement("div", {
2301
- className: "flex items-center text-sm"
2302
- }, t("field path label"))), /* @__PURE__ */ React15.createElement("div", {
2303
- role: "list",
2304
- className: "flex flex-col is-full"
2305
- }, fields?.map((field2) => /* @__PURE__ */ React15.createElement(List2.Item, {
2306
- key: field2.id,
2307
- item: field2,
2308
- classNames: mx9(grid, ghostHover, "overflow-hidden", !readonly && "cursor-pointer")
2309
- }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
2310
- onClick: () => handleSelect(field2)
2311
- }, field2.path), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
2312
- "data-testid": "hide-field-button",
2313
- icon: "ph--eye-slash--regular",
2314
- // TDOO(burdon): Is this the correct test?
2315
- disabled: view.projection.fields.length <= 1,
2316
- onClick: () => handleHide(field2.id)
2317
- }), !readonly && /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2318
- disabled: view.projection.fields.length <= 1,
2319
- onClick: () => handleDelete(field2.id)
2320
- })))))), hiddenProperties.length > 0 && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("label", {
2321
- className: mx9(inputTextLabel)
2322
- }, t("hidden fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
2323
- items: hiddenProperties,
2324
- isItem: (item) => typeof item === "string",
2325
- getId: (property) => property
2326
- }, ({ items: properties }) => /* @__PURE__ */ React15.createElement("div", {
2511
+ getId: (field) => field.id,
2512
+ onMove: readonly ? void 0 : handleMove,
2513
+ readonly
2514
+ }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("h3", {
2515
+ className: "text-sm"
2516
+ }, t("field path label")), /* @__PURE__ */ React15.createElement("div", {
2327
2517
  role: "list",
2328
- className: "flex flex-col is-full"
2329
- }, properties?.map((property) => /* @__PURE__ */ React15.createElement(List2.Item, {
2330
- key: property,
2331
- item: property,
2332
- classNames: mx9(grid, ghostHover, !readonly && "cursor-pointer")
2333
- }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, {
2334
- disabled: true
2335
- }), /* @__PURE__ */ React15.createElement(List2.ItemTitle, null, property), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
2336
- icon: "ph--eye--regular",
2337
- onClick: () => handleShow(property),
2338
- "data-testid": "show-field-button"
2339
- }))))))), field && /* @__PURE__ */ React15.createElement(FieldEditor, {
2340
- key: field.id,
2341
- projection,
2342
- field,
2343
- registry,
2344
- onSave: handleClose
2345
- }), !readonly && !field && /* @__PURE__ */ React15.createElement("div", {
2518
+ className: listGrid
2519
+ }, fields?.map((field) => {
2520
+ const hidden = field.visible === false;
2521
+ return /* @__PURE__ */ React15.createElement(List2.Item, {
2522
+ key: field.id,
2523
+ item: field,
2524
+ classNames: listItemGrid,
2525
+ "aria-expanded": expandedField === field.id
2526
+ }, /* @__PURE__ */ React15.createElement("div", {
2527
+ role: "none",
2528
+ className: mx7(subtleHover2, listItemGrid, "rounded-sm cursor-pointer min-bs-10")
2529
+ }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, {
2530
+ disabled: readonly || schemaReadonly
2531
+ }), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
2532
+ classNames: hidden && "text-subdued",
2533
+ onClick: () => handleToggleField(field)
2534
+ }, field.path), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
2535
+ label: t(hidden ? "show field label" : "hide field label"),
2536
+ "data-testid": hidden ? "show-field-button" : "hide-field-button",
2537
+ icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2538
+ autoHide: false,
2539
+ disabled: readonly || !hidden && projectionModel.fields.length <= 1,
2540
+ onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2541
+ }), !readonly && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2542
+ label: t("delete field label"),
2543
+ autoHide: false,
2544
+ disabled: readonly || schemaReadonly || view.projection.fields.length <= 1,
2545
+ onClick: () => handleDelete(field.id),
2546
+ "data-testid": "field.delete"
2547
+ }), /* @__PURE__ */ React15.createElement(IconButton4, {
2548
+ iconOnly: true,
2549
+ variant: "ghost",
2550
+ label: t("toggle expand label", {
2551
+ ns: "os"
2552
+ }),
2553
+ icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2554
+ onClick: () => handleToggleField(field)
2555
+ }))), expandedField === field.id && !readonly && /* @__PURE__ */ React15.createElement("div", {
2556
+ role: "none",
2557
+ className: "col-span-5 mbs-1 mbe-1 border border-separator rounded-md"
2558
+ }, /* @__PURE__ */ React15.createElement(FieldEditor, {
2559
+ readonly: readonly || schemaReadonly ? "disabled-input" : false,
2560
+ projection: projectionModel,
2561
+ field,
2562
+ registry,
2563
+ onSave: handleClose
2564
+ })));
2565
+ }))))), !readonly && !expandedField && /* @__PURE__ */ React15.createElement("div", {
2346
2566
  role: "none",
2347
2567
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2348
2568
  }, /* @__PURE__ */ React15.createElement(IconButton4, {
2349
2569
  icon: "ph--plus--regular",
2350
- label: t("button add property"),
2570
+ label: t("add property button label"),
2351
2571
  onClick: readonly ? void 0 : handleAdd,
2352
2572
  // TODO(burdon): Show field limit in ux (not tooltip).
2353
2573
  disabled: view.projection.fields.length >= VIEW_FIELD_LIMIT,
2354
- classNames: "flex is-full"
2574
+ classNames: "is-full"
2355
2575
  })));
2356
2576
  } finally {
2357
2577
  _effect.f();
2358
2578
  }
2359
- };
2579
+ });
2580
+ var customFields = ({ types, tags }) => ({
2581
+ query: (props) => {
2582
+ const handleChange = useCallback13((query) => props.onValueChange("object", query.ast), [
2583
+ props.onValueChange
2584
+ ]);
2585
+ return /* @__PURE__ */ React15.createElement(Input8.Root, null, /* @__PURE__ */ React15.createElement(InputHeader, {
2586
+ label: props.label
2587
+ }), /* @__PURE__ */ React15.createElement(QueryForm, {
2588
+ initialQuery: props.getValue(),
2589
+ types,
2590
+ tags,
2591
+ onChange: handleChange
2592
+ }));
2593
+ }
2594
+ });
2360
2595
  export {
2361
2596
  BooleanInput,
2362
2597
  ControlFrame,
@@ -2368,8 +2603,6 @@ export {
2368
2603
  ControlPage,
2369
2604
  ControlSection,
2370
2605
  ControlSectionHeading,
2371
- DeprecatedFormContainer,
2372
- DeprecatedFormInput,
2373
2606
  FieldEditor,
2374
2607
  Form,
2375
2608
  FormProvider,
@@ -2377,6 +2610,7 @@ export {
2377
2610
  InputHeader,
2378
2611
  MarkdownInput,
2379
2612
  NumberInput,
2613
+ ObjectPicker,
2380
2614
  SelectInput,
2381
2615
  SelectOptionInput,
2382
2616
  TextInput,