@dxos/react-ui-form 0.8.4-main.3a94e84 → 0.8.4-main.3c1ae3b
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.
- package/dist/lib/browser/index.mjs +2138 -1738
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +2138 -1738
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.d.ts +2 -2
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +1 -1
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +84 -5
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +5 -5
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +82 -5
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form-old.stories.d.ts +172 -0
- package/dist/types/src/components/Form/Form-old.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/Form.d.ts +78 -25
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +123 -51
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts +37 -0
- package/dist/types/src/components/Form/FormField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +78 -0
- package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts +9 -0
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormFieldSet.d.ts +19 -0
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/ArrayField.d.ts +18 -0
- package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/BooleanField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts +5 -0
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/NumberField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/RefField.d.ts +18 -0
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/SelectField.d.ts +10 -0
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +5 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +82 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/TextField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/TupleField.d.ts +6 -0
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/index.d.ts +12 -0
- package/dist/types/src/components/Form/fields/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/index.d.ts +2 -4
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +41 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +85 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +21 -9
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +83 -8
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +4 -3
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +3 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useFormHandler.d.ts +82 -0
- package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -0
- package/dist/types/src/hooks/useKeyHandler.d.ts +6 -0
- package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -0
- package/dist/types/src/hooks/useQueryRefOptions.d.ts +13 -6
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +1 -1
- package/dist/types/src/hooks/useRefQueryOptions.d.ts +8 -0
- package/dist/types/src/hooks/useRefQueryOptions.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +17 -8
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/field.d.ts +3 -3
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts +2 -2
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/properties.d.ts +7 -0
- package/dist/types/src/util/properties.d.ts.map +1 -0
- package/dist/types/src/util/refs.d.ts +2 -3
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +43 -36
- package/src/components/ControlSection/ControlSection.stories.tsx +11 -14
- package/src/components/ControlSection/ControlSection.tsx +26 -12
- package/src/components/FieldEditor/FieldEditor.stories.tsx +20 -20
- package/src/components/FieldEditor/FieldEditor.test.tsx +3 -2
- package/src/components/FieldEditor/FieldEditor.tsx +75 -77
- package/src/components/Form/Form-old.stories.tsx +314 -0
- package/src/components/Form/Form.stories.tsx +163 -219
- package/src/components/Form/Form.tsx +306 -98
- package/src/components/Form/FormField.tsx +280 -0
- package/src/components/Form/FormFieldComponent.stories.tsx +65 -0
- package/src/components/Form/FormFieldComponent.tsx +173 -0
- package/src/components/Form/FormFieldSet.tsx +124 -0
- package/src/components/Form/README.md +3 -0
- package/src/components/Form/fields/ArrayField.tsx +154 -0
- package/src/components/Form/fields/BooleanField.tsx +22 -0
- package/src/components/Form/fields/GeoPointField.tsx +120 -0
- package/src/components/Form/fields/MarkdownField.tsx +78 -0
- package/src/components/Form/fields/NumberField.tsx +39 -0
- package/src/components/Form/fields/RefField.tsx +206 -0
- package/src/components/Form/fields/SelectField.tsx +65 -0
- package/src/components/Form/{custom/SelectOptionsInput.stories.tsx → fields/SelectOptionField.stories.tsx} +25 -22
- package/src/components/Form/{custom/SelectOptionsInput.tsx → fields/SelectOptionField.tsx} +47 -42
- package/src/components/Form/fields/TextAreaField.tsx +38 -0
- package/src/components/Form/fields/TextField.tsx +38 -0
- package/src/components/Form/{custom/TupleInput.tsx → fields/TupleField.tsx} +15 -8
- package/src/components/Form/fields/index.ts +15 -0
- package/src/components/Form/index.ts +3 -4
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +207 -0
- package/src/components/ObjectPicker/ObjectPicker.tsx +166 -0
- package/src/components/ObjectPicker/index.ts +5 -0
- package/src/components/ViewEditor/ViewEditor.stories.tsx +131 -61
- package/src/components/ViewEditor/ViewEditor.test.tsx +19 -17
- package/src/components/ViewEditor/ViewEditor.tsx +277 -197
- package/src/components/index.ts +1 -2
- package/src/components/testing.tsx +20 -10
- package/src/hooks/index.ts +3 -2
- package/src/hooks/useFormHandler.ts +348 -0
- package/src/hooks/useKeyHandler.tsx +37 -0
- package/src/hooks/useQueryRefOptions.ts +49 -32
- package/src/hooks/useRefQueryOptions.ts +37 -0
- package/src/translations.ts +20 -11
- package/src/util/field.ts +33 -43
- package/src/util/formatting.ts +22 -22
- package/src/util/index.ts +1 -1
- package/src/util/properties.ts +18 -0
- package/src/util/refs.ts +12 -18
- package/dist/types/src/components/Form/ArrayField.d.ts +0 -16
- package/dist/types/src/components/Form/ArrayField.d.ts.map +0 -1
- package/dist/types/src/components/Form/Defaults.d.ts +0 -14
- package/dist/types/src/components/Form/Defaults.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormActions.d.ts +0 -9
- package/dist/types/src/components/Form/FormActions.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormContent.d.ts +0 -57
- package/dist/types/src/components/Form/FormContent.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormContext.d.ts +0 -23
- package/dist/types/src/components/Form/FormContext.d.ts.map +0 -1
- package/dist/types/src/components/Form/Input.d.ts +0 -26
- package/dist/types/src/components/Form/Input.d.ts.map +0 -1
- package/dist/types/src/components/Form/RefField.d.ts +0 -12
- package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +0 -4
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +0 -4
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +0 -7
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +0 -6
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/index.d.ts +0 -4
- package/dist/types/src/components/Form/custom/index.d.ts.map +0 -1
- package/dist/types/src/components/Form/factory.d.ts +0 -8
- package/dist/types/src/components/Form/factory.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/Form.d.ts +0 -15
- package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/index.d.ts +0 -2
- package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
- package/dist/types/src/hooks/useForm.d.ts +0 -67
- package/dist/types/src/hooks/useForm.d.ts.map +0 -1
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +0 -8
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +0 -1
- package/dist/types/src/util/schema.d.ts +0 -3
- package/dist/types/src/util/schema.d.ts.map +0 -1
- package/src/components/Form/ArrayField.tsx +0 -124
- package/src/components/Form/Defaults.tsx +0 -203
- package/src/components/Form/FormActions.tsx +0 -53
- package/src/components/Form/FormContent.tsx +0 -240
- package/src/components/Form/FormContext.tsx +0 -110
- package/src/components/Form/Input.tsx +0 -51
- package/src/components/Form/RefField.tsx +0 -213
- package/src/components/Form/custom/GeoPointInput.tsx +0 -72
- package/src/components/Form/custom/index.ts +0 -7
- package/src/components/Form/factory.tsx +0 -31
- package/src/components/deprecated/Form.stories.tsx +0 -62
- package/src/components/deprecated/Form.tsx +0 -119
- package/src/components/deprecated/FormInput.tsx +0 -71
- package/src/components/deprecated/index.ts +0 -5
- package/src/hooks/useForm.ts +0 -291
- package/src/hooks/useRefQueryLookupHandler.ts +0 -39
- package/src/util/schema.ts +0 -14
|
@@ -10,7 +10,7 @@ var translations = [
|
|
|
10
10
|
"hidden fields label": "Hidden Fields",
|
|
11
11
|
"empty readonly ref field label": "(none)",
|
|
12
12
|
// TODO(burdon): Standardize field/property.
|
|
13
|
-
"
|
|
13
|
+
"add property button label": "Add property",
|
|
14
14
|
"field property label": "Property",
|
|
15
15
|
"field property placeholder": "Property name",
|
|
16
16
|
"field format label": "Type",
|
|
@@ -20,9 +20,17 @@ var translations = [
|
|
|
20
20
|
"field limit reached": "Maximum number of fields reached",
|
|
21
21
|
"boolean input true value": "Yes",
|
|
22
22
|
"boolean input false value": "No",
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
23
|
+
"show field label": "Show field",
|
|
24
|
+
"hide field label": "Hide field",
|
|
25
|
+
"delete field label": "Delete field",
|
|
26
|
+
"ref field combobox input placeholder": "Search\u2026",
|
|
27
|
+
"ref field placeholder_one": "Select\u2026",
|
|
28
|
+
"ref field placeholder_other": "Select items\u2026",
|
|
29
|
+
"example placeholder": "Example",
|
|
30
|
+
"latitude placeholder": "Latitude (e.g., 40.7128)",
|
|
31
|
+
"longitude placeholder": "Longitude (e.g., -74.0060)",
|
|
32
|
+
"cancel button label": "Cancel",
|
|
33
|
+
"save button label": "Save",
|
|
26
34
|
// FormatEnum
|
|
27
35
|
"format boolean": "Boolean",
|
|
28
36
|
"format currency": "Currency",
|
|
@@ -36,7 +44,7 @@ var translations = [
|
|
|
36
44
|
"format hostname": "Hostname",
|
|
37
45
|
"format integer": "Integer",
|
|
38
46
|
"format json": "JSON",
|
|
39
|
-
"format
|
|
47
|
+
"format lnglat": "Geopoint",
|
|
40
48
|
"format markdown": "Markdown",
|
|
41
49
|
"format percent": "Percent",
|
|
42
50
|
"format ref": "Reference",
|
|
@@ -52,96 +60,48 @@ var translations = [
|
|
|
52
60
|
"format uri": "URI",
|
|
53
61
|
"format url": "URL",
|
|
54
62
|
"format uuid": "UUID",
|
|
55
|
-
//
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
//
|
|
63
|
+
// GeoPointField.
|
|
64
|
+
"latitude label": "Latitude",
|
|
65
|
+
"longitude label": "Longitude",
|
|
66
|
+
// SelectOptionsField.
|
|
59
67
|
"select option label": "Label",
|
|
60
68
|
"select option label placeholder": "Option label",
|
|
61
69
|
"select option color": "Color",
|
|
62
70
|
"select option delete": "Delete",
|
|
63
71
|
"select option add": "Add option",
|
|
64
72
|
// System schema message.
|
|
65
|
-
"system schema title": "System
|
|
66
|
-
"system schema description": "
|
|
73
|
+
"system schema title": "System type",
|
|
74
|
+
"system schema description": "System type: cannot add or remove fields."
|
|
67
75
|
}
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
];
|
|
71
79
|
|
|
72
|
-
// src/components/
|
|
80
|
+
// src/components/ControlSection/ControlSection.tsx
|
|
73
81
|
import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
|
|
74
82
|
import React from "react";
|
|
75
|
-
import { Input } from "@dxos/react-ui";
|
|
76
|
-
import {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
81
|
-
role: "none",
|
|
82
|
-
className: "container-max-width p-4 justify-center overflow-x-hidden overflow-y-auto"
|
|
83
|
-
}, /* @__PURE__ */ React.createElement("div", {
|
|
84
|
-
role: "form",
|
|
85
|
-
className: mx("flex flex-col", textBlockWidth, classNames)
|
|
86
|
-
}, children));
|
|
87
|
-
} finally {
|
|
88
|
-
_effect.f();
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
var DeprecatedFormInput = ({ label, description, secondary, children }) => {
|
|
83
|
+
import { Button, Input, toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
84
|
+
import { StackItem } from "@dxos/react-ui-stack";
|
|
85
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
86
|
+
var ControlPage = ({ children, classNames, ...props }) => {
|
|
92
87
|
var _effect = _useSignals();
|
|
93
88
|
try {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement("div", {
|
|
98
|
-
role: "none",
|
|
99
|
-
className: "flex flex-col w-full"
|
|
100
|
-
}, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
101
|
-
classNames: "flex min-bs-[--rail-action] items-center",
|
|
102
|
-
style: {
|
|
103
|
-
fontSize: "unset"
|
|
104
|
-
}
|
|
105
|
-
}, label), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, {
|
|
106
|
-
classNames: "mbs-0.5"
|
|
107
|
-
}, /* @__PURE__ */ React.createElement(Input.Description, null, description))), /* @__PURE__ */ React.createElement("div", {
|
|
108
|
-
role: "none"
|
|
89
|
+
return /* @__PURE__ */ React.createElement(StackItem.Content, {
|
|
90
|
+
scrollable: true,
|
|
91
|
+
classNames: "[--control-spacing:var(--dx-trimMd)]"
|
|
109
92
|
}, /* @__PURE__ */ React.createElement("div", {
|
|
110
93
|
role: "none",
|
|
111
|
-
className: "
|
|
112
|
-
}, children))));
|
|
113
|
-
if (secondary) {
|
|
114
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
115
|
-
role: "none"
|
|
116
|
-
}, primary, secondary);
|
|
117
|
-
}
|
|
118
|
-
return primary;
|
|
119
|
-
} finally {
|
|
120
|
-
_effect.f();
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
// src/components/ControlSection/ControlSection.tsx
|
|
125
|
-
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
126
|
-
import React2 from "react";
|
|
127
|
-
import { Button, Input as Input2, toLocalizedString, useTranslation } from "@dxos/react-ui";
|
|
128
|
-
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
129
|
-
var ControlPage = ({ children, classNames, ...props }) => {
|
|
130
|
-
var _effect = _useSignals2();
|
|
131
|
-
try {
|
|
132
|
-
return /* @__PURE__ */ React2.createElement("div", {
|
|
133
|
-
role: "none",
|
|
134
|
-
className: mx2("pli-cardSpacingInline", classNames),
|
|
94
|
+
className: mx("pli-cardSpacingInline pbe-trimLg", classNames),
|
|
135
95
|
...props
|
|
136
|
-
}, children);
|
|
96
|
+
}, children));
|
|
137
97
|
} finally {
|
|
138
98
|
_effect.f();
|
|
139
99
|
}
|
|
140
100
|
};
|
|
141
101
|
var ControlSection = ({ title, description, children }) => {
|
|
142
|
-
var _effect =
|
|
102
|
+
var _effect = _useSignals();
|
|
143
103
|
try {
|
|
144
|
-
return /* @__PURE__ */
|
|
104
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ControlSectionHeading, {
|
|
145
105
|
title,
|
|
146
106
|
description
|
|
147
107
|
}), children);
|
|
@@ -150,12 +110,12 @@ var ControlSection = ({ title, description, children }) => {
|
|
|
150
110
|
}
|
|
151
111
|
};
|
|
152
112
|
var ControlSectionHeading = ({ title, description }) => {
|
|
153
|
-
var _effect =
|
|
113
|
+
var _effect = _useSignals();
|
|
154
114
|
try {
|
|
155
115
|
const { t } = useTranslation(translationKey);
|
|
156
|
-
return /* @__PURE__ */
|
|
116
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h2", {
|
|
157
117
|
className: "pli-trimMd container-max-width text-xl mbs-trimLg mbe-trimMd"
|
|
158
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */
|
|
118
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
|
|
159
119
|
className: "pli-trimMd mlb-trimMd container-max-width text-description"
|
|
160
120
|
}, toLocalizedString(description, t)));
|
|
161
121
|
} finally {
|
|
@@ -163,9 +123,9 @@ var ControlSectionHeading = ({ title, description }) => {
|
|
|
163
123
|
}
|
|
164
124
|
};
|
|
165
125
|
var ControlGroupButton = ({ classNames, ...props }) => {
|
|
166
|
-
var _effect =
|
|
126
|
+
var _effect = _useSignals();
|
|
167
127
|
try {
|
|
168
|
-
return /* @__PURE__ */
|
|
128
|
+
return /* @__PURE__ */ React.createElement(Button, {
|
|
169
129
|
...props,
|
|
170
130
|
classNames: [
|
|
171
131
|
"md:col-span-2",
|
|
@@ -177,41 +137,46 @@ var ControlGroupButton = ({ classNames, ...props }) => {
|
|
|
177
137
|
}
|
|
178
138
|
};
|
|
179
139
|
var ControlGroup = ({ children, classNames }) => {
|
|
180
|
-
var _effect =
|
|
140
|
+
var _effect = _useSignals();
|
|
181
141
|
try {
|
|
182
|
-
return /* @__PURE__ */
|
|
142
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
183
143
|
role: "none",
|
|
184
|
-
className:
|
|
144
|
+
className: mx("group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-trimMd", "[--control-spacing:0px] [&_input]:justify-self-end [&_button]:justify-self-end", classNames)
|
|
185
145
|
}, children);
|
|
186
146
|
} finally {
|
|
187
147
|
_effect.f();
|
|
188
148
|
}
|
|
189
149
|
};
|
|
190
150
|
var ControlFrame = ({ children }) => {
|
|
191
|
-
var _effect =
|
|
151
|
+
var _effect = _useSignals();
|
|
192
152
|
try {
|
|
193
|
-
return /* @__PURE__ */
|
|
153
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
194
154
|
role: "none",
|
|
195
|
-
className: "
|
|
155
|
+
className: mx("container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-trimSm md:gap-trimMd p-trimMd", "border border-separator rounded-md")
|
|
196
156
|
}, children);
|
|
197
157
|
} finally {
|
|
198
158
|
_effect.f();
|
|
199
159
|
}
|
|
200
160
|
};
|
|
201
|
-
var controlItemClasses =
|
|
202
|
-
|
|
203
|
-
|
|
161
|
+
var controlItemClasses = mx([
|
|
162
|
+
"container-max-width grid md:col-span-2 grid-cols-subgrid gap-trimSm items-center",
|
|
163
|
+
// TODO(burdon): Use grid gap consistently or apply margins consistently?
|
|
164
|
+
"mlb-[--control-spacing] *:first:!mbs-0 *:last:!mbe-0 pli-trimMd plb-trimMd",
|
|
165
|
+
"border border-separator rounded-md"
|
|
166
|
+
]);
|
|
167
|
+
var controlItemTitleClasses = "mbe-0 text-lg text-baseText font-normal";
|
|
168
|
+
var controlItemDescriptionClasses = "mlb-trimSm md:mbe-0 text-base text-description";
|
|
204
169
|
var ControlItem = ({ title, description, children }) => {
|
|
205
|
-
var _effect =
|
|
170
|
+
var _effect = _useSignals();
|
|
206
171
|
try {
|
|
207
172
|
const { t } = useTranslation(translationKey);
|
|
208
|
-
return /* @__PURE__ */
|
|
173
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
209
174
|
className: controlItemClasses
|
|
210
|
-
}, /* @__PURE__ */
|
|
175
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
211
176
|
role: "none"
|
|
212
|
-
}, /* @__PURE__ */
|
|
177
|
+
}, /* @__PURE__ */ React.createElement("h3", {
|
|
213
178
|
className: controlItemTitleClasses
|
|
214
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */
|
|
179
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
|
|
215
180
|
className: controlItemDescriptionClasses
|
|
216
181
|
}, toLocalizedString(description, t))), children);
|
|
217
182
|
} finally {
|
|
@@ -219,16 +184,16 @@ var ControlItem = ({ title, description, children }) => {
|
|
|
219
184
|
}
|
|
220
185
|
};
|
|
221
186
|
var ControlItemInput = ({ title, description, children }) => {
|
|
222
|
-
var _effect =
|
|
187
|
+
var _effect = _useSignals();
|
|
223
188
|
try {
|
|
224
189
|
const { t } = useTranslation(translationKey);
|
|
225
|
-
return /* @__PURE__ */
|
|
190
|
+
return /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement("div", {
|
|
226
191
|
className: controlItemClasses
|
|
227
|
-
}, /* @__PURE__ */
|
|
192
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
228
193
|
role: "none"
|
|
229
|
-
}, /* @__PURE__ */
|
|
194
|
+
}, /* @__PURE__ */ React.createElement(Input.Label, {
|
|
230
195
|
classNames: controlItemTitleClasses
|
|
231
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */
|
|
196
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, null, /* @__PURE__ */ React.createElement(Input.Description, {
|
|
232
197
|
classNames: controlItemDescriptionClasses
|
|
233
198
|
}, toLocalizedString(description, t)))), children));
|
|
234
199
|
} finally {
|
|
@@ -236,15 +201,15 @@ var ControlItemInput = ({ title, description, children }) => {
|
|
|
236
201
|
}
|
|
237
202
|
};
|
|
238
203
|
var ControlFrameItem = ({ title, description, children }) => {
|
|
239
|
-
var _effect =
|
|
204
|
+
var _effect = _useSignals();
|
|
240
205
|
try {
|
|
241
206
|
const { t } = useTranslation(translationKey);
|
|
242
|
-
return /* @__PURE__ */
|
|
207
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
243
208
|
role: "group",
|
|
244
209
|
className: "min-is-0"
|
|
245
|
-
}, /* @__PURE__ */
|
|
210
|
+
}, /* @__PURE__ */ React.createElement("h3", {
|
|
246
211
|
className: "text-lg mbe-2"
|
|
247
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */
|
|
212
|
+
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React.createElement("p", {
|
|
248
213
|
className: "mlb-trimSm md:mbe-0 text-description"
|
|
249
214
|
}, toLocalizedString(description, t)), children);
|
|
250
215
|
} finally {
|
|
@@ -253,555 +218,362 @@ var ControlFrameItem = ({ title, description, children }) => {
|
|
|
253
218
|
};
|
|
254
219
|
|
|
255
220
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
256
|
-
import { useSignals as
|
|
257
|
-
import
|
|
258
|
-
import {
|
|
221
|
+
import { useSignals as _useSignals18 } from "@preact-signals/safe-react/tracking";
|
|
222
|
+
import React18, { useCallback as useCallback16, useEffect as useEffect6, useMemo as useMemo8, useState as useState6 } from "react";
|
|
223
|
+
import { Format as Format4, FormatEnums, formatToType } from "@dxos/echo/internal";
|
|
259
224
|
import { log as log3 } from "@dxos/log";
|
|
260
|
-
import { useTranslation as
|
|
261
|
-
import {
|
|
262
|
-
|
|
263
|
-
// src/components/Form/custom/GeoPointInput.tsx
|
|
264
|
-
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
265
|
-
import React4, { useCallback, useState, useEffect, useMemo } from "react";
|
|
266
|
-
import { GeoLocation } from "@dxos/echo-schema";
|
|
267
|
-
import { Input as Input4, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
268
|
-
import { safeParseFloat } from "@dxos/util";
|
|
225
|
+
import { useAsyncEffect as useAsyncEffect2, useTranslation as useTranslation9 } from "@dxos/react-ui";
|
|
226
|
+
import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
|
|
269
227
|
|
|
270
|
-
// src/
|
|
271
|
-
import {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
import { errorText, mx as mx3 } from "@dxos/react-ui-theme";
|
|
276
|
-
var InputHeader = ({ error, label, readonly }) => {
|
|
277
|
-
var _effect = _useSignals3();
|
|
278
|
-
try {
|
|
279
|
-
const Label = readonly ? "span" : Input3.Label;
|
|
280
|
-
const labelProps = readonly ? {} : {
|
|
281
|
-
classNames: "!mlb-0"
|
|
282
|
-
};
|
|
283
|
-
return /* @__PURE__ */ React3.createElement("div", {
|
|
284
|
-
role: "none",
|
|
285
|
-
className: mx3("flex justify-between items-center", labelSpacing)
|
|
286
|
-
}, /* @__PURE__ */ React3.createElement(Label, labelProps, label), error && /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
|
|
287
|
-
asChild: true,
|
|
288
|
-
content: error,
|
|
289
|
-
side: "bottom"
|
|
290
|
-
}, /* @__PURE__ */ React3.createElement(Icon, {
|
|
291
|
-
icon: "ph--warning--regular",
|
|
292
|
-
size: 4,
|
|
293
|
-
classNames: errorText
|
|
294
|
-
})));
|
|
295
|
-
} finally {
|
|
296
|
-
_effect.f();
|
|
228
|
+
// src/util/field.ts
|
|
229
|
+
import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
|
|
230
|
+
var parseValue = ({ type, format, value: value3 }) => {
|
|
231
|
+
if (value3 === void 0 || value3 === null || value3 === "") {
|
|
232
|
+
return void 0;
|
|
297
233
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
0
|
|
309
|
-
], [
|
|
310
|
-
getValue3
|
|
311
|
-
]);
|
|
312
|
-
const geoLocation = useMemo(() => GeoLocation.fromGeoPoint(geoPoint), [
|
|
313
|
-
geoPoint
|
|
314
|
-
]);
|
|
315
|
-
const [longitudeText, setLongitudeText] = useState(geoLocation.longitude?.toString());
|
|
316
|
-
const [latitudeText, setLatitudeText] = useState(geoLocation.latitude?.toString());
|
|
317
|
-
useEffect(() => {
|
|
318
|
-
const location = GeoLocation.fromGeoPoint(geoPoint);
|
|
319
|
-
setLongitudeText(location.longitude.toString());
|
|
320
|
-
setLatitudeText(location.latitude.toString());
|
|
321
|
-
}, [
|
|
322
|
-
geoPoint
|
|
323
|
-
]);
|
|
324
|
-
const handleCoordinateChange = useCallback((coordinateType, setText) => (event) => {
|
|
325
|
-
const inputText = event.target.value;
|
|
326
|
-
setText(inputText);
|
|
327
|
-
if (inputText !== "" && inputText !== "-") {
|
|
328
|
-
const coord = safeParseFloat(inputText);
|
|
329
|
-
if (coord !== void 0 && !isNaN(coord)) {
|
|
330
|
-
const currentLocation = GeoLocation.fromGeoPoint(getValue3() ?? [
|
|
331
|
-
0,
|
|
332
|
-
0
|
|
333
|
-
]);
|
|
334
|
-
const newLocation = {
|
|
335
|
-
...currentLocation,
|
|
336
|
-
[coordinateType]: coord
|
|
337
|
-
};
|
|
338
|
-
const newValue = GeoLocation.toGeoPoint(newLocation);
|
|
339
|
-
onValueChange(type, newValue);
|
|
234
|
+
const parseScalar = (type2) => {
|
|
235
|
+
switch (type2) {
|
|
236
|
+
case TypeEnum.Boolean: {
|
|
237
|
+
if (typeof value3 === "string") {
|
|
238
|
+
const lowercaseValue = value3.toLowerCase();
|
|
239
|
+
if (lowercaseValue === "0" || lowercaseValue === "false") {
|
|
240
|
+
return false;
|
|
241
|
+
} else if (lowercaseValue === "1" || lowercaseValue === "true") {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
340
244
|
}
|
|
245
|
+
return Boolean(value3);
|
|
341
246
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
247
|
+
case TypeEnum.Number: {
|
|
248
|
+
const cleaned = typeof value3 === "string" ? value3.replace(/[^0-9.-]+/g, "") : value3;
|
|
249
|
+
const num = Number(cleaned);
|
|
250
|
+
return Number.isNaN(num) ? null : num;
|
|
251
|
+
}
|
|
252
|
+
case TypeEnum.String:
|
|
253
|
+
case TypeEnum.Ref:
|
|
254
|
+
return String(value3);
|
|
255
|
+
default: {
|
|
256
|
+
return value3;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
if (!format) {
|
|
261
|
+
return parseScalar(type);
|
|
262
|
+
}
|
|
263
|
+
switch (format) {
|
|
264
|
+
case Format.TypeFormat.Boolean:
|
|
265
|
+
return parseScalar(TypeEnum.Boolean);
|
|
266
|
+
case Format.TypeFormat.Number:
|
|
267
|
+
case Format.TypeFormat.Percent:
|
|
268
|
+
case Format.TypeFormat.Currency:
|
|
269
|
+
return parseScalar(TypeEnum.Number);
|
|
270
|
+
case Format.TypeFormat.String:
|
|
271
|
+
case Format.TypeFormat.Markdown: {
|
|
272
|
+
return parseScalar(TypeEnum.String);
|
|
273
|
+
}
|
|
274
|
+
case Format.TypeFormat.Ref:
|
|
275
|
+
throw new Error(`unexpected format: ${Format.TypeFormat.Ref}`);
|
|
276
|
+
case Format.TypeFormat.DateTime:
|
|
277
|
+
case Format.TypeFormat.Date:
|
|
278
|
+
case Format.TypeFormat.Time:
|
|
279
|
+
case Format.TypeFormat.Timestamp: {
|
|
280
|
+
const date = new Date(value3);
|
|
281
|
+
return isNaN(date.getTime()) ? null : date;
|
|
282
|
+
}
|
|
283
|
+
case Format.TypeFormat.GeoPoint: {
|
|
284
|
+
if (typeof value3 === "string") {
|
|
285
|
+
const cleaned = value3.replace(/[^0-9.,-]+/g, "");
|
|
286
|
+
const parts = cleaned.split(",");
|
|
287
|
+
if (parts.length === 2) {
|
|
288
|
+
const lat = parseFloat(parts[0]);
|
|
289
|
+
const long = parseFloat(parts[1]);
|
|
290
|
+
if (!isNaN(lat) && !isNaN(long)) {
|
|
291
|
+
return GeoLocation.toGeoPoint({
|
|
292
|
+
latitude: lat,
|
|
293
|
+
longitude: long
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return [
|
|
299
|
+
0,
|
|
300
|
+
0
|
|
301
|
+
];
|
|
302
|
+
}
|
|
303
|
+
default: {
|
|
304
|
+
return value3;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
var cellClassesForFieldType = ({ type, format }) => {
|
|
309
|
+
switch (format || type) {
|
|
310
|
+
case Format.TypeFormat.Markdown:
|
|
311
|
+
return void 0;
|
|
312
|
+
case Format.TypeFormat.Time:
|
|
313
|
+
case Format.TypeFormat.Timestamp:
|
|
314
|
+
case Format.TypeFormat.DateTime:
|
|
315
|
+
case Format.TypeFormat.Date:
|
|
316
|
+
case Format.TypeFormat.Duration:
|
|
317
|
+
return [
|
|
318
|
+
"font-mono",
|
|
319
|
+
"text-right"
|
|
320
|
+
];
|
|
321
|
+
case Format.TypeFormat.Currency:
|
|
322
|
+
return [
|
|
323
|
+
"text-right"
|
|
324
|
+
];
|
|
325
|
+
case Format.TypeFormat.JSON:
|
|
326
|
+
case Format.TypeFormat.DID:
|
|
327
|
+
return [
|
|
328
|
+
"font-mono"
|
|
329
|
+
];
|
|
330
|
+
case TypeEnum.Number:
|
|
331
|
+
case TypeEnum.Boolean:
|
|
332
|
+
return [
|
|
333
|
+
"text-right",
|
|
334
|
+
"font-mono"
|
|
335
|
+
];
|
|
336
|
+
case TypeEnum.String:
|
|
337
|
+
return void 0;
|
|
338
|
+
case TypeEnum.Ref:
|
|
339
|
+
return void 0;
|
|
340
|
+
default:
|
|
341
|
+
return void 0;
|
|
374
342
|
}
|
|
375
343
|
};
|
|
344
|
+
var pathNotUniqueError = (path) => ({
|
|
345
|
+
path: "path",
|
|
346
|
+
message: `'${path}' is already present`
|
|
347
|
+
});
|
|
376
348
|
|
|
377
|
-
// src/
|
|
378
|
-
import {
|
|
379
|
-
import
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const { status, error } = getStatus();
|
|
393
|
-
const options = getValue3();
|
|
394
|
-
useEffect2(() => {
|
|
395
|
-
if (options === void 0) {
|
|
396
|
-
onValueChange(type, []);
|
|
349
|
+
// src/util/formatting.ts
|
|
350
|
+
import { format as formatDate } from "date-fns/format";
|
|
351
|
+
import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
|
|
352
|
+
var formatForDisplay = ({ type, format, value: value3, locale = void 0 }) => {
|
|
353
|
+
const formatScalar = (type2) => {
|
|
354
|
+
switch (type2) {
|
|
355
|
+
case TypeEnum2.Boolean:
|
|
356
|
+
return value3.toLocaleString().toUpperCase();
|
|
357
|
+
case TypeEnum2.Number:
|
|
358
|
+
return value3.toLocaleString(locale);
|
|
359
|
+
case TypeEnum2.String:
|
|
360
|
+
case TypeEnum2.Ref:
|
|
361
|
+
return String(value3);
|
|
362
|
+
default: {
|
|
363
|
+
return String(value3);
|
|
397
364
|
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
if (!format) {
|
|
368
|
+
return formatScalar(type);
|
|
369
|
+
}
|
|
370
|
+
switch (format) {
|
|
371
|
+
case Format2.TypeFormat.Boolean: {
|
|
372
|
+
return formatScalar(TypeEnum2.Boolean);
|
|
373
|
+
}
|
|
374
|
+
case Format2.TypeFormat.Number: {
|
|
375
|
+
return formatScalar(TypeEnum2.Number);
|
|
376
|
+
}
|
|
377
|
+
case Format2.TypeFormat.String:
|
|
378
|
+
case Format2.TypeFormat.Ref: {
|
|
379
|
+
return formatScalar(TypeEnum2.String);
|
|
380
|
+
}
|
|
381
|
+
case Format2.TypeFormat.Percent: {
|
|
382
|
+
return `${value3 * 100}%`;
|
|
383
|
+
}
|
|
384
|
+
case Format2.TypeFormat.Currency: {
|
|
385
|
+
return value3.toLocaleString(locale, {
|
|
386
|
+
style: "currency",
|
|
387
|
+
currency: "USD",
|
|
388
|
+
minimumFractionDigits: 2,
|
|
389
|
+
maximumFractionDigits: 2
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
case Format2.TypeFormat.Date: {
|
|
393
|
+
try {
|
|
394
|
+
return formatDate(new Date(value3), "yyyy-MM-dd");
|
|
395
|
+
} catch (error) {
|
|
396
|
+
return "Invalid Date";
|
|
408
397
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const newOption = {
|
|
416
|
-
id: newId,
|
|
417
|
-
title: "",
|
|
418
|
-
color: randomHue()
|
|
419
|
-
};
|
|
420
|
-
onValueChange(type, [
|
|
421
|
-
...options ?? [],
|
|
422
|
-
newOption
|
|
423
|
-
]);
|
|
424
|
-
setSelectedId(newId);
|
|
425
|
-
setIsNewOption(true);
|
|
426
|
-
}, [
|
|
427
|
-
options,
|
|
428
|
-
type,
|
|
429
|
-
onValueChange
|
|
430
|
-
]);
|
|
431
|
-
const handleDelete = useCallback2((id) => {
|
|
432
|
-
const newOptions = options?.filter((option) => option.id !== id) ?? [];
|
|
433
|
-
onValueChange(type, newOptions);
|
|
434
|
-
setSelectedId(null);
|
|
435
|
-
}, [
|
|
436
|
-
options,
|
|
437
|
-
type,
|
|
438
|
-
onValueChange
|
|
439
|
-
]);
|
|
440
|
-
const handleMove = useCallback2((from, to) => {
|
|
441
|
-
if (!options) {
|
|
442
|
-
return;
|
|
398
|
+
}
|
|
399
|
+
case Format2.TypeFormat.Time: {
|
|
400
|
+
try {
|
|
401
|
+
return formatDate(new Date(value3), "HH:mm:ss");
|
|
402
|
+
} catch (error) {
|
|
403
|
+
return "Invalid Time";
|
|
443
404
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
}, [
|
|
451
|
-
options,
|
|
452
|
-
type,
|
|
453
|
-
onValueChange
|
|
454
|
-
]);
|
|
455
|
-
const handleClick = useCallback2((id) => {
|
|
456
|
-
setSelectedId((current) => current === id ? null : id);
|
|
457
|
-
}, []);
|
|
458
|
-
const handleTitleChange = useCallback2((id) => (e) => {
|
|
459
|
-
const newOptions = options?.map((o) => o.id === id ? {
|
|
460
|
-
...o,
|
|
461
|
-
title: e.target.value
|
|
462
|
-
} : o);
|
|
463
|
-
onValueChange(type, newOptions ?? []);
|
|
464
|
-
}, [
|
|
465
|
-
options,
|
|
466
|
-
type,
|
|
467
|
-
onValueChange
|
|
468
|
-
]);
|
|
469
|
-
const handleKeyDown = useCallback2((e) => {
|
|
470
|
-
if (e.key === "Enter") {
|
|
471
|
-
setSelectedId(null);
|
|
405
|
+
}
|
|
406
|
+
case Format2.TypeFormat.DateTime: {
|
|
407
|
+
try {
|
|
408
|
+
return formatDate(new Date(value3), "yyyy-MM-dd HH:mm:ss");
|
|
409
|
+
} catch (error) {
|
|
410
|
+
return "Invalid DateTime";
|
|
472
411
|
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
color: hue
|
|
478
|
-
} : o);
|
|
479
|
-
onValueChange(type, newOptions ?? []);
|
|
480
|
-
}, [
|
|
481
|
-
options,
|
|
482
|
-
type,
|
|
483
|
-
onValueChange
|
|
484
|
-
]);
|
|
485
|
-
useEffect2(() => {
|
|
486
|
-
if (selected && isNewOption && inputRef.current) {
|
|
487
|
-
inputRef.current.focus();
|
|
488
|
-
setIsNewOption(false);
|
|
412
|
+
}
|
|
413
|
+
case Format2.TypeFormat.GeoPoint: {
|
|
414
|
+
if (value3 === null || value3 === void 0) {
|
|
415
|
+
return "";
|
|
489
416
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
items: options,
|
|
503
|
-
isItem: (item) => true,
|
|
504
|
-
onMove: handleMove
|
|
505
|
-
}, ({ items }) => /* @__PURE__ */ React5.createElement("div", {
|
|
506
|
-
role: "list",
|
|
507
|
-
className: "w-full overflow-auto"
|
|
508
|
-
}, items?.map((item) => /* @__PURE__ */ React5.createElement("div", {
|
|
509
|
-
key: item.id
|
|
510
|
-
}, /* @__PURE__ */ React5.createElement(List.Item, {
|
|
511
|
-
role: "button",
|
|
512
|
-
item,
|
|
513
|
-
classNames: [
|
|
514
|
-
"p-1 plb-2",
|
|
515
|
-
"flex flex-col",
|
|
516
|
-
"cursor-pointer",
|
|
517
|
-
"hover:bg-hoverOverlay"
|
|
518
|
-
],
|
|
519
|
-
"aria-expanded": selected === item.id
|
|
520
|
-
}, /* @__PURE__ */ React5.createElement("div", {
|
|
521
|
-
className: "flex items-center"
|
|
522
|
-
}, /* @__PURE__ */ React5.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React5.createElement(List.ItemTitle, {
|
|
523
|
-
onClick: () => handleClick(item.id),
|
|
524
|
-
classNames: "flex-1"
|
|
525
|
-
}, /* @__PURE__ */ React5.createElement(Tag, {
|
|
526
|
-
palette: item.color
|
|
527
|
-
}, item.title || "\u200B")), /* @__PURE__ */ React5.createElement(Icon2, {
|
|
528
|
-
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
529
|
-
onClick: () => handleClick(item.id)
|
|
530
|
-
})), selected === item.id && /* @__PURE__ */ React5.createElement("div", {
|
|
531
|
-
className: "mis-4 mbs-2 flex flex-col gap-1"
|
|
532
|
-
}, /* @__PURE__ */ React5.createElement(Input5.Label, {
|
|
533
|
-
classNames: "text-xs"
|
|
534
|
-
}, t("select option label")), /* @__PURE__ */ React5.createElement("div", {
|
|
535
|
-
className: "flex flex-row items-center gap-1"
|
|
536
|
-
}, /* @__PURE__ */ React5.createElement(Input5.TextInput, {
|
|
537
|
-
placeholder: t("select option label placeholder"),
|
|
538
|
-
ref: selected === item.id ? inputRef : void 0,
|
|
539
|
-
value: item.title,
|
|
540
|
-
onChange: handleTitleChange(item.id),
|
|
541
|
-
onKeyDown: handleKeyDown,
|
|
542
|
-
classNames: "flex-1",
|
|
543
|
-
"data-no-submit": true
|
|
544
|
-
}), /* @__PURE__ */ React5.createElement(Toolbar.Root, {
|
|
545
|
-
classNames: "p-0 m-0 !is-auto"
|
|
546
|
-
}, /* @__PURE__ */ React5.createElement(HuePicker, {
|
|
547
|
-
value: item.color,
|
|
548
|
-
onChange: handleColorChange(item.id),
|
|
549
|
-
rootVariant: "toolbar-button"
|
|
550
|
-
})), /* @__PURE__ */ React5.createElement(IconButton, {
|
|
551
|
-
icon: "ph--trash--fill",
|
|
552
|
-
iconOnly: true,
|
|
553
|
-
label: t("select option delete"),
|
|
554
|
-
onClick: () => handleDelete(item.id)
|
|
555
|
-
})))))), /* @__PURE__ */ React5.createElement("div", {
|
|
556
|
-
role: "listitem"
|
|
557
|
-
}, /* @__PURE__ */ React5.createElement("div", {
|
|
558
|
-
role: "button",
|
|
559
|
-
className: mx4("p-1 plb-2", "flex flex-col", "cursor-pointer", "hover:bg-hoverOverlay"),
|
|
560
|
-
onClick: handleAdd
|
|
561
|
-
}, /* @__PURE__ */ React5.createElement("div", {
|
|
562
|
-
className: "flex items-center gap-1"
|
|
563
|
-
}, /* @__PURE__ */ React5.createElement(Icon2, {
|
|
564
|
-
icon: "ph--plus--regular"
|
|
565
|
-
}), /* @__PURE__ */ React5.createElement("span", {
|
|
566
|
-
className: "text-sm"
|
|
567
|
-
}, t("select option add")))))))));
|
|
568
|
-
} finally {
|
|
569
|
-
_effect.f();
|
|
570
|
-
}
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
// src/components/Form/custom/TupleInput.tsx
|
|
574
|
-
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
575
|
-
import React6 from "react";
|
|
576
|
-
import { Input as Input6 } from "@dxos/react-ui";
|
|
577
|
-
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
578
|
-
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
579
|
-
var gridCols = [
|
|
580
|
-
"grid-cols-1",
|
|
581
|
-
"grid-cols-2",
|
|
582
|
-
"grid-cols-3",
|
|
583
|
-
"grid-cols-4"
|
|
584
|
-
];
|
|
585
|
-
var TupleInput = ({ binding, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
586
|
-
var _effect = _useSignals6();
|
|
587
|
-
try {
|
|
588
|
-
const { status, error } = getStatus();
|
|
589
|
-
const values = getValue3() ?? {};
|
|
590
|
-
return /* @__PURE__ */ React6.createElement(Input6.Root, {
|
|
591
|
-
validationValence: status
|
|
592
|
-
}, /* @__PURE__ */ React6.createElement(InputHeader, {
|
|
593
|
-
error,
|
|
594
|
-
label
|
|
595
|
-
}), /* @__PURE__ */ React6.createElement("div", {
|
|
596
|
-
className: mx5("grid gap-2", gridCols[binding.length - 1])
|
|
597
|
-
}, binding.map((prop) => /* @__PURE__ */ React6.createElement(Input6.TextInput, {
|
|
598
|
-
key: prop,
|
|
599
|
-
type: "number",
|
|
600
|
-
disabled,
|
|
601
|
-
value: values[prop],
|
|
602
|
-
onChange: (event) => onValueChange(type, {
|
|
603
|
-
...values,
|
|
604
|
-
[prop]: safeParseFloat2(event.target.value, 0)
|
|
605
|
-
}),
|
|
606
|
-
onBlur
|
|
607
|
-
}))));
|
|
608
|
-
} finally {
|
|
609
|
-
_effect.f();
|
|
610
|
-
}
|
|
611
|
-
};
|
|
612
|
-
|
|
613
|
-
// src/components/Form/Defaults.tsx
|
|
614
|
-
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
615
|
-
import React7, { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2 } from "react";
|
|
616
|
-
import { Input as Input7, Select, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
617
|
-
var TextInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
618
|
-
var _effect = _useSignals7();
|
|
619
|
-
try {
|
|
620
|
-
const { status, error } = getStatus();
|
|
621
|
-
return disabled && !getValue3() ? null : disabled && inputOnly ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.Root, {
|
|
622
|
-
validationValence: status
|
|
623
|
-
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
624
|
-
error,
|
|
625
|
-
label
|
|
626
|
-
}), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextInput, {
|
|
627
|
-
disabled,
|
|
628
|
-
placeholder,
|
|
629
|
-
value: getValue3() ?? "",
|
|
630
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
631
|
-
onBlur
|
|
632
|
-
}), inputOnly && /* @__PURE__ */ React7.createElement(Input7.Validation, null, error));
|
|
633
|
-
} finally {
|
|
634
|
-
_effect.f();
|
|
417
|
+
if (Array.isArray(value3) && value3.length >= 2 && value3.every(Number.isFinite)) {
|
|
418
|
+
const { latitude, longitude } = GeoLocation2.fromGeoPoint(value3);
|
|
419
|
+
return `${latitude},${longitude}`;
|
|
420
|
+
}
|
|
421
|
+
return String(value3);
|
|
422
|
+
}
|
|
423
|
+
default: {
|
|
424
|
+
if (value3 === null || value3 === "undefined") {
|
|
425
|
+
return "";
|
|
426
|
+
}
|
|
427
|
+
return String(value3);
|
|
428
|
+
}
|
|
635
429
|
}
|
|
636
430
|
};
|
|
637
|
-
var
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
652
|
-
onBlur
|
|
653
|
-
}), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
|
|
654
|
-
} finally {
|
|
655
|
-
_effect.f();
|
|
431
|
+
var formatForEditing = ({ type, format, value: value3, locale = void 0 }) => {
|
|
432
|
+
const formatScalar = (type2) => {
|
|
433
|
+
switch (type2) {
|
|
434
|
+
case TypeEnum2.Boolean:
|
|
435
|
+
case TypeEnum2.Number:
|
|
436
|
+
case TypeEnum2.String:
|
|
437
|
+
case TypeEnum2.Ref:
|
|
438
|
+
return String(value3);
|
|
439
|
+
default:
|
|
440
|
+
return String(value3);
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
if (!format) {
|
|
444
|
+
return formatScalar(type);
|
|
656
445
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
446
|
+
switch (format) {
|
|
447
|
+
case Format2.TypeFormat.Boolean:
|
|
448
|
+
case Format2.TypeFormat.Number:
|
|
449
|
+
case Format2.TypeFormat.String:
|
|
450
|
+
case Format2.TypeFormat.Ref: {
|
|
451
|
+
return formatScalar(type);
|
|
452
|
+
}
|
|
453
|
+
case Format2.TypeFormat.Percent: {
|
|
454
|
+
return String(value3 * 100);
|
|
455
|
+
}
|
|
456
|
+
case Format2.TypeFormat.Currency: {
|
|
457
|
+
return String(value3);
|
|
458
|
+
}
|
|
459
|
+
case Format2.TypeFormat.DateTime: {
|
|
460
|
+
const date = new Date(value3);
|
|
461
|
+
return date.toISOString();
|
|
462
|
+
}
|
|
463
|
+
case Format2.TypeFormat.Date: {
|
|
464
|
+
const date = new Date(value3);
|
|
465
|
+
return date.toISOString().split("T")[0];
|
|
466
|
+
}
|
|
467
|
+
case Format2.TypeFormat.Time: {
|
|
468
|
+
const date = new Date(value3);
|
|
469
|
+
return date.toISOString().split("T")[1].split(".")[0];
|
|
470
|
+
}
|
|
471
|
+
case Format2.TypeFormat.GeoPoint: {
|
|
472
|
+
if (value3 === null || value3 === void 0) {
|
|
473
|
+
return "";
|
|
474
|
+
}
|
|
475
|
+
if (Array.isArray(value3) && value3.length >= 2 && value3.every(Number.isFinite)) {
|
|
476
|
+
const { latitude, longitude } = GeoLocation2.fromGeoPoint(value3);
|
|
477
|
+
return `${latitude},${longitude}`;
|
|
478
|
+
}
|
|
479
|
+
return String(value3);
|
|
480
|
+
}
|
|
481
|
+
default: {
|
|
482
|
+
return String(value3);
|
|
483
|
+
}
|
|
675
484
|
}
|
|
676
485
|
};
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
onValueChange
|
|
685
|
-
]);
|
|
686
|
-
return disabled && !value ? null : /* @__PURE__ */ React7.createElement(Input7.Root, {
|
|
687
|
-
validationValence: status
|
|
688
|
-
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
689
|
-
error,
|
|
690
|
-
label
|
|
691
|
-
}), disabled ? /* @__PURE__ */ React7.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value)?.label ?? String(value)) : /* @__PURE__ */ React7.createElement(Select.Root, {
|
|
692
|
-
value,
|
|
693
|
-
onValueChange: handleValueChange
|
|
694
|
-
}, /* @__PURE__ */ React7.createElement(Select.TriggerButton, {
|
|
695
|
-
classNames: "is-full",
|
|
696
|
-
disabled,
|
|
697
|
-
placeholder
|
|
698
|
-
}), /* @__PURE__ */ React7.createElement(Select.Portal, null, /* @__PURE__ */ React7.createElement(Select.Content, null, /* @__PURE__ */ React7.createElement(Select.Viewport, null, options?.map(({ value: value2, label: label2 }) => (
|
|
699
|
-
// NOTE: Numeric values are converted to and from strings.
|
|
700
|
-
/* @__PURE__ */ React7.createElement(Select.Option, {
|
|
701
|
-
key: String(value2),
|
|
702
|
-
value: String(value2)
|
|
703
|
-
}, label2 ?? String(value2))
|
|
704
|
-
)))))), inputOnly && /* @__PURE__ */ React7.createElement(Input7.DescriptionAndValidation, null, error));
|
|
705
|
-
} finally {
|
|
706
|
-
_effect.f();
|
|
707
|
-
}
|
|
486
|
+
|
|
487
|
+
// src/util/properties.ts
|
|
488
|
+
import * as Option from "effect/Option";
|
|
489
|
+
import { Annotation } from "@dxos/echo";
|
|
490
|
+
import { getProperties } from "@dxos/effect";
|
|
491
|
+
var getFormProperties = (ast) => {
|
|
492
|
+
return getProperties(ast).filter((prop) => Annotation.FormInputAnnotation.getFromAst(prop.type).pipe(Option.getOrElse(() => true)));
|
|
708
493
|
};
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
494
|
+
|
|
495
|
+
// src/util/refs.ts
|
|
496
|
+
import { Ref } from "@dxos/echo";
|
|
497
|
+
import { getArrayElementType, isArrayType } from "@dxos/effect";
|
|
498
|
+
var getRefProps = (ast) => {
|
|
499
|
+
if (isArrayType(ast)) {
|
|
500
|
+
const elementType = getArrayElementType(ast);
|
|
501
|
+
if (elementType) {
|
|
502
|
+
if (Ref.isRefType(elementType)) {
|
|
503
|
+
return {
|
|
504
|
+
ast: elementType,
|
|
505
|
+
isArray: true
|
|
506
|
+
};
|
|
719
507
|
}
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
adjustHeight();
|
|
728
|
-
}, [
|
|
729
|
-
getValue3(),
|
|
730
|
-
adjustHeight
|
|
731
|
-
]);
|
|
732
|
-
return /* @__PURE__ */ React7.createElement(Input7.Root, {
|
|
733
|
-
validationValence: status
|
|
734
|
-
}, !inputOnly && /* @__PURE__ */ React7.createElement(InputHeader, {
|
|
735
|
-
error,
|
|
736
|
-
label
|
|
737
|
-
}), disabled ? /* @__PURE__ */ React7.createElement("p", null, getValue3() ?? "") : /* @__PURE__ */ React7.createElement(Input7.TextArea, {
|
|
738
|
-
ref: textareaRef,
|
|
739
|
-
disabled,
|
|
740
|
-
placeholder,
|
|
741
|
-
value: getValue3() ?? "",
|
|
742
|
-
classNames: "min-bs-auto max-h-40 overflow-auto",
|
|
743
|
-
onChange: (event) => onValueChange(type, event.target.value),
|
|
744
|
-
onBlur,
|
|
745
|
-
style: {
|
|
746
|
-
resize: "none"
|
|
747
|
-
},
|
|
748
|
-
spellCheck: false
|
|
749
|
-
}), inputOnly && /* @__PURE__ */ React7.createElement(Input7.Validation, null, error));
|
|
750
|
-
} finally {
|
|
751
|
-
_effect.f();
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (Ref.isRefType(ast)) {
|
|
511
|
+
return {
|
|
512
|
+
ast,
|
|
513
|
+
isArray: false
|
|
514
|
+
};
|
|
752
515
|
}
|
|
516
|
+
return void 0;
|
|
753
517
|
};
|
|
754
518
|
|
|
755
|
-
// src/components/Form/
|
|
756
|
-
import { useSignals as
|
|
757
|
-
import
|
|
758
|
-
import
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
import {
|
|
762
|
-
import
|
|
763
|
-
import { IconButton as IconButton2, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
764
|
-
import { cardSpacing } from "@dxos/react-ui-stack";
|
|
765
|
-
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
519
|
+
// src/components/Form/fields/ArrayField.tsx
|
|
520
|
+
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
521
|
+
import * as Option3 from "effect/Option";
|
|
522
|
+
import * as SchemaAST2 from "effect/SchemaAST";
|
|
523
|
+
import React6, { useCallback as useCallback5 } from "react";
|
|
524
|
+
import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
|
|
525
|
+
import { invariant } from "@dxos/invariant";
|
|
526
|
+
import { IconButton as IconButton2, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
766
527
|
|
|
767
|
-
// src/components/Form/
|
|
768
|
-
import { useSignals as
|
|
769
|
-
import
|
|
770
|
-
import
|
|
771
|
-
import {
|
|
772
|
-
import { createJsonPath as
|
|
528
|
+
// src/components/Form/Form.tsx
|
|
529
|
+
import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
|
|
530
|
+
import { createContext } from "@radix-ui/react-context";
|
|
531
|
+
import * as Schema2 from "effect/Schema";
|
|
532
|
+
import React5, { useMemo as useMemo4, useRef } from "react";
|
|
533
|
+
import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
|
|
534
|
+
import { IconButton, ScrollArea, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
535
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
|
773
536
|
|
|
774
|
-
// src/hooks/
|
|
775
|
-
import {
|
|
776
|
-
import { useCallback
|
|
777
|
-
import { getValue
|
|
537
|
+
// src/hooks/useFormHandler.ts
|
|
538
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
539
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
540
|
+
import { getValue as getValue$, setValue as setValue$ } from "@dxos/echo/internal";
|
|
778
541
|
import { createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
779
|
-
import { invariant } from "@dxos/invariant";
|
|
780
542
|
import { log } from "@dxos/log";
|
|
543
|
+
import { useDefaultValue } from "@dxos/react-ui";
|
|
781
544
|
import { validateSchema } from "@dxos/schema";
|
|
782
|
-
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/
|
|
783
|
-
var
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
545
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useFormHandler.ts";
|
|
546
|
+
var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: defaultValuesProp, onValuesChanged, onValidate, onSave, onCancel, ...props }) => {
|
|
547
|
+
const [changed, setChanged] = useState({});
|
|
548
|
+
const [touched, setTouched] = useState({});
|
|
549
|
+
const [errors, setErrors] = useState({});
|
|
550
|
+
const [saving, setSaving] = useState(false);
|
|
551
|
+
const defaultValues = useDefaultValue(defaultValuesProp, () => ({}));
|
|
552
|
+
const [values, setValues] = useControllableState({
|
|
553
|
+
prop: valuesProp,
|
|
554
|
+
defaultProp: defaultValues,
|
|
555
|
+
onChange: () => {
|
|
556
|
+
setValues(valuesProp ?? defaultValues);
|
|
557
|
+
setChanged({});
|
|
558
|
+
setTouched({});
|
|
559
|
+
setErrors({});
|
|
560
|
+
setSaving(false);
|
|
561
|
+
}
|
|
792
562
|
});
|
|
793
|
-
const
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
initialValues
|
|
798
|
-
]);
|
|
799
|
-
const [touched, setTouched] = useState3(createKeySet(initialValues, false));
|
|
800
|
-
const [changed, setChanged] = useState3(createKeySet(initialValues, false));
|
|
801
|
-
const [errors, setErrors] = useState3({});
|
|
802
|
-
const [saving, setSaving] = useState3(false);
|
|
803
|
-
const validate = useCallback4((values2) => {
|
|
563
|
+
const validate = useCallback((values2) => {
|
|
564
|
+
if (!schema) {
|
|
565
|
+
return false;
|
|
566
|
+
}
|
|
804
567
|
let errors2 = validateSchema(schema, values2) ?? [];
|
|
568
|
+
log("validate", {
|
|
569
|
+
values: values2,
|
|
570
|
+
errors: errors2
|
|
571
|
+
}, {
|
|
572
|
+
F: __dxlog_file,
|
|
573
|
+
L: 149,
|
|
574
|
+
S: void 0,
|
|
575
|
+
C: (f, a) => f(...a)
|
|
576
|
+
});
|
|
805
577
|
if (errors2.length === 0 && onValidate) {
|
|
806
578
|
const validatedValues = values2;
|
|
807
579
|
errors2 = onValidate(validatedValues) ?? [];
|
|
@@ -813,36 +585,38 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
813
585
|
schema,
|
|
814
586
|
onValidate
|
|
815
587
|
]);
|
|
816
|
-
const [
|
|
817
|
-
|
|
588
|
+
const [schemaChanged, setSchemaChanged] = useState(false);
|
|
589
|
+
useEffect(() => setSchemaChanged(true), [
|
|
818
590
|
schema
|
|
819
591
|
]);
|
|
820
|
-
|
|
821
|
-
if (
|
|
592
|
+
useEffect(() => {
|
|
593
|
+
if (schemaChanged) {
|
|
822
594
|
validate(values);
|
|
823
|
-
|
|
595
|
+
setSchemaChanged(false);
|
|
824
596
|
}
|
|
825
597
|
}, [
|
|
598
|
+
validate,
|
|
826
599
|
values,
|
|
827
|
-
|
|
600
|
+
schemaChanged
|
|
828
601
|
]);
|
|
829
|
-
const
|
|
602
|
+
const isValid = useMemo(() => {
|
|
830
603
|
return Object.keys(errors).length === 0;
|
|
831
604
|
}, [
|
|
832
605
|
errors
|
|
833
606
|
]);
|
|
834
|
-
const canSave =
|
|
607
|
+
const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors.
|
|
835
608
|
!Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
|
|
836
609
|
touched,
|
|
837
610
|
errors,
|
|
838
611
|
saving
|
|
839
612
|
]);
|
|
840
|
-
const handleSave =
|
|
613
|
+
const handleSave = useCallback(async () => {
|
|
841
614
|
if (validate(values)) {
|
|
842
615
|
setSaving(true);
|
|
843
616
|
try {
|
|
844
617
|
await onSave?.(values, {
|
|
845
|
-
changed
|
|
618
|
+
changed,
|
|
619
|
+
isValid
|
|
846
620
|
});
|
|
847
621
|
} finally {
|
|
848
622
|
setSaving(false);
|
|
@@ -852,11 +626,17 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
852
626
|
values,
|
|
853
627
|
validate,
|
|
854
628
|
onSave,
|
|
855
|
-
changed
|
|
629
|
+
changed,
|
|
630
|
+
isValid
|
|
856
631
|
]);
|
|
857
|
-
const
|
|
632
|
+
const handleCancel = useCallback(() => {
|
|
633
|
+
onCancel?.();
|
|
634
|
+
}, [
|
|
635
|
+
onCancel
|
|
636
|
+
]);
|
|
637
|
+
const getStatus = useCallback((path) => {
|
|
858
638
|
const jsonPath = Array.isArray(path) ? createJsonPath(path) : path;
|
|
859
|
-
const
|
|
639
|
+
const [_, error] = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`)) ?? [];
|
|
860
640
|
const isTouched = touched[jsonPath];
|
|
861
641
|
if (!isTouched) {
|
|
862
642
|
return {
|
|
@@ -865,111 +645,121 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
865
645
|
};
|
|
866
646
|
}
|
|
867
647
|
return {
|
|
868
|
-
status:
|
|
869
|
-
error:
|
|
648
|
+
status: error ? "error" : void 0,
|
|
649
|
+
error: error ? error ?? void 0 : void 0
|
|
870
650
|
};
|
|
871
651
|
}, [
|
|
872
652
|
errors,
|
|
873
653
|
touched
|
|
874
654
|
]);
|
|
875
|
-
const
|
|
876
|
-
return getValue(values, createJsonPath(path));
|
|
655
|
+
const getValue = useCallback((path) => {
|
|
656
|
+
return getValue$(values, createJsonPath(path));
|
|
877
657
|
}, [
|
|
878
658
|
values
|
|
879
659
|
]);
|
|
880
|
-
const onValueChange =
|
|
660
|
+
const onValueChange = useCallback((path, type, value3) => {
|
|
661
|
+
log("onValueChange", {
|
|
662
|
+
path,
|
|
663
|
+
value: value3
|
|
664
|
+
}, {
|
|
665
|
+
F: __dxlog_file,
|
|
666
|
+
L: 248,
|
|
667
|
+
S: void 0,
|
|
668
|
+
C: (f, a) => f(...a)
|
|
669
|
+
});
|
|
881
670
|
const jsonPath = createJsonPath(path);
|
|
882
|
-
let parsedValue =
|
|
671
|
+
let parsedValue = value3;
|
|
883
672
|
try {
|
|
884
|
-
if (type === "
|
|
885
|
-
parsedValue = parseFloat(
|
|
673
|
+
if (type._tag === "NumberKeyword") {
|
|
674
|
+
parsedValue = parseFloat(value3) || 0;
|
|
886
675
|
}
|
|
887
676
|
} catch (err) {
|
|
888
677
|
log.catch(err, void 0, {
|
|
889
678
|
F: __dxlog_file,
|
|
890
|
-
L:
|
|
679
|
+
L: 257,
|
|
891
680
|
S: void 0,
|
|
892
681
|
C: (f, a) => f(...a)
|
|
893
682
|
});
|
|
894
683
|
parsedValue = void 0;
|
|
895
684
|
}
|
|
896
685
|
const newValues = {
|
|
897
|
-
...setValue(values, jsonPath, parsedValue)
|
|
686
|
+
...setValue$(values, jsonPath, parsedValue)
|
|
898
687
|
};
|
|
899
688
|
setValues(newValues);
|
|
900
|
-
|
|
901
|
-
...
|
|
689
|
+
const newChanged = {
|
|
690
|
+
...changed,
|
|
902
691
|
[jsonPath]: true
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
692
|
+
};
|
|
693
|
+
setChanged({
|
|
694
|
+
...changed,
|
|
695
|
+
[jsonPath]: true
|
|
696
|
+
});
|
|
697
|
+
const isValid2 = validate(newValues);
|
|
698
|
+
onValuesChanged?.(newValues, {
|
|
699
|
+
isValid: isValid2,
|
|
700
|
+
changed: newChanged
|
|
701
|
+
});
|
|
911
702
|
}, [
|
|
912
703
|
values,
|
|
913
|
-
|
|
704
|
+
changed,
|
|
914
705
|
validate,
|
|
915
|
-
|
|
916
|
-
changed
|
|
706
|
+
onValuesChanged
|
|
917
707
|
]);
|
|
918
|
-
const
|
|
708
|
+
const onBlur = useCallback(async (path) => {
|
|
919
709
|
const jsonPath = createJsonPath(path);
|
|
920
710
|
setTouched((touched2) => ({
|
|
921
711
|
...touched2,
|
|
922
712
|
[jsonPath]: true
|
|
923
713
|
}));
|
|
924
|
-
validate(values);
|
|
714
|
+
const isValid2 = validate(values);
|
|
715
|
+
if (Object.keys(changed).length > 0 && isValid2 && autoSave) {
|
|
716
|
+
await onSave?.(values, {
|
|
717
|
+
changed,
|
|
718
|
+
isValid: isValid2
|
|
719
|
+
});
|
|
720
|
+
}
|
|
925
721
|
}, [
|
|
926
722
|
validate,
|
|
927
|
-
values
|
|
723
|
+
values,
|
|
724
|
+
changed,
|
|
725
|
+
autoSave,
|
|
726
|
+
onSave
|
|
928
727
|
]);
|
|
929
|
-
return
|
|
728
|
+
return useMemo(() => ({
|
|
930
729
|
// State.
|
|
730
|
+
schema,
|
|
931
731
|
values,
|
|
932
732
|
errors,
|
|
933
733
|
touched,
|
|
934
734
|
changed,
|
|
735
|
+
isValid,
|
|
935
736
|
canSave,
|
|
936
|
-
|
|
737
|
+
autoSave,
|
|
937
738
|
// Actions.
|
|
938
|
-
handleSave,
|
|
739
|
+
onSave: handleSave,
|
|
740
|
+
onCancel: handleCancel,
|
|
939
741
|
// Field utils.
|
|
940
742
|
getStatus,
|
|
941
|
-
getValue
|
|
743
|
+
getValue,
|
|
744
|
+
onBlur,
|
|
942
745
|
onValueChange,
|
|
943
|
-
|
|
746
|
+
...props
|
|
944
747
|
}), [
|
|
748
|
+
schema,
|
|
945
749
|
values,
|
|
946
750
|
errors,
|
|
947
751
|
touched,
|
|
948
752
|
changed,
|
|
949
753
|
canSave,
|
|
950
|
-
|
|
951
|
-
handleSave,
|
|
754
|
+
isValid,
|
|
952
755
|
getStatus,
|
|
953
|
-
|
|
756
|
+
getValue,
|
|
757
|
+
onBlur,
|
|
954
758
|
onValueChange,
|
|
955
|
-
|
|
759
|
+
onSave,
|
|
760
|
+
onCancel
|
|
956
761
|
]);
|
|
957
762
|
};
|
|
958
|
-
var createKeySet = (obj, value) => {
|
|
959
|
-
invariant(obj, void 0, {
|
|
960
|
-
F: __dxlog_file,
|
|
961
|
-
L: 275,
|
|
962
|
-
S: void 0,
|
|
963
|
-
A: [
|
|
964
|
-
"obj",
|
|
965
|
-
""
|
|
966
|
-
]
|
|
967
|
-
});
|
|
968
|
-
return Object.keys(obj).reduce((acc, key) => ({
|
|
969
|
-
...acc,
|
|
970
|
-
[key]: value
|
|
971
|
-
}), {});
|
|
972
|
-
};
|
|
973
763
|
var flatMap = (errors) => {
|
|
974
764
|
return errors.reduce((result, { path, message }) => {
|
|
975
765
|
const jsonPath = fromEffectValidationPath(path);
|
|
@@ -980,645 +770,1052 @@ var flatMap = (errors) => {
|
|
|
980
770
|
}, {});
|
|
981
771
|
};
|
|
982
772
|
|
|
983
|
-
// src/hooks/
|
|
984
|
-
import { useCallback as
|
|
985
|
-
import {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
const { objects } = await query.run();
|
|
995
|
-
return objects.map((object) => {
|
|
996
|
-
const dxn = getObjectDXN(object);
|
|
997
|
-
if (!dxn) {
|
|
998
|
-
return void 0;
|
|
773
|
+
// src/hooks/useKeyHandler.tsx
|
|
774
|
+
import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
|
|
775
|
+
import { addEventListener } from "@dxos/async";
|
|
776
|
+
var useKeyHandler = (formElement, form) => {
|
|
777
|
+
const handleKeyDown = useCallback2((event) => {
|
|
778
|
+
switch (event.key) {
|
|
779
|
+
case "Enter": {
|
|
780
|
+
if (event.metaKey && form.canSave) {
|
|
781
|
+
form.onSave();
|
|
782
|
+
}
|
|
783
|
+
break;
|
|
999
784
|
}
|
|
1000
|
-
|
|
1001
|
-
dxn,
|
|
1002
|
-
label: object?.name ?? object?.id ?? ""
|
|
1003
|
-
};
|
|
1004
|
-
return item;
|
|
1005
|
-
}).filter(isNonNullable);
|
|
785
|
+
}
|
|
1006
786
|
}, [
|
|
1007
|
-
|
|
787
|
+
form.isValid,
|
|
788
|
+
form.canSave,
|
|
789
|
+
form.onSave,
|
|
790
|
+
form.autoSave
|
|
791
|
+
]);
|
|
792
|
+
useEffect2(() => {
|
|
793
|
+
if (!formElement) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
return addEventListener(formElement, "keydown", handleKeyDown);
|
|
797
|
+
}, [
|
|
798
|
+
formElement,
|
|
799
|
+
handleKeyDown
|
|
1008
800
|
]);
|
|
1009
801
|
};
|
|
1010
802
|
|
|
1011
803
|
// src/hooks/useQueryRefOptions.ts
|
|
1012
|
-
import {
|
|
804
|
+
import { useCallback as useCallback3, useState as useState2 } from "react";
|
|
1013
805
|
import { log as log2 } from "@dxos/log";
|
|
806
|
+
import { useAsyncEffect } from "@dxos/react-ui";
|
|
1014
807
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/hooks/useQueryRefOptions.ts";
|
|
1015
|
-
var useQueryRefOptions = ({
|
|
1016
|
-
const [options, setOptions] =
|
|
1017
|
-
const [loading, setLoading] =
|
|
1018
|
-
|
|
1019
|
-
|
|
808
|
+
var useQueryRefOptions = ({ typename, onQueryRefOptions }) => {
|
|
809
|
+
const [options, setOptions] = useState2([]);
|
|
810
|
+
const [loading, setLoading] = useState2(false);
|
|
811
|
+
const [state, setState] = useState2({});
|
|
812
|
+
const update = useCallback3(() => setState({}), []);
|
|
813
|
+
useAsyncEffect(async () => {
|
|
814
|
+
if (!typename || !onQueryRefOptions) {
|
|
1020
815
|
return;
|
|
1021
816
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
|
|
817
|
+
setLoading(true);
|
|
818
|
+
try {
|
|
819
|
+
const options2 = await onQueryRefOptions({
|
|
820
|
+
typename
|
|
821
|
+
});
|
|
822
|
+
log2("options", {
|
|
823
|
+
options: options2.length
|
|
824
|
+
}, {
|
|
825
|
+
F: __dxlog_file2,
|
|
826
|
+
L: 50,
|
|
827
|
+
S: void 0,
|
|
828
|
+
C: (f, a) => f(...a)
|
|
829
|
+
});
|
|
830
|
+
setOptions(options2.map((option) => {
|
|
831
|
+
const dxn = option.dxn.toString();
|
|
832
|
+
return {
|
|
833
|
+
id: dxn,
|
|
834
|
+
label: option.label ?? dxn,
|
|
835
|
+
hue: "neutral"
|
|
836
|
+
};
|
|
837
|
+
}));
|
|
838
|
+
} catch (error) {
|
|
839
|
+
log2.error("Failed to fetch ref options:", error, {
|
|
840
|
+
F: __dxlog_file2,
|
|
841
|
+
L: 62,
|
|
842
|
+
S: void 0,
|
|
843
|
+
C: (f, a) => f(...a)
|
|
844
|
+
});
|
|
845
|
+
setOptions([]);
|
|
846
|
+
} finally {
|
|
847
|
+
setLoading(false);
|
|
848
|
+
}
|
|
849
|
+
}, [
|
|
850
|
+
typename,
|
|
851
|
+
onQueryRefOptions,
|
|
852
|
+
state
|
|
853
|
+
]);
|
|
854
|
+
return {
|
|
855
|
+
options,
|
|
856
|
+
update,
|
|
857
|
+
loading
|
|
858
|
+
};
|
|
859
|
+
};
|
|
860
|
+
|
|
861
|
+
// src/hooks/useRefQueryOptions.ts
|
|
862
|
+
import { useCallback as useCallback4 } from "react";
|
|
863
|
+
import { Obj } from "@dxos/echo";
|
|
864
|
+
import { Filter } from "@dxos/react-client/echo";
|
|
865
|
+
import { isNonNullable } from "@dxos/util";
|
|
866
|
+
var useRefQueryOptions = ({ space }) => {
|
|
867
|
+
return useCallback4(async ({ typename }) => {
|
|
868
|
+
if (!space) {
|
|
869
|
+
return [];
|
|
870
|
+
}
|
|
871
|
+
const query = space.db.query(Filter.typename(typename));
|
|
872
|
+
const objects = await query.run();
|
|
873
|
+
return objects.map((object) => {
|
|
874
|
+
const dxn = Obj.getDXN(object);
|
|
875
|
+
if (!dxn) {
|
|
876
|
+
return void 0;
|
|
1044
877
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
878
|
+
return {
|
|
879
|
+
dxn,
|
|
880
|
+
label: Obj.getLabel(object) ?? object?.id ?? ""
|
|
881
|
+
};
|
|
882
|
+
}).filter(isNonNullable);
|
|
1047
883
|
}, [
|
|
1048
|
-
|
|
1049
|
-
onQueryRefOptions
|
|
884
|
+
space
|
|
1050
885
|
]);
|
|
1051
|
-
return {
|
|
1052
|
-
options,
|
|
1053
|
-
loading
|
|
1054
|
-
};
|
|
1055
886
|
};
|
|
1056
887
|
|
|
1057
|
-
// src/components/Form/
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
};
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
return getValue2(formValues, jsonPath);
|
|
1066
|
-
};
|
|
1067
|
-
var useInputProps = (path = []) => {
|
|
1068
|
-
const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
|
|
1069
|
-
const stablePath = useMemo3(() => path, [
|
|
1070
|
-
Array.isArray(path) ? path.join(".") : path
|
|
1071
|
-
]);
|
|
1072
|
-
return useMemo3(() => ({
|
|
1073
|
-
getStatus: () => getStatus(stablePath),
|
|
1074
|
-
getValue: () => getFormValue(stablePath),
|
|
1075
|
-
onValueChange: (type, value) => onValueChange(stablePath, type, value),
|
|
1076
|
-
onBlur: () => onTouched(stablePath)
|
|
1077
|
-
}), [
|
|
1078
|
-
getStatus,
|
|
1079
|
-
getFormValue,
|
|
1080
|
-
onValueChange,
|
|
1081
|
-
onTouched,
|
|
1082
|
-
stablePath
|
|
1083
|
-
]);
|
|
1084
|
-
};
|
|
1085
|
-
var FormProvider = ({ children, formRef, autoSave, ...formOptions }) => {
|
|
1086
|
-
var _effect = _useSignals8();
|
|
888
|
+
// src/components/Form/FormFieldComponent.tsx
|
|
889
|
+
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
890
|
+
import React2, { Component } from "react";
|
|
891
|
+
import { Icon, Input as Input2, Tooltip } from "@dxos/react-ui";
|
|
892
|
+
import { labelSpacing } from "@dxos/react-ui-stack";
|
|
893
|
+
import { errorText, mx as mx2 } from "@dxos/react-ui-theme";
|
|
894
|
+
var FormFieldLabel = ({ label, error, readonly, asChild }) => {
|
|
895
|
+
var _effect = _useSignals2();
|
|
1087
896
|
try {
|
|
1088
|
-
const
|
|
1089
|
-
const
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
autoSave
|
|
1107
|
-
]);
|
|
1108
|
-
useEffect6(() => {
|
|
1109
|
-
if (!formRef?.current) {
|
|
1110
|
-
return;
|
|
1111
|
-
}
|
|
1112
|
-
const formElement = formRef.current;
|
|
1113
|
-
formElement.addEventListener("keydown", handleKeyDown);
|
|
1114
|
-
return () => formElement.removeEventListener("keydown", handleKeyDown);
|
|
1115
|
-
}, [
|
|
1116
|
-
formRef,
|
|
1117
|
-
form.canSave,
|
|
1118
|
-
form.formIsValid,
|
|
1119
|
-
form.handleSave,
|
|
1120
|
-
autoSave
|
|
1121
|
-
]);
|
|
1122
|
-
return /* @__PURE__ */ React8.createElement(FormContext.Provider, {
|
|
1123
|
-
value: form
|
|
1124
|
-
}, children);
|
|
897
|
+
const Label = readonly || asChild ? "span" : Input2.Label;
|
|
898
|
+
const labelProps = readonly || asChild ? {
|
|
899
|
+
className: "text-description text-sm"
|
|
900
|
+
} : {
|
|
901
|
+
classNames: "!mlb-0 text-sm"
|
|
902
|
+
};
|
|
903
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
904
|
+
role: "none",
|
|
905
|
+
className: mx2("flex justify-between items-center", labelSpacing)
|
|
906
|
+
}, /* @__PURE__ */ React2.createElement(Label, labelProps, label), error && /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
|
|
907
|
+
asChild: true,
|
|
908
|
+
content: error,
|
|
909
|
+
side: "bottom"
|
|
910
|
+
}, /* @__PURE__ */ React2.createElement(Icon, {
|
|
911
|
+
icon: "ph--warning--regular",
|
|
912
|
+
size: 4,
|
|
913
|
+
classNames: errorText
|
|
914
|
+
})));
|
|
1125
915
|
} finally {
|
|
1126
916
|
_effect.f();
|
|
1127
917
|
}
|
|
1128
918
|
};
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
var
|
|
1132
|
-
var _effect = _useSignals9();
|
|
919
|
+
FormFieldLabel.displayName = "Form.FieldLabel";
|
|
920
|
+
var FormFieldWrapper = (props) => {
|
|
921
|
+
var _effect = _useSignals2();
|
|
1133
922
|
try {
|
|
1134
|
-
const {
|
|
1135
|
-
const {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
onClick: handleSave
|
|
1151
|
-
}));
|
|
923
|
+
const { children, readonly, layout, label, getStatus, getValue } = props;
|
|
924
|
+
const { status, error } = getStatus();
|
|
925
|
+
const value3 = getValue();
|
|
926
|
+
if (layout === "static" && value3 == null) {
|
|
927
|
+
return null;
|
|
928
|
+
}
|
|
929
|
+
const str = String(value3 ?? "");
|
|
930
|
+
return /* @__PURE__ */ React2.createElement(Input2.Root, {
|
|
931
|
+
validationValence: status
|
|
932
|
+
}, layout !== "inline" && /* @__PURE__ */ React2.createElement(FormFieldLabel, {
|
|
933
|
+
error,
|
|
934
|
+
readonly,
|
|
935
|
+
label
|
|
936
|
+
}), layout === "static" ? /* @__PURE__ */ React2.createElement("p", null, str) : children ? children({
|
|
937
|
+
value: value3
|
|
938
|
+
}) : null, layout === "full" && /* @__PURE__ */ React2.createElement(Input2.DescriptionAndValidation, null, /* @__PURE__ */ React2.createElement(Input2.Validation, null, error)));
|
|
1152
939
|
} finally {
|
|
1153
940
|
_effect.f();
|
|
1154
941
|
}
|
|
1155
942
|
};
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
import React12, { forwardRef, useMemo as useMemo5 } from "react";
|
|
1162
|
-
import { createJsonPath as createJsonPath3, findNode as findNode3, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
1163
|
-
import { mx as mx8 } from "@dxos/react-ui-theme";
|
|
1164
|
-
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
1165
|
-
import { isNotFalsy } from "@dxos/util";
|
|
1166
|
-
|
|
1167
|
-
// src/components/Form/ArrayField.tsx
|
|
1168
|
-
import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
|
|
1169
|
-
import { SchemaAST as SchemaAST3, pipe } from "effect";
|
|
1170
|
-
import { capitalize } from "effect/String";
|
|
1171
|
-
import React10, { Fragment, useCallback as useCallback7 } from "react";
|
|
1172
|
-
import { findNode as findNode2, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
1173
|
-
import { invariant as invariant2 } from "@dxos/invariant";
|
|
1174
|
-
import { IconButton as IconButton3, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1175
|
-
import { getSchemaProperties } from "@dxos/schema";
|
|
1176
|
-
|
|
1177
|
-
// src/util/field.ts
|
|
1178
|
-
import { FormatEnum, GeoLocation as GeoLocation2, TypeEnum } from "@dxos/echo-schema";
|
|
1179
|
-
var parseValue = ({ type, format, value }) => {
|
|
1180
|
-
if (value === void 0 || value === null || value === "") {
|
|
1181
|
-
return void 0;
|
|
943
|
+
var FormFieldErrorBoundary = class extends Component {
|
|
944
|
+
static getDerivedStateFromError(error) {
|
|
945
|
+
return {
|
|
946
|
+
error
|
|
947
|
+
};
|
|
1182
948
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
case TypeEnum.Boolean: {
|
|
1186
|
-
if (typeof value === "string") {
|
|
1187
|
-
const lowercaseValue = value.toLowerCase();
|
|
1188
|
-
if (lowercaseValue === "0" || lowercaseValue === "false") {
|
|
1189
|
-
return false;
|
|
1190
|
-
} else if (lowercaseValue === "1" || lowercaseValue === "true") {
|
|
1191
|
-
return true;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
return Boolean(value);
|
|
1195
|
-
}
|
|
1196
|
-
case TypeEnum.Number: {
|
|
1197
|
-
const cleaned = typeof value === "string" ? value.replace(/[^0-9.-]+/g, "") : value;
|
|
1198
|
-
const num = Number(cleaned);
|
|
1199
|
-
return Number.isNaN(num) ? null : num;
|
|
1200
|
-
}
|
|
1201
|
-
case TypeEnum.String:
|
|
1202
|
-
case TypeEnum.Ref:
|
|
1203
|
-
return String(value);
|
|
1204
|
-
default: {
|
|
1205
|
-
return value;
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
949
|
+
state = {
|
|
950
|
+
error: void 0
|
|
1208
951
|
};
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
switch (format) {
|
|
1213
|
-
case FormatEnum.Boolean:
|
|
1214
|
-
return parseScalar(TypeEnum.Boolean);
|
|
1215
|
-
case FormatEnum.Number:
|
|
1216
|
-
case FormatEnum.Percent:
|
|
1217
|
-
case FormatEnum.Currency:
|
|
1218
|
-
return parseScalar(TypeEnum.Number);
|
|
1219
|
-
case FormatEnum.String:
|
|
1220
|
-
case FormatEnum.Markdown: {
|
|
1221
|
-
return parseScalar(TypeEnum.String);
|
|
1222
|
-
}
|
|
1223
|
-
case FormatEnum.Ref:
|
|
1224
|
-
throw new Error(`unexpected format: ${FormatEnum.Ref}`);
|
|
1225
|
-
case FormatEnum.DateTime:
|
|
1226
|
-
case FormatEnum.Date:
|
|
1227
|
-
case FormatEnum.Time:
|
|
1228
|
-
case FormatEnum.Timestamp: {
|
|
1229
|
-
const date = new Date(value);
|
|
1230
|
-
return isNaN(date.getTime()) ? null : date;
|
|
1231
|
-
}
|
|
1232
|
-
case FormatEnum.GeoPoint: {
|
|
1233
|
-
if (typeof value === "string") {
|
|
1234
|
-
const cleaned = value.replace(/[^0-9.,-]+/g, "");
|
|
1235
|
-
const parts = cleaned.split(",");
|
|
1236
|
-
if (parts.length === 2) {
|
|
1237
|
-
const lat = parseFloat(parts[0]);
|
|
1238
|
-
const long = parseFloat(parts[1]);
|
|
1239
|
-
if (!isNaN(lat) && !isNaN(long)) {
|
|
1240
|
-
return GeoLocation2.toGeoPoint({
|
|
1241
|
-
latitude: lat,
|
|
1242
|
-
longitude: long
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
return [
|
|
1248
|
-
0,
|
|
1249
|
-
0
|
|
1250
|
-
];
|
|
1251
|
-
}
|
|
1252
|
-
default: {
|
|
1253
|
-
return value;
|
|
952
|
+
componentDidUpdate(prevProps) {
|
|
953
|
+
if (prevProps.path !== this.props.path) {
|
|
954
|
+
this.resetError();
|
|
1254
955
|
}
|
|
1255
956
|
}
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
"font-mono"
|
|
1264
|
-
];
|
|
1265
|
-
case TypeEnum.Boolean:
|
|
1266
|
-
return [
|
|
1267
|
-
"text-right",
|
|
1268
|
-
"font-mono"
|
|
1269
|
-
];
|
|
1270
|
-
case TypeEnum.String:
|
|
1271
|
-
return void 0;
|
|
1272
|
-
case TypeEnum.Ref:
|
|
1273
|
-
return void 0;
|
|
1274
|
-
default: {
|
|
1275
|
-
return void 0;
|
|
1276
|
-
}
|
|
957
|
+
render() {
|
|
958
|
+
if (this.state.error) {
|
|
959
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
960
|
+
className: "flex gap-2 border border-roseFill font-mono text-sm"
|
|
961
|
+
}, /* @__PURE__ */ React2.createElement("span", {
|
|
962
|
+
className: "bg-roseFill text-surfaceText pli-1 font-thin"
|
|
963
|
+
}, "ERROR"), String(this.props.path?.join(".")));
|
|
1277
964
|
}
|
|
965
|
+
return this.props.children;
|
|
1278
966
|
}
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
case FormatEnum.Timestamp:
|
|
1284
|
-
case FormatEnum.DateTime:
|
|
1285
|
-
case FormatEnum.Date:
|
|
1286
|
-
case FormatEnum.Duration:
|
|
1287
|
-
return [
|
|
1288
|
-
"font-mono",
|
|
1289
|
-
"text-right"
|
|
1290
|
-
];
|
|
1291
|
-
case FormatEnum.Currency:
|
|
1292
|
-
return [
|
|
1293
|
-
"text-right"
|
|
1294
|
-
];
|
|
1295
|
-
case FormatEnum.JSON:
|
|
1296
|
-
case FormatEnum.DID:
|
|
1297
|
-
return [
|
|
1298
|
-
"font-mono"
|
|
1299
|
-
];
|
|
1300
|
-
default:
|
|
1301
|
-
return void 0;
|
|
967
|
+
resetError() {
|
|
968
|
+
this.setState({
|
|
969
|
+
error: void 0
|
|
970
|
+
});
|
|
1302
971
|
}
|
|
1303
972
|
};
|
|
1304
|
-
var pathNotUniqueError = (path) => ({
|
|
1305
|
-
path: "path",
|
|
1306
|
-
message: `'${path}' is already present`
|
|
1307
|
-
});
|
|
1308
973
|
|
|
1309
|
-
// src/
|
|
1310
|
-
import {
|
|
1311
|
-
import
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
974
|
+
// src/components/Form/FormFieldSet.tsx
|
|
975
|
+
import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
|
|
976
|
+
import React4, { forwardRef, useMemo as useMemo3 } from "react";
|
|
977
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
978
|
+
import { isTruthy } from "@dxos/util";
|
|
979
|
+
|
|
980
|
+
// src/components/Form/FormField.tsx
|
|
981
|
+
import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
|
|
982
|
+
import * as Match from "effect/Match";
|
|
983
|
+
import * as Option2 from "effect/Option";
|
|
984
|
+
import * as Schema from "effect/Schema";
|
|
985
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
986
|
+
import * as String2 from "effect/String";
|
|
987
|
+
import React3, { useMemo as useMemo2 } from "react";
|
|
988
|
+
import { Format as Format3 } from "@dxos/echo";
|
|
989
|
+
import { createJsonPath as createJsonPath2, findNode, getAnnotation, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion, isNestedType } from "@dxos/effect";
|
|
990
|
+
import { useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
991
|
+
var FormField = (props) => {
|
|
992
|
+
var _effect = _useSignals3();
|
|
993
|
+
try {
|
|
994
|
+
const { type, name, path, projection, fieldMap, fieldProvider, readonly, layout, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onCreate, onQueryRefOptions } = props;
|
|
995
|
+
const { t } = useTranslation2(translationKey);
|
|
996
|
+
const title = getAnnotation(SchemaAST.TitleAnnotationId)(type);
|
|
997
|
+
const description = getAnnotation(SchemaAST.DescriptionAnnotationId)(type);
|
|
998
|
+
const examples = getAnnotation(SchemaAST.ExamplesAnnotationId)(type);
|
|
999
|
+
const label = useMemo2(() => title ?? String2.capitalize(name), [
|
|
1000
|
+
title,
|
|
1001
|
+
name
|
|
1002
|
+
]);
|
|
1003
|
+
const placeholder = useMemo2(() => examples?.length ? `${t("example placeholder")}: ${examples[0]}` : description ?? label, [
|
|
1004
|
+
examples,
|
|
1005
|
+
description,
|
|
1006
|
+
label
|
|
1007
|
+
]);
|
|
1008
|
+
const fieldState = useFormFieldState(FormField.displayName, path);
|
|
1009
|
+
const fieldProps = {
|
|
1010
|
+
type,
|
|
1011
|
+
format: Format3.FormatAnnotation.getFromAst(type).pipe((annotation) => Option2.getOrUndefined(annotation)),
|
|
1012
|
+
readonly,
|
|
1013
|
+
label,
|
|
1014
|
+
placeholder,
|
|
1015
|
+
layout,
|
|
1016
|
+
...fieldState
|
|
1017
|
+
};
|
|
1018
|
+
const jsonPath = createJsonPath2(path ?? []);
|
|
1019
|
+
const CustomField = fieldMap?.[jsonPath];
|
|
1020
|
+
if (CustomField) {
|
|
1021
|
+
return /* @__PURE__ */ React3.createElement(CustomField, fieldProps);
|
|
1340
1022
|
}
|
|
1341
|
-
|
|
1342
|
-
|
|
1023
|
+
const component = fieldProvider?.({
|
|
1024
|
+
schema: Schema.make(type),
|
|
1025
|
+
prop: name,
|
|
1026
|
+
fieldProps
|
|
1027
|
+
});
|
|
1028
|
+
if (component) {
|
|
1029
|
+
return component;
|
|
1343
1030
|
}
|
|
1344
|
-
|
|
1345
|
-
return
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
maximumFractionDigits: 2
|
|
1031
|
+
if (isArrayType2(type)) {
|
|
1032
|
+
return /* @__PURE__ */ React3.createElement(ArrayField, {
|
|
1033
|
+
fieldProps: fieldState,
|
|
1034
|
+
label,
|
|
1035
|
+
...props
|
|
1350
1036
|
});
|
|
1351
1037
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
} catch (error) {
|
|
1356
|
-
return "Invalid Date";
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
case FormatEnum2.Time: {
|
|
1360
|
-
try {
|
|
1361
|
-
return formatDate(new Date(value), "HH:mm:ss");
|
|
1362
|
-
} catch (error) {
|
|
1363
|
-
return "Invalid Time";
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
case FormatEnum2.DateTime: {
|
|
1367
|
-
try {
|
|
1368
|
-
return formatDate(new Date(value), "yyyy-MM-dd HH:mm:ss");
|
|
1369
|
-
} catch (error) {
|
|
1370
|
-
return "Invalid DateTime";
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
case FormatEnum2.GeoPoint: {
|
|
1374
|
-
if (value === null || value === void 0) {
|
|
1375
|
-
return "";
|
|
1376
|
-
}
|
|
1377
|
-
if (Array.isArray(value) && value.length >= 2 && value.every(Number.isFinite)) {
|
|
1378
|
-
const { latitude, longitude } = GeoLocation3.fromGeoPoint(value);
|
|
1379
|
-
return `${latitude},${longitude}`;
|
|
1380
|
-
}
|
|
1381
|
-
return String(value);
|
|
1382
|
-
}
|
|
1383
|
-
default: {
|
|
1384
|
-
if (value === null || value === "undefined") {
|
|
1385
|
-
return "";
|
|
1386
|
-
}
|
|
1387
|
-
return String(value);
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
};
|
|
1391
|
-
var formatForEditing = ({ type, format, value, locale = void 0 }) => {
|
|
1392
|
-
const formatScalar = (type2) => {
|
|
1393
|
-
switch (type2) {
|
|
1394
|
-
case TypeEnum2.Boolean:
|
|
1395
|
-
case TypeEnum2.Number:
|
|
1396
|
-
case TypeEnum2.String:
|
|
1397
|
-
case TypeEnum2.Ref:
|
|
1398
|
-
return String(value);
|
|
1399
|
-
default:
|
|
1400
|
-
return String(value);
|
|
1401
|
-
}
|
|
1402
|
-
};
|
|
1403
|
-
if (!format) {
|
|
1404
|
-
return formatScalar(type);
|
|
1405
|
-
}
|
|
1406
|
-
switch (format) {
|
|
1407
|
-
case FormatEnum2.Boolean:
|
|
1408
|
-
case FormatEnum2.Number:
|
|
1409
|
-
case FormatEnum2.String:
|
|
1410
|
-
case FormatEnum2.Ref: {
|
|
1411
|
-
return formatScalar(type);
|
|
1412
|
-
}
|
|
1413
|
-
case FormatEnum2.Percent: {
|
|
1414
|
-
return String(value * 100);
|
|
1415
|
-
}
|
|
1416
|
-
case FormatEnum2.Currency: {
|
|
1417
|
-
return String(value);
|
|
1418
|
-
}
|
|
1419
|
-
case FormatEnum2.DateTime: {
|
|
1420
|
-
const date = new Date(value);
|
|
1421
|
-
return date.toISOString();
|
|
1422
|
-
}
|
|
1423
|
-
case FormatEnum2.Date: {
|
|
1424
|
-
const date = new Date(value);
|
|
1425
|
-
return date.toISOString().split("T")[0];
|
|
1038
|
+
const Field = getFormField(fieldProps);
|
|
1039
|
+
if (Field) {
|
|
1040
|
+
return /* @__PURE__ */ React3.createElement(Field, fieldProps);
|
|
1426
1041
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
return
|
|
1042
|
+
const options = getOptions(type);
|
|
1043
|
+
if (options) {
|
|
1044
|
+
return /* @__PURE__ */ React3.createElement(SelectField, {
|
|
1045
|
+
...fieldProps,
|
|
1046
|
+
options: options.map((option) => ({
|
|
1047
|
+
value: option,
|
|
1048
|
+
label: option.toString()
|
|
1049
|
+
}))
|
|
1050
|
+
});
|
|
1430
1051
|
}
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1052
|
+
const refProps = getRefProps(type);
|
|
1053
|
+
if (refProps) {
|
|
1054
|
+
return /* @__PURE__ */ React3.createElement(RefField, {
|
|
1055
|
+
...fieldProps,
|
|
1056
|
+
...refProps,
|
|
1057
|
+
createSchema,
|
|
1058
|
+
createOptionLabel,
|
|
1059
|
+
createOptionIcon,
|
|
1060
|
+
createInitialValuePath,
|
|
1061
|
+
onCreate,
|
|
1062
|
+
onQueryRefOptions
|
|
1063
|
+
});
|
|
1440
1064
|
}
|
|
1441
|
-
|
|
1442
|
-
|
|
1065
|
+
if (isNestedType(type)) {
|
|
1066
|
+
const baseNode = findNode(type, isDiscriminatedUnion);
|
|
1067
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST.isTypeLiteral);
|
|
1068
|
+
if (typeLiteral) {
|
|
1069
|
+
const schema = Schema.make(typeLiteral);
|
|
1070
|
+
return /* @__PURE__ */ React3.createElement(FormFieldSet, {
|
|
1071
|
+
schema,
|
|
1072
|
+
path,
|
|
1073
|
+
readonly,
|
|
1074
|
+
layout,
|
|
1075
|
+
label,
|
|
1076
|
+
projection,
|
|
1077
|
+
fieldMap,
|
|
1078
|
+
fieldProvider,
|
|
1079
|
+
createOptionLabel,
|
|
1080
|
+
createOptionIcon,
|
|
1081
|
+
onCreate,
|
|
1082
|
+
onQueryRefOptions
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1443
1085
|
}
|
|
1086
|
+
return null;
|
|
1087
|
+
} finally {
|
|
1088
|
+
_effect.f();
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
FormField.displayName = "Form.FormField";
|
|
1092
|
+
var getFormField = ({ type, format }) => {
|
|
1093
|
+
const formatField = Match.value(format).pipe(Match.withReturnType(), Match.when(Format3.TypeFormat.GeoPoint, () => GeoPointField), Match.when(Format3.TypeFormat.Markdown, () => MarkdownField), Match.when(Format3.TypeFormat.Text, () => TextAreaField), Match.orElse(() => void 0));
|
|
1094
|
+
if (formatField) {
|
|
1095
|
+
return formatField;
|
|
1096
|
+
}
|
|
1097
|
+
switch (type._tag) {
|
|
1098
|
+
// TODO(wittjosiah): Schema.Any is currently used to represent template inputs.
|
|
1099
|
+
case "AnyKeyword":
|
|
1100
|
+
case "StringKeyword":
|
|
1101
|
+
return TextField;
|
|
1102
|
+
case "NumberKeyword":
|
|
1103
|
+
return NumberField;
|
|
1104
|
+
case "BooleanKeyword":
|
|
1105
|
+
return BooleanField;
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
var getOptions = (ast) => {
|
|
1109
|
+
if (isLiteralUnion(ast)) {
|
|
1110
|
+
return ast.types.map((type) => type.literal).filter((v) => v !== null);
|
|
1444
1111
|
}
|
|
1112
|
+
return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
|
|
1445
1113
|
};
|
|
1446
1114
|
|
|
1447
|
-
// src/
|
|
1448
|
-
|
|
1449
|
-
|
|
1115
|
+
// src/components/Form/FormFieldSet.tsx
|
|
1116
|
+
var FormFieldSet = /* @__PURE__ */ forwardRef(({ classNames, label, schema, readonly, path, exclude, sort, projection, layout, ...props }, forwardRef4) => {
|
|
1117
|
+
var _effect = _useSignals4();
|
|
1118
|
+
try {
|
|
1119
|
+
const values = useFormValues(FormFieldSet.displayName, path);
|
|
1120
|
+
const properties = useMemo3(() => {
|
|
1121
|
+
if (!schema) {
|
|
1122
|
+
return [];
|
|
1123
|
+
}
|
|
1124
|
+
const props2 = getFormProperties(schema.ast);
|
|
1125
|
+
if (projection) {
|
|
1126
|
+
const fieldProjections = projection.getFieldProjections();
|
|
1127
|
+
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
1128
|
+
const visibleProps = props2.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
1129
|
+
const orderedProps = [];
|
|
1130
|
+
for (const fieldProjection of fieldProjections) {
|
|
1131
|
+
const fieldPath = String(fieldProjection.field.path);
|
|
1132
|
+
const prop = visibleProps.find((p) => p.name === fieldPath);
|
|
1133
|
+
if (prop) {
|
|
1134
|
+
orderedProps.push(prop);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
1138
|
+
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
1139
|
+
orderedProps.push(...remainingProps);
|
|
1140
|
+
return orderedProps;
|
|
1141
|
+
}
|
|
1142
|
+
const filtered = exclude ? exclude(props2) : props2;
|
|
1143
|
+
return sort ? filtered.sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filtered;
|
|
1144
|
+
}, [
|
|
1145
|
+
schema,
|
|
1146
|
+
values,
|
|
1147
|
+
exclude,
|
|
1148
|
+
sort,
|
|
1149
|
+
projection?.fields
|
|
1150
|
+
]);
|
|
1151
|
+
if ((readonly || layout === "static") && values == null) {
|
|
1152
|
+
return null;
|
|
1153
|
+
}
|
|
1154
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
1155
|
+
role: "form",
|
|
1156
|
+
className: mx3("is-full", layout === "inline" && "flex flex-col gap-2", classNames),
|
|
1157
|
+
ref: forwardRef4
|
|
1158
|
+
}, layout !== "inline" && label && /* @__PURE__ */ React4.createElement(FormFieldLabel, {
|
|
1159
|
+
label,
|
|
1160
|
+
asChild: true
|
|
1161
|
+
}), properties.map((property) => {
|
|
1162
|
+
const name = property.name.toString();
|
|
1163
|
+
return /* @__PURE__ */ React4.createElement(FormFieldErrorBoundary, {
|
|
1164
|
+
key: name,
|
|
1165
|
+
path: [
|
|
1166
|
+
...path ?? [],
|
|
1167
|
+
name
|
|
1168
|
+
]
|
|
1169
|
+
}, /* @__PURE__ */ React4.createElement(FormField, {
|
|
1170
|
+
type: property.type,
|
|
1171
|
+
name,
|
|
1172
|
+
path: [
|
|
1173
|
+
...path ?? [],
|
|
1174
|
+
name
|
|
1175
|
+
],
|
|
1176
|
+
readonly,
|
|
1177
|
+
layout,
|
|
1178
|
+
projection,
|
|
1179
|
+
...props
|
|
1180
|
+
}));
|
|
1181
|
+
}).filter(isTruthy));
|
|
1182
|
+
} finally {
|
|
1183
|
+
_effect.f();
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
FormFieldSet.displayName = "Form.Fields";
|
|
1450
1187
|
|
|
1451
|
-
// src/
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
var
|
|
1455
|
-
const
|
|
1456
|
-
const
|
|
1457
|
-
return
|
|
1188
|
+
// src/components/Form/Form.tsx
|
|
1189
|
+
var omitId = (schema) => schema.pipe(Schema2.omit("id"));
|
|
1190
|
+
var [FormContextProvider, useFormContext] = createContext("Form");
|
|
1191
|
+
var useFormValues = (componentName, path = []) => {
|
|
1192
|
+
const jsonPath = createJsonPath3(path);
|
|
1193
|
+
const { form: { values } } = useFormContext(componentName);
|
|
1194
|
+
return getValue$2(values, jsonPath);
|
|
1458
1195
|
};
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1196
|
+
var useFormFieldState = (componentName, path = []) => {
|
|
1197
|
+
const stablePath = useMemo4(() => path, [
|
|
1198
|
+
Array.isArray(path) ? path.join(".") : path
|
|
1199
|
+
]);
|
|
1200
|
+
const { form: { getStatus, getValue, onBlur, onValueChange } } = useFormContext(componentName);
|
|
1201
|
+
return useMemo4(() => ({
|
|
1202
|
+
getStatus: () => getStatus(stablePath),
|
|
1203
|
+
getValue: () => getValue(stablePath),
|
|
1204
|
+
onBlur: () => onBlur(stablePath),
|
|
1205
|
+
onValueChange: (ast, value3) => onValueChange(stablePath, ast, value3)
|
|
1206
|
+
}), [
|
|
1207
|
+
getStatus,
|
|
1208
|
+
getValue,
|
|
1209
|
+
onBlur,
|
|
1210
|
+
onValueChange,
|
|
1211
|
+
stablePath
|
|
1212
|
+
]);
|
|
1213
|
+
};
|
|
1214
|
+
var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
|
|
1215
|
+
var _effect = _useSignals5();
|
|
1216
|
+
try {
|
|
1217
|
+
const form = useFormHandler({
|
|
1218
|
+
schema,
|
|
1219
|
+
values,
|
|
1220
|
+
onSave,
|
|
1221
|
+
onCancel,
|
|
1222
|
+
...props
|
|
1223
|
+
});
|
|
1224
|
+
return /* @__PURE__ */ React5.createElement(FormContextProvider, {
|
|
1225
|
+
form,
|
|
1226
|
+
...props
|
|
1227
|
+
}, children);
|
|
1228
|
+
} finally {
|
|
1229
|
+
_effect.f();
|
|
1468
1230
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1231
|
+
};
|
|
1232
|
+
FormRoot.displayName = "Form.Root";
|
|
1233
|
+
var FormViewport = ({ classNames, children }) => {
|
|
1234
|
+
var _effect = _useSignals5();
|
|
1235
|
+
try {
|
|
1236
|
+
return /* @__PURE__ */ React5.createElement(ScrollArea.Root, null, /* @__PURE__ */ React5.createElement(ScrollArea.Viewport, {
|
|
1237
|
+
classNames: [
|
|
1238
|
+
"plb-cardSpacingBlock",
|
|
1239
|
+
classNames
|
|
1240
|
+
]
|
|
1241
|
+
}, children), /* @__PURE__ */ React5.createElement(ScrollArea.Scrollbar, {
|
|
1242
|
+
orientation: "vertical"
|
|
1243
|
+
}, /* @__PURE__ */ React5.createElement(ScrollArea.Thumb, null)));
|
|
1244
|
+
} finally {
|
|
1245
|
+
_effect.f();
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
FormViewport.displayName = "Form.Viewport";
|
|
1249
|
+
var FormContent = ({ classNames, children }) => {
|
|
1250
|
+
var _effect = _useSignals5();
|
|
1251
|
+
try {
|
|
1252
|
+
const { form, testId } = useFormContext(FormContent.displayName);
|
|
1253
|
+
const ref = useRef(null);
|
|
1254
|
+
useKeyHandler(ref.current, form);
|
|
1255
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1256
|
+
ref,
|
|
1257
|
+
role: "form",
|
|
1258
|
+
className: mx4("flex flex-col is-full pli-cardSpacingInline", classNames),
|
|
1259
|
+
"data-testid": testId
|
|
1260
|
+
}, children);
|
|
1261
|
+
} finally {
|
|
1262
|
+
_effect.f();
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
FormContent.displayName = "Form.Content";
|
|
1266
|
+
var FormFieldSet2 = ({ classNames }) => {
|
|
1267
|
+
var _effect = _useSignals5();
|
|
1268
|
+
try {
|
|
1269
|
+
const { form, ...props } = useFormContext(FormFieldSet2.displayName);
|
|
1270
|
+
return /* @__PURE__ */ React5.createElement(FormFieldSet, {
|
|
1271
|
+
classNames,
|
|
1272
|
+
schema: form.schema,
|
|
1273
|
+
...props
|
|
1274
|
+
});
|
|
1275
|
+
} finally {
|
|
1276
|
+
_effect.f();
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
FormFieldSet2.displayName = "Form.FieldSet";
|
|
1280
|
+
var FormActions = ({ classNames }) => {
|
|
1281
|
+
var _effect = _useSignals5();
|
|
1282
|
+
try {
|
|
1283
|
+
const { t } = useTranslation3(translationKey);
|
|
1284
|
+
const { form: { isValid, onSave, onCancel }, readonly, layout } = useFormContext(FormActions.displayName);
|
|
1285
|
+
if (readonly || layout === "static") {
|
|
1286
|
+
return null;
|
|
1479
1287
|
}
|
|
1288
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1289
|
+
role: "none",
|
|
1290
|
+
className: mx4("grid grid-flow-col auto-cols-fr gap-2 pbs-cardSpacingBlock", classNames)
|
|
1291
|
+
}, onCancel && /* @__PURE__ */ React5.createElement(IconButton, {
|
|
1292
|
+
icon: "ph--x--regular",
|
|
1293
|
+
iconEnd: true,
|
|
1294
|
+
label: t("cancel button label"),
|
|
1295
|
+
onClick: onCancel,
|
|
1296
|
+
"data-testid": "cancel-button"
|
|
1297
|
+
}), onSave && /* @__PURE__ */ React5.createElement(IconButton, {
|
|
1298
|
+
type: "submit",
|
|
1299
|
+
variant: "primary",
|
|
1300
|
+
disabled: !isValid,
|
|
1301
|
+
icon: "ph--check--regular",
|
|
1302
|
+
iconEnd: true,
|
|
1303
|
+
label: t("save button label"),
|
|
1304
|
+
onClick: onSave,
|
|
1305
|
+
"data-testid": "save-button"
|
|
1306
|
+
}));
|
|
1307
|
+
} finally {
|
|
1308
|
+
_effect.f();
|
|
1480
1309
|
}
|
|
1481
|
-
|
|
1310
|
+
};
|
|
1311
|
+
FormActions.displayName = "Form.Actions";
|
|
1312
|
+
var FormSubmit = ({ classNames, label, icon }) => {
|
|
1313
|
+
var _effect = _useSignals5();
|
|
1314
|
+
try {
|
|
1315
|
+
const { t } = useTranslation3(translationKey);
|
|
1316
|
+
const { form: { isValid, onSave }, readonly, layout } = useFormContext(FormSubmit.displayName);
|
|
1317
|
+
if (readonly || layout === "static") {
|
|
1318
|
+
return null;
|
|
1319
|
+
}
|
|
1320
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1321
|
+
role: "none",
|
|
1322
|
+
className: mx4("flex is-full pbs-cardSpacingBlock", classNames)
|
|
1323
|
+
}, /* @__PURE__ */ React5.createElement(IconButton, {
|
|
1324
|
+
classNames: "is-full",
|
|
1325
|
+
type: "submit",
|
|
1326
|
+
variant: "primary",
|
|
1327
|
+
disabled: !isValid,
|
|
1328
|
+
icon: icon ?? "ph--check--regular",
|
|
1329
|
+
label: label ?? t("save button label"),
|
|
1330
|
+
onClick: onSave,
|
|
1331
|
+
"data-testid": "save-button"
|
|
1332
|
+
}));
|
|
1333
|
+
} finally {
|
|
1334
|
+
_effect.f();
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1337
|
+
FormSubmit.displayName = "Form.Submit";
|
|
1338
|
+
var Form = {
|
|
1339
|
+
Root: FormRoot,
|
|
1340
|
+
Viewport: FormViewport,
|
|
1341
|
+
Content: FormContent,
|
|
1342
|
+
FieldSet: FormFieldSet2,
|
|
1343
|
+
Actions: FormActions,
|
|
1344
|
+
Submit: FormSubmit,
|
|
1345
|
+
Label: FormFieldLabel
|
|
1482
1346
|
};
|
|
1483
1347
|
|
|
1484
|
-
// src/components/Form/ArrayField.tsx
|
|
1485
|
-
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
1486
|
-
var ArrayField = ({
|
|
1487
|
-
var _effect =
|
|
1348
|
+
// src/components/Form/fields/ArrayField.tsx
|
|
1349
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/Form/fields/ArrayField.tsx";
|
|
1350
|
+
var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
|
|
1351
|
+
var _effect = _useSignals6();
|
|
1488
1352
|
try {
|
|
1489
|
-
const { t } =
|
|
1490
|
-
const
|
|
1491
|
-
const
|
|
1492
|
-
|
|
1353
|
+
const { t } = useTranslation4(translationKey);
|
|
1354
|
+
const elementType = getArrayElementType2(type);
|
|
1355
|
+
const { onValueChange } = inputProps;
|
|
1356
|
+
const values = useFormValues(ArrayField.displayName, path) ?? [];
|
|
1357
|
+
invariant(Array.isArray(values), `Expected array at: ${path?.join(".")}`, {
|
|
1493
1358
|
F: __dxlog_file3,
|
|
1494
|
-
L:
|
|
1359
|
+
L: 40,
|
|
1495
1360
|
S: void 0,
|
|
1496
1361
|
A: [
|
|
1497
1362
|
"Array.isArray(values)",
|
|
1498
|
-
"`
|
|
1363
|
+
"`Expected array at: ${path?.join('.')}`"
|
|
1499
1364
|
]
|
|
1500
1365
|
});
|
|
1501
|
-
const label = title ?? pipe(name, capitalize);
|
|
1502
|
-
const elementType = findArrayElementType(ast);
|
|
1503
1366
|
const getDefaultObjectValue = (typeNode) => {
|
|
1504
|
-
const baseNode = findNode2(typeNode,
|
|
1505
|
-
const typeLiteral = baseNode ?
|
|
1367
|
+
const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
|
|
1368
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST2.isTypeLiteral);
|
|
1506
1369
|
if (!typeLiteral) {
|
|
1507
1370
|
return {};
|
|
1508
1371
|
}
|
|
1509
|
-
return Object.fromEntries(
|
|
1510
|
-
prop.
|
|
1511
|
-
|
|
1512
|
-
|
|
1372
|
+
return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
|
|
1373
|
+
const defaultValue = SchemaAST2.getDefaultAnnotation(prop.type).pipe((annotation) => Option3.getOrUndefined(annotation));
|
|
1374
|
+
return [
|
|
1375
|
+
prop.name,
|
|
1376
|
+
defaultValue
|
|
1377
|
+
];
|
|
1378
|
+
}));
|
|
1513
1379
|
};
|
|
1514
|
-
const
|
|
1515
|
-
|
|
1516
|
-
|
|
1380
|
+
const handleAdd = useCallback5(() => {
|
|
1381
|
+
const defaultValue = isNestedType2(type) && elementType ? getDefaultObjectValue(elementType) : getDefaultValue(elementType);
|
|
1382
|
+
onValueChange(type, [
|
|
1517
1383
|
...values,
|
|
1518
|
-
|
|
1384
|
+
defaultValue
|
|
1519
1385
|
]);
|
|
1520
1386
|
}, [
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
values
|
|
1387
|
+
onValueChange,
|
|
1388
|
+
type,
|
|
1389
|
+
elementType,
|
|
1390
|
+
values
|
|
1391
|
+
]);
|
|
1392
|
+
const handleDelete = useCallback5((idx) => {
|
|
1393
|
+
onValueChange(type, values.filter((_, i) => i !== idx));
|
|
1394
|
+
}, [
|
|
1395
|
+
onValueChange,
|
|
1396
|
+
type,
|
|
1397
|
+
values
|
|
1398
|
+
]);
|
|
1399
|
+
if (!elementType || (readonly || layout === "static") && values.length < 1) {
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1402
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, (layout !== "static" || values.length > 0) && /* @__PURE__ */ React6.createElement(FormFieldLabel, {
|
|
1403
|
+
readonly,
|
|
1404
|
+
label,
|
|
1405
|
+
asChild: true
|
|
1406
|
+
}), /* @__PURE__ */ React6.createElement("div", {
|
|
1407
|
+
role: "none",
|
|
1408
|
+
className: "flex flex-col gap-2"
|
|
1409
|
+
}, values.map((_, index) => {
|
|
1410
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
1411
|
+
role: "none",
|
|
1412
|
+
key: index,
|
|
1413
|
+
className: "grid grid-cols-[1fr_min-content] gap-2 last:mb-3"
|
|
1414
|
+
}, /* @__PURE__ */ React6.createElement(FormField, {
|
|
1415
|
+
autoFocus: index === values.length - 1,
|
|
1416
|
+
type: elementType,
|
|
1417
|
+
path: [
|
|
1418
|
+
...path ?? [],
|
|
1419
|
+
index
|
|
1420
|
+
],
|
|
1421
|
+
readonly: readonly || layout === "static",
|
|
1422
|
+
layout: "inline",
|
|
1423
|
+
...props
|
|
1424
|
+
}), !readonly && layout !== "static" && /* @__PURE__ */ React6.createElement("div", {
|
|
1425
|
+
role: "none",
|
|
1426
|
+
className: "flex flex-col bs-full justify-end"
|
|
1427
|
+
}, /* @__PURE__ */ React6.createElement("div", {
|
|
1428
|
+
role: "none",
|
|
1429
|
+
className: "flex items-center bs-[var(--line-height)]"
|
|
1430
|
+
}, /* @__PURE__ */ React6.createElement(IconButton2, {
|
|
1431
|
+
icon: "ph--x--regular",
|
|
1432
|
+
iconOnly: true,
|
|
1433
|
+
label: t("button remove"),
|
|
1434
|
+
onClick: () => handleDelete(index),
|
|
1435
|
+
classNames: "self-center"
|
|
1436
|
+
}))));
|
|
1437
|
+
})), !readonly && layout !== "static" && /* @__PURE__ */ React6.createElement(IconButton2, {
|
|
1438
|
+
classNames: "flex is-full _mlb-cardSpacingBlock",
|
|
1439
|
+
icon: "ph--plus--regular",
|
|
1440
|
+
label: t("add field"),
|
|
1441
|
+
onClick: handleAdd
|
|
1442
|
+
}));
|
|
1443
|
+
} finally {
|
|
1444
|
+
_effect.f();
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1447
|
+
ArrayField.displayName = "Form.ArrayField";
|
|
1448
|
+
var getDefaultValue = (ast) => {
|
|
1449
|
+
switch (ast?._tag) {
|
|
1450
|
+
case "StringKeyword": {
|
|
1451
|
+
return "";
|
|
1452
|
+
}
|
|
1453
|
+
case "NumberKeyword": {
|
|
1454
|
+
return 0;
|
|
1455
|
+
}
|
|
1456
|
+
case "BooleanKeyword": {
|
|
1457
|
+
return false;
|
|
1458
|
+
}
|
|
1459
|
+
default: {
|
|
1460
|
+
if (ast && isNestedType2(ast)) {
|
|
1461
|
+
return {};
|
|
1462
|
+
} else {
|
|
1463
|
+
throw new Error(`Unsupported type: ${ast?._tag}`);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1468
|
+
|
|
1469
|
+
// src/components/Form/fields/BooleanField.tsx
|
|
1470
|
+
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
1471
|
+
import React7, { useCallback as useCallback6 } from "react";
|
|
1472
|
+
import { Input as Input3 } from "@dxos/react-ui";
|
|
1473
|
+
var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
|
|
1474
|
+
var _effect = _useSignals7();
|
|
1475
|
+
try {
|
|
1476
|
+
const handleChange = useCallback6((value3) => onValueChange?.(type, value3), [
|
|
1477
|
+
type,
|
|
1478
|
+
onValueChange
|
|
1479
|
+
]);
|
|
1480
|
+
return /* @__PURE__ */ React7.createElement(FormFieldWrapper, {
|
|
1481
|
+
readonly,
|
|
1482
|
+
...props
|
|
1483
|
+
}, ({ value: value3 }) => /* @__PURE__ */ React7.createElement(Input3.Switch, {
|
|
1484
|
+
disabled: !!readonly,
|
|
1485
|
+
checked: value3,
|
|
1486
|
+
onCheckedChange: handleChange
|
|
1487
|
+
}));
|
|
1488
|
+
} finally {
|
|
1489
|
+
_effect.f();
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
|
|
1493
|
+
// src/components/Form/fields/GeoPointField.tsx
|
|
1494
|
+
import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
|
|
1495
|
+
import React8, { useCallback as useCallback7, useEffect as useEffect3, useMemo as useMemo5, useState as useState3 } from "react";
|
|
1496
|
+
import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
|
|
1497
|
+
import { Input as Input4, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
1498
|
+
import { safeParseFloat } from "@dxos/util";
|
|
1499
|
+
var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1500
|
+
var _effect = _useSignals8();
|
|
1501
|
+
try {
|
|
1502
|
+
const { t } = useTranslation5(translationKey);
|
|
1503
|
+
const { status, error } = getStatus();
|
|
1504
|
+
const geoPoint = useMemo5(() => getValue() ?? [
|
|
1505
|
+
0,
|
|
1506
|
+
0
|
|
1507
|
+
], [
|
|
1508
|
+
getValue
|
|
1509
|
+
]);
|
|
1510
|
+
const value3 = useMemo5(() => GeoLocation3.fromGeoPoint(geoPoint), [
|
|
1511
|
+
geoPoint
|
|
1512
|
+
]);
|
|
1513
|
+
const [longitudeText, setLongitudeText] = useState3(value3.longitude?.toString());
|
|
1514
|
+
const [latitudeText, setLatitudeText] = useState3(value3.latitude?.toString());
|
|
1515
|
+
useEffect3(() => {
|
|
1516
|
+
const location = GeoLocation3.fromGeoPoint(geoPoint);
|
|
1517
|
+
setLongitudeText(location.longitude?.toString());
|
|
1518
|
+
setLatitudeText(location.latitude?.toString());
|
|
1519
|
+
}, [
|
|
1520
|
+
geoPoint
|
|
1521
|
+
]);
|
|
1522
|
+
const handleChange = useCallback7((coordinateType, setText) => (event) => {
|
|
1523
|
+
const inputText = event.target.value;
|
|
1524
|
+
setText(inputText);
|
|
1525
|
+
if (inputText !== "" && inputText !== "-") {
|
|
1526
|
+
const coord = safeParseFloat(inputText);
|
|
1527
|
+
if (coord !== void 0 && !isNaN(coord)) {
|
|
1528
|
+
const currentLocation = GeoLocation3.fromGeoPoint(getValue() ?? [
|
|
1529
|
+
0,
|
|
1530
|
+
0
|
|
1531
|
+
]);
|
|
1532
|
+
const newLocation = {
|
|
1533
|
+
...currentLocation,
|
|
1534
|
+
[coordinateType]: coord
|
|
1535
|
+
};
|
|
1536
|
+
const newValue = GeoLocation3.toGeoPoint(newLocation);
|
|
1537
|
+
onValueChange(type, newValue);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}, [
|
|
1541
|
+
type,
|
|
1542
|
+
getValue,
|
|
1543
|
+
onValueChange
|
|
1544
|
+
]);
|
|
1545
|
+
if ((readonly || layout === "static") && !value3?.latitude && !value3?.longitude) {
|
|
1546
|
+
return null;
|
|
1547
|
+
}
|
|
1548
|
+
return /* @__PURE__ */ React8.createElement(Input4.Root, {
|
|
1549
|
+
validationValence: status
|
|
1550
|
+
}, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
|
|
1551
|
+
error,
|
|
1552
|
+
readonly,
|
|
1553
|
+
label,
|
|
1554
|
+
asChild: true
|
|
1555
|
+
}), layout === "static" ? /* @__PURE__ */ React8.createElement(LatLng, value3) : /* @__PURE__ */ React8.createElement("div", {
|
|
1556
|
+
role: "none",
|
|
1557
|
+
className: "grid grid-cols-2 gap-2"
|
|
1558
|
+
}, /* @__PURE__ */ React8.createElement("div", null, /* @__PURE__ */ React8.createElement(Input4.Root, null, layout !== "inline" && /* @__PURE__ */ React8.createElement(Input4.Label, null, t("latitude label")), /* @__PURE__ */ React8.createElement(Input4.TextInput, {
|
|
1559
|
+
type: "number",
|
|
1560
|
+
step: "0.00001",
|
|
1561
|
+
min: "-90",
|
|
1562
|
+
max: "90",
|
|
1563
|
+
disabled: !!readonly,
|
|
1564
|
+
placeholder: t("latitude placeholder"),
|
|
1565
|
+
value: latitudeText ?? "",
|
|
1566
|
+
onChange: handleChange("latitude", setLatitudeText),
|
|
1567
|
+
onBlur
|
|
1568
|
+
}))), /* @__PURE__ */ React8.createElement("div", null, /* @__PURE__ */ React8.createElement(Input4.Root, null, layout !== "inline" && /* @__PURE__ */ React8.createElement(Input4.Label, null, t("longitude label")), /* @__PURE__ */ React8.createElement(Input4.TextInput, {
|
|
1569
|
+
type: "number",
|
|
1570
|
+
step: "0.00001",
|
|
1571
|
+
min: "-180",
|
|
1572
|
+
max: "180",
|
|
1573
|
+
disabled: !!readonly,
|
|
1574
|
+
placeholder: t("longitude placeholder"),
|
|
1575
|
+
value: longitudeText ?? "",
|
|
1576
|
+
onChange: handleChange("longitude", setLongitudeText),
|
|
1577
|
+
onBlur
|
|
1578
|
+
})))));
|
|
1579
|
+
} finally {
|
|
1580
|
+
_effect.f();
|
|
1581
|
+
}
|
|
1582
|
+
};
|
|
1583
|
+
var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
1584
|
+
var _effect = _useSignals8();
|
|
1585
|
+
try {
|
|
1586
|
+
const latHem = latitude >= 0 ? "N" : "S";
|
|
1587
|
+
const lngHem = longitude >= 0 ? "E" : "W";
|
|
1588
|
+
return /* @__PURE__ */ React8.createElement("span", {
|
|
1589
|
+
className: "inline-flex items-center gap-1"
|
|
1590
|
+
}, /* @__PURE__ */ React8.createElement("span", null, /* @__PURE__ */ React8.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React8.createElement("span", {
|
|
1591
|
+
className: "text-subdued"
|
|
1592
|
+
}, "\xB0", latHem)), /* @__PURE__ */ React8.createElement("span", null, /* @__PURE__ */ React8.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React8.createElement("span", {
|
|
1593
|
+
className: "text-subdued"
|
|
1594
|
+
}, "\xB0", lngHem)));
|
|
1595
|
+
} finally {
|
|
1596
|
+
_effect.f();
|
|
1597
|
+
}
|
|
1598
|
+
};
|
|
1599
|
+
|
|
1600
|
+
// src/components/Form/fields/MarkdownField.tsx
|
|
1601
|
+
import { useSignals as _useSignals9 } from "@preact-signals/safe-react/tracking";
|
|
1602
|
+
import React9, { useCallback as useCallback8, useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
1603
|
+
import { Input as Input5 } from "@dxos/react-ui";
|
|
1604
|
+
var MarkdownField = ({ type, readonly, label, placeholder, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1605
|
+
var _effect = _useSignals9();
|
|
1606
|
+
try {
|
|
1607
|
+
const { status, error } = getStatus();
|
|
1608
|
+
const textareaRef = useRef2(null);
|
|
1609
|
+
const adjustHeight = useCallback8(() => {
|
|
1610
|
+
const textarea = textareaRef.current;
|
|
1611
|
+
if (textarea) {
|
|
1612
|
+
textarea.style.blockSize = "auto";
|
|
1613
|
+
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
1614
|
+
}
|
|
1615
|
+
}, []);
|
|
1616
|
+
useEffect4(() => {
|
|
1617
|
+
adjustHeight();
|
|
1618
|
+
}, [
|
|
1619
|
+
adjustHeight
|
|
1525
1620
|
]);
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
inputProps.onValueChange(type, newValues);
|
|
1621
|
+
useEffect4(() => {
|
|
1622
|
+
adjustHeight();
|
|
1529
1623
|
}, [
|
|
1624
|
+
getValue(),
|
|
1625
|
+
adjustHeight
|
|
1626
|
+
]);
|
|
1627
|
+
const handleChange = useCallback8((event) => onValueChange(type, event.target.value), [
|
|
1530
1628
|
type,
|
|
1531
|
-
|
|
1532
|
-
values
|
|
1629
|
+
onValueChange
|
|
1533
1630
|
]);
|
|
1534
|
-
|
|
1631
|
+
const value3 = getValue();
|
|
1632
|
+
if ((readonly || layout === "static") && !value3) {
|
|
1535
1633
|
return null;
|
|
1536
1634
|
}
|
|
1537
|
-
return
|
|
1538
|
-
|
|
1635
|
+
return /* @__PURE__ */ React9.createElement(Input5.Root, {
|
|
1636
|
+
validationValence: status
|
|
1637
|
+
}, layout !== "inline" && /* @__PURE__ */ React9.createElement(FormFieldLabel, {
|
|
1638
|
+
error,
|
|
1639
|
+
readonly,
|
|
1539
1640
|
label
|
|
1540
|
-
}), /* @__PURE__ */
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1641
|
+
}), layout === "static" ? /* @__PURE__ */ React9.createElement("p", null, value3) : /* @__PURE__ */ React9.createElement(Input5.TextArea, {
|
|
1642
|
+
ref: textareaRef,
|
|
1643
|
+
disabled: !!readonly,
|
|
1644
|
+
placeholder,
|
|
1645
|
+
value: value3 ?? "",
|
|
1646
|
+
classNames: "min-bs-auto max-bs-40 overflow-auto",
|
|
1647
|
+
onChange: handleChange,
|
|
1648
|
+
onBlur,
|
|
1649
|
+
style: {
|
|
1650
|
+
resize: "none"
|
|
1651
|
+
},
|
|
1652
|
+
spellCheck: false
|
|
1653
|
+
}), layout === "full" && /* @__PURE__ */ React9.createElement(Input5.Validation, null, error));
|
|
1654
|
+
} finally {
|
|
1655
|
+
_effect.f();
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
|
|
1659
|
+
// src/components/Form/fields/NumberField.tsx
|
|
1660
|
+
import { useSignals as _useSignals10 } from "@preact-signals/safe-react/tracking";
|
|
1661
|
+
import React10, { useCallback as useCallback9 } from "react";
|
|
1662
|
+
import { Input as Input6 } from "@dxos/react-ui";
|
|
1663
|
+
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
1664
|
+
var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
|
|
1665
|
+
var _effect = _useSignals10();
|
|
1666
|
+
try {
|
|
1667
|
+
const handleChange = useCallback9((event) => onValueChange(type, safeParseFloat2(event.target.value) || 0), [
|
|
1668
|
+
type,
|
|
1669
|
+
onValueChange
|
|
1670
|
+
]);
|
|
1671
|
+
return /* @__PURE__ */ React10.createElement(FormFieldWrapper, {
|
|
1672
|
+
readonly,
|
|
1673
|
+
...props
|
|
1674
|
+
}, ({ value: value3 = "" }) => /* @__PURE__ */ React10.createElement(Input6.TextInput, {
|
|
1675
|
+
type: "number",
|
|
1676
|
+
disabled: !!readonly,
|
|
1677
|
+
placeholder,
|
|
1678
|
+
value: value3,
|
|
1679
|
+
onChange: handleChange,
|
|
1680
|
+
onBlur
|
|
1575
1681
|
}));
|
|
1576
1682
|
} finally {
|
|
1577
1683
|
_effect.f();
|
|
1578
1684
|
}
|
|
1579
1685
|
};
|
|
1580
1686
|
|
|
1581
|
-
// src/components/Form/RefField.tsx
|
|
1582
|
-
import { useSignals as
|
|
1583
|
-
import
|
|
1584
|
-
import {
|
|
1585
|
-
import {
|
|
1687
|
+
// src/components/Form/fields/RefField.tsx
|
|
1688
|
+
import { useSignals as _useSignals12 } from "@preact-signals/safe-react/tracking";
|
|
1689
|
+
import "@dxos/lit-ui/dx-tag-picker.pcss";
|
|
1690
|
+
import React12, { useCallback as useCallback11, useMemo as useMemo7 } from "react";
|
|
1691
|
+
import { Ref as Ref2 } from "@dxos/echo";
|
|
1692
|
+
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
1693
|
+
import { findAnnotation } from "@dxos/effect";
|
|
1586
1694
|
import { DXN } from "@dxos/keys";
|
|
1587
|
-
import {
|
|
1588
|
-
import { Input as
|
|
1589
|
-
import {
|
|
1590
|
-
import { descriptionText, mx as mx7 } from "@dxos/react-ui-theme";
|
|
1695
|
+
import { DxAnchor } from "@dxos/lit-ui/react";
|
|
1696
|
+
import { Button as Button2, Icon as Icon3, Input as Input7, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1697
|
+
import { descriptionText, mx as mx5 } from "@dxos/react-ui-theme";
|
|
1591
1698
|
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
1592
|
-
|
|
1699
|
+
|
|
1700
|
+
// src/components/ObjectPicker/ObjectPicker.tsx
|
|
1701
|
+
import { useSignals as _useSignals11 } from "@preact-signals/safe-react/tracking";
|
|
1702
|
+
import React11, { forwardRef as forwardRef2, useCallback as useCallback10, useMemo as useMemo6, useState as useState4 } from "react";
|
|
1703
|
+
import { Icon as Icon2, Popover, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1704
|
+
import { Combobox } from "@dxos/react-ui-searchlist";
|
|
1705
|
+
var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
|
|
1593
1706
|
var _effect = _useSignals11();
|
|
1594
1707
|
try {
|
|
1708
|
+
const { t } = useTranslation6(translationKey);
|
|
1709
|
+
const [showForm, setShowForm] = useState4(false);
|
|
1710
|
+
const [searchString, setSearchString] = useState4("");
|
|
1711
|
+
const handleFormSave = useCallback10((values) => {
|
|
1712
|
+
onCreate?.(values);
|
|
1713
|
+
setShowForm(false);
|
|
1714
|
+
setSearchString("");
|
|
1715
|
+
}, [
|
|
1716
|
+
onCreate
|
|
1717
|
+
]);
|
|
1718
|
+
const handleFormCancel = useCallback10(() => {
|
|
1719
|
+
setShowForm(false);
|
|
1720
|
+
setSearchString("");
|
|
1721
|
+
}, []);
|
|
1722
|
+
const handleClick = useCallback10((event) => {
|
|
1723
|
+
if (createSchema && event.target.closest('[data-value="__create__"]')) {
|
|
1724
|
+
event.stopPropagation();
|
|
1725
|
+
event.preventDefault();
|
|
1726
|
+
setShowForm(true);
|
|
1727
|
+
}
|
|
1728
|
+
}, [
|
|
1729
|
+
createSchema
|
|
1730
|
+
]);
|
|
1731
|
+
const handleKeyDown = useCallback10((event) => {
|
|
1732
|
+
if (event.key === "Enter" && createSchema && event.currentTarget.querySelector('[role="option"][aria-selected="true"][data-value="__create__"]')) {
|
|
1733
|
+
event.stopPropagation();
|
|
1734
|
+
event.preventDefault();
|
|
1735
|
+
setShowForm(true);
|
|
1736
|
+
}
|
|
1737
|
+
}, [
|
|
1738
|
+
createSchema
|
|
1739
|
+
]);
|
|
1740
|
+
const labelById = useMemo6(() => options.reduce((acc, option) => {
|
|
1741
|
+
acc[option.id.toLowerCase()] = option.label.toLowerCase();
|
|
1742
|
+
return acc;
|
|
1743
|
+
}, {}), [
|
|
1744
|
+
options
|
|
1745
|
+
]);
|
|
1746
|
+
return /* @__PURE__ */ React11.createElement(Combobox.Content, {
|
|
1747
|
+
...props,
|
|
1748
|
+
ref,
|
|
1749
|
+
filter: (value3, search) => value3 === "__create__" || labelById[value3]?.includes(search.toLowerCase()) ? 1 : 0,
|
|
1750
|
+
onClickCapture: handleClick,
|
|
1751
|
+
onKeyDownCapture: handleKeyDown
|
|
1752
|
+
}, showForm && createSchema ? /* @__PURE__ */ React11.createElement(Popover.Viewport, null, /* @__PURE__ */ React11.createElement(Form.Root, {
|
|
1753
|
+
testId: "create-referenced-object-form",
|
|
1754
|
+
schema: createSchema,
|
|
1755
|
+
values: createInitialValuePath ? {
|
|
1756
|
+
[createInitialValuePath]: searchString
|
|
1757
|
+
} : {},
|
|
1758
|
+
onSave: handleFormSave,
|
|
1759
|
+
onCancel: handleFormCancel
|
|
1760
|
+
}, /* @__PURE__ */ React11.createElement(Form.Viewport, null, /* @__PURE__ */ React11.createElement(Form.Content, null, /* @__PURE__ */ React11.createElement(Form.FieldSet, null), /* @__PURE__ */ React11.createElement(Form.Actions, null))))) : /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Combobox.Input, {
|
|
1761
|
+
placeholder: t("ref field combobox input placeholder"),
|
|
1762
|
+
value: searchString,
|
|
1763
|
+
onValueChange: setSearchString,
|
|
1764
|
+
autoFocus: true
|
|
1765
|
+
}), /* @__PURE__ */ React11.createElement(Combobox.List, null, options.map((option) => /* @__PURE__ */ React11.createElement(Combobox.Item, {
|
|
1766
|
+
key: option.id,
|
|
1767
|
+
value: option.id,
|
|
1768
|
+
onSelect: () => onSelect(option.id),
|
|
1769
|
+
classNames: "flex items-center gap-2"
|
|
1770
|
+
}, /* @__PURE__ */ React11.createElement("span", {
|
|
1771
|
+
className: "grow"
|
|
1772
|
+
}, option.label), selectedIds?.includes(option.id) && /* @__PURE__ */ React11.createElement(Icon2, {
|
|
1773
|
+
icon: "ph--check--regular"
|
|
1774
|
+
}))), searchString.length > 0 && createOptionLabel && createOptionIcon && createSchema && onCreate && /* @__PURE__ */ React11.createElement(Combobox.Item, {
|
|
1775
|
+
value: "__create__",
|
|
1776
|
+
classNames: "flex items-center gap-2"
|
|
1777
|
+
}, /* @__PURE__ */ React11.createElement(Icon2, {
|
|
1778
|
+
icon: createOptionIcon
|
|
1779
|
+
}), t(createOptionLabel[0], {
|
|
1780
|
+
ns: createOptionLabel[1].ns,
|
|
1781
|
+
text: searchString
|
|
1782
|
+
})))), /* @__PURE__ */ React11.createElement(Combobox.Arrow, null));
|
|
1783
|
+
} finally {
|
|
1784
|
+
_effect.f();
|
|
1785
|
+
}
|
|
1786
|
+
});
|
|
1787
|
+
ObjectPickerContent.displayName = "ObjectPickerContent";
|
|
1788
|
+
var ObjectPicker = {
|
|
1789
|
+
Root: Combobox.Root,
|
|
1790
|
+
Trigger: Combobox.Trigger,
|
|
1791
|
+
VirtualTrigger: Combobox.VirtualTrigger,
|
|
1792
|
+
Content: ObjectPickerContent
|
|
1793
|
+
};
|
|
1794
|
+
|
|
1795
|
+
// src/components/Form/fields/RefField.tsx
|
|
1796
|
+
var isRefSnapShot = (val) => {
|
|
1797
|
+
return typeof val === "object" && typeof val?.["/"] === "string";
|
|
1798
|
+
};
|
|
1799
|
+
var RefField = (props) => {
|
|
1800
|
+
var _effect = _useSignals12();
|
|
1801
|
+
try {
|
|
1802
|
+
const { type, readonly, label, placeholder, layout, getStatus, getValue, array, createOptionLabel, createOptionIcon, createSchema, createInitialValuePath, onCreate, onQueryRefOptions, onValueChange } = props;
|
|
1595
1803
|
const { t } = useTranslation7(translationKey);
|
|
1596
|
-
const
|
|
1597
|
-
|
|
1804
|
+
const { status, error } = getStatus();
|
|
1805
|
+
const typename = useMemo7(() => type ? findAnnotation(type, ReferenceAnnotationId)?.typename : void 0, [
|
|
1806
|
+
type
|
|
1598
1807
|
]);
|
|
1599
|
-
const { options
|
|
1600
|
-
|
|
1808
|
+
const { options, update: updateOptions } = useQueryRefOptions({
|
|
1809
|
+
typename,
|
|
1601
1810
|
onQueryRefOptions
|
|
1602
1811
|
});
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
getValue: getValue3,
|
|
1611
|
-
onBlur,
|
|
1612
|
-
onValueChange,
|
|
1613
|
-
...restInputProps
|
|
1614
|
-
});
|
|
1615
|
-
}
|
|
1616
|
-
const handleGetValue = useCallback8(() => {
|
|
1617
|
-
const formValue = getValue3();
|
|
1618
|
-
const unknownToRefOption = (val) => {
|
|
1619
|
-
if (Ref.isRef(val)) {
|
|
1620
|
-
const dxnString = val.dxn.toString();
|
|
1621
|
-
const matchingOption = availableOptions.find((option2) => option2.id === dxnString);
|
|
1812
|
+
const handleGetValue = useCallback11(() => {
|
|
1813
|
+
const formValue = getValue();
|
|
1814
|
+
const unknownToRefOption = (value3) => {
|
|
1815
|
+
const isRef = Ref2.isRef(value3);
|
|
1816
|
+
if (isRef || isRefSnapShot(value3)) {
|
|
1817
|
+
const dxnString = isRef ? value3.dxn.toString() : value3["/"];
|
|
1818
|
+
const matchingOption = options.find((option2) => option2.id === dxnString);
|
|
1622
1819
|
if (matchingOption) {
|
|
1623
1820
|
return matchingOption;
|
|
1624
1821
|
}
|
|
@@ -1636,332 +1833,450 @@ var RefField = ({ type, label, disabled, placeholder, inputOnly, array, ast, get
|
|
|
1636
1833
|
}
|
|
1637
1834
|
return [];
|
|
1638
1835
|
}, [
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
]);
|
|
1643
|
-
const handleSearch = useCallback8((text, ids) => availableOptions.filter((option) => !ids.includes(option.id)).filter((option) => option.label.toLowerCase().includes(text.toLowerCase())).map((option) => ({
|
|
1644
|
-
id: option.id,
|
|
1645
|
-
label: option.label,
|
|
1646
|
-
hue: option.hue
|
|
1647
|
-
})), [
|
|
1648
|
-
availableOptions
|
|
1836
|
+
options,
|
|
1837
|
+
array,
|
|
1838
|
+
getValue
|
|
1649
1839
|
]);
|
|
1650
|
-
const handleUpdate =
|
|
1840
|
+
const handleUpdate = useCallback11((ids) => {
|
|
1651
1841
|
if (ids.length === 0) {
|
|
1652
|
-
onValueChange(
|
|
1842
|
+
onValueChange(type, void 0);
|
|
1653
1843
|
return;
|
|
1654
1844
|
}
|
|
1655
1845
|
const refs = ids.map((id) => {
|
|
1656
|
-
const item =
|
|
1846
|
+
const item = options.find((option) => option.id === id);
|
|
1657
1847
|
if (item) {
|
|
1658
1848
|
const dxn = DXN.parse(item.id);
|
|
1659
|
-
return
|
|
1849
|
+
return Ref2.fromDXN(dxn);
|
|
1660
1850
|
}
|
|
1661
1851
|
return null;
|
|
1662
1852
|
}).filter(isNonNullable2);
|
|
1663
1853
|
if (array) {
|
|
1664
|
-
onValueChange(
|
|
1854
|
+
onValueChange(type, refs);
|
|
1665
1855
|
} else {
|
|
1666
|
-
onValueChange(
|
|
1856
|
+
onValueChange(type, refs[0]);
|
|
1667
1857
|
}
|
|
1668
1858
|
}, [
|
|
1669
|
-
|
|
1859
|
+
options,
|
|
1860
|
+
type,
|
|
1670
1861
|
array,
|
|
1671
1862
|
onValueChange
|
|
1672
1863
|
]);
|
|
1673
|
-
const
|
|
1674
|
-
|
|
1864
|
+
const handleCreate = useCallback11((values) => {
|
|
1865
|
+
onCreate?.(values);
|
|
1866
|
+
updateOptions();
|
|
1867
|
+
}, [
|
|
1868
|
+
onCreate,
|
|
1869
|
+
updateOptions
|
|
1870
|
+
]);
|
|
1871
|
+
const items = handleGetValue();
|
|
1872
|
+
const selectedIds = useMemo7(() => items.map((i) => i.id), [
|
|
1873
|
+
items
|
|
1874
|
+
]);
|
|
1875
|
+
const toggleSelect = useCallback11((id) => {
|
|
1876
|
+
if (array) {
|
|
1877
|
+
const nextIds = selectedIds.includes(id) ? selectedIds.filter((x) => x !== id) : [
|
|
1878
|
+
...selectedIds,
|
|
1879
|
+
id
|
|
1880
|
+
];
|
|
1881
|
+
handleUpdate(nextIds);
|
|
1882
|
+
} else {
|
|
1883
|
+
if (selectedIds[0] === id) {
|
|
1884
|
+
handleUpdate([]);
|
|
1885
|
+
} else {
|
|
1886
|
+
handleUpdate([
|
|
1887
|
+
id
|
|
1888
|
+
]);
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
}, [
|
|
1892
|
+
array,
|
|
1893
|
+
selectedIds,
|
|
1894
|
+
handleUpdate
|
|
1675
1895
|
]);
|
|
1676
|
-
if (!
|
|
1896
|
+
if (!typename || (readonly || layout === "static") && items.length < 1) {
|
|
1677
1897
|
return null;
|
|
1678
1898
|
}
|
|
1679
|
-
|
|
1680
|
-
const items = handleGetValue();
|
|
1681
|
-
return disabled && items.length < 1 ? null : /* @__PURE__ */ React11.createElement(Input8.Root, {
|
|
1899
|
+
return /* @__PURE__ */ React12.createElement(Input7.Root, {
|
|
1682
1900
|
validationValence: status
|
|
1683
|
-
},
|
|
1901
|
+
}, layout !== "inline" && /* @__PURE__ */ React12.createElement(FormFieldLabel, {
|
|
1684
1902
|
error,
|
|
1903
|
+
readonly,
|
|
1685
1904
|
label
|
|
1686
|
-
}), /* @__PURE__ */
|
|
1687
|
-
"
|
|
1688
|
-
},
|
|
1689
|
-
className: mx7(descriptionText, "mbe-2")
|
|
1690
|
-
}, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React11.createElement(DxRefTag, {
|
|
1905
|
+
}), /* @__PURE__ */ React12.createElement("div", null, readonly ? items.length < 1 ? /* @__PURE__ */ React12.createElement("p", {
|
|
1906
|
+
className: mx5(descriptionText, "mbe-2")
|
|
1907
|
+
}, t("empty readonly ref field label")) : items.map((item) => /* @__PURE__ */ React12.createElement(DxAnchor, {
|
|
1691
1908
|
key: item.id,
|
|
1692
1909
|
refid: item.id,
|
|
1693
|
-
rootclassname: "mie-1"
|
|
1694
|
-
|
|
1695
|
-
|
|
1910
|
+
rootclassname: "mie-1"
|
|
1911
|
+
}, item.label)) : /* @__PURE__ */ React12.createElement(ObjectPicker.Root, null, /* @__PURE__ */ React12.createElement(ObjectPicker.Trigger, {
|
|
1912
|
+
asChild: true,
|
|
1913
|
+
classNames: "p-0"
|
|
1914
|
+
}, items?.length === 1 ? /* @__PURE__ */ React12.createElement("div", {
|
|
1915
|
+
className: "flex gap-2 is-full"
|
|
1916
|
+
}, items?.map((item) => /* @__PURE__ */ React12.createElement(Input7.Root, {
|
|
1917
|
+
key: item.id
|
|
1918
|
+
}, /* @__PURE__ */ React12.createElement(Input7.TextInput, {
|
|
1919
|
+
value: item.label,
|
|
1920
|
+
readOnly: true,
|
|
1921
|
+
classNames: "is-full"
|
|
1922
|
+
})))) : /* @__PURE__ */ React12.createElement(Button2, {
|
|
1923
|
+
classNames: "is-full text-start gap-2"
|
|
1924
|
+
}, /* @__PURE__ */ React12.createElement("div", {
|
|
1925
|
+
role: "none",
|
|
1926
|
+
className: "grow overflow-hidden"
|
|
1927
|
+
}, /* @__PURE__ */ React12.createElement("span", {
|
|
1928
|
+
className: "flex truncate text-description"
|
|
1929
|
+
}, placeholder ?? t("ref field placeholder", {
|
|
1930
|
+
count: array ? 99 : 1
|
|
1931
|
+
}))), /* @__PURE__ */ React12.createElement(Icon3, {
|
|
1932
|
+
size: 3,
|
|
1933
|
+
icon: "ph--caret-down--bold"
|
|
1934
|
+
}))), /* @__PURE__ */ React12.createElement(ObjectPicker.Content, {
|
|
1935
|
+
classNames: "popover-card-width",
|
|
1936
|
+
options,
|
|
1937
|
+
selectedIds,
|
|
1938
|
+
createSchema,
|
|
1939
|
+
createOptionLabel,
|
|
1940
|
+
createOptionIcon,
|
|
1941
|
+
createInitialValuePath,
|
|
1942
|
+
onCreate: handleCreate,
|
|
1943
|
+
onSelect: toggleSelect
|
|
1944
|
+
}))), layout === "full" && /* @__PURE__ */ React12.createElement(Input7.DescriptionAndValidation, null, error));
|
|
1945
|
+
} finally {
|
|
1946
|
+
_effect.f();
|
|
1947
|
+
}
|
|
1948
|
+
};
|
|
1949
|
+
|
|
1950
|
+
// src/components/Form/fields/SelectField.tsx
|
|
1951
|
+
import { useSignals as _useSignals13 } from "@preact-signals/safe-react/tracking";
|
|
1952
|
+
import React13, { useCallback as useCallback12 } from "react";
|
|
1953
|
+
import { Input as Input8, Select } from "@dxos/react-ui";
|
|
1954
|
+
var SelectField = ({ type, readonly, label, layout, placeholder, options, getStatus, getValue, onValueChange }) => {
|
|
1955
|
+
var _effect = _useSignals13();
|
|
1956
|
+
try {
|
|
1957
|
+
const { status, error } = getStatus();
|
|
1958
|
+
const value3 = getValue();
|
|
1959
|
+
const handleValueChange = useCallback12((value4) => onValueChange(type, value4), [
|
|
1960
|
+
type,
|
|
1961
|
+
onValueChange
|
|
1962
|
+
]);
|
|
1963
|
+
if ((readonly || layout === "static") && value3 == null) {
|
|
1964
|
+
return null;
|
|
1965
|
+
}
|
|
1966
|
+
return /* @__PURE__ */ React13.createElement(Input8.Root, {
|
|
1967
|
+
validationValence: status
|
|
1968
|
+
}, layout !== "inline" && /* @__PURE__ */ React13.createElement(FormFieldLabel, {
|
|
1969
|
+
error,
|
|
1970
|
+
readonly,
|
|
1971
|
+
label
|
|
1972
|
+
}), layout === "static" ? /* @__PURE__ */ React13.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value3)?.label ?? String(value3)) : /* @__PURE__ */ React13.createElement(Select.Root, {
|
|
1973
|
+
value: value3,
|
|
1974
|
+
onValueChange: handleValueChange
|
|
1975
|
+
}, /* @__PURE__ */ React13.createElement(Select.TriggerButton, {
|
|
1976
|
+
classNames: "is-full",
|
|
1977
|
+
disabled: !!readonly,
|
|
1978
|
+
placeholder
|
|
1979
|
+
}), /* @__PURE__ */ React13.createElement(Select.Portal, null, /* @__PURE__ */ React13.createElement(Select.Content, null, /* @__PURE__ */ React13.createElement(Select.Viewport, null, options?.map(({ value: value4, label: label2 }) => (
|
|
1980
|
+
// NOTE: Numeric values are converted to and from strings.
|
|
1981
|
+
/* @__PURE__ */ React13.createElement(Select.Option, {
|
|
1982
|
+
key: String(value4),
|
|
1983
|
+
value: String(value4)
|
|
1984
|
+
}, label2 ?? String(value4))
|
|
1985
|
+
))), /* @__PURE__ */ React13.createElement(Select.Arrow, null)))), layout === "full" && /* @__PURE__ */ React13.createElement(Input8.DescriptionAndValidation, null, error));
|
|
1986
|
+
} finally {
|
|
1987
|
+
_effect.f();
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1990
|
+
|
|
1991
|
+
// src/components/Form/fields/SelectOptionField.tsx
|
|
1992
|
+
import { useSignals as _useSignals14 } from "@preact-signals/safe-react/tracking";
|
|
1993
|
+
import React14, { useCallback as useCallback13, useEffect as useEffect5, useRef as useRef3, useState as useState5 } from "react";
|
|
1994
|
+
import { PublicKey } from "@dxos/keys";
|
|
1995
|
+
import { IconButton as IconButton3, Input as Input9, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
|
|
1996
|
+
import { List } from "@dxos/react-ui-list";
|
|
1997
|
+
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1998
|
+
import { hues, subtleHover } from "@dxos/react-ui-theme";
|
|
1999
|
+
var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
|
|
2000
|
+
var _effect = _useSignals14();
|
|
2001
|
+
try {
|
|
2002
|
+
const { t } = useTranslation8(translationKey);
|
|
2003
|
+
const { status, error } = getStatus();
|
|
2004
|
+
const [selected, setSelectedId] = useState5(null);
|
|
2005
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
2006
|
+
const inputRef = useRef3(null);
|
|
2007
|
+
const options = getValue();
|
|
2008
|
+
useEffect5(() => {
|
|
2009
|
+
if (options === void 0) {
|
|
2010
|
+
onValueChange(type, []);
|
|
2011
|
+
}
|
|
2012
|
+
}, [
|
|
2013
|
+
options,
|
|
2014
|
+
type,
|
|
2015
|
+
onValueChange
|
|
2016
|
+
]);
|
|
2017
|
+
const randomHue = () => {
|
|
2018
|
+
const usedHues = new Set(options?.map((option) => option.color) ?? []);
|
|
2019
|
+
const unusedHues = hues.filter((hue) => !usedHues.has(hue));
|
|
2020
|
+
if (unusedHues.length > 0) {
|
|
2021
|
+
return unusedHues[Math.floor(Math.random() * unusedHues.length)];
|
|
2022
|
+
}
|
|
2023
|
+
const lastThree = new Set(options?.slice(-3).map((option) => option.color) ?? []);
|
|
2024
|
+
const availableHues = hues.filter((hue) => !lastThree.has(hue));
|
|
2025
|
+
return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hues[Math.floor(Math.random() * hues.length)];
|
|
2026
|
+
};
|
|
2027
|
+
const handleAdd = useCallback13(() => {
|
|
2028
|
+
const newId = PublicKey.random().truncate();
|
|
2029
|
+
const newOption = {
|
|
2030
|
+
id: newId,
|
|
2031
|
+
title: "",
|
|
2032
|
+
color: randomHue()
|
|
2033
|
+
};
|
|
2034
|
+
onValueChange(type, [
|
|
2035
|
+
...options ?? [],
|
|
2036
|
+
newOption
|
|
2037
|
+
]);
|
|
2038
|
+
setSelectedId(newId);
|
|
2039
|
+
setIsNewOption(true);
|
|
2040
|
+
}, [
|
|
2041
|
+
options,
|
|
2042
|
+
type,
|
|
2043
|
+
onValueChange
|
|
2044
|
+
]);
|
|
2045
|
+
const handleDelete = useCallback13((id) => {
|
|
2046
|
+
const newOptions = options?.filter((option) => option.id !== id) ?? [];
|
|
2047
|
+
onValueChange(type, newOptions);
|
|
2048
|
+
setSelectedId(null);
|
|
2049
|
+
}, [
|
|
2050
|
+
options,
|
|
2051
|
+
type,
|
|
2052
|
+
onValueChange
|
|
2053
|
+
]);
|
|
2054
|
+
const handleMove = useCallback13((from, to) => {
|
|
2055
|
+
if (!options) {
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
2058
|
+
const newOptions = [
|
|
2059
|
+
...options
|
|
2060
|
+
];
|
|
2061
|
+
const [removed] = newOptions.splice(from, 1);
|
|
2062
|
+
newOptions.splice(to, 0, removed);
|
|
2063
|
+
onValueChange(type, newOptions);
|
|
2064
|
+
}, [
|
|
2065
|
+
options,
|
|
2066
|
+
type,
|
|
2067
|
+
onValueChange
|
|
2068
|
+
]);
|
|
2069
|
+
const handleClick = useCallback13((id) => {
|
|
2070
|
+
setSelectedId((current) => current === id ? null : id);
|
|
2071
|
+
}, []);
|
|
2072
|
+
const handleTitleChange = useCallback13((id) => (e) => {
|
|
2073
|
+
const newOptions = options?.map((o) => o.id === id ? {
|
|
2074
|
+
...o,
|
|
2075
|
+
title: e.target.value
|
|
2076
|
+
} : o);
|
|
2077
|
+
onValueChange(type, newOptions ?? []);
|
|
2078
|
+
}, [
|
|
2079
|
+
options,
|
|
2080
|
+
type,
|
|
2081
|
+
onValueChange
|
|
2082
|
+
]);
|
|
2083
|
+
const handleKeyDown = useCallback13((ev) => {
|
|
2084
|
+
if (ev.key === "Enter") {
|
|
2085
|
+
setSelectedId(null);
|
|
2086
|
+
}
|
|
2087
|
+
}, []);
|
|
2088
|
+
const handleColorChange = useCallback13((id) => (hue) => {
|
|
2089
|
+
const newOptions = options?.map((o) => o.id === id ? {
|
|
2090
|
+
...o,
|
|
2091
|
+
color: hue
|
|
2092
|
+
} : o);
|
|
2093
|
+
onValueChange(type, newOptions ?? []);
|
|
2094
|
+
}, [
|
|
2095
|
+
options,
|
|
2096
|
+
type,
|
|
2097
|
+
onValueChange
|
|
2098
|
+
]);
|
|
2099
|
+
useEffect5(() => {
|
|
2100
|
+
if (selected && isNewOption && inputRef.current) {
|
|
2101
|
+
inputRef.current.focus();
|
|
2102
|
+
setIsNewOption(false);
|
|
1696
2103
|
}
|
|
1697
|
-
},
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
2104
|
+
}, [
|
|
2105
|
+
selected,
|
|
2106
|
+
isNewOption
|
|
2107
|
+
]);
|
|
2108
|
+
return /* @__PURE__ */ React14.createElement(Input9.Root, {
|
|
2109
|
+
validationValence: status
|
|
2110
|
+
}, /* @__PURE__ */ React14.createElement(FormFieldLabel, {
|
|
2111
|
+
error,
|
|
2112
|
+
readonly,
|
|
2113
|
+
label
|
|
2114
|
+
}), /* @__PURE__ */ React14.createElement("div", {
|
|
2115
|
+
role: "none"
|
|
2116
|
+
}, options && /* @__PURE__ */ React14.createElement(List.Root, {
|
|
2117
|
+
items: options,
|
|
2118
|
+
isItem: (_item) => true,
|
|
2119
|
+
onMove: readonly ? void 0 : handleMove,
|
|
2120
|
+
readonly: !!readonly
|
|
2121
|
+
}, ({ items }) => /* @__PURE__ */ React14.createElement("div", {
|
|
2122
|
+
role: "list",
|
|
2123
|
+
className: "is-full overflow-auto"
|
|
2124
|
+
}, items?.map((item) => /* @__PURE__ */ React14.createElement("div", {
|
|
2125
|
+
key: item.id
|
|
2126
|
+
}, /* @__PURE__ */ React14.createElement(List.Item, {
|
|
2127
|
+
role: "button",
|
|
2128
|
+
item,
|
|
2129
|
+
classNames: [
|
|
2130
|
+
subtleHover,
|
|
2131
|
+
"flex flex-col cursor-pointer rounded-sm"
|
|
2132
|
+
],
|
|
2133
|
+
"aria-expanded": selected === item.id
|
|
2134
|
+
}, /* @__PURE__ */ React14.createElement("div", {
|
|
2135
|
+
className: "flex items-center"
|
|
2136
|
+
}, /* @__PURE__ */ React14.createElement(List.ItemDragHandle, {
|
|
2137
|
+
disabled: !!readonly
|
|
2138
|
+
}), /* @__PURE__ */ React14.createElement(List.ItemTitle, {
|
|
2139
|
+
onClick: () => handleClick(item.id),
|
|
2140
|
+
classNames: "flex-1"
|
|
2141
|
+
}, /* @__PURE__ */ React14.createElement(Tag, {
|
|
2142
|
+
palette: item.color
|
|
2143
|
+
}, item.title || "\u200B")), /* @__PURE__ */ React14.createElement(IconButton3, {
|
|
2144
|
+
iconOnly: true,
|
|
2145
|
+
variant: "ghost",
|
|
2146
|
+
label: t(selected === item.id ? "collapse label" : "expand label", {
|
|
2147
|
+
ns: "os"
|
|
2148
|
+
}),
|
|
2149
|
+
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2150
|
+
onClick: () => handleClick(item.id)
|
|
2151
|
+
})), selected === item.id && /* @__PURE__ */ React14.createElement("div", {
|
|
2152
|
+
className: "pli-cardSpacingInline plb-cardSpacingBlock flex flex-col gap-1 density-fine"
|
|
2153
|
+
}, /* @__PURE__ */ React14.createElement(Input9.Label, {
|
|
2154
|
+
classNames: "text-xs"
|
|
2155
|
+
}, t("select option label")), /* @__PURE__ */ React14.createElement("div", {
|
|
2156
|
+
className: "grid grid-cols-[1fr_min-content_min-content] gap-1"
|
|
2157
|
+
}, /* @__PURE__ */ React14.createElement(Input9.TextInput, {
|
|
2158
|
+
disabled: !!readonly,
|
|
2159
|
+
placeholder: t("select option label placeholder"),
|
|
2160
|
+
ref: selected === item.id ? inputRef : void 0,
|
|
2161
|
+
value: item.title,
|
|
2162
|
+
onChange: handleTitleChange(item.id),
|
|
2163
|
+
onKeyDown: handleKeyDown,
|
|
2164
|
+
classNames: "flex-1"
|
|
2165
|
+
}), /* @__PURE__ */ React14.createElement(HuePicker, {
|
|
2166
|
+
disabled: !!readonly,
|
|
2167
|
+
value: item.color,
|
|
2168
|
+
onChange: handleColorChange(item.id)
|
|
2169
|
+
}), /* @__PURE__ */ React14.createElement(IconButton3, {
|
|
2170
|
+
disabled: !!readonly,
|
|
2171
|
+
icon: "ph--trash--fill",
|
|
2172
|
+
iconOnly: true,
|
|
2173
|
+
label: t("select option delete"),
|
|
2174
|
+
onClick: () => handleDelete(item.id)
|
|
2175
|
+
})))))), /* @__PURE__ */ React14.createElement(IconButton3, {
|
|
2176
|
+
variant: "ghost",
|
|
2177
|
+
icon: "ph--plus--regular",
|
|
2178
|
+
label: t("select option add"),
|
|
2179
|
+
onClick: handleAdd,
|
|
2180
|
+
disabled: !!readonly,
|
|
2181
|
+
classNames: "is-full"
|
|
2182
|
+
})))));
|
|
1706
2183
|
} finally {
|
|
1707
2184
|
_effect.f();
|
|
1708
2185
|
}
|
|
1709
2186
|
};
|
|
1710
|
-
|
|
1711
|
-
|
|
2187
|
+
|
|
2188
|
+
// src/components/Form/fields/TextField.tsx
|
|
2189
|
+
import { useSignals as _useSignals15 } from "@preact-signals/safe-react/tracking";
|
|
2190
|
+
import React15, { useCallback as useCallback14 } from "react";
|
|
2191
|
+
import { Input as Input10 } from "@dxos/react-ui";
|
|
2192
|
+
var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
|
|
2193
|
+
var _effect = _useSignals15();
|
|
1712
2194
|
try {
|
|
1713
|
-
const
|
|
1714
|
-
const dxn = DXN.tryParse(dxnString);
|
|
1715
|
-
if (dxn) {
|
|
1716
|
-
onValueChange?.("object", Ref.fromDXN(dxn));
|
|
1717
|
-
} else if (dxnString === "") {
|
|
1718
|
-
onValueChange?.("object", void 0);
|
|
1719
|
-
} else {
|
|
1720
|
-
onValueChange?.("string", dxnString);
|
|
1721
|
-
}
|
|
1722
|
-
};
|
|
1723
|
-
const handleGetValue = () => {
|
|
1724
|
-
const formValue = getValue3();
|
|
1725
|
-
if (typeof formValue === "string") {
|
|
1726
|
-
return formValue;
|
|
1727
|
-
}
|
|
1728
|
-
if (Ref.isRef(formValue)) {
|
|
1729
|
-
return formValue.dxn.toString();
|
|
1730
|
-
}
|
|
1731
|
-
return void 0;
|
|
1732
|
-
};
|
|
1733
|
-
return /* @__PURE__ */ React11.createElement(TextInput, {
|
|
2195
|
+
const handleChange = useCallback14((event) => onValueChange(type, event.target.value), [
|
|
1734
2196
|
type,
|
|
1735
|
-
|
|
1736
|
-
|
|
2197
|
+
onValueChange
|
|
2198
|
+
]);
|
|
2199
|
+
return /* @__PURE__ */ React15.createElement(FormFieldWrapper, {
|
|
2200
|
+
readonly,
|
|
2201
|
+
...props
|
|
2202
|
+
}, ({ value: value3 = "" }) => /* @__PURE__ */ React15.createElement(Input10.TextInput, {
|
|
2203
|
+
noAutoFill: true,
|
|
2204
|
+
disabled: !!readonly,
|
|
1737
2205
|
placeholder,
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
});
|
|
2206
|
+
value: value3,
|
|
2207
|
+
onChange: handleChange,
|
|
2208
|
+
onBlur
|
|
2209
|
+
}));
|
|
1743
2210
|
} finally {
|
|
1744
2211
|
_effect.f();
|
|
1745
2212
|
}
|
|
1746
2213
|
};
|
|
1747
2214
|
|
|
1748
|
-
// src/components/Form/
|
|
1749
|
-
import {
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
case FormatEnum4.Markdown:
|
|
1755
|
-
return MarkdownInput;
|
|
1756
|
-
}
|
|
1757
|
-
switch (type) {
|
|
1758
|
-
case "string":
|
|
1759
|
-
return TextInput;
|
|
1760
|
-
case "number":
|
|
1761
|
-
return NumberInput;
|
|
1762
|
-
case "boolean":
|
|
1763
|
-
return BooleanInput;
|
|
1764
|
-
}
|
|
1765
|
-
};
|
|
1766
|
-
|
|
1767
|
-
// src/components/Form/FormContent.tsx
|
|
1768
|
-
var FormField = ({ property, path, readonly, inline, onQueryRefOptions, lookupComponent, Custom }) => {
|
|
1769
|
-
var _effect = _useSignals12();
|
|
2215
|
+
// src/components/Form/fields/TextAreaField.tsx
|
|
2216
|
+
import { useSignals as _useSignals16 } from "@preact-signals/safe-react/tracking";
|
|
2217
|
+
import React16, { useCallback as useCallback15 } from "react";
|
|
2218
|
+
import { Input as Input11 } from "@dxos/react-ui";
|
|
2219
|
+
var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
|
|
2220
|
+
var _effect = _useSignals16();
|
|
1770
2221
|
try {
|
|
1771
|
-
const
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
title,
|
|
1775
|
-
name
|
|
1776
|
-
]);
|
|
1777
|
-
const placeholder = useMemo5(() => examples?.length ? `Example: "${examples[0]}"` : description, [
|
|
1778
|
-
examples,
|
|
1779
|
-
description
|
|
2222
|
+
const handleChange = useCallback15((event) => onValueChange(type, event.target.value), [
|
|
2223
|
+
type,
|
|
2224
|
+
onValueChange
|
|
1780
2225
|
]);
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
});
|
|
1793
|
-
if (FoundComponent) {
|
|
1794
|
-
return FoundComponent;
|
|
1795
|
-
}
|
|
1796
|
-
const jsonPath = createJsonPath3(path ?? []);
|
|
1797
|
-
const CustomComponent = Custom?.[jsonPath];
|
|
1798
|
-
if (CustomComponent) {
|
|
1799
|
-
return /* @__PURE__ */ React12.createElement(CustomComponent, {
|
|
1800
|
-
type,
|
|
1801
|
-
format,
|
|
1802
|
-
label,
|
|
1803
|
-
inputOnly: inline,
|
|
1804
|
-
placeholder,
|
|
1805
|
-
disabled: readonly,
|
|
1806
|
-
...inputProps
|
|
1807
|
-
});
|
|
1808
|
-
}
|
|
1809
|
-
const refProps = getRefProps(property);
|
|
1810
|
-
if (refProps) {
|
|
1811
|
-
return /* @__PURE__ */ React12.createElement(RefField, {
|
|
1812
|
-
ast: refProps.ast,
|
|
1813
|
-
array: refProps.isArray,
|
|
1814
|
-
type,
|
|
1815
|
-
format,
|
|
1816
|
-
label,
|
|
1817
|
-
placeholder,
|
|
1818
|
-
disabled: readonly,
|
|
1819
|
-
inputOnly: inline,
|
|
1820
|
-
onQueryRefOptions,
|
|
1821
|
-
...inputProps
|
|
1822
|
-
});
|
|
1823
|
-
}
|
|
1824
|
-
if (array) {
|
|
1825
|
-
return /* @__PURE__ */ React12.createElement(ArrayField, {
|
|
1826
|
-
property,
|
|
1827
|
-
path,
|
|
1828
|
-
inputProps,
|
|
1829
|
-
readonly,
|
|
1830
|
-
Custom
|
|
1831
|
-
});
|
|
1832
|
-
}
|
|
1833
|
-
const InputComponent = getInputComponent(type, format);
|
|
1834
|
-
if (InputComponent) {
|
|
1835
|
-
return /* @__PURE__ */ React12.createElement(InputComponent, {
|
|
1836
|
-
type,
|
|
1837
|
-
format,
|
|
1838
|
-
label,
|
|
1839
|
-
inputOnly: inline,
|
|
1840
|
-
placeholder,
|
|
1841
|
-
disabled: readonly,
|
|
1842
|
-
...inputProps
|
|
1843
|
-
});
|
|
1844
|
-
}
|
|
1845
|
-
if (options) {
|
|
1846
|
-
return /* @__PURE__ */ React12.createElement(SelectInput, {
|
|
1847
|
-
type,
|
|
1848
|
-
format,
|
|
1849
|
-
disabled: readonly,
|
|
1850
|
-
inputOnly: inline,
|
|
1851
|
-
label,
|
|
1852
|
-
options: options.map((option) => ({
|
|
1853
|
-
value: option,
|
|
1854
|
-
label: String(option)
|
|
1855
|
-
})),
|
|
1856
|
-
placeholder,
|
|
1857
|
-
...inputProps
|
|
1858
|
-
});
|
|
1859
|
-
}
|
|
1860
|
-
if (type === "object") {
|
|
1861
|
-
const baseNode = findNode3(ast, isDiscriminatedUnion2);
|
|
1862
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode3(ast, SchemaAST4.isTypeLiteral);
|
|
1863
|
-
if (typeLiteral) {
|
|
1864
|
-
return /* @__PURE__ */ React12.createElement(React12.Fragment, null, !inline && /* @__PURE__ */ React12.createElement("h3", {
|
|
1865
|
-
className: mx8("text-lg mlb-inputSpacingBlock first:mbs-0")
|
|
1866
|
-
}, label), /* @__PURE__ */ React12.createElement(FormFields, {
|
|
1867
|
-
schema: Schema.make(typeLiteral),
|
|
1868
|
-
path,
|
|
1869
|
-
readonly,
|
|
1870
|
-
onQueryRefOptions,
|
|
1871
|
-
Custom,
|
|
1872
|
-
lookupComponent
|
|
1873
|
-
}));
|
|
1874
|
-
}
|
|
1875
|
-
}
|
|
1876
|
-
return null;
|
|
2226
|
+
return /* @__PURE__ */ React16.createElement(FormFieldWrapper, {
|
|
2227
|
+
readonly,
|
|
2228
|
+
...props
|
|
2229
|
+
}, ({ value: value3 = "" }) => /* @__PURE__ */ React16.createElement(Input11.TextArea, {
|
|
2230
|
+
rows: 3,
|
|
2231
|
+
disabled: !!readonly,
|
|
2232
|
+
placeholder,
|
|
2233
|
+
value: value3,
|
|
2234
|
+
onChange: handleChange,
|
|
2235
|
+
onBlur
|
|
2236
|
+
}));
|
|
1877
2237
|
} finally {
|
|
1878
2238
|
_effect.f();
|
|
1879
2239
|
}
|
|
1880
2240
|
};
|
|
1881
|
-
var FormFields = /* @__PURE__ */ forwardRef(({ classNames, testId, schema, path, filter, sort, readonly, lookupComponent, Custom, onQueryRefOptions }, forwardRef2) => {
|
|
1882
|
-
var _effect = _useSignals12();
|
|
1883
|
-
try {
|
|
1884
|
-
const values = useFormValues(path);
|
|
1885
|
-
const properties = useMemo5(() => {
|
|
1886
|
-
const props = getSchemaProperties2(schema.ast, values);
|
|
1887
|
-
const filtered = filter ? filter(props) : props;
|
|
1888
|
-
return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
|
|
1889
|
-
}, [
|
|
1890
|
-
schema,
|
|
1891
|
-
values,
|
|
1892
|
-
filter,
|
|
1893
|
-
sort
|
|
1894
|
-
]);
|
|
1895
|
-
return /* @__PURE__ */ React12.createElement("div", {
|
|
1896
|
-
role: "form",
|
|
1897
|
-
className: mx8("is-full", classNames),
|
|
1898
|
-
ref: forwardRef2
|
|
1899
|
-
}, properties.map((property) => {
|
|
1900
|
-
return /* @__PURE__ */ React12.createElement(FormField, {
|
|
1901
|
-
key: property.name,
|
|
1902
|
-
property,
|
|
1903
|
-
path: [
|
|
1904
|
-
...path ?? [],
|
|
1905
|
-
property.name
|
|
1906
|
-
],
|
|
1907
|
-
readonly,
|
|
1908
|
-
onQueryRefOptions,
|
|
1909
|
-
lookupComponent,
|
|
1910
|
-
Custom
|
|
1911
|
-
});
|
|
1912
|
-
}).filter(isNotFalsy));
|
|
1913
|
-
} finally {
|
|
1914
|
-
_effect.f();
|
|
1915
|
-
}
|
|
1916
|
-
});
|
|
1917
2241
|
|
|
1918
|
-
// src/components/Form/
|
|
1919
|
-
|
|
1920
|
-
|
|
2242
|
+
// src/components/Form/fields/TupleField.tsx
|
|
2243
|
+
import { useSignals as _useSignals17 } from "@preact-signals/safe-react/tracking";
|
|
2244
|
+
import React17 from "react";
|
|
2245
|
+
import { Input as Input12 } from "@dxos/react-ui";
|
|
2246
|
+
import { mx as mx6 } from "@dxos/react-ui-theme";
|
|
2247
|
+
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
2248
|
+
var gridCols = [
|
|
2249
|
+
"grid-cols-1",
|
|
2250
|
+
"grid-cols-2",
|
|
2251
|
+
"grid-cols-3",
|
|
2252
|
+
"grid-cols-4"
|
|
2253
|
+
];
|
|
2254
|
+
var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValueChange, onBlur }) => {
|
|
2255
|
+
var _effect = _useSignals17();
|
|
1921
2256
|
try {
|
|
1922
|
-
const
|
|
1923
|
-
const
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
if (autoFocus && formRef.current) {
|
|
1929
|
-
const input = formRef.current.querySelector("input");
|
|
1930
|
-
if (input) {
|
|
1931
|
-
input.focus();
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
}, [
|
|
1935
|
-
autoFocus
|
|
1936
|
-
]);
|
|
1937
|
-
return /* @__PURE__ */ React13.createElement(FormProvider, {
|
|
1938
|
-
formRef,
|
|
1939
|
-
schema,
|
|
1940
|
-
autoSave,
|
|
1941
|
-
initialValues,
|
|
1942
|
-
onValuesChanged,
|
|
1943
|
-
onValidate,
|
|
1944
|
-
onValid: handleValid,
|
|
1945
|
-
onSave
|
|
1946
|
-
}, /* @__PURE__ */ React13.createElement("div", {
|
|
1947
|
-
role: "none",
|
|
1948
|
-
className: "contents",
|
|
1949
|
-
"data-testid": testId
|
|
1950
|
-
}, /* @__PURE__ */ React13.createElement(FormFields, {
|
|
1951
|
-
...props,
|
|
1952
|
-
ref: formRef,
|
|
1953
|
-
classNames: [
|
|
1954
|
-
outerSpacing === "blockStart-0" ? "pli-cardSpacingInline mbe-cardSpacingBlock [&>.mbs-inputSpacingBlock:first-child]:!mbs-0" : outerSpacing === "scroll-fields" ? "pli-cardSpacingInline pbe-cardSpacingBlock" : outerSpacing ? cardSpacing2 : false,
|
|
1955
|
-
outerSpacing === "scroll-fields" && cardDialogOverflow,
|
|
1956
|
-
classNames
|
|
1957
|
-
],
|
|
1958
|
-
readonly,
|
|
1959
|
-
schema
|
|
1960
|
-
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React13.createElement(FormActions, {
|
|
2257
|
+
const { status, error } = getStatus();
|
|
2258
|
+
const values = getValue() ?? {};
|
|
2259
|
+
return /* @__PURE__ */ React17.createElement(Input12.Root, {
|
|
2260
|
+
validationValence: status
|
|
2261
|
+
}, /* @__PURE__ */ React17.createElement(FormFieldLabel, {
|
|
2262
|
+
error,
|
|
1961
2263
|
readonly,
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
2264
|
+
label
|
|
2265
|
+
}), /* @__PURE__ */ React17.createElement("div", {
|
|
2266
|
+
className: mx6("grid gap-2", gridCols[binding.length - 1])
|
|
2267
|
+
}, binding.map((prop) => /* @__PURE__ */ React17.createElement(Input12.TextInput, {
|
|
2268
|
+
key: prop,
|
|
2269
|
+
type: "number",
|
|
2270
|
+
disabled: !!readonly,
|
|
2271
|
+
value: values[prop],
|
|
2272
|
+
onChange: (event) => {
|
|
2273
|
+
onValueChange(type, {
|
|
2274
|
+
...values,
|
|
2275
|
+
[prop]: safeParseFloat3(event.target.value, 0)
|
|
2276
|
+
});
|
|
2277
|
+
},
|
|
2278
|
+
onBlur
|
|
2279
|
+
}))));
|
|
1965
2280
|
} finally {
|
|
1966
2281
|
_effect.f();
|
|
1967
2282
|
}
|
|
@@ -1969,45 +2284,67 @@ var Form = ({ classNames, testId, values: initialValues, autoFocus, readonly, au
|
|
|
1969
2284
|
|
|
1970
2285
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
1971
2286
|
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1972
|
-
var FieldEditor = ({ projection, field, registry, onSave, onCancel
|
|
1973
|
-
var _effect =
|
|
2287
|
+
var FieldEditor = ({ readonly, projection, field, registry, onSave, onCancel }) => {
|
|
2288
|
+
var _effect = _useSignals18();
|
|
1974
2289
|
try {
|
|
1975
|
-
const { t } =
|
|
1976
|
-
const [props, setProps] =
|
|
1977
|
-
|
|
2290
|
+
const { t } = useTranslation9(translationKey);
|
|
2291
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2292
|
+
useEffect6(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1978
2293
|
field,
|
|
1979
2294
|
projection
|
|
1980
2295
|
]);
|
|
1981
|
-
const [schemas, setSchemas] =
|
|
1982
|
-
|
|
2296
|
+
const [schemas, setSchemas] = useState6([]);
|
|
2297
|
+
useAsyncEffect2(async () => {
|
|
1983
2298
|
if (!registry) {
|
|
1984
2299
|
return;
|
|
1985
2300
|
}
|
|
1986
2301
|
const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
|
|
1987
2302
|
fire: true
|
|
1988
2303
|
});
|
|
1989
|
-
const
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
});
|
|
1993
|
-
return () => {
|
|
1994
|
-
clearTimeout(t2);
|
|
1995
|
-
subscription?.();
|
|
1996
|
-
};
|
|
2304
|
+
const schemas2 = await registry.query().run();
|
|
2305
|
+
setSchemas(schemas2);
|
|
2306
|
+
return () => subscription?.();
|
|
1997
2307
|
}, [
|
|
1998
2308
|
registry
|
|
1999
2309
|
]);
|
|
2000
|
-
const [referenceSchema, setReferenceSchema] =
|
|
2001
|
-
|
|
2310
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2311
|
+
useEffect6(() => {
|
|
2002
2312
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
2003
2313
|
}, [
|
|
2004
2314
|
schemas,
|
|
2005
2315
|
props?.referenceSchema
|
|
2006
2316
|
]);
|
|
2007
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2317
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
2008
2318
|
fieldSchema: getFormatSchema(props?.format)
|
|
2009
2319
|
});
|
|
2010
|
-
const
|
|
2320
|
+
const fieldMap = useMemo8(() => ({
|
|
2321
|
+
["format"]: (props2) => /* @__PURE__ */ React18.createElement(SelectField, {
|
|
2322
|
+
...props2,
|
|
2323
|
+
options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
|
|
2324
|
+
value: value3,
|
|
2325
|
+
label: t(`format ${value3}`)
|
|
2326
|
+
}))
|
|
2327
|
+
}),
|
|
2328
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React18.createElement(SelectField, {
|
|
2329
|
+
...props2,
|
|
2330
|
+
options: schemas.map((schema) => ({
|
|
2331
|
+
value: schema.typename
|
|
2332
|
+
}))
|
|
2333
|
+
}),
|
|
2334
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React18.createElement(SelectField, {
|
|
2335
|
+
...props2,
|
|
2336
|
+
options: referenceSchema ? getFormProperties(referenceSchema.ast).sort((a, b) => a.name.toString().localeCompare(b.name.toString())).map((p) => ({
|
|
2337
|
+
value: p.name.toString()
|
|
2338
|
+
})) : []
|
|
2339
|
+
}),
|
|
2340
|
+
["options"]: (props2) => /* @__PURE__ */ React18.createElement(SelectOptionField, props2)
|
|
2341
|
+
}), [
|
|
2342
|
+
t,
|
|
2343
|
+
schemas,
|
|
2344
|
+
referenceSchema
|
|
2345
|
+
]);
|
|
2346
|
+
const propIsNotType = useCallback16((props2) => props2.filter((prop) => prop.name !== "type"), []);
|
|
2347
|
+
const handleValuesChanged = useCallback16((_props) => {
|
|
2011
2348
|
setFieldSchema((prev) => {
|
|
2012
2349
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
2013
2350
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -2028,10 +2365,12 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
|
|
|
2028
2365
|
});
|
|
2029
2366
|
setProps((props2) => {
|
|
2030
2367
|
const type = formatToType[_props.format];
|
|
2368
|
+
const additionalProps = formatToAdditionalPropertyAttributes[_props.format];
|
|
2031
2369
|
if (props2.type !== type) {
|
|
2032
2370
|
return {
|
|
2033
2371
|
...props2,
|
|
2034
2372
|
..._props,
|
|
2373
|
+
...additionalProps,
|
|
2035
2374
|
type
|
|
2036
2375
|
};
|
|
2037
2376
|
}
|
|
@@ -2042,7 +2381,7 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
|
|
|
2042
2381
|
props.format,
|
|
2043
2382
|
props.referenceSchema
|
|
2044
2383
|
]);
|
|
2045
|
-
const handleValidate =
|
|
2384
|
+
const handleValidate = useCallback16(({ property }) => {
|
|
2046
2385
|
if (property && projection.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
2047
2386
|
return [
|
|
2048
2387
|
{
|
|
@@ -2055,7 +2394,7 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
|
|
|
2055
2394
|
projection.fields,
|
|
2056
2395
|
field
|
|
2057
2396
|
]);
|
|
2058
|
-
const handleSave =
|
|
2397
|
+
const handleSave = useCallback16((props2) => {
|
|
2059
2398
|
projection.setFieldProjection({
|
|
2060
2399
|
field,
|
|
2061
2400
|
props: props2
|
|
@@ -2066,56 +2405,31 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
|
|
|
2066
2405
|
field,
|
|
2067
2406
|
onSave
|
|
2068
2407
|
]);
|
|
2069
|
-
const handleCancel =
|
|
2070
|
-
requestAnimationFrame(() => onCancel?.());
|
|
2408
|
+
const handleCancel = useCallback16(() => {
|
|
2071
2409
|
onSave();
|
|
2410
|
+
requestAnimationFrame(() => onCancel?.());
|
|
2072
2411
|
}, [
|
|
2073
2412
|
onSave
|
|
2074
2413
|
]);
|
|
2075
|
-
const custom = useMemo7(() => ({
|
|
2076
|
-
["format"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
2077
|
-
...props2,
|
|
2078
|
-
options: FormatEnums.filter((value) => value !== FormatEnum5.None).map((value) => ({
|
|
2079
|
-
value,
|
|
2080
|
-
label: t(`format ${value}`)
|
|
2081
|
-
}))
|
|
2082
|
-
}),
|
|
2083
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
2084
|
-
...props2,
|
|
2085
|
-
options: schemas.map((schema) => ({
|
|
2086
|
-
value: schema.typename
|
|
2087
|
-
}))
|
|
2088
|
-
}),
|
|
2089
|
-
["referencePath"]: (props2) => /* @__PURE__ */ React14.createElement(SelectInput, {
|
|
2090
|
-
...props2,
|
|
2091
|
-
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
2092
|
-
value: p.name
|
|
2093
|
-
})) : []
|
|
2094
|
-
}),
|
|
2095
|
-
["options"]: (props2) => /* @__PURE__ */ React14.createElement(SelectOptionInput, props2)
|
|
2096
|
-
}), [
|
|
2097
|
-
t,
|
|
2098
|
-
schemas,
|
|
2099
|
-
referenceSchema
|
|
2100
|
-
]);
|
|
2101
|
-
const propIsNotType = useCallback9((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
2102
2414
|
if (!fieldSchema) {
|
|
2103
2415
|
log3.warn("invalid format", {
|
|
2104
2416
|
props
|
|
2105
2417
|
}, {
|
|
2106
2418
|
F: __dxlog_file4,
|
|
2107
|
-
L:
|
|
2419
|
+
L: 166,
|
|
2108
2420
|
S: void 0,
|
|
2109
2421
|
C: (f, a) => f(...a)
|
|
2110
2422
|
});
|
|
2111
2423
|
return null;
|
|
2112
2424
|
}
|
|
2113
|
-
return /* @__PURE__ */
|
|
2425
|
+
return /* @__PURE__ */ React18.createElement(Form.Root, {
|
|
2114
2426
|
key: field.id,
|
|
2427
|
+
fieldMap,
|
|
2115
2428
|
autoFocus: true,
|
|
2116
|
-
|
|
2429
|
+
readonly,
|
|
2117
2430
|
schema: fieldSchema,
|
|
2118
|
-
|
|
2431
|
+
values: props,
|
|
2432
|
+
exclude: propIsNotType,
|
|
2119
2433
|
sort: [
|
|
2120
2434
|
"property",
|
|
2121
2435
|
"format"
|
|
@@ -2123,123 +2437,214 @@ var FieldEditor = ({ projection, field, registry, onSave, onCancel, outerSpacing
|
|
|
2123
2437
|
onValuesChanged: handleValuesChanged,
|
|
2124
2438
|
onValidate: handleValidate,
|
|
2125
2439
|
onSave: handleSave,
|
|
2126
|
-
onCancel: handleCancel
|
|
2127
|
-
|
|
2128
|
-
outerSpacing
|
|
2129
|
-
});
|
|
2440
|
+
onCancel: handleCancel
|
|
2441
|
+
}, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null), /* @__PURE__ */ React18.createElement(Form.Actions, null)));
|
|
2130
2442
|
} finally {
|
|
2131
2443
|
_effect.f();
|
|
2132
2444
|
}
|
|
2133
2445
|
};
|
|
2134
2446
|
|
|
2135
2447
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2136
|
-
import { useSignals as
|
|
2137
|
-
import
|
|
2138
|
-
import
|
|
2139
|
-
import
|
|
2140
|
-
import
|
|
2141
|
-
import {
|
|
2448
|
+
import { useSignals as _useSignals19 } from "@preact-signals/safe-react/tracking";
|
|
2449
|
+
import * as Array2 from "effect/Array";
|
|
2450
|
+
import * as Match2 from "effect/Match";
|
|
2451
|
+
import * as Option4 from "effect/Option";
|
|
2452
|
+
import * as Schema3 from "effect/Schema";
|
|
2453
|
+
import React19, { forwardRef as forwardRef3, useCallback as useCallback17, useImperativeHandle, useMemo as useMemo9, useState as useState7 } from "react";
|
|
2454
|
+
import { Filter as Filter2, Format as Format5, Query, QueryAST } from "@dxos/echo";
|
|
2455
|
+
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2456
|
+
import "@dxos/echo-db";
|
|
2457
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2458
|
+
import { Callout, IconButton as IconButton4, Input as Input13, useTranslation as useTranslation10 } from "@dxos/react-ui";
|
|
2459
|
+
import { QueryForm } from "@dxos/react-ui-components";
|
|
2142
2460
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
2143
|
-
import {
|
|
2144
|
-
import {
|
|
2145
|
-
import { FieldSchema, VIEW_FIELD_LIMIT, ProjectionModel } from "@dxos/schema";
|
|
2461
|
+
import { mx as mx7, subtleHover as subtleHover2 } from "@dxos/react-ui-theme";
|
|
2462
|
+
import { FieldSchema, ProjectionModel, VIEW_FIELD_LIMIT, getTypenameFromQuery } from "@dxos/schema";
|
|
2146
2463
|
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
2147
|
-
var
|
|
2148
|
-
var
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
})
|
|
2152
|
-
}).pipe(Schema2.mutable);
|
|
2153
|
-
var ViewEditor = ({ classNames, schema, view, registry, readonly: _readonly, showHeading = false, onTypenameChanged, onDelete, outerSpacing = true }) => {
|
|
2154
|
-
var _effect = _useSignals15();
|
|
2464
|
+
var listGrid = "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]";
|
|
2465
|
+
var listItemGrid = "grid grid-cols-subgrid col-span-5";
|
|
2466
|
+
var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2467
|
+
var _effect = _useSignals19();
|
|
2155
2468
|
try {
|
|
2156
|
-
const
|
|
2157
|
-
const
|
|
2469
|
+
const schemaReadonly = !isMutable(schema);
|
|
2470
|
+
const { t } = useTranslation10(translationKey);
|
|
2471
|
+
const projectionModel = useMemo9(() => {
|
|
2158
2472
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2159
2473
|
return new ProjectionModel(jsonSchema, view.projection);
|
|
2160
2474
|
}, [
|
|
2161
2475
|
schema,
|
|
2162
|
-
view.projection
|
|
2476
|
+
JSON.stringify(view.projection)
|
|
2163
2477
|
]);
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
const viewValues = useMemo8(() => {
|
|
2167
|
-
return {
|
|
2168
|
-
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
2169
|
-
// TODO(burdon): Settings should have domain name owned by user.
|
|
2170
|
-
typename: view.query.typename
|
|
2171
|
-
};
|
|
2172
|
-
}, [
|
|
2173
|
-
view.query.typename
|
|
2478
|
+
useImperativeHandle(forwardedRef, () => projectionModel, [
|
|
2479
|
+
projectionModel
|
|
2174
2480
|
]);
|
|
2175
|
-
const
|
|
2176
|
-
|
|
2177
|
-
|
|
2481
|
+
const [expandedField, setExpandedField] = useState7();
|
|
2482
|
+
const queueTarget = Match2.value(view.query.ast).pipe(Match2.when({
|
|
2483
|
+
type: "options"
|
|
2484
|
+
}, ({ options }) => {
|
|
2485
|
+
return Option4.fromNullable(options.queues).pipe(Option4.flatMap((queues) => Array2.head(queues)), Option4.getOrUndefined);
|
|
2486
|
+
}), Match2.orElse(() => void 0));
|
|
2487
|
+
const viewSchema = useMemo9(() => {
|
|
2488
|
+
const base = Schema3.Struct({
|
|
2489
|
+
query: mode === "schema" ? Format5.URL.annotations({
|
|
2490
|
+
title: "Record type"
|
|
2491
|
+
}) : QueryAST.Query.annotations({
|
|
2492
|
+
title: "Query"
|
|
2493
|
+
})
|
|
2494
|
+
});
|
|
2495
|
+
if (mode === "tag") {
|
|
2496
|
+
return Schema3.Struct({
|
|
2497
|
+
...base.fields,
|
|
2498
|
+
target: Schema3.optional(Schema3.String.annotations({
|
|
2499
|
+
title: "Target Queue"
|
|
2500
|
+
}))
|
|
2501
|
+
}).pipe(Schema3.mutable);
|
|
2178
2502
|
}
|
|
2179
|
-
|
|
2503
|
+
return base.pipe(Schema3.mutable);
|
|
2180
2504
|
}, [
|
|
2181
|
-
|
|
2505
|
+
mode
|
|
2182
2506
|
]);
|
|
2183
|
-
const
|
|
2184
|
-
|
|
2507
|
+
const viewValues = useMemo9(() => ({
|
|
2508
|
+
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2509
|
+
target: queueTarget
|
|
2510
|
+
}), [
|
|
2511
|
+
mode,
|
|
2512
|
+
view.query.ast,
|
|
2513
|
+
queueTarget
|
|
2514
|
+
]);
|
|
2515
|
+
const fieldMap = useMemo9(() => mode === "tag" ? customFields({
|
|
2516
|
+
types,
|
|
2517
|
+
tags
|
|
2518
|
+
}) : void 0, [
|
|
2519
|
+
mode,
|
|
2520
|
+
types,
|
|
2521
|
+
tags
|
|
2522
|
+
]);
|
|
2523
|
+
const handleAdd = useCallback17(() => {
|
|
2524
|
+
invariant2(!readonly, void 0, {
|
|
2185
2525
|
F: __dxlog_file5,
|
|
2186
|
-
L:
|
|
2526
|
+
L: 129,
|
|
2187
2527
|
S: void 0,
|
|
2188
2528
|
A: [
|
|
2189
2529
|
"!readonly",
|
|
2190
2530
|
""
|
|
2191
2531
|
]
|
|
2192
2532
|
});
|
|
2193
|
-
const
|
|
2194
|
-
|
|
2533
|
+
const field = projectionModel.createFieldProjection();
|
|
2534
|
+
setExpandedField(field.id);
|
|
2195
2535
|
}, [
|
|
2196
2536
|
schema,
|
|
2197
|
-
|
|
2537
|
+
projectionModel,
|
|
2198
2538
|
readonly
|
|
2199
2539
|
]);
|
|
2200
|
-
const handleUpdate =
|
|
2201
|
-
|
|
2540
|
+
const handleUpdate = useCallback17((values) => {
|
|
2541
|
+
requestAnimationFrame(() => {
|
|
2542
|
+
const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : values.query;
|
|
2543
|
+
onQueryChanged?.(query, values.target);
|
|
2544
|
+
});
|
|
2545
|
+
}, [
|
|
2546
|
+
onQueryChanged,
|
|
2547
|
+
view,
|
|
2548
|
+
queueTarget,
|
|
2549
|
+
mode
|
|
2550
|
+
]);
|
|
2551
|
+
const handleDelete = useCallback17((fieldId) => {
|
|
2552
|
+
invariant2(!readonly, void 0, {
|
|
2202
2553
|
F: __dxlog_file5,
|
|
2203
|
-
L:
|
|
2554
|
+
L: 146,
|
|
2204
2555
|
S: void 0,
|
|
2205
2556
|
A: [
|
|
2206
2557
|
"!readonly",
|
|
2207
2558
|
""
|
|
2208
2559
|
]
|
|
2209
2560
|
});
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2561
|
+
if (fieldId === expandedField) {
|
|
2562
|
+
setExpandedField(void 0);
|
|
2563
|
+
}
|
|
2564
|
+
onDelete?.(fieldId);
|
|
2565
|
+
}, [
|
|
2566
|
+
expandedField,
|
|
2567
|
+
onDelete,
|
|
2568
|
+
readonly
|
|
2569
|
+
]);
|
|
2570
|
+
return /* @__PURE__ */ React19.createElement("div", {
|
|
2571
|
+
role: "none",
|
|
2572
|
+
className: mx7(classNames)
|
|
2573
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React19.createElement(Callout.Root, {
|
|
2574
|
+
valence: "info",
|
|
2575
|
+
classNames: "mlb-cardSpacingBlock"
|
|
2576
|
+
}, /* @__PURE__ */ React19.createElement(Callout.Title, null, t("system schema description"))), /* @__PURE__ */ React19.createElement(Form.Root, {
|
|
2577
|
+
schema: viewSchema,
|
|
2578
|
+
values: viewValues,
|
|
2579
|
+
fieldMap,
|
|
2580
|
+
autoSave: true,
|
|
2581
|
+
onSave: handleUpdate
|
|
2582
|
+
}, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), /* @__PURE__ */ React19.createElement(FormFieldLabel, {
|
|
2583
|
+
label: t("fields label"),
|
|
2584
|
+
asChild: true
|
|
2585
|
+
}), /* @__PURE__ */ React19.createElement(FieldList, {
|
|
2586
|
+
schema,
|
|
2587
|
+
view,
|
|
2588
|
+
registry,
|
|
2589
|
+
readonly,
|
|
2590
|
+
showHeading,
|
|
2591
|
+
onDelete: handleDelete
|
|
2592
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React19.createElement("div", {
|
|
2593
|
+
role: "none",
|
|
2594
|
+
className: "mlb-cardSpacingBlock"
|
|
2595
|
+
}, /* @__PURE__ */ React19.createElement(IconButton4, {
|
|
2596
|
+
icon: "ph--plus--regular",
|
|
2597
|
+
label: t("add property button label"),
|
|
2598
|
+
onClick: readonly ? void 0 : handleAdd,
|
|
2599
|
+
// TODO(burdon): Show field limit in ux (not tooltip).
|
|
2600
|
+
disabled: view.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
2601
|
+
classNames: "is-full"
|
|
2602
|
+
})));
|
|
2603
|
+
} finally {
|
|
2604
|
+
_effect.f();
|
|
2605
|
+
}
|
|
2606
|
+
});
|
|
2607
|
+
var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
2608
|
+
var _effect = _useSignals19();
|
|
2609
|
+
try {
|
|
2610
|
+
const schemaReadonly = !isMutable(schema);
|
|
2611
|
+
const { t } = useTranslation10(translationKey);
|
|
2612
|
+
const projectionModel = useMemo9(() => {
|
|
2613
|
+
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2614
|
+
return new ProjectionModel(jsonSchema, view.projection);
|
|
2615
|
+
}, [
|
|
2616
|
+
schema,
|
|
2617
|
+
JSON.stringify(view.projection)
|
|
2618
|
+
]);
|
|
2619
|
+
const [expandedField, setExpandedField] = useState7();
|
|
2620
|
+
const handleToggleField = useCallback17((field) => {
|
|
2621
|
+
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2215
2622
|
}, [
|
|
2216
|
-
view.query.typename,
|
|
2217
|
-
onTypenameChanged,
|
|
2218
2623
|
readonly
|
|
2219
2624
|
]);
|
|
2220
|
-
const handleDelete =
|
|
2221
|
-
|
|
2625
|
+
const handleDelete = useCallback17((fieldId) => {
|
|
2626
|
+
invariant2(!readonly, void 0, {
|
|
2222
2627
|
F: __dxlog_file5,
|
|
2223
|
-
L:
|
|
2628
|
+
L: 218,
|
|
2224
2629
|
S: void 0,
|
|
2225
2630
|
A: [
|
|
2226
2631
|
"!readonly",
|
|
2227
2632
|
""
|
|
2228
2633
|
]
|
|
2229
2634
|
});
|
|
2230
|
-
if (fieldId ===
|
|
2231
|
-
|
|
2635
|
+
if (fieldId === expandedField) {
|
|
2636
|
+
setExpandedField(void 0);
|
|
2232
2637
|
}
|
|
2233
2638
|
onDelete?.(fieldId);
|
|
2234
2639
|
}, [
|
|
2235
|
-
|
|
2640
|
+
expandedField,
|
|
2236
2641
|
onDelete,
|
|
2237
2642
|
readonly
|
|
2238
2643
|
]);
|
|
2239
|
-
const handleMove =
|
|
2240
|
-
|
|
2644
|
+
const handleMove = useCallback17((fromIndex, toIndex) => {
|
|
2645
|
+
invariant2(!readonly, void 0, {
|
|
2241
2646
|
F: __dxlog_file5,
|
|
2242
|
-
L:
|
|
2647
|
+
L: 230,
|
|
2243
2648
|
S: void 0,
|
|
2244
2649
|
A: [
|
|
2245
2650
|
"!readonly",
|
|
@@ -2256,111 +2661,101 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly: _readonly, sho
|
|
|
2256
2661
|
view.projection.fields,
|
|
2257
2662
|
readonly
|
|
2258
2663
|
]);
|
|
2259
|
-
const handleClose =
|
|
2260
|
-
const
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
projection.hideFieldProjection(fieldId);
|
|
2664
|
+
const handleClose = useCallback17(() => setExpandedField(void 0), []);
|
|
2665
|
+
const handleHide = useCallback17((fieldId) => {
|
|
2666
|
+
setExpandedField(void 0);
|
|
2667
|
+
projectionModel.hideFieldProjection(fieldId);
|
|
2264
2668
|
}, [
|
|
2265
|
-
|
|
2669
|
+
projectionModel
|
|
2266
2670
|
]);
|
|
2267
|
-
const handleShow =
|
|
2268
|
-
|
|
2269
|
-
|
|
2671
|
+
const handleShow = useCallback17((property) => {
|
|
2672
|
+
setExpandedField(void 0);
|
|
2673
|
+
projectionModel.showFieldProjection(property);
|
|
2270
2674
|
}, [
|
|
2271
|
-
|
|
2675
|
+
projectionModel
|
|
2272
2676
|
]);
|
|
2273
|
-
return /* @__PURE__ */
|
|
2274
|
-
role: "none",
|
|
2275
|
-
className: mx9(classNames)
|
|
2276
|
-
}, readonly && /* @__PURE__ */ React15.createElement("div", {
|
|
2277
|
-
role: "none",
|
|
2278
|
-
className: mx9("is-full", outerSpacing && "plb-cardSpacingBlock pli-cardSpacingInline")
|
|
2279
|
-
}, /* @__PURE__ */ React15.createElement(Callout.Root, {
|
|
2280
|
-
valence: "info"
|
|
2281
|
-
}, /* @__PURE__ */ React15.createElement(Callout.Title, null, t("system schema description")))), /* @__PURE__ */ React15.createElement(Form, {
|
|
2282
|
-
autoSave: true,
|
|
2283
|
-
schema: ViewMetaSchema,
|
|
2284
|
-
values: viewValues,
|
|
2285
|
-
readonly,
|
|
2286
|
-
onSave: handleUpdate,
|
|
2287
|
-
outerSpacing
|
|
2288
|
-
}), /* @__PURE__ */ React15.createElement("div", {
|
|
2289
|
-
role: "none",
|
|
2290
|
-
className: outerSpacing ? cardSpacing3 : "mlb-cardSpacingBlock"
|
|
2291
|
-
}, /* @__PURE__ */ React15.createElement("label", {
|
|
2292
|
-
className: mx9(inputTextLabel)
|
|
2293
|
-
}, t("fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
|
|
2677
|
+
return /* @__PURE__ */ React19.createElement(List2.Root, {
|
|
2294
2678
|
items: view.projection.fields,
|
|
2295
|
-
isItem:
|
|
2296
|
-
getId: (
|
|
2297
|
-
readonly,
|
|
2298
|
-
|
|
2299
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
}, /* @__PURE__ */ React15.createElement("div", null), /* @__PURE__ */ React15.createElement("div", {
|
|
2303
|
-
className: "flex items-center text-sm"
|
|
2304
|
-
}, t("field path label"))), /* @__PURE__ */ React15.createElement("div", {
|
|
2305
|
-
role: "list",
|
|
2306
|
-
className: "flex flex-col is-full"
|
|
2307
|
-
}, fields?.map((field2) => /* @__PURE__ */ React15.createElement(List2.Item, {
|
|
2308
|
-
key: field2.id,
|
|
2309
|
-
item: field2,
|
|
2310
|
-
classNames: mx9(grid, ghostHover, "overflow-hidden", !readonly && "cursor-pointer")
|
|
2311
|
-
}, /* @__PURE__ */ React15.createElement(List2.ItemDragHandle, null), /* @__PURE__ */ React15.createElement(List2.ItemTitle, {
|
|
2312
|
-
onClick: () => handleSelect(field2)
|
|
2313
|
-
}, field2.path), /* @__PURE__ */ React15.createElement(List2.ItemButton, {
|
|
2314
|
-
"data-testid": "hide-field-button",
|
|
2315
|
-
icon: "ph--eye-slash--regular",
|
|
2316
|
-
// TDOO(burdon): Is this the correct test?
|
|
2317
|
-
disabled: view.projection.fields.length <= 1,
|
|
2318
|
-
onClick: () => handleHide(field2.id)
|
|
2319
|
-
}), !readonly && /* @__PURE__ */ React15.createElement(List2.ItemDeleteButton, {
|
|
2320
|
-
disabled: view.projection.fields.length <= 1,
|
|
2321
|
-
onClick: () => handleDelete(field2.id)
|
|
2322
|
-
})))))), hiddenProperties.length > 0 && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("label", {
|
|
2323
|
-
className: mx9(inputTextLabel)
|
|
2324
|
-
}, t("hidden fields label")), /* @__PURE__ */ React15.createElement(List2.Root, {
|
|
2325
|
-
items: hiddenProperties,
|
|
2326
|
-
isItem: (item) => typeof item === "string",
|
|
2327
|
-
getId: (property) => property
|
|
2328
|
-
}, ({ items: properties }) => /* @__PURE__ */ React15.createElement("div", {
|
|
2679
|
+
isItem: Schema3.is(FieldSchema),
|
|
2680
|
+
getId: (field) => field.id,
|
|
2681
|
+
onMove: readonly ? void 0 : handleMove,
|
|
2682
|
+
readonly
|
|
2683
|
+
}, ({ items: fields }) => /* @__PURE__ */ React19.createElement(React19.Fragment, null, showHeading && /* @__PURE__ */ React19.createElement("h3", {
|
|
2684
|
+
className: "text-sm"
|
|
2685
|
+
}, t("field path label")), /* @__PURE__ */ React19.createElement("div", {
|
|
2329
2686
|
role: "list",
|
|
2330
|
-
className:
|
|
2331
|
-
},
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2687
|
+
className: listGrid
|
|
2688
|
+
}, fields?.map((field) => {
|
|
2689
|
+
const hidden = field.visible === false;
|
|
2690
|
+
return /* @__PURE__ */ React19.createElement(List2.Item, {
|
|
2691
|
+
key: field.id,
|
|
2692
|
+
item: field,
|
|
2693
|
+
classNames: listItemGrid,
|
|
2694
|
+
"aria-expanded": expandedField === field.id
|
|
2695
|
+
}, /* @__PURE__ */ React19.createElement("div", {
|
|
2696
|
+
role: "none",
|
|
2697
|
+
className: mx7(subtleHover2, listItemGrid, "rounded-sm cursor-pointer min-bs-10")
|
|
2698
|
+
}, /* @__PURE__ */ React19.createElement(List2.ItemDragHandle, {
|
|
2699
|
+
disabled: readonly || schemaReadonly
|
|
2700
|
+
}), /* @__PURE__ */ React19.createElement(List2.ItemTitle, {
|
|
2701
|
+
classNames: hidden && "text-subdued",
|
|
2702
|
+
onClick: () => handleToggleField(field)
|
|
2703
|
+
}, field.path), /* @__PURE__ */ React19.createElement(List2.ItemButton, {
|
|
2704
|
+
label: t(hidden ? "show field label" : "hide field label"),
|
|
2705
|
+
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2706
|
+
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2707
|
+
autoHide: false,
|
|
2708
|
+
disabled: readonly || !hidden && projectionModel.fields.length <= 1,
|
|
2709
|
+
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2710
|
+
}), !readonly && /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement(List2.ItemDeleteButton, {
|
|
2711
|
+
label: t("delete field label"),
|
|
2712
|
+
autoHide: false,
|
|
2713
|
+
disabled: readonly || schemaReadonly || view.projection.fields.length <= 1,
|
|
2714
|
+
onClick: () => handleDelete(field.id),
|
|
2715
|
+
"data-testid": "field.delete"
|
|
2716
|
+
}), /* @__PURE__ */ React19.createElement(IconButton4, {
|
|
2717
|
+
iconOnly: true,
|
|
2718
|
+
variant: "ghost",
|
|
2719
|
+
label: t("toggle expand label", {
|
|
2720
|
+
ns: "os"
|
|
2721
|
+
}),
|
|
2722
|
+
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2723
|
+
onClick: () => handleToggleField(field),
|
|
2724
|
+
"data-testid": "field.toggle"
|
|
2725
|
+
}))), expandedField === field.id && !readonly && /* @__PURE__ */ React19.createElement("div", {
|
|
2726
|
+
role: "none",
|
|
2727
|
+
className: "col-span-5 mbs-1 mbe-1 border border-separator rounded-md"
|
|
2728
|
+
}, /* @__PURE__ */ React19.createElement(FieldEditor, {
|
|
2729
|
+
readonly: readonly || schemaReadonly,
|
|
2730
|
+
registry,
|
|
2731
|
+
projection: projectionModel,
|
|
2732
|
+
field,
|
|
2733
|
+
onSave: handleClose
|
|
2734
|
+
})));
|
|
2735
|
+
}))));
|
|
2358
2736
|
} finally {
|
|
2359
2737
|
_effect.f();
|
|
2360
2738
|
}
|
|
2361
2739
|
};
|
|
2740
|
+
var customFields = ({ types, tags }) => ({
|
|
2741
|
+
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2742
|
+
const handleChange = useCallback17((query) => onValueChange(type, query.ast), [
|
|
2743
|
+
onValueChange
|
|
2744
|
+
]);
|
|
2745
|
+
return /* @__PURE__ */ React19.createElement(Input13.Root, null, /* @__PURE__ */ React19.createElement(FormFieldLabel, {
|
|
2746
|
+
readonly,
|
|
2747
|
+
label
|
|
2748
|
+
}), /* @__PURE__ */ React19.createElement(QueryForm, {
|
|
2749
|
+
initialQuery: getValue(),
|
|
2750
|
+
types,
|
|
2751
|
+
tags,
|
|
2752
|
+
onChange: handleChange
|
|
2753
|
+
}));
|
|
2754
|
+
}
|
|
2755
|
+
});
|
|
2362
2756
|
export {
|
|
2363
|
-
|
|
2757
|
+
ArrayField,
|
|
2758
|
+
BooleanField,
|
|
2364
2759
|
ControlFrame,
|
|
2365
2760
|
ControlFrameItem,
|
|
2366
2761
|
ControlGroup,
|
|
@@ -2370,34 +2765,39 @@ export {
|
|
|
2370
2765
|
ControlPage,
|
|
2371
2766
|
ControlSection,
|
|
2372
2767
|
ControlSectionHeading,
|
|
2373
|
-
DeprecatedFormContainer,
|
|
2374
|
-
DeprecatedFormInput,
|
|
2375
2768
|
FieldEditor,
|
|
2376
2769
|
Form,
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2770
|
+
FormFieldErrorBoundary,
|
|
2771
|
+
FormFieldLabel,
|
|
2772
|
+
FormFieldWrapper,
|
|
2773
|
+
GeoPointField,
|
|
2774
|
+
MarkdownField,
|
|
2775
|
+
NumberField,
|
|
2776
|
+
ObjectPicker,
|
|
2777
|
+
RefField,
|
|
2778
|
+
SelectField,
|
|
2779
|
+
SelectOptionField,
|
|
2780
|
+
TextAreaField,
|
|
2781
|
+
TextField,
|
|
2782
|
+
TupleField,
|
|
2386
2783
|
ViewEditor,
|
|
2387
2784
|
cellClassesForFieldType,
|
|
2388
2785
|
controlItemClasses,
|
|
2389
|
-
findArrayElementType,
|
|
2390
2786
|
formatForDisplay,
|
|
2391
2787
|
formatForEditing,
|
|
2788
|
+
getDefaultValue,
|
|
2789
|
+
getFormProperties,
|
|
2392
2790
|
getRefProps,
|
|
2791
|
+
omitId,
|
|
2393
2792
|
parseValue,
|
|
2394
2793
|
pathNotUniqueError,
|
|
2395
2794
|
translations,
|
|
2396
|
-
useForm,
|
|
2397
2795
|
useFormContext,
|
|
2796
|
+
useFormFieldState,
|
|
2797
|
+
useFormHandler,
|
|
2398
2798
|
useFormValues,
|
|
2399
|
-
|
|
2799
|
+
useKeyHandler,
|
|
2400
2800
|
useQueryRefOptions,
|
|
2401
|
-
|
|
2801
|
+
useRefQueryOptions
|
|
2402
2802
|
};
|
|
2403
2803
|
//# sourceMappingURL=index.mjs.map
|