@dxos/react-ui-form 0.8.4-main.c1de068 → 0.8.4-main.e098934

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 (94) hide show
  1. package/dist/lib/browser/index.mjs +601 -528
  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 +601 -528
  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 +79 -4
  10. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
  12. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  13. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +74 -4
  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 +5 -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 +126 -30
  22. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/FormContent.d.ts +16 -10
  25. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/FormContext.d.ts +1 -1
  27. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/Input.d.ts +4 -1
  29. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/RefField.d.ts +10 -4
  31. package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -1
  33. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  34. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +1 -1
  35. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +74 -3
  37. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/custom/TupleInput.d.ts +1 -1
  39. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  40. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +3 -2
  41. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  42. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +76 -5
  43. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  44. package/dist/types/src/components/index.d.ts +0 -1
  45. package/dist/types/src/components/index.d.ts.map +1 -1
  46. package/dist/types/src/components/testing.d.ts +6 -3
  47. package/dist/types/src/components/testing.d.ts.map +1 -1
  48. package/dist/types/src/hooks/useForm.d.ts +1 -1
  49. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  50. package/dist/types/src/translations.d.ts +9 -4
  51. package/dist/types/src/translations.d.ts.map +1 -1
  52. package/dist/types/src/util/field.d.ts.map +1 -1
  53. package/dist/types/tsconfig.tsbuildinfo +1 -1
  54. package/package.json +35 -30
  55. package/src/components/ControlSection/ControlSection.stories.tsx +8 -10
  56. package/src/components/ControlSection/ControlSection.tsx +26 -12
  57. package/src/components/FieldEditor/FieldEditor.stories.tsx +8 -9
  58. package/src/components/FieldEditor/FieldEditor.test.tsx +3 -2
  59. package/src/components/FieldEditor/FieldEditor.tsx +22 -17
  60. package/src/components/Form/ArrayField.tsx +8 -8
  61. package/src/components/Form/Defaults.tsx +22 -20
  62. package/src/components/Form/Form.stories.tsx +129 -93
  63. package/src/components/Form/Form.tsx +16 -12
  64. package/src/components/Form/FormActions.tsx +2 -1
  65. package/src/components/Form/FormContent.tsx +96 -34
  66. package/src/components/Form/FormContext.tsx +5 -5
  67. package/src/components/Form/Input.tsx +4 -1
  68. package/src/components/Form/RefField.tsx +126 -40
  69. package/src/components/Form/custom/GeoPointInput.tsx +29 -21
  70. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +7 -6
  71. package/src/components/Form/custom/SelectOptionsInput.tsx +29 -30
  72. package/src/components/Form/custom/TupleInput.tsx +2 -2
  73. package/src/components/Form/factory.tsx +1 -1
  74. package/src/components/ViewEditor/ViewEditor.stories.tsx +58 -26
  75. package/src/components/ViewEditor/ViewEditor.test.tsx +7 -10
  76. package/src/components/ViewEditor/ViewEditor.tsx +151 -132
  77. package/src/components/index.ts +0 -2
  78. package/src/components/testing.tsx +15 -9
  79. package/src/hooks/useForm.ts +5 -3
  80. package/src/hooks/useRefQueryLookupHandler.ts +1 -1
  81. package/src/translations.ts +11 -5
  82. package/src/util/field.ts +8 -18
  83. package/dist/types/src/components/deprecated/Form.d.ts +0 -15
  84. package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
  85. package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
  86. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
  87. package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
  88. package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
  89. package/dist/types/src/components/deprecated/index.d.ts +0 -2
  90. package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
  91. package/src/components/deprecated/Form.stories.tsx +0 -62
  92. package/src/components/deprecated/Form.tsx +0 -119
  93. package/src/components/deprecated/FormInput.tsx +0 -71
  94. package/src/components/deprecated/index.ts +0 -5
@@ -20,6 +20,11 @@ var translations = [
20
20
  "field limit reached": "Maximum number of fields reached",
21
21
  "boolean input true value": "Yes",
22
22
  "boolean input false value": "No",
23
+ "show field label": "Show field",
24
+ "hide field label": "Hide field",
25
+ "delete field label": "Delete field",
26
+ "ref field placeholder_one": "Select\u2026",
27
+ "ref field placeholder_other": "Select items\u2026",
23
28
  // TODO(burdon): Factor out?
24
29
  "button cancel": "Cancel",
25
30
  "button save": "Save",
@@ -52,9 +57,9 @@ var translations = [
52
57
  "format uri": "URI",
53
58
  "format url": "URL",
54
59
  "format uuid": "UUID",
55
- // Placeholders.
56
- "placeholder latitude": "Latitude",
57
- "placeholder longitude": "Longitude",
60
+ // GeoPointInput.
61
+ "latitude label": "Latitude",
62
+ "longitude label": "Longitude",
58
63
  // SelectOptionsInput.
59
64
  "select option label": "Label",
60
65
  "select option label placeholder": "Option label",
@@ -62,86 +67,37 @@ var translations = [
62
67
  "select option delete": "Delete",
63
68
  "select option add": "Add option",
64
69
  // System schema message.
65
- "system schema title": "System Schema",
66
- "system schema description": "This is a system schema and cannot be modified."
70
+ "system schema title": "System record type",
71
+ "system schema description": "This is a system record type and cannot be modified, though the view can still be configured."
67
72
  }
68
73
  }
69
74
  }
70
75
  ];
71
76
 
72
- // src/components/deprecated/FormInput.tsx
77
+ // src/components/ControlSection/ControlSection.tsx
73
78
  import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
74
79
  import React from "react";
75
- import { Input } from "@dxos/react-ui";
76
- import { mx, textBlockWidth } from "@dxos/react-ui-theme";
77
- var DeprecatedFormContainer = ({ children, classNames }) => {
78
- var _effect = _useSignals();
79
- try {
80
- return /* @__PURE__ */ React.createElement("div", {
81
- role: "none",
82
- className: "container-max-width p-4 justify-center overflow-x-hidden overflow-y-auto"
83
- }, /* @__PURE__ */ React.createElement("div", {
84
- role: "form",
85
- className: mx("flex flex-col", textBlockWidth, classNames)
86
- }, children));
87
- } finally {
88
- _effect.f();
89
- }
90
- };
91
- var DeprecatedFormInput = ({ label, description, secondary, children }) => {
80
+ import { Button, Input, toLocalizedString, useTranslation } from "@dxos/react-ui";
81
+ import { StackItem } from "@dxos/react-ui-stack";
82
+ import { mx } from "@dxos/react-ui-theme";
83
+ var ControlPage = ({ children, classNames, ...props }) => {
92
84
  var _effect = _useSignals();
93
85
  try {
94
- const primary = /* @__PURE__ */ React.createElement("div", {
95
- role: "none",
96
- className: "flex w-full gap-4 py-1"
97
- }, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement("div", {
98
- role: "none",
99
- className: "flex flex-col w-full"
100
- }, /* @__PURE__ */ React.createElement(Input.Label, {
101
- classNames: "flex min-bs-[--rail-action] items-center",
102
- style: {
103
- fontSize: "unset"
104
- }
105
- }, label), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, {
106
- classNames: "mbs-0.5"
107
- }, /* @__PURE__ */ React.createElement(Input.Description, null, description))), /* @__PURE__ */ React.createElement("div", {
108
- role: "none"
86
+ return /* @__PURE__ */ React.createElement(StackItem.Content, {
87
+ classNames: "block overflow-y-auto [--control-spacing:var(--dx-trimMd)]"
109
88
  }, /* @__PURE__ */ React.createElement("div", {
110
89
  role: "none",
111
- className: "flex min-bs-[--rail-action] items-center"
112
- }, children))));
113
- if (secondary) {
114
- return /* @__PURE__ */ React.createElement("div", {
115
- role: "none"
116
- }, primary, secondary);
117
- }
118
- return primary;
119
- } finally {
120
- _effect.f();
121
- }
122
- };
123
-
124
- // src/components/ControlSection/ControlSection.tsx
125
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
126
- import React2 from "react";
127
- import { Button, Input as Input2, toLocalizedString, useTranslation } from "@dxos/react-ui";
128
- import { mx as mx2 } from "@dxos/react-ui-theme";
129
- var ControlPage = ({ children, classNames, ...props }) => {
130
- var _effect = _useSignals2();
131
- try {
132
- return /* @__PURE__ */ React2.createElement("div", {
133
- role: "none",
134
- className: mx2("pli-cardSpacingInline", classNames),
90
+ className: mx("pli-cardSpacingInline pbe-trimLg", classNames),
135
91
  ...props
136
- }, children);
92
+ }, children));
137
93
  } finally {
138
94
  _effect.f();
139
95
  }
140
96
  };
141
97
  var ControlSection = ({ title, description, children }) => {
142
- var _effect = _useSignals2();
98
+ var _effect = _useSignals();
143
99
  try {
144
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ControlSectionHeading, {
100
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ControlSectionHeading, {
145
101
  title,
146
102
  description
147
103
  }), children);
@@ -150,12 +106,12 @@ var ControlSection = ({ title, description, children }) => {
150
106
  }
151
107
  };
152
108
  var ControlSectionHeading = ({ title, description }) => {
153
- var _effect = _useSignals2();
109
+ var _effect = _useSignals();
154
110
  try {
155
111
  const { t } = useTranslation(translationKey);
156
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("h2", {
112
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h2", {
157
113
  className: "pli-trimMd container-max-width text-xl mbs-trimLg mbe-trimMd"
158
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
114
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
159
115
  className: "pli-trimMd mlb-trimMd container-max-width text-description"
160
116
  }, toLocalizedString(description, t)));
161
117
  } finally {
@@ -163,9 +119,9 @@ var ControlSectionHeading = ({ title, description }) => {
163
119
  }
164
120
  };
