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