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