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

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