@dxos/react-ui-form 0.8.4-main.fd6878d → 0.8.4-main.fffef41

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