165
121
  var ControlGroupButton = ({ classNames, ...props }) => {
166
- var _effect = _useSignals2();
122
+ var _effect = _useSignals();
167
123
  try {
168
- return /* @__PURE__ */ React2.createElement(Button, {
124
+ return /* @__PURE__ */ React.createElement(Button, {
169
125
  ...props,
170
126
  classNames: [
171
127
  "md:col-span-2",
@@ -177,41 +133,46 @@ var ControlGroupButton = ({ classNames, ...props }) => {
177
133
  }
178
134
  };
179
135
  var ControlGroup = ({ children, classNames }) => {
180
- var _effect = _useSignals2();
136
+ var _effect = _useSignals();
181
137
  try {
182
- return /* @__PURE__ */ React2.createElement("div", {
138
+ return /* @__PURE__ */ React.createElement("div", {
183
139
  role: "none",
184
- className: mx2("group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-trimMd", classNames)
140
+ className: mx("group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-trimMd", "[--control-spacing:0px] [&_input]:justify-self-end [&_button]:justify-self-end", classNames)
185
141
  }, children);
186
142
  } finally {
187
143
  _effect.f();
188
144
  }
189
145
  };
190
146
  var ControlFrame = ({ children }) => {
191
- var _effect = _useSignals2();
147
+ var _effect = _useSignals();
192
148
  try {
193
- return /* @__PURE__ */ React2.createElement("div", {
149
+ return /* @__PURE__ */ React.createElement("div", {
194
150
  role: "none",
195
- className: "p-trimMd container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-trimSm md:gap-trimMd border border-separator rounded-md"
151
+ className: mx("container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-trimSm md:gap-trimMd p-trimMd", "border border-separator rounded-md")
196
152
  }, children);
197
153
  } finally {
198
154
  _effect.f();
199
155
  }
200
156
  };
201
- 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";
202
- var controlItemTitleClasses = "text-lg font-normal";
203
- var controlItemDescriptionClasses = "text-base mlb-trimSm md:mbe-0 text-description";
157
+ var controlItemClasses = mx([
158
+ "container-max-width grid md:col-span-2 grid-cols-subgrid gap-trimSm items-center",
159
+ // TODO(burdon): Use grid gap consistently or apply margins consistently?
160
+ "mlb-[--control-spacing] *:first:!mbs-0 *:last:!mbe-0 pli-trimMd plb-trimMd",
161
+ "border border-separator rounded-md"
162
+ ]);
163
+ var controlItemTitleClasses = "mbe-0 text-lg text-baseText font-normal";
164
+ var controlItemDescriptionClasses = "mlb-trimSm md:mbe-0 text-base text-description";
204
165
  var ControlItem = ({ title, description, children }) => {
205
- var _effect = _useSignals2();
166
+ var _effect = _useSignals();
206
167
  try {
207
168
  const { t } = useTranslation(translationKey);
208
- return /* @__PURE__ */ React2.createElement("div", {
169
+ return /* @__PURE__ */ React.createElement("div", {
209
170
  className: controlItemClasses
210
- }, /* @__PURE__ */ React2.createElement("div", {
171
+ }, /* @__PURE__ */ React.createElement("div", {
211
172
  role: "none"
212
- }, /* @__PURE__ */ React2.createElement("h3", {
173
+ }, /* @__PURE__ */ React.createElement("h3", {
213
174
  className: controlItemTitleClasses
214
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
175
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
215
176
  className: controlItemDescriptionClasses
216
177
  }, toLocalizedString(description, t))), children);
217
178
  } finally {
@@ -219,16 +180,16 @@ var ControlItem = ({ title, description, children }) => {
219
180
  }
220
181
  };
221
182
  var ControlItemInput = ({ title, description, children }) => {
222
- var _effect = _useSignals2();
183
+ var _effect = _useSignals();
223
184
  try {
224
185
  const { t } = useTranslation(translationKey);
225
- return /* @__PURE__ */ React2.createElement(Input2.Root, null, /* @__PURE__ */ React2.createElement("div", {
186
+ return /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement("div", {
226
187
  className: controlItemClasses
227
- }, /* @__PURE__ */ React2.createElement("div", {
188
+ }, /* @__PURE__ */ React.createElement("div", {
228
189
  role: "none"
229
- }, /* @__PURE__ */ React2.createElement(Input2.Label, {
190
+ }, /* @__PURE__ */ React.createElement(Input.Label, {
230
191
  classNames: controlItemTitleClasses
231
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement(Input2.DescriptionAndValidation, null, /* @__PURE__ */ React2.createElement(Input2.Description, {
192
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, null, /* @__PURE__ */ React.createElement(Input.Description, {
232
193
  classNames: controlItemDescriptionClasses
233
194
  }, toLocalizedString(description, t)))), children));
234
195
  } finally {
@@ -236,15 +197,15 @@ var ControlItemInput = ({ title, description, children }) => {
236
197
  }
237
198
  };
238
199
  var ControlFrameItem = ({ title, description, children }) => {
239
- var _effect = _useSignals2();
200
+ var _effect = _useSignals();
240
201
  try {
241
202
  const { t } = useTranslation(translationKey);
242
- return /* @__PURE__ */ React2.createElement("div", {
203
+ return /* @__PURE__ */ React.createElement("div", {
243
204
  role: "group",
244
205
  className: "min-is-0"
245
- }, /* @__PURE__ */ React2.createElement("h3", {
206
+ }, /* @__PURE__ */ React.createElement("h3", {
246
207
  className: "text-lg mbe-2"
247
- }, toLocalizedString(title, t)), description && /* @__PURE__ */ React2.createElement("p", {
208
+ }, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
248
209
  className: "mlb-trimSm md:mbe-0 text-description"
249
210
  }, toLocalizedString(description, t)), children);
250
211
  } finally {
@@ -253,41 +214,41 @@ var ControlFrameItem = ({ title, description, children }) => {
253
214
  };
254
215
 
255
216
  // src/components/FieldEditor/FieldEditor.tsx
256
- import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
257
- import React14, { useCallback as useCallback9, useEffect as useEffect8, useMemo as useMemo7, useState as useState5 } from "react";
217
+ import { useSignals as _useSignals13 } from "@preact-signals/safe-react/tracking";
218
+ import React13, { useCallback as useCallback9, useEffect as useEffect8, useMemo as useMemo7, useState as useState6 } from "react";
258
219
  import { FormatEnum as FormatEnum5, FormatEnums, formatToType } from "@dxos/echo-schema";
259
220
  import { log as log3 } from "@dxos/log";
260
- import { useTranslation as useTranslation8 } from "@dxos/react-ui";
221
+ import { useAsyncEffect, useTranslation as useTranslation8 } from "@dxos/react-ui";
261
222
  import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
262
223
 
263
224
  // src/components/Form/custom/GeoPointInput.tsx
264
- import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
265
- import React4, { useCallback, useState, useEffect, useMemo } from "react";
225
+ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
226
+ import React3, { useCallback, useEffect, useMemo, useState } from "react";
266
227
  import { GeoLocation } from "@dxos/echo-schema";
267
- import { Input as Input4, useTranslation as useTranslation2 } from "@dxos/react-ui";
228
+ import { Input as Input3, useTranslation as useTranslation2 } from "@dxos/react-ui";
268
229
  import { safeParseFloat } from "@dxos/util";
269
230
 
270
231
  // src/components/Form/Input.tsx
271
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
272
- import React3 from "react";
273
- import { Icon, Input as Input3, Tooltip } from "@dxos/react-ui";
232
+ import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
233
+ import React2 from "react";
234
+ import { Icon, Input as Input2, Tooltip } from "@dxos/react-ui";
274
235
  import { labelSpacing } from "@dxos/react-ui-stack";
275
- import { errorText, mx as mx3 } from "@dxos/react-ui-theme";
236
+ import { errorText, mx as mx2 } from "@dxos/react-ui-theme";
276
237
  var InputHeader = ({ error, label, readonly }) => {
277
- var _effect = _useSignals3();
238
+ var _effect = _useSignals2();
278
239
  try {
279
- const Label = readonly ? "span" : Input3.Label;
240
+ const Label = readonly ? "span" : Input2.Label;
280
241
  const labelProps = readonly ? {} : {
281
242
  classNames: "!mlb-0"
282
243
  };
283
- return /* @__PURE__ */ React3.createElement("div", {
244
+ return /* @__PURE__ */ React2.createElement("div", {
284
245
  role: "none",
285
- className: mx3("flex justify-between items-center", labelSpacing)
286
- }, /* @__PURE__ */ React3.createElement(Label, labelProps, label), error && /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
246
+ className: mx2("flex justify-between items-center", labelSpacing)
247
+ }, /* @__PURE__ */ React2.createElement(Label, labelProps, label), error && /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
287
248
  asChild: true,
288
249
  content: error,
289
250
  side: "bottom"
290
- }, /* @__PURE__ */ React3.createElement(Icon, {
251
+ }, /* @__PURE__ */ React2.createElement(Icon, {
291
252
  icon: "ph--warning--regular",
292
253
  size: 4,
293
254
  classNames: errorText
@@ -298,8 +259,8 @@ var InputHeader = ({ error, label, readonly }) => {
298
259
  };
299
260
 
300
261
  // src/components/Form/custom/GeoPointInput.tsx
301
- var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
302
- var _effect = _useSignals4();
262
+ var GeoPointInput = ({ type, label, readonly, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
263
+ var _effect = _useSignals3();
303
264
  try {
304
265
  const { t } = useTranslation2(translationKey);
305
266
  const { status, error } = getStatus();
@@ -344,46 +305,52 @@ var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, on
344
305
  onValueChange,
345
306
  type
346
307
  ]);
347
- return /* @__PURE__ */ React4.createElement(Input4.Root, {
308
+ return /* @__PURE__ */ React3.createElement(Input3.Root, {
348
309
  validationValence: status
349
- }, /* @__PURE__ */ React4.createElement(InputHeader, {
310
+ }, /* @__PURE__ */ React3.createElement(InputHeader, {
350
311
  error,
351
312
  label
352
- }), /* @__PURE__ */ React4.createElement("div", {
313
+ }), /* @__PURE__ */ React3.createElement("div", {
353
314
  role: "none",
354
315
  className: "grid grid-cols-2 gap-2"
355
- }, /* @__PURE__ */ React4.createElement(Input4.TextInput, {
356
- type: "text",
357
- pattern: "^-?[0-9]*\\.?[0-9]*$",
358
- disabled,
359
- placeholder: t("placeholder latitude"),
316
+ }, /* @__PURE__ */ React3.createElement("div", {
317
+ role: "none"
318
+ }, /* @__PURE__ */ React3.createElement(Input3.Label, null, t("latitude label")), /* @__PURE__ */ React3.createElement(Input3.TextInput, {
319
+ type: "number",
320
+ step: "0.00001",
321
+ min: "-90",
322
+ max: "90",
323
+ disabled: !!readonly,
360
324
  value: latitudeText,
361
325
  onChange: handleCoordinateChange("latitude", setLatitudeText),
362
326
  onBlur
363
- }), /* @__PURE__ */ React4.createElement(Input4.TextInput, {
364
- type: "text",
365
- pattern: "^-?[0-9]*\\.?[0-9]*$",
366
- disabled,
367
- placeholder: t("placeholder longitude"),
327
+ })), /* @__PURE__ */ React3.createElement("div", {
328
+ role: "none"
329
+ }, /* @__PURE__ */ React3.createElement(Input3.Label, null, t("longitude label")), /* @__PURE__ */ React3.createElement(Input3.TextInput, {
330
+ type: "number",
331
+ step: "0.00001",
332
+ min: "-180",
333
+ max: "180",
334
+ disabled: !!readonly,
368
335
  value: longitudeText,
369
336
  onChange: handleCoordinateChange("longitude", setLongitudeText),
370
337
  onBlur
371
- })));
338
+ }))));
372
339
  } finally {
373
340
  _effect.f();
374
341
  }
375
342
  };
376
343
 
377
344
  // src/components/Form/custom/SelectOptionsInput.tsx
378
- import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
379
- import React5, { useCallback as useCallback2, useEffect as useEffect2, useState as useState2, useRef } from "react";
345
+ import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
346
+ import React4, { useCallback as useCallback2, useEffect as useEffect2, useRef, useState as useState2 } from "react";
380
347
  import { PublicKey } from "@dxos/keys";
381
- import { Icon as Icon2, IconButton, Input as Input5, Tag, Toolbar, useTranslation as useTranslation3 } from "@dxos/react-ui";
348
+ import { IconButton, Input as Input4, Tag, useTranslation as useTranslation3 } from "@dxos/react-ui";
382
349
  import { List } from "@dxos/react-ui-list";
383
350
  import { HuePicker } from "@dxos/react-ui-pickers";
384
- import { hues, mx as mx4 } from "@dxos/react-ui-theme";
385
- var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange }) => {
386
- var _effect = _useSignals5();
351
+ import { hues, subtleHover } from "@dxos/react-ui-theme";
352
+ var SelectOptionInput = ({ type, label, readonly, getStatus, getValue: getValue3, onValueChange }) => {
353
+ var _effect = _useSignals4();
387
354
  try {
388
355
  const [selected, setSelectedId] = useState2(null);
389
356
  const [isNewOption, setIsNewOption] = useState2(false);
@@ -491,49 +458,56 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
491
458
  selected,
492
459
  isNewOption
493
460
  ]);
494
- return /* @__PURE__ */ React5.createElement(Input5.Root, {
461
+ return /* @__PURE__ */ React4.createElement(Input4.Root, {
495
462
  validationValence: status
496
- }, /* @__PURE__ */ React5.createElement(InputHeader, {
463
+ }, /* @__PURE__ */ React4.createElement(InputHeader, {
497
464
  error,
498
465
  label
499
- }), /* @__PURE__ */ React5.createElement("div", {
466
+ }), /* @__PURE__ */ React4.createElement("div", {
500
467
  role: "none"
501
- }, options && /* @__PURE__ */ React5.createElement(List.Root, {
468
+ }, options && /* @__PURE__ */ React4.createElement(List.Root, {
502
469
  items: options,
503
470
  isItem: (item) => true,
504
- onMove: handleMove
505
- }, ({ items }) => /* @__PURE__ */ React5.createElement("div", {
471
+ onMove: readonly ? void 0 : handleMove,
472
+ readonly: !!readonly
473
+ }, ({ items }) => /* @__PURE__ */ React4.createElement("div", {
506
474
  role: "list",
507
475
  className: "w-full overflow-auto"
508
- }, items?.map((item) => /* @__PURE__ */ React5.createElement("div", {
476
+ }, items?.map((item) => /* @__PURE__ */ React4.createElement("div", {
509
477
  key: item.id
510
- }, /* @__PURE__ */ React5.createElement(List.Item, {
478
+ }, /* @__PURE__ */ React4.createElement(List.Item, {
511
479
  role: "button",
512
480
  item,
513
481
  classNames: [
514
- "p-1 plb-2",
515
- "flex flex-col",
516
- "cursor-pointer",
517
- "hover:bg-hoverOverlay"
482
+ subtleHover,
483
+ "flex flex-col cursor-pointer rounded-sm"
518
484
  ],
519
485
  "aria-expanded": selected === item.id
520
- }, /* @__PURE__ */ React5.createElement("div", {
486
+ }, /* @__PURE__ */ React4.createElement("div", {
521
487
  className: "flex items-center"
522
- }, /* @__PURE__ */ React5.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React5.createElement(List.ItemTitle, {
488
+ }, /* @__PURE__ */ React4.createElement(List.ItemDragHandle, {
489
+ disabled: !!readonly
490
+ }), /* @__PURE__ */ React4.createElement(List.ItemTitle, {
523
491
  onClick: () => handleClick(item.id),
524
492
  classNames: "flex-1"
525
- }, /* @__PURE__ */ React5.createElement(Tag, {
493
+ }, /* @__PURE__ */ React4.createElement(Tag, {
526
494
  palette: item.color
527
- }, item.title || "\u200B")), /* @__PURE__ */ React5.createElement(Icon2, {
495
+ }, item.title || "\u200B")), /* @__PURE__ */ React4.createElement(IconButton, {
496
+ iconOnly: true,
497
+ variant: "ghost",
498
+ label: t(selected === item.id ? "collapse label" : "expand label", {
499
+ ns: "os"
500
+ }),
528
501
  icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
529
502
  onClick: () => handleClick(item.id)
530
- })), selected === item.id && /* @__PURE__ */ React5.createElement("div", {
531
- className: "mis-4 mbs-2 flex flex-col gap-1"
532
- }, /* @__PURE__ */ React5.createElement(Input5.Label, {
503
+ })), selected === item.id && /* @__PURE__ */ React4.createElement("div", {
504
+ className: "pli-cardSpacingInline plb-cardSpacingBlock flex flex-col gap-1 density-fine"
505
+ }, /* @__PURE__ */ React4.createElement(Input4.Label, {
533
506
  classNames: "text-xs"
534
- }, t("select option label")), /* @__PURE__ */ React5.createElement("div", {
535
- className: "flex flex-row items-center gap-1"
536
- }, /* @__PURE__ */ React5.createElement(Input5.TextInput, {
507
+ }, t("select option label")), /* @__PURE__ */ React4.createElement("div", {
508
+ className: "grid grid-cols-[1fr_min-content_min-content] gap-1"
509
+ }, /* @__PURE__ */ React4.createElement(Input4.TextInput, {
510
+ disabled: !!readonly,
537
511
  placeholder: t("select option label placeholder"),
538
512
  ref: selected === item.id ? inputRef : void 0,
539
513
  value: item.title,
@@ -541,40 +515,34 @@ var SelectOptionInput = ({ type, label, disabled, getStatus, getValue: getValue3
541
515
  onKeyDown: handleKeyDown,
542
516
  classNames: "flex-1",
543
517
  "data-no-submit": true
544
- }), /* @__PURE__ */ React5.createElement(Toolbar.Root, {
545
- classNames: "p-0 m-0 !is-auto"
546
- }, /* @__PURE__ */ React5.createElement(HuePicker, {
518
+ }), /* @__PURE__ */ React4.createElement(HuePicker, {
519
+ disabled: !!readonly,
547
520
  value: item.color,
548
- onChange: handleColorChange(item.id),
549
- rootVariant: "toolbar-button"
550
- })), /* @__PURE__ */ React5.createElement(IconButton, {
521
+ onChange: handleColorChange(item.id)
522
+ }), /* @__PURE__ */ React4.createElement(IconButton, {
523
+ disabled: !!readonly,
551
524
  icon: "ph--trash--fill",
552
525
  iconOnly: true,
553
526
  label: t("select option delete"),
554
527
  onClick: () => handleDelete(item.id)
555
- })))))), /* @__PURE__ */ React5.createElement("div", {
556
- role: "listitem"
557
- }, /* @__PURE__ */ React5.createElement("div", {
558
- role: "button",
559
- className: mx4("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
560
- onClick: handleAdd
561
- }, /* @__PURE__ */ React5.createElement("div", {
562
- className: "flex items-center gap-1"
563
- }, /* @__PURE__ */ React5.createElement(Icon2, {
564
- icon: "ph--plus--regular"
565
- }), /* @__PURE__ */ React5.createElement("span", {
566
- className: "text-sm"
567
- }, t("select option add")))))))));
528
+ })))))), /* @__PURE__ */ React4.createElement(IconButton, {
529
+ variant: "ghost",
530
+ icon: "ph--plus--regular",
531
+ label: t("select option add"),
532
+ onClick: handleAdd,
533
+ disabled: !!readonly,
534
+ classNames: "is-full"
535
+ })))));
568
536
  } finally {
569
537
  _effect.f();
570
538
  }
571
539
  };
572
540
 
573
541
  // 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 mx5 } from "@dxos/react-ui-theme";
542
+ import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
543
+ import React5 from "react";
544
+ import { Input as Input5 } from "@dxos/react-ui";
545
+ import { mx as mx3 } from "@dxos/react-ui-theme";
578
546
  import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
579
547
  var gridCols = [
580
548
  "grid-cols-1",
@@ -582,22 +550,22 @@ var gridCols = [
582
550
  "grid-cols-3",
583
551
  "grid-cols-4"
584
552
  ];
585
- var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
586
- var _effect = _useSignals6();
553
+ var TupleInput = ({ binding, type, label, readonly, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
554
+ var _effect = _useSignals5();
587
555
  try {
588
556
  const { status, error } = getStatus();
589
557
  const values = getValue3() ?? {};
590
- return /* @__PURE__ */ React6.createElement(Input6.Root, {
558
+ return /* @__PURE__ */ React5.createElement(Input5.Root, {
591
559
  validationValence: status
592
- }, /* @__PURE__ */ React6.createElement(InputHeader, {
560
+ }, /* @__PURE__ */ React5.createElement(InputHeader, {
593
561
  error,
594
562
  label
595
- }), /* @__PURE__ */ React6.createElement("div", {
596
- className: mx5("grid gap-2", gridCols[binding.length - 1])
597
- }, binding.map((prop) => /* @__PURE__ */ React6.createElement(Input6.TextInput, {
563
+ }), /* @__PURE__ */ React5.createElement("div", {
564
+ className: mx3("grid gap-2", gridCols[binding.length - 1])
565
+ }, binding.map((prop) => /* @__PURE__ */ React5.createElement(Input5.TextInput, {
598
566
  key: prop,
599
567
  type: "number",
600
- disabled,
568
+ disabled: !!readonly,
601
569
  value: values[prop],
602
570
  onChange: (event) => onValueChange(type, {
603
571
  ...values,
@@ -611,71 +579,72 @@ var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValu
611
579
  };
612
580
 
613
581
  // 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();
582
+ import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
583
+ import React6, { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2 } from "react";
584
+ import { Input as Input6, Select, useTranslation as useTranslation4 } from "@dxos/react-ui";
585
+ var TextInput = ({ type, label, inputOnly, readonly, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
586
+ var _effect = _useSignals6();
619
587
  try {
620
588
  const { status, error } = getStatus();
621
- return disabled && !getValue3() ? null : disabled && inputOnly ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.Root, {
589
+ return readonly && !getValue3() ? null : readonly === "static" && inputOnly ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.Root, {
622
590
  validationValence: status
623
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
591
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
624
592
  error,
625
593
  label
626
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextInput, {
627
- disabled,
594
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.TextInput, {
595
+ disabled: !!readonly,
628
596
  placeholder,
629
597
  value: getValue3() ?? "",
630
598
  onChange: (event) => onValueChange(type, event.target.value),
631
599
  onBlur
632
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.Validation, null, error));
600
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.Validation, null, error));
633
601
  } finally {
634
602
  _effect.f();
635
603
  }
636
604
  };
637
- var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
638
- var _effect = _useSignals7();
605
+ var NumberInput = ({ type, label, inputOnly, readonly, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
606
+ var _effect = _useSignals6();
639
607
  try {
640
608
  const { status, error } = getStatus();
641
- return disabled && !getValue3() ? null : disabled && inputOnly ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.Root, {
609
+ return readonly && !getValue3() ? null : readonly === "static" && inputOnly ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.Root, {
642
610
  validationValence: status
643
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
611
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
644
612
  error,
645
613
  label
646
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextInput, {
614
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.TextInput, {
647
615
  type: "number",
648
- disabled,
616
+ disabled: !!readonly,
649
617
  placeholder,
650
- value: getValue3() ?? 0,
618
+ value: getValue3(),
651
619
  onChange: (event) => onValueChange(type, event.target.value),
652
620
  onBlur
653
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
621
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
654
622
  } finally {
655
623
  _effect.f();
656
624
  }
657
625
  };
658
- var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange, disabled }) => {
659
- var _effect = _useSignals7();
626
+ var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange, readonly }) => {
627
+ var _effect = _useSignals6();
660
628
  try {
661
629
  const { status, error } = getStatus();
662
630
  const checked = Boolean(getValue3());
663
631
  const { t } = useTranslation4(translationKey);
664
- return /* @__PURE__ */ React7.createElement(Input7.Root, {
632
+ return /* @__PURE__ */ React6.createElement(Input6.Root, {
665
633
  validationValence: status
666
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
634
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
667
635
  error,
668
636
  label
669
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, t(checked ? "boolean input true value" : "boolean input false value")) : /* @__PURE__ */ React7.createElement(Input7.Switch, {
637
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, t(checked ? "boolean input true value" : "boolean input false value")) : /* @__PURE__ */ React6.createElement(Input6.Switch, {
638
+ disabled: !!readonly,
670
639
  checked,
671
640
  onCheckedChange: (value) => onValueChange(type, value)
672
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
641
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
673
642
  } finally {
674
643
  _effect.f();
675
644
  }
676
645
  };
677
- var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
678
- var _effect = _useSignals7();
646
+ var SelectInput = ({ type, label, inputOnly, readonly, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
647
+ var _effect = _useSignals6();
679
648
  try {
680
649
  const { status, error } = getStatus();
681
650
  const value = getValue3();
@@ -683,31 +652,31 @@ var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, get
683
652
  type,
684
653
  onValueChange
685
654
  ]);
686
- return disabled && !value ? null : /* @__PURE__ */ React7.createElement(Input7.Root, {
655
+ return readonly && !value ? null : /* @__PURE__ */ React6.createElement(Input6.Root, {
687
656
  validationValence: status
688
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
657
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
689
658
  error,
690
659
  label
691
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value)?.label ?? String(value)) : /* @__PURE__ */ React7.createElement(Select.Root, {
660
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value)?.label ?? String(value)) : /* @__PURE__ */ React6.createElement(Select.Root, {
692
661
  value,
693
662
  onValueChange: handleValueChange
694
- }, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
663
+ }, /* @__PURE__ */ React6.createElement(Select.TriggerButton, {
695
664
  classNames: "is-full",
696
- disabled,
665
+ disabled: !!readonly,
697
666
  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 }) => (
667
+ }), /* @__PURE__ */ React6.createElement(Select.Portal, null, /* @__PURE__ */ React6.createElement(Select.Content, null, /* @__PURE__ */ React6.createElement(Select.Viewport, null, options?.map(({ value: value2, label: label2 }) => (
699
668
  // NOTE: Numeric values are converted to and from strings.
700
- /* @__PURE__ */ React7.createElement(Select.Option, {
669
+ /* @__PURE__ */ React6.createElement(Select.Option, {
701
670
  key: String(value2),
702
671
  value: String(value2)
703
672
  }, label2 ?? String(value2))
704
- )))))), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
673
+ ))), /* @__PURE__ */ React6.createElement(Select.Arrow, null)))), inputOnly && /* @__PURE__ */ React6.createElement(Input6.DescriptionAndValidation, null, error));
705
674
  } finally {
706
675
  _effect.f();
707
676
  }
708
677
  };
709
- var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
710
- var _effect = _useSignals7();
678
+ var MarkdownInput = ({ type, label, inputOnly, readonly, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
679
+ var _effect = _useSignals6();
711
680
  try {
712
681
  const { status, error } = getStatus();
713
682
  const textareaRef = useRef2(null);
@@ -729,14 +698,14 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
729
698
  getValue3(),
730
699
  adjustHeight
731
700
  ]);
732
- return /* @__PURE__ */ React7.createElement(Input7.Root, {
701
+ return /* @__PURE__ */ React6.createElement(Input6.Root, {
733
702
  validationValence: status
734
- }, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
703
+ }, !inputOnly && /* @__PURE__ */ React6.createElement(InputHeader, {
735
704
  error,
736
705
  label
737
- }), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextArea, {
706
+ }), readonly === "static" ? /* @__PURE__ */ React6.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React6.createElement(Input6.TextArea, {
738
707
  ref: textareaRef,
739
- disabled,
708
+ disabled: !!readonly,
740
709
  placeholder,
741
710
  value: getValue3() ?? "",
742
711
  classNames: "min-bs-auto max-h-40 overflow-auto",
@@ -746,27 +715,28 @@ var MarkdownInput = ({ type, label, inputOnly, disabled, placeholder, getStatus,
746
715
  resize: "none"
747
716
  },
748
717
  spellCheck: false
749
- }), inputOnly && /* @__PURE__ */ React7.createElement(Input7.Validation, null, error));
718
+ }), inputOnly && /* @__PURE__ */ React6.createElement(Input6.Validation, null, error));
750
719
  } finally {
751
720
  _effect.f();
752
721
  }
753
722
  };
754
723
 
755
724
  // src/components/Form/Form.tsx
756
- 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 { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
726
+ import { useFocusFinders } from "@fluentui/react-tabster";
727
+ import React12, { useEffect as useEffect7, useMemo as useMemo6, useRef as useRef3 } from "react";
758
728
  import { cardDialogOverflow, cardSpacing as cardSpacing2 } from "@dxos/react-ui-stack";
759
729
 
760
730
  // src/components/Form/FormActions.tsx
761
- import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
762
- import React9 from "react";
731
+ import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
732
+ import React8 from "react";
763
733
  import { IconButton as IconButton2, useTranslation as useTranslation5 } from "@dxos/react-ui";
764
734
  import { cardSpacing } from "@dxos/react-ui-stack";
765
- import { mx as mx6 } from "@dxos/react-ui-theme";
735
+ import { mx as mx4 } from "@dxos/react-ui-theme";
766
736
 
767
737
  // src/components/Form/FormContext.tsx
768
- import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
769
- import React8, { createContext, useContext, useEffect as useEffect6, useMemo as useMemo3, useCallback as useCallback6 } from "react";
738
+ import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
739
+ import React7, { createContext, useCallback as useCallback6, useContext, useEffect as useEffect6, useMemo as useMemo3 } from "react";
770
740
  import { raise } from "@dxos/debug";
771
741
  import { getValue as getValue2 } from "@dxos/echo-schema";
772
742
  import { createJsonPath as createJsonPath2 } from "@dxos/effect";
@@ -783,7 +753,7 @@ var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.t
783
753
  var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
784
754
  invariant(SchemaAST.isTypeLiteral(schema.ast), void 0, {
785
755
  F: __dxlog_file,
786
- L: 93,
756
+ L: 95,
787
757
  S: void 0,
788
758
  A: [
789
759
  "SchemaAST.isTypeLiteral(schema.ast)",
@@ -887,7 +857,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
887
857
  } catch (err) {
888
858
  log.catch(err, void 0, {
889
859
  F: __dxlog_file,
890
- L: 213,
860
+ L: 215,
891
861
  S: void 0,
892
862
  C: (f, a) => f(...a)
893
863
  });
@@ -958,7 +928,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
958
928
  var createKeySet = (obj, value) => {
959
929
  invariant(obj, void 0, {
960
930
  F: __dxlog_file,
961
- L: 275,
931
+ L: 277,
962
932
  S: void 0,
963
933
  A: [
964
934
  "obj",
@@ -1083,7 +1053,7 @@ var useInputProps = (path = []) => {
1083
1053
  ]);
1084
1054
  };
1085
1055
  var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1086
- var _effect = _useSignals8();
1056
+ var _effect = _useSignals7();
1087
1057
  try {
1088
1058
  const form = useForm(formOptions);
1089
1059
  const handleKeyDown = useCallback6((event) => {
@@ -1119,7 +1089,7 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1119
1089
  form.handleSave,
1120
1090
  autoSave
1121
1091
  ]);
1122
- return /* @__PURE__ */ React8.createElement(FormContext.Provider, {
1092
+ return /* @__PURE__ */ React7.createElement(FormContext.Provider, {
1123
1093
  value: form
1124
1094
  }, children);
1125
1095
  } finally {
@@ -1129,19 +1099,19 @@ var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
1129
1099
 
1130
1100
  // src/components/Form/FormActions.tsx
1131
1101
  var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1132
- var _effect = _useSignals9();
1102
+ var _effect = _useSignals8();
1133
1103
  try {
1134
1104
  const { t } = useTranslation5(translationKey);
1135
1105
  const { canSave, handleSave } = useFormContext();
1136
- return /* @__PURE__ */ React9.createElement("div", {
1106
+ return /* @__PURE__ */ React8.createElement("div", {
1137
1107
  role: "none",
1138
- className: mx6(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, {
1108
+ className: mx4(outerSpacing === "scroll-fields" ? "pli-cardSpacingInline mbe-cardSpacingBlock" : outerSpacing ? cardSpacing : "mbs-cardSpacingBlock", "flex [&_button]:grow gap-1 first:mbs-0")
1109
+ }, onCancel && !readonly && /* @__PURE__ */ React8.createElement(IconButton2, {
1140
1110
  "data-testid": "cancel-button",
1141
1111
  icon: "ph--x--regular",
1142
1112
  label: t("button cancel"),
1143
1113
  onClick: onCancel
1144
- }), handleSave && /* @__PURE__ */ React9.createElement(IconButton2, {
1114
+ }), handleSave && /* @__PURE__ */ React8.createElement(IconButton2, {
1145
1115
  type: "submit",
1146
1116
  "data-testid": "save-button",
1147
1117
  disabled: !canSave,
@@ -1155,25 +1125,15 @@ var FormActions = ({ readonly, onCancel, outerSpacing = true }) => {
1155
1125
  };
1156
1126
 
1157
1127
  // src/components/Form/FormContent.tsx
1158
- import { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
1128
+ import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
1159
1129
  import { Schema, SchemaAST as SchemaAST4, pipe as pipe2 } from "effect";
1160
1130
  import { capitalize as capitalize2 } from "effect/String";
1161
- import React12, { forwardRef, useMemo as useMemo5 } from "react";
1131
+ import React11, { forwardRef, useMemo as useMemo5 } from "react";
1162
1132
  import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
1163
- import { mx as mx8 } from "@dxos/react-ui-theme";
1133
+ import { mx as mx6 } from "@dxos/react-ui-theme";
1164
1134
  import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
1165
1135
  import { isNotFalsy } from "@dxos/util";
1166
1136
 
1167
- // src/components/Form/ArrayField.tsx
1168
- import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1169
- import { SchemaAST as SchemaAST3, pipe } from "effect";
1170
- import { capitalize } from "effect/String";
1171
- import React10, { Fragment, useCallback as useCallback7 } from "react";
1172
- import { findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
1173
- import { invariant as invariant2 } from "@dxos/invariant";
1174
- import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
1175
- import { getSchemaProperties } from "@dxos/schema";
1176
-
1177
1137
  // src/util/field.ts
1178
1138
  import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
1179
1139
  var parseValue = ({ type, format, value }) => {
@@ -1255,28 +1215,7 @@ var parseValue = ({ type, format, value }) => {
1255
1215
  }
1256
1216
  };
1257
1217
  var cellClassesForFieldType = ({ type, format }) => {
1258
- if (!format) {
1259
- switch (type) {
1260
- case TypeEnum.Number:
1261
- return [
1262
- "text-right",
1263
- "font-mono"
1264
- ];
1265
- case TypeEnum.Boolean:
1266
- return [
1267
- "text-right",
1268
- "font-mono"
1269
- ];
1270
- case TypeEnum.String:
1271
- return void 0;
1272
- case TypeEnum.Ref:
1273
- return void 0;
1274
- default: {
1275
- return void 0;
1276
- }
1277
- }
1278
- }
1279
- switch (format) {
1218
+ switch (format || type) {
1280
1219
  case FormatEnum.Markdown:
1281
1220
  return void 0;
1282
1221
  case FormatEnum.Time:
@@ -1297,6 +1236,16 @@ var cellClassesForFieldType = ({ type, format }) => {
1297
1236
  return [
1298
1237
  "font-mono"
1299
1238
  ];
1239
+ case TypeEnum.Number:
1240
+ case TypeEnum.Boolean:
1241
+ return [
1242
+ "text-right",
1243
+ "font-mono"
1244
+ ];
1245
+ case TypeEnum.String:
1246
+ return void 0;
1247
+ case TypeEnum.Ref:
1248
+ return void 0;
1300
1249
  default:
1301
1250
  return void 0;
1302
1251
  }
@@ -1482,9 +1431,17 @@ var getRefProps = (property) => {
1482
1431
  };
1483
1432
 
1484
1433
  // src/components/Form/ArrayField.tsx
1434
+ import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
1435
+ import { SchemaAST as SchemaAST3, pipe } from "effect";
1436
+ import { capitalize } from "effect/String";
1437
+ import React9, { Fragment, useCallback as useCallback7 } from "react";
1438
+ import { SimpleType, findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion } from "@dxos/effect";
1439
+ import { invariant as invariant2 } from "@dxos/invariant";
1440
+ import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
1441
+ import { getSchemaProperties } from "@dxos/schema";
1485
1442
  var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
1486
1443
  var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
1487
- var _effect = _useSignals10();
1444
+ var _effect = _useSignals9();
1488
1445
  try {
1489
1446
  const { t } = useTranslation6(translationKey);
1490
1447
  const { ast, name, type, title } = property;
@@ -1534,14 +1491,14 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1534
1491
  if (!elementType) {
1535
1492
  return null;
1536
1493
  }
1537
- return readonly && values.length < 1 ? null : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(InputHeader, {
1494
+ return readonly && values.length < 1 ? null : /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(InputHeader, {
1538
1495
  readonly: true,
1539
1496
  label
1540
- }), /* @__PURE__ */ React10.createElement("div", {
1497
+ }), /* @__PURE__ */ React9.createElement("div", {
1541
1498
  role: "none",
1542
1499
  className: readonly ? "flex flex-wrap gap-1 mlb-1" : values.length > 0 ? "grid gap-1 grid-cols-[1fr_min-content] mlb-1" : "hidden"
1543
1500
  }, values.map((_value, index) => {
1544
- const field = /* @__PURE__ */ React10.createElement(FormField, {
1501
+ const field = /* @__PURE__ */ React9.createElement(FormField, {
1545
1502
  property: {
1546
1503
  ...property,
1547
1504
  array: false,
@@ -1556,18 +1513,18 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1556
1513
  Custom,
1557
1514
  lookupComponent
1558
1515
  });
1559
- return readonly ? field : /* @__PURE__ */ React10.createElement(Fragment, {
1516
+ return readonly ? field : /* @__PURE__ */ React9.createElement(Fragment, {
1560
1517
  key: index
1561
- }, /* @__PURE__ */ React10.createElement("div", {
1518
+ }, /* @__PURE__ */ React9.createElement("div", {
1562
1519
  role: "none"
1563
- }, field), /* @__PURE__ */ React10.createElement(IconButton3, {
1520
+ }, field), /* @__PURE__ */ React9.createElement(IconButton3, {
1564
1521
  icon: "ph--trash--regular",
1565
1522
  iconOnly: true,
1566
1523
  label: t("button remove"),
1567
1524
  onClick: () => handleRemove(index),
1568
1525
  classNames: "self-center"
1569
1526
  }));
1570
- })), !readonly && /* @__PURE__ */ React10.createElement(IconButton3, {
1527
+ })), !readonly && /* @__PURE__ */ React9.createElement(IconButton3, {
1571
1528
  classNames: "is-full mlb-cardSpacingBlock flex",
1572
1529
  icon: "ph--plus--regular",
1573
1530
  label: t("add field"),
@@ -1578,19 +1535,42 @@ var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponen
1578
1535
  }
1579
1536
  };
1580
1537
 
1538
+ // src/components/Form/factory.tsx
1539
+ import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
1540
+ var getInputComponent = (type, format) => {
1541
+ switch (format) {
1542
+ case FormatEnum4.GeoPoint:
1543
+ return GeoPointInput;
1544
+ case FormatEnum4.Markdown:
1545
+ return MarkdownInput;
1546
+ }
1547
+ switch (type) {
1548
+ case "string":
1549
+ return TextInput;
1550
+ case "number":
1551
+ return NumberInput;
1552
+ case "boolean":
1553
+ return BooleanInput;
1554
+ }
1555
+ };
1556
+
1581
1557
  // src/components/Form/RefField.tsx
1582
- import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
1583
- import React11, { useCallback as useCallback8, useMemo as useMemo4 } from "react";
1584
- import { Expando, getTypeAnnotation, Ref, ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo-schema";
1558
+ import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
1559
+ import React10, { useCallback as useCallback8, useMemo as useMemo4, useState as useState5 } from "react";
1560
+ import { Expando, Ref, ReferenceAnnotationId as ReferenceAnnotationId2, getTypeAnnotation } from "@dxos/echo-schema";
1585
1561
  import { findAnnotation as findAnnotation2 } from "@dxos/effect";
1586
1562
  import { DXN } from "@dxos/keys";
1587
- import { DxRefTag } from "@dxos/lit-ui/react";
1588
- import { Input as Input8, useTranslation as useTranslation7 } from "@dxos/react-ui";
1589
- import { TagPicker } from "@dxos/react-ui-tag-picker";
1590
- import { descriptionText, mx as mx7 } from "@dxos/react-ui-theme";
1563
+ import { DxAnchor } from "@dxos/lit-ui/react";
1564
+ import { Button as Button2, Icon as Icon2, Input as Input7, useTranslation as useTranslation7 } from "@dxos/react-ui";
1565
+ import { PopoverCombobox } from "@dxos/react-ui-searchlist";
1566
+ import { TagPickerItem } from "@dxos/react-ui-tag-picker";
1567
+ import { descriptionText, mx as mx5 } from "@dxos/react-ui-theme";
1591
1568
  import { isNonNullable as isNonNullable2 } from "@dxos/util";
1592
- var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, onValueChange, ...restInputProps }) => {
1593
- var _effect = _useSignals11();
1569
+ var isRefSnapShot = (val) => {
1570
+ return typeof val === "object" && typeof val?.["/"] === "string";
1571
+ };
1572
+ var RefField = ({ type, label, readonly, placeholder, inputOnly, array, ast, getValue: getValue3, onBlur, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreateFromQuery, onValueChange, ...restInputProps }) => {
1573
+ var _effect = _useSignals10();
1594
1574
  try {
1595
1575
  const { t } = useTranslation7(translationKey);
1596
1576
  const refTypeInfo = useMemo4(() => ast ? findAnnotation2(ast, ReferenceAnnotationId2) : void 0, [
@@ -1601,11 +1581,11 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1601
1581
  onQueryRefOptions
1602
1582
  });
1603
1583
  if (refTypeInfo && refTypeInfo?.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
1604
- return /* @__PURE__ */ React11.createElement(RefFieldFallback, {
1584
+ return /* @__PURE__ */ React10.createElement(RefFieldFallback, {
1605
1585
  type,
1606
1586
  label,
1607
1587
  placeholder,
1608
- disabled,
1588
+ readonly,
1609
1589
  inputOnly,
1610
1590
  getValue: getValue3,
1611
1591
  onBlur,
@@ -1616,8 +1596,9 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1616
1596
  const handleGetValue = useCallback8(() => {
1617
1597
  const formValue = getValue3();
1618
1598
  const unknownToRefOption = (val) => {
1619
- if (Ref.isRef(val)) {
1620
- const dxnString = val.dxn.toString();
1599
+ const isRef = Ref.isRef(val);
1600
+ if (isRef || isRefSnapShot(val)) {
1601
+ const dxnString = isRef ? val.dxn.toString() : val["/"];
1621
1602
  const matchingOption = availableOptions.find((option2) => option2.id === dxnString);
1622
1603
  if (matchingOption) {
1623
1604
  return matchingOption;
@@ -1640,13 +1621,6 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1640
1621
  availableOptions,
1641
1622
  array
1642
1623
  ]);
1643
- const handleSearch = useCallback8((text, ids) => availableOptions.filter((option) => !ids.includes(option.id)).filter((option) => option.label.toLowerCase().includes(text.toLowerCase())).map((option) => ({
1644
- id: option.id,
1645
- label: option.label,
1646
- hue: option.hue
1647
- })), [
1648
- availableOptions
1649
- ]);
1650
1624
  const handleUpdate = useCallback8((ids) => {
1651
1625
  if (ids.length === 0) {
1652
1626
  onValueChange("object", void 0);
@@ -1670,45 +1644,115 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
1670
1644
  array,
1671
1645
  onValueChange
1672
1646
  ]);
1673
- const tagPickerMode = useMemo4(() => array ? "multi-select" : "single-select", [
1674
- array
1675
- ]);
1676
1647
  if (!refTypeInfo) {
1677
1648
  return null;
1678
1649
  }
1679
1650
  const { status, error } = restInputProps.getStatus();
1680
1651
  const items = handleGetValue();
1681
- return disabled && items.length < 1 ? null : /* @__PURE__ */ React11.createElement(Input8.Root, {
1652
+ const selectedIds = useMemo4(() => items.map((i) => i.id), [
1653
+ items
1654
+ ]);
1655
+ const labelById = useMemo4(() => availableOptions.reduce((acc, option) => {
1656
+ acc[option.id.toLowerCase()] = option.label.toLowerCase();
1657
+ return acc;
1658
+ }, {}), [
1659
+ availableOptions
1660
+ ]);
1661
+ const [query, setQuery] = useState5("");
1662
+ const toggleSelect = useCallback8((id) => {
1663
+ if (array) {
1664
+ const nextIds = selectedIds.includes(id) ? selectedIds.filter((x) => x !== id) : [
1665
+ ...selectedIds,
1666
+ id
1667
+ ];
1668
+ handleUpdate(nextIds);
1669
+ } else {
1670
+ if (selectedIds[0] === id) {
1671
+ handleUpdate([]);
1672
+ } else {
1673
+ handleUpdate([
1674
+ id
1675
+ ]);
1676
+ }
1677
+ }
1678
+ }, [
1679
+ array,
1680
+ selectedIds,
1681
+ handleUpdate
1682
+ ]);
1683
+ return readonly && items.length < 1 ? null : /* @__PURE__ */ React10.createElement(Input7.Root, {
1682
1684
  validationValence: status
1683
- }, !inputOnly && /* @__PURE__ */ React11.createElement(InputHeader, {
1685
+ }, !inputOnly && /* @__PURE__ */ React10.createElement(InputHeader, {
1684
1686
  error,
1685
1687
  label
1686
- }), /* @__PURE__ */ React11.createElement("div", {
1688
+ }), /* @__PURE__ */ React10.createElement("div", {
1687
1689
  "data-no-submit": true
1688
- }, disabled ? items.length < 1 ? /* @__PURE__ */ React11.createElement("p", {
1689
- className: mx7(descriptionText, "mbe-2")
1690
- }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React11.createElement(DxRefTag, {
1690
+ }, readonly ? items.length < 1 ? /* @__PURE__ */ React10.createElement("p", {
1691
+ className: mx5(descriptionText, "mbe-2")
1692
+ }, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React10.createElement(DxAnchor, {
1691
1693
  key: item.id,
1692
1694
  refid: item.id,
1693
- rootclassname: "mie-1",
1694
- style: {
1695
- marginInlineEnd: ".25rem"
1695
+ rootclassname: "mie-1"
1696
+ }, item.label)) : /* @__PURE__ */ React10.createElement(PopoverCombobox.Root, null, /* @__PURE__ */ React10.createElement(PopoverCombobox.Trigger, {
1697
+ asChild: true
1698
+ }, /* @__PURE__ */ React10.createElement(Button2, {
1699
+ variant: "ghost",
1700
+ classNames: "is-full text-start gap-2"
1701
+ }, /* @__PURE__ */ React10.createElement("div", {
1702
+ role: "none",
1703
+ className: "grow"
1704
+ }, items?.length ? items?.map((item) => /* @__PURE__ */ React10.createElement(TagPickerItem, {
1705
+ key: item.id,
1706
+ itemId: item.id,
1707
+ label: item.label,
1708
+ ...item.hue ? {
1709
+ hue: item.hue
1710
+ } : {},
1711
+ removeLabel: t("remove item label"),
1712
+ onItemClick: (event) => {
1713
+ if (event.action === "remove") {
1714
+ toggleSelect(item.id);
1715
+ }
1696
1716
  }
1697
- }, item.label)) : /* @__PURE__ */ React11.createElement(TagPicker, {
1698
- readonly: disabled,
1699
- items,
1700
- mode: tagPickerMode,
1701
- onBlur: (event) => onBlur(event),
1702
- onUpdate: handleUpdate,
1703
- onSearch: handleSearch,
1704
- classNames: "bg-inputSurface p-1.5 rounded-sm"
1705
- })), inputOnly && /* @__PURE__ */ React11.createElement(Input8.DescriptionAndValidation, null, error));
1717
+ })) : /* @__PURE__ */ React10.createElement("span", {
1718
+ className: "text-description"
1719
+ }, placeholder ?? t("ref field placeholder", {
1720
+ count: array ? 99 : 1
1721
+ }))), /* @__PURE__ */ React10.createElement(Icon2, {
1722
+ size: 3,
1723
+ icon: "ph--caret-down--bold"
1724
+ }))), /* @__PURE__ */ React10.createElement(PopoverCombobox.Content, {
1725
+ filter: (value, search) => value === "__create__" || labelById[value]?.includes(search.toLowerCase()) ? 1 : 0
1726
+ }, /* @__PURE__ */ React10.createElement(PopoverCombobox.Input, {
1727
+ placeholder: "Search...",
1728
+ value: query,
1729
+ onValueChange: (v) => setQuery(v),
1730
+ autoFocus: true
1731
+ }), /* @__PURE__ */ React10.createElement(PopoverCombobox.List, null, availableOptions.map((option) => /* @__PURE__ */ React10.createElement(PopoverCombobox.Item, {
1732
+ key: option.id,
1733
+ value: option.id,
1734
+ onSelect: () => toggleSelect(option.id),
1735
+ classNames: "flex items-center gap-2"
1736
+ }, /* @__PURE__ */ React10.createElement("span", {
1737
+ className: "grow"
1738
+ }, option.label), selectedIds.includes(option.id) && /* @__PURE__ */ React10.createElement(Icon2, {
1739
+ icon: "ph--check--regular"
1740
+ }))), query.length > 0 && createOptionLabel && createOptionIcon && onCreateFromQuery && /* @__PURE__ */ React10.createElement(PopoverCombobox.Item, {
1741
+ value: "__create__",
1742
+ onSelect: () => onCreateFromQuery?.(refTypeInfo, query),
1743
+ classNames: "flex items-center gap-2"
1744
+ }, /* @__PURE__ */ React10.createElement(Icon2, {
1745
+ icon: createOptionIcon
1746
+ }), t(createOptionLabel[0], {
1747
+ ns: createOptionLabel[1].ns,
1748
+ text: query
1749
+ }))), /* @__PURE__ */ React10.createElement(PopoverCombobox.Arrow, null)))), inputOnly && /* @__PURE__ */ React10.createElement(Input7.DescriptionAndValidation, null, error));
1706
1750
  } finally {
1707
1751
  _effect.f();
1708
1752
  }
1709
1753
  };
1710
- var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1711
- var _effect = _useSignals11();
1754
+ var RefFieldFallback = ({ type, label, readonly, placeholder, inputOnly, getValue: getValue3, onValueChange, ...restInputProps }) => {
1755
+ var _effect = _useSignals10();
1712
1756
  try {
1713
1757
  const handleOnValueChange = (_type, dxnString) => {
1714
1758
  const dxn = DXN.tryParse(dxnString);
@@ -1730,10 +1774,10 @@ var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValu
1730
1774
  }
1731
1775
  return void 0;
1732
1776
  };
1733
- return /* @__PURE__ */ React11.createElement(TextInput, {
1777
+ return /* @__PURE__ */ React10.createElement(TextInput, {
1734
1778
  type,
1735
1779
  label,
1736
- disabled,
1780
+ readonly,
1737
1781
  placeholder,
1738
1782
  inputOnly,
1739
1783
  getValue: handleGetValue,
@@ -1745,28 +1789,9 @@ var RefFieldFallback = ({ type, label, disabled, placeholder, inputOnly, getValu
1745
1789
  }
1746
1790
  };
1747
1791
 
1748
- // src/components/Form/factory.tsx
1749
- import { FormatEnum as FormatEnum4 } from "@dxos/echo-schema";
1750
- var getInputComponent = (type, format) => {
1751
- switch (format) {
1752
- case FormatEnum4.GeoPoint:
1753
- return GeoPointInput;
1754
- case FormatEnum4.Markdown:
1755
- return MarkdownInput;
1756
- }
1757
- switch (type) {
1758
- case "string":
1759
- return TextInput;
1760
- case "number":
1761
- return NumberInput;
1762
- case "boolean":
1763
- return BooleanInput;
1764
- }
1765
- };
1766
-
1767
1792
  // src/components/Form/FormContent.tsx
1768
- var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
1769
- var _effect = _useSignals12();
1793
+ var FormField = ({ property, path, readonly, inline, projection, onQueryRefOptions, createOptionLabel, createOptionIcon, onCreateFromQuery, lookupComponent, Custom }) => {
1794
+ var _effect = _useSignals11();
1770
1795
  try {
1771
1796
  const { ast, name, type, format, title, description, options, examples, array } = property;
1772
1797
  const inputProps = useInputProps(path);
@@ -1785,7 +1810,7 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1785
1810
  type,
1786
1811
  format,
1787
1812
  label,
1788
- disabled: readonly,
1813
+ readonly,
1789
1814
  placeholder,
1790
1815
  ...inputProps
1791
1816
  }
@@ -1796,33 +1821,36 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1796
1821
  const jsonPath = createJsonPath3(path ?? []);
1797
1822
  const CustomComponent = Custom?.[jsonPath];
1798
1823
  if (CustomComponent) {
1799
- return /* @__PURE__ */ React12.createElement(CustomComponent, {
1824
+ return /* @__PURE__ */ React11.createElement(CustomComponent, {
1800
1825
  type,
1801
1826
  format,
1802
1827
  label,
1803
1828
  inputOnly: inline,
1804
1829
  placeholder,
1805
- disabled: readonly,
1830
+ readonly,
1806
1831
  ...inputProps
1807
1832
  });
1808
1833
  }
1809
1834
  const refProps = getRefProps(property);
1810
1835
  if (refProps) {
1811
- return /* @__PURE__ */ React12.createElement(RefField, {
1836
+ return /* @__PURE__ */ React11.createElement(RefField, {
1812
1837
  ast: refProps.ast,
1813
1838
  array: refProps.isArray,
1814
1839
  type,
1815
1840
  format,
1816
1841
  label,
1817
1842
  placeholder,
1818
- disabled: readonly,
1843
+ readonly,
1819
1844
  inputOnly: inline,
1820
1845
  onQueryRefOptions,
1846
+ createOptionLabel,
1847
+ createOptionIcon,
1848
+ onCreateFromQuery,
1821
1849
  ...inputProps
1822
1850
  });
1823
1851
  }
1824
1852
  if (array) {
1825
- return /* @__PURE__ */ React12.createElement(ArrayField, {
1853
+ return /* @__PURE__ */ React11.createElement(ArrayField, {
1826
1854
  property,
1827
1855
  path,
1828
1856
  inputProps,
@@ -1832,21 +1860,21 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1832
1860
  }
1833
1861
  const InputComponent = getInputComponent(type, format);
1834
1862
  if (InputComponent) {
1835
- return /* @__PURE__ */ React12.createElement(InputComponent, {
1863
+ return /* @__PURE__ */ React11.createElement(InputComponent, {
1836
1864
  type,
1837
1865
  format,
1838
1866
  label,
1839
1867
  inputOnly: inline,
1840
1868
  placeholder,
1841
- disabled: readonly,
1869
+ readonly,
1842
1870
  ...inputProps
1843
1871
  });
1844
1872
  }
1845
1873
  if (options) {
1846
- return /* @__PURE__ */ React12.createElement(SelectInput, {
1874
+ return /* @__PURE__ */ React11.createElement(SelectInput, {
1847
1875
  type,
1848
1876
  format,
1849
- disabled: readonly,
1877
+ readonly,
1850
1878
  inputOnly: inline,
1851
1879
  label,
1852
1880
  options: options.map((option) => ({
@@ -1861,13 +1889,17 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1861
1889
  const baseNode = findNode3(ast, isDiscriminatedUnion2);
1862
1890
  const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
1863
1891
  if (typeLiteral) {
1864
- return /* @__PURE__ */ React12.createElement(React12.Fragment, null, !inline && /* @__PURE__ */ React12.createElement("h3", {
1865
- className: mx8("text-lg mlb-inputSpacingBlock first:mbs-0")
1866
- }, label), /* @__PURE__ */ React12.createElement(FormFields, {
1892
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, !inline && /* @__PURE__ */ React11.createElement("h3", {
1893
+ className: mx6("text-lg mlb-inputSpacingBlock first:mbs-0")
1894
+ }, label), /* @__PURE__ */ React11.createElement(FormFields, {
1867
1895
  schema: Schema.make(typeLiteral),
1868
1896
  path,
1869
1897
  readonly,
1898
+ projection,
1870
1899
  onQueryRefOptions,
1900
+ createOptionLabel,
1901
+ createOptionIcon,
1902
+ onCreateFromQuery,
1871
1903
  Custom,
1872
1904
  lookupComponent
1873
1905
  }));
@@ -1878,26 +1910,44 @@ var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupCo
1878
1910
  _effect.f();
1879
1911
  }
1880
1912
  };
1881
- var FormFields = /* @__PURE__ */ forwardRef(({ classNames, testId, schema, path, filter, sort, readonly, lookupComponent, Custom, onQueryRefOptions }, forwardRef2) => {
1882
- var _effect = _useSignals12();
1913
+ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, schema, path, filter, sort, projection, readonly, lookupComponent, Custom, onQueryRefOptions, ...props }, forwardRef2) => {
1914
+ var _effect = _useSignals11();
1883
1915
  try {
1884
1916
  const values = useFormValues(path);
1885
1917
  const properties = useMemo5(() => {
1886
- const props = getSchemaProperties2(schema.ast, values);
1887
- const filtered = filter ? filter(props) : props;
1918
+ const props2 = getSchemaProperties2(schema.ast, values);
1919
+ if (projection) {
1920
+ const fieldProjections = projection.getFieldProjections();
1921
+ const hiddenProperties = new Set(projection.getHiddenProperties());
1922
+ const visibleProps = props2.filter((prop) => !hiddenProperties.has(prop.name));
1923
+ const orderedProps = [];
1924
+ for (const fieldProjection of fieldProjections) {
1925
+ const fieldPath = String(fieldProjection.field.path);
1926
+ const prop = visibleProps.find((p) => p.name === fieldPath);
1927
+ if (prop) {
1928
+ orderedProps.push(prop);
1929
+ }
1930
+ }
1931
+ const projectionPaths = new Set(fieldProjections.map((fp) => String(fp.field.path)));
1932
+ const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name));
1933
+ orderedProps.push(...remainingProps);
1934
+ return orderedProps;
1935
+ }
1936
+ const filtered = filter ? filter(props2) : props2;
1888
1937
  return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
1889
1938
  }, [
1890
1939
  schema,
1891
1940
  values,
1892
1941
  filter,
1893
- sort
1942
+ sort,
1943
+ projection?.fields
1894
1944
  ]);
1895
- return /* @__PURE__ */ React12.createElement("div", {
1945
+ return /* @__PURE__ */ React11.createElement("div", {
1896
1946
  role: "form",
1897
- className: mx8("is-full", classNames),
1947
+ className: mx6("is-full", classNames),
1898
1948
  ref: forwardRef2
1899
1949
  }, properties.map((property) => {
1900
- return /* @__PURE__ */ React12.createElement(FormField, {
1950
+ return /* @__PURE__ */ React11.createElement(FormField, {
1901
1951
  key: property.name,
1902
1952
  property,
1903
1953
  path: [
@@ -1905,9 +1955,11 @@ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, testId, schema, path,
1905
1955
  property.name
1906
1956
  ],
1907
1957
  readonly,
1958
+ projection,
1908
1959
  onQueryRefOptions,
1909
1960
  lookupComponent,
1910
- Custom
1961
+ Custom,
1962
+ ...props
1911
1963
  });
1912
1964
  }).filter(isNotFalsy));
1913
1965
  } finally {
@@ -1916,25 +1968,26 @@ var FormFields = /* @__PURE__ */ forwardRef(({ classNames, testId, schema, path,
1916
1968
  });
1917
1969
 
1918
1970
  // src/components/Form/Form.tsx
1919
- var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, onCancel, schema, onValuesChanged, onValidate, onSave, ...props }) => {
1920
- var _effect = _useSignals13();
1971
+ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, autoSave, outerSpacing = true, schema, onCancel, onValuesChanged, onValidate, onSave, ...props }) => {
1972
+ var _effect = _useSignals12();
1921
1973
  try {
1922
1974
  const formRef = useRef3(null);
1923
- const handleValid = useMemo6(() => autoSave ? onSave : void 0, [
1924
- autoSave,
1925
- onSave
1926
- ]);
1975
+ const { findFirstFocusable } = useFocusFinders();
1927
1976
  useEffect7(() => {
1928
1977
  if (autoFocus && formRef.current) {
1929
- const input = formRef.current.querySelector("input");
1930
- if (input) {
1931
- input.focus();
1978
+ const firstFocusable = findFirstFocusable(formRef.current);
1979
+ if (firstFocusable) {
1980
+ firstFocusable.focus();
1932
1981
  }
1933
1982
  }
1934
1983
  }, [
1935
1984
  autoFocus
1936
1985
  ]);
1937
- return /* @__PURE__ */ React13.createElement(FormProvider, {
1986
+ const handleValid = useMemo6(() => autoSave ? onSave : void 0, [
1987
+ autoSave,
1988
+ onSave
1989
+ ]);
1990
+ return /* @__PURE__ */ React12.createElement(FormProvider, {
1938
1991
  formRef,
1939
1992
  schema,
1940
1993
  autoSave,
@@ -1943,11 +1996,11 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1943
1996
  onValidate,
1944
1997
  onValid: handleValid,
1945
1998
  onSave
1946
- }, /* @__PURE__ */ React13.createElement("div", {
1999
+ }, /* @__PURE__ */ React12.createElement("div", {
1947
2000
  role: "none",
1948
2001
  className: "contents",
1949
2002
  "data-testid": testId
1950
- }, /* @__PURE__ */ React13.createElement(FormFields, {
2003
+ }, /* @__PURE__ */ React12.createElement(FormFields, {
1951
2004
  ...props,
1952
2005
  ref: formRef,
1953
2006
  classNames: [
@@ -1957,7 +2010,7 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1957
2010
  ],
1958
2011
  readonly,
1959
2012
  schema
1960
- }), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React13.createElement(FormActions, {
2013
+ }), (onCancel || onSave) && !autoSave && !readonly && /* @__PURE__ */ React12.createElement(FormActions, {
1961
2014
  readonly,
1962
2015
  onCancel,
1963
2016
  outerSpacing
@@ -1969,42 +2022,37 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
1969
2022
 
1970
2023
  // src/components/FieldEditor/FieldEditor.tsx
1971
2024
  var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
1972
- var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing }) => {
1973
- var _effect = _useSignals14();
2025
+ var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel, outerSpacing }) => {
2026
+ var _effect = _useSignals13();
1974
2027
  try {
1975
2028
  const { t } = useTranslation8(translationKey);
1976
- const [props, setProps] = useState5(projection.getFieldProjection(field.id).props);
2029
+ const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
1977
2030
  useEffect8(() => setProps(projection.getFieldProjection(field.id).props), [
1978
2031
  field,
1979
2032
  projection
1980
2033
  ]);
1981
- const [schemas, setSchemas] = useState5([]);
1982
- useEffect8(() => {
2034
+ const [schemas, setSchemas] = useState6([]);
2035
+ useAsyncEffect(async () => {
1983
2036
  if (!registry) {
1984
2037
  return;
1985
2038
  }
1986
2039
  const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
1987
2040
  fire: true
1988
2041
  });
1989
- const t2 = setTimeout(async () => {
1990
- const schemas2 = await registry.query().run();
1991
- setSchemas(schemas2);
1992
- });
1993
- return () => {
1994
- clearTimeout(t2);
1995
- subscription?.();
1996
- };
2042
+ const schemas2 = await registry.query().run();
2043
+ setSchemas(schemas2);
2044
+ return () => subscription?.();
1997
2045
  }, [
1998
2046
  registry
1999
2047
  ]);
2000
- const [referenceSchema, setReferenceSchema] = useState5();
2048
+ const [referenceSchema, setReferenceSchema] = useState6();
2001
2049
  useEffect8(() => {
2002
2050
  setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
2003
2051
  }, [
2004
2052
  schemas,
2005
2053
  props?.referenceSchema
2006
2054
  ]);
2007
- const [{ fieldSchema }, setFieldSchema] = useState5({
2055
+ const [{ fieldSchema }, setFieldSchema] = useState6({
2008
2056
  fieldSchema: getFormatSchema(props?.format)
2009
2057
  });
2010
2058
  const handleValuesChanged = useCallback9((_props) => {
@@ -2073,26 +2121,26 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2073
2121
  onSave
2074
2122
  ]);
2075
2123
  const custom = useMemo7(() => ({
2076
- ["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2124
+ ["format"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2077
2125
  ...props2,
2078
2126
  options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
2079
2127
  value,
2080
2128
  label: t(`format ${value}`)
2081
2129
  }))
2082
2130
  }),
2083
- ["referenceSchema"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2131
+ ["referenceSchema"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2084
2132
  ...props2,
2085
2133
  options: schemas.map((schema) => ({
2086
2134
  value: schema.typename
2087
2135
  }))
2088
2136
  }),
2089
- ["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
2137
+ ["referencePath"]: (props2) => /* @__PURE__ */ React13.createElement(SelectInput, {
2090
2138
  ...props2,
2091
2139
  options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
2092
2140
  value: p.name
2093
2141
  })) : []
2094
2142
  }),
2095
- ["options"]: (props2) => /* @__PURE__ */ React14.createElement(SelectOptionInput, props2)
2143
+ ["options"]: (props2) => /* @__PURE__ */ React13.createElement(SelectOptionInput, props2)
2096
2144
  }), [
2097
2145
  t,
2098
2146
  schemas,
@@ -2104,15 +2152,16 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2104
2152
  props
2105
2153
  }, {
2106
2154
  F: __dxlog_file4,
2107
- L: 173,
2155
+ L: 177,
2108
2156
  S: void 0,
2109
2157
  C: (f, a) => f(...a)
2110
2158
  });
2111
2159
  return null;
2112
2160
  }
2113
- return /* @__PURE__ */ React14.createElement(Form, {
2161
+ return /* @__PURE__ */ React13.createElement(Form, {
2114
2162
  key: field.id,
2115
2163
  autoFocus: true,
2164
+ readonly,
2116
2165
  values: props,
2117
2166
  schema: fieldSchema,
2118
2167
  filter: propIsNotType,
@@ -2133,74 +2182,84 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
2133
2182
  };
2134
2183
 
2135
2184
  // src/components/ViewEditor/ViewEditor.tsx
2136
- import { useSignals as _useSignals15 } from "@preact-signals/safe-react/tracking";
2137
- import { Schema as Schema2 } from "effect";
2138
- import React15, { useCallback as useCallback10, useMemo as useMemo8, useState as useState6 } from "react";
2185
+ import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
2186
+ import { Match, Schema as Schema2 } from "effect";
2187
+ import React14, { useCallback as useCallback10, useMemo as useMemo8, useState as useState7 } from "react";
2139
2188
  import { EchoSchema, Format, isMutable, toJsonSchema } from "@dxos/echo-schema";
2140
2189
  import { invariant as invariant3 } from "@dxos/invariant";
2190
+ import { getSpace } from "@dxos/react-client/echo";
2141
2191
  import { Callout, IconButton as IconButton4, useTranslation as useTranslation9 } from "@dxos/react-ui";
2192
+ import { QueryEditor, QuerySerializer, createExpression } from "@dxos/react-ui-components";
2142
2193
  import { List as List2 } from "@dxos/react-ui-list";
2143
2194
  import { cardSpacing as cardSpacing3 } from "@dxos/react-ui-stack";
2144
- import { ghostHover, inputTextLabel, mx as mx9 } from "@dxos/react-ui-theme";
2145
- import { FieldSchema, VIEW_FIELD_LIMIT, ProjectionModel } from "@dxos/schema";
2195
+ import { inputTextLabel, mx as mx7, subtleHover as subtleHover2 } from "@dxos/react-ui-theme";
2196
+ import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, typenameFromQuery } from "@dxos/schema";
2146
2197
  var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
2147
- var grid = "grid grid-cols-[32px_1fr_32px_32px] min-bs-[2.5rem]";
2148
- var ViewMetaSchema = Schema2.Struct({
2149
- typename: Format.URL.annotations({
2150
- title: "Typename"
2151
- })
2152
- }).pipe(Schema2.mutable);
2153
- var ViewEditor = ({ classNames, schema, view, registry, readonly: _readonly, showHeading = false, onTypenameChanged, onDelete, outerSpacing = true }) => {
2154
- var _effect = _useSignals15();
2198
+ var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
2199
+ var listItemGrid = "grid grid-cols-subgrid col-span-5";
2200
+ var ViewEditor = ({ classNames, schema, view, kind = "basic", registry, readonly, showHeading = false, onQueryChanged, onDelete, outerSpacing = true }) => {
2201
+ var _effect = _useSignals14();
2155
2202
  try {
2203
+ const space = getSpace(view);
2204
+ const schemaReadonly = !isMutable(schema);
2156
2205
  const { t } = useTranslation9(translationKey);
2157
- const projection = useMemo8(() => {
2206
+ const projectionModel = useMemo8(() => {
2158
2207
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
2159
2208
  return new ProjectionModel(jsonSchema, view.projection);
2160
2209
  }, [
2161
2210
  schema,
2162
2211
  view.projection
2163
2212
  ]);
2164
- const [field, setField] = 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
- };
2213
+ const [expandedField, setExpandedField] = useState7();
2214
+ const serializedQuery = Match.value(kind).pipe(Match.when("basic", () => typenameFromQuery(view.query)), Match.when("advanced", () => {
2215
+ if (view.query.type !== "select") {
2216
+ return "";
2217
+ }
2218
+ const serializer = new QuerySerializer();
2219
+ return serializer.serialize(createExpression(view.query.filter));
2220
+ }), Match.exhaustive);
2221
+ const viewSchema = useMemo8(() => {
2222
+ return Schema2.Struct({
2223
+ query: kind === "basic" ? Format.URL.annotations({
2224
+ title: "Record type"
2225
+ }) : Schema2.String.annotations({
2226
+ title: "Query"
2227
+ })
2228
+ }).pipe(Schema2.mutable);
2172
2229
  }, [
2173
- view.query.typename
2230
+ kind
2174
2231
  ]);
2175
- const handleSelect = useCallback10((field2) => {
2176
- if (readonly) {
2177
- return;
2178
- }
2179
- setField((f) => f === field2 ? void 0 : field2);
2232
+ const viewValues = useMemo8(() => ({
2233
+ query: serializedQuery
2234
+ }), [
2235
+ serializedQuery
2236
+ ]);
2237
+ const handleToggleField = useCallback10((field) => {
2238
+ setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
2180
2239
  }, [
2181
2240
  readonly
2182
2241
  ]);
2183
2242
  const handleAdd = useCallback10(() => {
2184
2243
  invariant3(!readonly, void 0, {
2185
2244
  F: __dxlog_file5,
2186
- L: 88,
2245
+ L: 106,
2187
2246
  S: void 0,
2188
2247
  A: [
2189
2248
  "!readonly",
2190
2249
  ""
2191
2250
  ]
2192
2251
  });
2193
- const field2 = projection.createFieldProjection();
2194
- setField(field2);
2252
+ const field = projectionModel.createFieldProjection();
2253
+ setExpandedField(field.id);
2195
2254
  }, [
2196
2255
  schema,
2197
- projection,
2256
+ projectionModel,
2198
2257
  readonly
2199
2258
  ]);
2200
- const handleUpdate = useCallback10(({ typename }) => {
2259
+ const handleUpdate = useCallback10(({ query }) => {
2201
2260
  invariant3(!readonly, void 0, {
2202
2261
  F: __dxlog_file5,
2203
- L: 95,
2262
+ L: 113,
2204
2263
  S: void 0,
2205
2264
  A: [
2206
2265
  "!readonly",
@@ -2208,38 +2267,38 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly: _readonly, sho
2208
2267
  ]
2209
2268
  });
2210
2269
  requestAnimationFrame(() => {
2211
- if (view.query.typename !== typename && !readonly) {
2212
- onTypenameChanged?.(typename);
2270
+ if (serializedQuery !== query && !readonly) {
2271
+ onQueryChanged?.(query);
2213
2272
  }
2214
2273
  });
2215
2274
  }, [
2216
- view.query.typename,
2217
- onTypenameChanged,
2275
+ serializedQuery,
2276
+ onQueryChanged,
2218
2277
  readonly
2219
2278
  ]);
2220
2279
  const handleDelete = useCallback10((fieldId) => {
2221
2280
  invariant3(!readonly, void 0, {
2222
2281
  F: __dxlog_file5,
2223
- L: 107,
2282
+ L: 125,
2224
2283
  S: void 0,
2225
2284
  A: [
2226
2285
  "!readonly",
2227
2286
  ""
2228
2287
  ]
2229
2288
  });
2230
- if (fieldId === field?.id) {
2231
- setField(void 0);
2289
+ if (fieldId === expandedField) {
2290
+ setExpandedField(void 0);
2232
2291
  }
2233
2292
  onDelete?.(fieldId);
2234
2293
  }, [
2235
- field,
2294
+ expandedField,
2236
2295
  onDelete,
2237
2296
  readonly
2238
2297
  ]);
2239
2298
  const handleMove = useCallback10((fromIndex, toIndex) => {
2240
2299
  invariant3(!readonly, void 0, {
2241
2300
  F: __dxlog_file5,
2242
- L: 119,
2301
+ L: 137,
2243
2302
  S: void 0,
2244
2303
  A: [
2245
2304
  "!readonly",
@@ -2256,104 +2315,120 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly: _readonly, sho
2256
2315
  view.projection.fields,
2257
2316
  readonly
2258
2317
  ]);
2259
- const handleClose = useCallback10(() => setField(void 0), []);
2260
- const hiddenProperties = projection.getHiddenProperties();
2318
+ const handleClose = useCallback10(() => setExpandedField(void 0), []);
2261
2319
  const handleHide = useCallback10((fieldId) => {
2262
- setField(void 0);
2263
- projection.hideFieldProjection(fieldId);
2320
+ setExpandedField(void 0);
2321
+ projectionModel.hideFieldProjection(fieldId);
2264
2322
  }, [
2265
- projection
2323
+ projectionModel
2266
2324
  ]);
2267
2325
  const handleShow = useCallback10((property) => {
2268
- setField(void 0);
2269
- projection.showFieldProjection(property);
2326
+ setExpandedField(void 0);
2327
+ projectionModel.showFieldProjection(property);
2270
2328
  }, [
2271
- projection
2329
+ projectionModel
2272
2330
  ]);
2273
- return /* @__PURE__ */ React15.createElement("div", {
2274
- role: "none",
2275
- className: mx9(classNames)
2276
- }, readonly && /* @__PURE__ */ React15.createElement("div", {
2331
+ const custom = useMemo8(() => kind === "advanced" ? {
2332
+ ["query"]: (props) => {
2333
+ const handleChange = useCallback10((text) => props.onValueChange("string", text), [
2334
+ props.onValueChange
2335
+ ]);
2336
+ return /* @__PURE__ */ React14.createElement(QueryEditor, {
2337
+ space,
2338
+ initialValue: props.getValue(),
2339
+ onChange: handleChange
2340
+ });
2341
+ }
2342
+ } : {}, []);
2343
+ return /* @__PURE__ */ React14.createElement("div", {
2277
2344
  role: "none",
2278
- className: mx9("is-full", outerSpacing && "plb-cardSpacingBlock pli-cardSpacingInline")
2279
- }, /* @__PURE__ */ React15.createElement(Callout.Root, {
2280
- valence: "info"
2281
- }, /* @__PURE__ */ React15.createElement(Callout.Title, null, t("system schema description")))), /* @__PURE__ */ React15.createElement(Form, {
2345
+ className: mx7(classNames)
2346
+ }, schemaReadonly && /* @__PURE__ */ React14.createElement(Callout.Root, {
2347
+ valence: "info",
2348
+ classNames: [
2349
+ "mlb-cardSpacingBlock",
2350
+ outerSpacing && "mli-cardSpacingInline"
2351
+ ]
2352
+ }, /* @__PURE__ */ React14.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React14.createElement(Form, {
2282
2353
  autoSave: true,
2283
- schema: ViewMetaSchema,
2354
+ schema: viewSchema,
2284
2355
  values: viewValues,
2285
- readonly,
2356
+ readonly: readonly ? "disabled-input" : false,
2286
2357
  onSave: handleUpdate,
2287
- outerSpacing
2288
- }), /* @__PURE__ */ React15.createElement("div", {
2358
+ outerSpacing,
2359
+ Custom: custom
2360
+ }), /* @__PURE__ */ React14.createElement("div", {
2289
2361
  role: "none",
2290
2362
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2291
- }, /* @__PURE__ */ React15.createElement("label", {
2292
- className: mx9(inputTextLabel)
2293
- }, t("fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
2363
+ }, /* @__PURE__ */ React14.createElement("h2", {
2364
+ className: mx7(inputTextLabel)
2365
+ }, t("fields label")), /* @__PURE__ */ React14.createElement(List2.Root, {
2294
2366
  items: view.projection.fields,
2295
2367
  isItem: Schema2.is(FieldSchema),
2296
- getId: (field2) => field2.id,
2297
- readonly,
2298
- onMove: readonly ? void 0 : handleMove
2299
- }, ({ items: fields }) => /* @__PURE__ */ React15.createElement(React15.Fragment, null, showHeading && /* @__PURE__ */ React15.createElement("div", {
2300
- role: "heading",
2301
- className: grid
2302
- }, /* @__PURE__ */ React15.createElement("div", null), /* @__PURE__ */ React15.createElement("div", {
2303
- className: "flex items-center text-sm"
2304
- }, t("field path label"))), /* @__PURE__ */ React15.createElement("div", {
2305
- role: "list",
2306
- className: "flex flex-col is-full"
2307
- }, fields?.map((field2) => /* @__PURE__ */ React15.createElement(List2.Item, {
2308
- key: field2.id,
2309
- item: field2,
2310
- classNames: mx9(grid, ghostHover, "overflow-hidden", !readonly && "cursor-pointer")
2311
- }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
2312
- onClick: () => handleSelect(field2)
2313
- }, field2.path), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
2314
- "data-testid": "hide-field-button",
2315
- icon: "ph--eye-slash--regular",
2316
- // TDOO(burdon): Is this the correct test?
2317
- disabled: view.projection.fields.length <= 1,
2318
- onClick: () => handleHide(field2.id)
2319
- }), !readonly && /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
2320
- disabled: view.projection.fields.length <= 1,
2321
- onClick: () => handleDelete(field2.id)
2322
- })))))), hiddenProperties.length > 0 && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("label", {
2323
- className: mx9(inputTextLabel)
2324
- }, t("hidden fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
2325
- items: hiddenProperties,
2326
- isItem: (item) => typeof item === "string",
2327
- getId: (property) => property
2328
- }, ({ items: properties }) => /* @__PURE__ */ React15.createElement("div", {
2368
+ getId: (field) => field.id,
2369
+ onMove: readonly ? void 0 : handleMove,
2370
+ readonly
2371
+ }, ({ items: fields }) => /* @__PURE__ */ React14.createElement(React14.Fragment, null, showHeading && /* @__PURE__ */ React14.createElement("h3", {
2372
+ className: "text-sm"
2373
+ }, t("field path label")), /* @__PURE__ */ React14.createElement("div", {
2329
2374
  role: "list",
2330
- className: "flex flex-col is-full"
2331
- }, properties?.map((property) => /* @__PURE__ */ React15.createElement(List2.Item, {
2332
- key: property,
2333
- item: property,
2334
- classNames: mx9(grid, ghostHover, !readonly && "cursor-pointer")
2335
- }, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, {
2336
- disabled: true
2337
- }), /* @__PURE__ */ React15.createElement(List2.ItemTitle, null, property), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
2338
- icon: "ph--eye--regular",
2339
- onClick: () => handleShow(property),
2340
- "data-testid": "show-field-button"
2341
- }))))))), field && /* @__PURE__ */ React15.createElement(FieldEditor, {
2342
- key: field.id,
2343
- projection,
2344
- field,
2345
- registry,
2346
- onSave: handleClose
2347
- }), !readonly && !field && /* @__PURE__ */ React15.createElement("div", {
2375
+ className: listGrid
2376
+ }, fields?.map((field) => {
2377
+ const hidden = field.visible === false;
2378
+ return /* @__PURE__ */ React14.createElement(List2.Item, {
2379
+ key: field.id,
2380
+ item: field,
2381
+ classNames: listItemGrid,
2382
+ "aria-expanded": expandedField === field.id
2383
+ }, /* @__PURE__ */ React14.createElement("div", {
2384
+ role: "none",
2385
+ className: mx7(subtleHover2, listItemGrid, "rounded-sm cursor-pointer min-bs-10")
2386
+ }, /* @__PURE__ */ React14.createElement(List2.ItemDragHandle, {
2387
+ disabled: readonly
2388
+ }), /* @__PURE__ */ React14.createElement(List2.ItemTitle, {
2389
+ classNames: hidden && "text-subdued",
2390
+ onClick: () => handleToggleField(field)
2391
+ }, field.path), /* @__PURE__ */ React14.createElement(List2.ItemButton, {
2392
+ label: t(hidden ? "show field label" : "hide field label"),
2393
+ "data-testid": hidden ? "show-field-button" : "hide-field-button",
2394
+ icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
2395
+ autoHide: false,
2396
+ disabled: readonly || !hidden && projectionModel.fields.length <= 1,
2397
+ onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
2398
+ }), /* @__PURE__ */ React14.createElement(List2.ItemDeleteButton, {
2399
+ label: t("delete field label"),
2400
+ autoHide: false,
2401
+ disabled: readonly || schemaReadonly || view.projection.fields.length <= 1,
2402
+ onClick: () => handleDelete(field.id),
2403
+ "data-testid": "field.delete"
2404
+ }), /* @__PURE__ */ React14.createElement(IconButton4, {
2405
+ iconOnly: true,
2406
+ variant: "ghost",
2407
+ label: t("toggle expand label", {
2408
+ ns: "os"
2409
+ }),
2410
+ icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
2411
+ onClick: () => handleToggleField(field)
2412
+ })), expandedField === field.id && /* @__PURE__ */ React14.createElement("div", {
2413
+ role: "none",
2414
+ className: "col-span-5 mbs-1 mbe-1 border border-separator rounded-md"
2415
+ }, /* @__PURE__ */ React14.createElement(FieldEditor, {
2416
+ readonly: readonly || schemaReadonly ? "disabled-input" : false,
2417
+ projection: projectionModel,
2418
+ field,
2419
+ registry,
2420
+ onSave: handleClose
2421
+ })));
2422
+ }))))), !readonly && !expandedField && /* @__PURE__ */ React14.createElement("div", {
2348
2423
  role: "none",
2349
2424
  className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
2350
- }, /* @__PURE__ */ React15.createElement(IconButton4, {
2425
+ }, /* @__PURE__ */ React14.createElement(IconButton4, {
2351
2426
  icon: "ph--plus--regular",
2352
2427
  label: t("button add property"),
2353
2428
  onClick: readonly ? void 0 : handleAdd,
2354
2429
  // TODO(burdon): Show field limit in ux (not tooltip).
2355
2430
  disabled: view.projection.fields.length >= VIEW_FIELD_LIMIT,
2356
- classNames: "flex is-full"
2431
+ classNames: "is-full"
2357
2432
  })));
2358
2433
  } finally {
2359
2434
  _effect.f();
@@ -2370,8 +2445,6 @@ export {
2370
2445
  ControlPage,
2371
2446
  ControlSection,
2372
2447
  ControlSectionHeading,
2373
- DeprecatedFormContainer,
2374
- DeprecatedFormInput,
2375
2448
  FieldEditor,
2376
2449
  Form,
2377
2450
  FormProvider,