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