@parallelworks/ui 0.12.1 → 0.13.0
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/chunks/{BareModal-DBa84JZO.js → BareModal-BqroLbZ5.js} +1 -0
- package/dist/chunks/{CodePreviewEditor-hwjZof0M.js → CodePreviewEditor-67A_SKgE.js} +1 -1
- package/dist/chunks/{CreateModal-DLCC8t_x.js → CreateModal-k_e1dI8c.js} +27 -7
- package/dist/chunks/{Monaco-DCwRDrPm.js → Monaco-H56KyEdb.js} +22 -12
- package/dist/chunks/{PageHeader-dyoL44ue.js → PageHeader-FhtphHGc.js} +44 -10
- package/dist/chunks/{Provider-CfFV-vc5.js → Provider-CbFVFB7O.js} +8 -2
- package/dist/chunks/RequiredMark-DfLdYbYZ.js +11 -0
- package/dist/chunks/{StatusBadge-P6C2tv7Z.js → StatusBadge-RRUI78iS.js} +4 -4
- package/dist/chunks/{SwitchToggle-DcPCXkqL.js → SwitchToggle-DbW0Q__L.js} +49 -32
- package/dist/chunks/{Table-ByziK93x.js → Table-CutP1bRt.js} +22 -6
- package/dist/chunks/{Tooltip-WgbiC_nd.js → Tooltip-n9w7Tkt1.js} +28 -3
- package/dist/chunks/{editor-BH81U5-C.js → editor-BZ9Buwi4.js} +34 -23
- package/dist/chunks/lib-DyJvmbzj.js +256 -0
- package/dist/chunks/{list-CWVR3dfZ.js → list-3jZW8rmM.js} +33 -13
- package/dist/components/Breadcrumbs.d.ts +9 -0
- package/dist/components/CollapsiblePanel.d.ts +4 -4
- package/dist/components/CreateModal.d.ts +8 -8
- package/dist/components/Dropdown.d.ts +5 -3
- package/dist/components/Input.d.ts +1 -1
- package/dist/components/Listbox.d.ts +7 -4
- package/dist/components/Loader.d.ts +1 -1
- package/dist/components/MultiSelect.d.ts +8 -5
- package/dist/components/PageHeader.d.ts +3 -3
- package/dist/components/Pagination.d.ts +2 -2
- package/dist/components/Provider.d.ts +9 -3
- package/dist/components/RequiredMark.d.ts +1 -0
- package/dist/components/SettingRow.d.ts +1 -1
- package/dist/components/SwitchToggle.d.ts +3 -2
- package/dist/components/Table.d.ts +5 -3
- package/dist/components/Tooltip.d.ts +7 -1
- package/dist/components/dropdownUtils.d.ts +6 -6
- package/dist/editor/FormCodePanel.d.ts +3 -3
- package/dist/editor/Monaco.d.ts +2 -2
- package/dist/editor/index.js +1 -1
- package/dist/file-explorer/FileExplorer.d.ts +2 -2
- package/dist/file-explorer/helpers.d.ts +2 -2
- package/dist/file-explorer/index.js +46 -18
- package/dist/file-explorer/lib/fileExplorer.d.ts +1 -1
- package/dist/file-explorer/lib/types.d.ts +21 -21
- package/dist/form/FieldWrapper.d.ts +6 -1
- package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
- package/dist/form/Fields/StepField.d.ts +1 -1
- package/dist/form/Form.d.ts +28 -27
- package/dist/form/SpecialTypes/DropdownWrapper.d.ts +16 -3
- package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +11 -11
- package/dist/form/SpecialTypes/FormikCustomInput.d.ts +12 -10
- package/dist/form/SpecialTypes/FormikMultiSelectDropdown.d.ts +1 -1
- package/dist/form/SpecialTypes/FormikNumericInput.d.ts +2 -2
- package/dist/form/Wizard/WizardContainer.d.ts +1 -1
- package/dist/form/Wizard/WizardStepContent.d.ts +2 -2
- package/dist/form/Wizard/types.d.ts +21 -14
- package/dist/form/Wizard/utils.d.ts +1 -1
- package/dist/form/fieldContext.d.ts +19 -0
- package/dist/form/index.d.ts +2 -1
- package/dist/form/index.js +191 -106
- package/dist/form/lib.d.ts +3 -3
- package/dist/form/types/fieldComponentTypes.d.ts +2 -2
- package/dist/form/useParsedOpts.d.ts +1 -1
- package/dist/form/utils/getParentValue.d.ts +3 -1
- package/dist/form/utils/getValueUsingPath.d.ts +1 -1
- package/dist/form/utils/pwResolver.d.ts +4 -4
- package/dist/icons.d.ts +5 -5
- package/dist/index.d.ts +3 -2
- package/dist/index.js +51 -21
- package/dist/list/ActionToolbar.d.ts +4 -4
- package/dist/list/ListPage.d.ts +3 -3
- package/dist/list/ListTable.d.ts +1 -1
- package/dist/list/RowContextMenu.d.ts +20 -20
- package/dist/list/index.js +2 -2
- package/dist/logviewer/index.js +24 -7
- package/dist/styles/theme.css +6 -6
- package/dist/styles.css +1 -1
- package/dist/theme/index.js +4 -3
- package/dist/workflow/AnnotationBanner.d.ts +2 -1
- package/dist/workflow/DependencyGraph.d.ts +15 -3
- package/dist/workflow/JobSummary.d.ts +2 -25
- package/dist/workflow/MatrixGroup.d.ts +3 -2
- package/dist/workflow/TreeView.d.ts +1 -32
- package/dist/workflow/index.js +235 -138
- package/dist/workflow/types.d.ts +48 -0
- package/package.json +2 -6
- package/dist/chunks/lib-DTgL8klR.js +0 -191
|
@@ -4,6 +4,19 @@ import { Fragment as Fragment$1 } from "react";
|
|
|
4
4
|
import { Tooltip } from "react-tooltip";
|
|
5
5
|
//#region src/components/Tooltip.tsx
|
|
6
6
|
var TOOLTIP_ID = "global-tooltip";
|
|
7
|
+
/** Anchor props that reveal `content` only while the text is ellipsized; `measure` picks the clipped descendant when it isn't the anchor. */
|
|
8
|
+
function truncationTooltipProps(content, measure) {
|
|
9
|
+
return {
|
|
10
|
+
role: "none",
|
|
11
|
+
"data-tooltip-id": TOOLTIP_ID,
|
|
12
|
+
onMouseEnter: (event) => {
|
|
13
|
+
const anchor = event.currentTarget;
|
|
14
|
+
const measured = measure ? measure(anchor) : anchor;
|
|
15
|
+
if (measured && measured.scrollWidth > measured.clientWidth) anchor.setAttribute("data-tooltip-content", content);
|
|
16
|
+
else anchor.removeAttribute("data-tooltip-content");
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
7
20
|
var linkRegex = /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g;
|
|
8
21
|
function formatLine(line) {
|
|
9
22
|
const nodes = [];
|
|
@@ -40,12 +53,14 @@ function KbdShortcut({ keys }) {
|
|
|
40
53
|
})] }, `${part}-${idx}`))
|
|
41
54
|
});
|
|
42
55
|
}
|
|
56
|
+
var globalCloseEvents = { escape: true };
|
|
43
57
|
/** Singleton rendered at layout root; anchors opt in via data-tooltip-id={TOOLTIP_ID}, data-tooltip-content, and data-tooltip-shortcut. */
|
|
44
58
|
function GlobalTooltip() {
|
|
45
59
|
return /* @__PURE__ */ jsx(Tooltip, {
|
|
46
60
|
id: TOOLTIP_ID,
|
|
47
61
|
className: "max-w-lg break-words config-tips normal-case text-left z-[10000]",
|
|
48
62
|
place: "top",
|
|
63
|
+
globalCloseEvents,
|
|
49
64
|
render: ({ content, activeAnchor }) => {
|
|
50
65
|
const body = formatTooltipContent(content);
|
|
51
66
|
const shortcut = activeAnchor?.getAttribute("data-tooltip-shortcut");
|
|
@@ -58,14 +73,24 @@ function GlobalTooltip() {
|
|
|
58
73
|
});
|
|
59
74
|
}
|
|
60
75
|
function TooltipInfo({ text, className = "", children, place = "top", tabIndex }) {
|
|
61
|
-
|
|
76
|
+
const anchorProps = {
|
|
62
77
|
"data-tooltip-id": TOOLTIP_ID,
|
|
63
78
|
"data-tooltip-content": text,
|
|
64
79
|
"data-tooltip-place": place,
|
|
65
|
-
className
|
|
80
|
+
className
|
|
81
|
+
};
|
|
82
|
+
if (children || !text) return /* @__PURE__ */ jsx("div", {
|
|
83
|
+
...anchorProps,
|
|
66
84
|
tabIndex,
|
|
67
85
|
children: children || /* @__PURE__ */ jsx(TooltipIcon, { className: "tooltip" })
|
|
68
86
|
});
|
|
87
|
+
return /* @__PURE__ */ jsx("div", {
|
|
88
|
+
...anchorProps,
|
|
89
|
+
role: "img",
|
|
90
|
+
"aria-label": text,
|
|
91
|
+
tabIndex: tabIndex ?? 0,
|
|
92
|
+
children: /* @__PURE__ */ jsx(TooltipIcon, { className: "tooltip" })
|
|
93
|
+
});
|
|
69
94
|
}
|
|
70
95
|
//#endregion
|
|
71
|
-
export { formatTooltipContent as i, TOOLTIP_ID as n, TooltipInfo as r, GlobalTooltip as t };
|
|
96
|
+
export { truncationTooltipProps as a, formatTooltipContent as i, TOOLTIP_ID as n, TooltipInfo as r, GlobalTooltip as t };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { CheckIcon, CopyIcon, EyeIcon, EyeOffIcon } from "../icons.js";
|
|
2
|
-
import { c as useStrings, i as useNotify } from "./Provider-
|
|
2
|
+
import { c as useStrings, i as useNotify } from "./Provider-CbFVFB7O.js";
|
|
3
3
|
import { t as Loader } from "./Loader-BXoXTZGc.js";
|
|
4
4
|
import { t as SwitchToggleSmall } from "./SwitchToggleSmall-FcsaYSTs.js";
|
|
5
|
-
import { c as FieldWrapper, n as flattenGroups, r as impureSetValueFromPath } from "./lib-
|
|
5
|
+
import { c as FieldWrapper, n as flattenGroups, r as impureSetValueFromPath } from "./lib-DyJvmbzj.js";
|
|
6
6
|
import cx from "classnames";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { Suspense, lazy, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { Suspense, lazy, useId, useMemo, useRef, useState } from "react";
|
|
9
9
|
import { convertToDynamicForm, parseStringsOfObj, parseStringsOfObjReady } from "@parallelworks/workflow-parser";
|
|
10
10
|
import { useField, useFormikContext } from "formik";
|
|
11
11
|
//#region src/editor/Editor.tsx
|
|
12
|
-
var MonacoEditor = lazy(() => import("./Monaco-
|
|
12
|
+
var MonacoEditor = lazy(() => import("./Monaco-H56KyEdb.js"));
|
|
13
13
|
function Editor({ ...props }) {
|
|
14
14
|
return /* @__PURE__ */ jsx(Suspense, {
|
|
15
15
|
fallback: /* @__PURE__ */ jsx(Loader, { text: "Loading editor..." }),
|
|
@@ -19,7 +19,7 @@ function Editor({ ...props }) {
|
|
|
19
19
|
//#endregion
|
|
20
20
|
//#region src/editor/EditorField.tsx
|
|
21
21
|
function hasResetKeys(obj) {
|
|
22
|
-
return obj.editorKeyPostfix
|
|
22
|
+
return typeof obj === "object" && obj !== null && "editorKeyPostfix" in obj && typeof obj.editorKeyPostfix === "string";
|
|
23
23
|
}
|
|
24
24
|
function EditorField(props) {
|
|
25
25
|
const { field, label, labelPosition, disabled, onChange, tooltipComponent, spaceCompact, setFormDirty } = props;
|
|
@@ -51,9 +51,10 @@ function EditorField(props) {
|
|
|
51
51
|
labelPosition,
|
|
52
52
|
spaceCompact,
|
|
53
53
|
children: /* @__PURE__ */ jsx(Editor, {
|
|
54
|
+
ariaLabel: label,
|
|
54
55
|
height: "200px",
|
|
55
56
|
path: field.name,
|
|
56
|
-
|
|
57
|
+
...touchedRef.current ? {} : { value },
|
|
57
58
|
className: cx("bg-(--theme-input-bg) w-11 border focus:border rounded text-[10px] leading-4 pl-[6px]", disabled && "opacity-75"),
|
|
58
59
|
readOnly: disabled,
|
|
59
60
|
onChange: handleChange,
|
|
@@ -63,53 +64,59 @@ function EditorField(props) {
|
|
|
63
64
|
}
|
|
64
65
|
//#endregion
|
|
65
66
|
//#region src/editor/FormCodePanel.tsx
|
|
67
|
+
var isObject = (value) => typeof value === "object" && value !== null;
|
|
66
68
|
var shouldIgnoreField = (fieldSchema, inputs, arrayIndex) => {
|
|
67
|
-
if (!fieldSchema?.ignore || !fieldSchema?.hidden) return false;
|
|
69
|
+
if (!fieldSchema?.["ignore"] || !fieldSchema?.["hidden"]) return false;
|
|
68
70
|
if (!parseStringsOfObjReady) return false;
|
|
69
71
|
return parseStringsOfObj({
|
|
70
72
|
inputs,
|
|
71
73
|
obj: convertToDynamicForm(fieldSchema),
|
|
72
74
|
index: arrayIndex ?? -1
|
|
73
|
-
})
|
|
75
|
+
})["hidden"] === true;
|
|
74
76
|
};
|
|
75
77
|
var filterFields = (formJSON, data, prefix, rootData, arrayIndex) => {
|
|
76
78
|
const filteredFields = [];
|
|
77
79
|
return {
|
|
78
80
|
filteredFields,
|
|
79
81
|
filtered: Object.keys(data).reduce((acc, key) => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
const value = data[key];
|
|
83
|
+
const fieldSchema = formJSON[key];
|
|
84
|
+
if (value !== null && Array.isArray(value)) {
|
|
85
|
+
const items = [];
|
|
86
|
+
acc[key] = items;
|
|
87
|
+
if (!fieldSchema) return acc;
|
|
88
|
+
const nestedSchema = isObject(fieldSchema) ? fieldSchema["options"] : void 0;
|
|
89
|
+
for (let i = 0; i < value.length; i++) {
|
|
84
90
|
let filteredFieldsNested = [];
|
|
85
91
|
let filteredNested = {};
|
|
86
|
-
|
|
87
|
-
|
|
92
|
+
const item = value[i];
|
|
93
|
+
if (isObject(item)) {
|
|
94
|
+
const result = filterFields(isObject(nestedSchema) ? nestedSchema : {}, item, key + `[${i}].`, rootData || data, i);
|
|
88
95
|
filteredNested = result.filtered;
|
|
89
96
|
filteredFieldsNested = result.filteredFields;
|
|
90
|
-
} else filteredNested =
|
|
97
|
+
} else filteredNested = item;
|
|
91
98
|
filteredFields.push(...filteredFieldsNested);
|
|
92
|
-
|
|
99
|
+
items[i] = filteredNested;
|
|
93
100
|
}
|
|
94
101
|
return acc;
|
|
95
102
|
}
|
|
96
|
-
if (
|
|
97
|
-
const { filteredFields: filteredFieldsNested, filtered: filteredNested } = filterFields(
|
|
103
|
+
if (fieldSchema && isObject(value)) {
|
|
104
|
+
const { filteredFields: filteredFieldsNested, filtered: filteredNested } = filterFields(isObject(fieldSchema) ? fieldSchema : {}, value, key + ".", rootData || data, arrayIndex);
|
|
98
105
|
filteredFields.push(...filteredFieldsNested);
|
|
99
106
|
acc[key] = filteredNested;
|
|
100
107
|
return acc;
|
|
101
108
|
}
|
|
102
|
-
if (
|
|
109
|
+
if (isObject(fieldSchema) && fieldSchema["sensitive"]) {
|
|
103
110
|
const name = prefix ? prefix + key : key;
|
|
104
111
|
filteredFields.push({
|
|
105
112
|
key: name,
|
|
106
|
-
value
|
|
113
|
+
value
|
|
107
114
|
});
|
|
108
115
|
return acc;
|
|
109
116
|
}
|
|
110
117
|
const contextData = rootData || data;
|
|
111
|
-
if (
|
|
112
|
-
acc[key] =
|
|
118
|
+
if (isObject(fieldSchema) && shouldIgnoreField(fieldSchema, contextData, arrayIndex)) return acc;
|
|
119
|
+
acc[key] = value;
|
|
113
120
|
return acc;
|
|
114
121
|
}, {})
|
|
115
122
|
};
|
|
@@ -123,6 +130,7 @@ var populateFiltered = (filteredFields, data) => {
|
|
|
123
130
|
function FormCodePanel({ formJSON, data, mutate, height = "600px", disabled = false }) {
|
|
124
131
|
const notify = useNotify();
|
|
125
132
|
const { common: t } = useStrings();
|
|
133
|
+
const uid = useId();
|
|
126
134
|
const [jsonHasErrors, setJsonHasErrors] = useState(false);
|
|
127
135
|
const [showHidden, setShowHidden] = useState(false);
|
|
128
136
|
const [copied, setCopied] = useState(false);
|
|
@@ -156,9 +164,11 @@ function FormCodePanel({ formJSON, data, mutate, height = "600px", disabled = fa
|
|
|
156
164
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
157
165
|
className: "bg-(--theme-muted-panel-bg) text-(--theme-muted-panel-color) flex shrink-0 items-center gap-3 border-b border-(--theme-border) px-3 py-2",
|
|
158
166
|
children: [hasHiddenFields && /* @__PURE__ */ jsxs("label", {
|
|
167
|
+
htmlFor: `${uid}-show-hidden`,
|
|
159
168
|
title: t.showHiddenFieldsHint,
|
|
160
169
|
className: "flex cursor-pointer select-none items-center gap-2 text-sm text-(--theme-app)",
|
|
161
170
|
children: [/* @__PURE__ */ jsx(SwitchToggleSmall, {
|
|
171
|
+
id: `${uid}-show-hidden`,
|
|
162
172
|
value: showHidden,
|
|
163
173
|
"aria-label": t.showHiddenFields,
|
|
164
174
|
onClick: () => setShowHidden((prev) => !prev)
|
|
@@ -199,6 +209,7 @@ function FormCodePanel({ formJSON, data, mutate, height = "600px", disabled = fa
|
|
|
199
209
|
onChange: (e) => {
|
|
200
210
|
try {
|
|
201
211
|
const parsed = JSON.parse(e);
|
|
212
|
+
if (!isObject(parsed)) return;
|
|
202
213
|
mutate(showHiddenRef.current ? parsed : populateFiltered(filteredFieldsRef.current, parsed));
|
|
203
214
|
} catch {
|
|
204
215
|
console.log("JSON.parse error in slurm editor");
|
|
@@ -240,7 +251,7 @@ function createEditorThemes() {
|
|
|
240
251
|
};
|
|
241
252
|
const light = {
|
|
242
253
|
disabledBg: themeVar("--theme-input-disabled-bg", "#f3f4f6"),
|
|
243
|
-
disabledFg: themeVar("--theme-muted-text-color", "#
|
|
254
|
+
disabledFg: themeVar("--theme-muted-text-color", "#5f6b76"),
|
|
244
255
|
border: themeVar("--theme-border", "#d1d5db"),
|
|
245
256
|
selection: themeVar("--theme-element", "#2f81f7"),
|
|
246
257
|
selectionFg: themeVar("--theme-element-text", "#ffffff")
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { t as RequiredMark } from "./RequiredMark-DfLdYbYZ.js";
|
|
2
|
+
import cx from "classnames";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { createContext, useContext, useId, useMemo } from "react";
|
|
5
|
+
//#region src/form/fieldContext.tsx
|
|
6
|
+
var FieldContext = createContext({ required: false });
|
|
7
|
+
var FieldProvider = FieldContext.Provider;
|
|
8
|
+
/** True when the surrounding FieldWrapper is showing the required asterisk. */
|
|
9
|
+
function useFieldRequired() {
|
|
10
|
+
return useContext(FieldContext).required;
|
|
11
|
+
}
|
|
12
|
+
/** Ties the single focusable control of a field to its FieldWrapper label. */
|
|
13
|
+
function useFieldControlProps() {
|
|
14
|
+
const { id, descriptionId } = useContext(FieldContext);
|
|
15
|
+
return {
|
|
16
|
+
id,
|
|
17
|
+
"aria-describedby": descriptionId
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** For controls and groups that can only be named through aria-labelledby. */
|
|
21
|
+
function useFieldLabelledByProps() {
|
|
22
|
+
const { labelId, descriptionId } = useContext(FieldContext);
|
|
23
|
+
return {
|
|
24
|
+
"aria-labelledby": labelId,
|
|
25
|
+
"aria-describedby": descriptionId
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/form/FieldWrapper.tsx
|
|
30
|
+
function FieldWrapper({ label, tooltipComponent, description, labelPosition = "left", spaceCompact = false, optional = false, children }) {
|
|
31
|
+
const uid = useId();
|
|
32
|
+
const id = `${uid}control`;
|
|
33
|
+
const labelId = `${uid}label`;
|
|
34
|
+
const descriptionId = description ? `${uid}description` : void 0;
|
|
35
|
+
const field = useMemo(() => ({
|
|
36
|
+
required: !optional,
|
|
37
|
+
id,
|
|
38
|
+
labelId,
|
|
39
|
+
descriptionId
|
|
40
|
+
}), [
|
|
41
|
+
optional,
|
|
42
|
+
id,
|
|
43
|
+
labelId,
|
|
44
|
+
descriptionId
|
|
45
|
+
]);
|
|
46
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
47
|
+
className: cx("flex w-full", labelPosition === "left" ? "items-start" : "items-left flex-col"),
|
|
48
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
49
|
+
htmlFor: id,
|
|
50
|
+
id: labelId,
|
|
51
|
+
className: cx("relative", labelPosition === "left" ? "form-label" : "form-label-top", spaceCompact && "form-label-compact"),
|
|
52
|
+
children: [
|
|
53
|
+
label,
|
|
54
|
+
!optional && /* @__PURE__ */ jsx(RequiredMark, {}),
|
|
55
|
+
tooltipComponent
|
|
56
|
+
]
|
|
57
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
58
|
+
className: "w-full",
|
|
59
|
+
children: [/* @__PURE__ */ jsx(FieldProvider, {
|
|
60
|
+
value: field,
|
|
61
|
+
children: typeof children === "function" ? children({
|
|
62
|
+
id,
|
|
63
|
+
labelId,
|
|
64
|
+
describedBy: descriptionId
|
|
65
|
+
}) : children
|
|
66
|
+
}), description && /* @__PURE__ */ jsx("div", {
|
|
67
|
+
id: descriptionId,
|
|
68
|
+
className: "text-xs theme-muted-text mt-1 leading-relaxed",
|
|
69
|
+
children: description
|
|
70
|
+
})]
|
|
71
|
+
})]
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/form/utils/secondaryField.ts
|
|
76
|
+
function findSecondaryOption(options, value) {
|
|
77
|
+
for (const candidate of options) {
|
|
78
|
+
if (!candidate || typeof candidate !== "object") continue;
|
|
79
|
+
const option = candidate;
|
|
80
|
+
if (option.value === value) return option;
|
|
81
|
+
if (Array.isArray(option.options)) {
|
|
82
|
+
const nestedOption = findSecondaryOption(option.options, value);
|
|
83
|
+
if (nestedOption) return nestedOption;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function applySecondaryField(secondaryField, secondaryValue, setFieldValue) {
|
|
88
|
+
if (secondaryField === void 0 || secondaryValue === void 0) return;
|
|
89
|
+
const fields = Array.isArray(secondaryField) ? secondaryField : [secondaryField];
|
|
90
|
+
const values = Array.isArray(secondaryValue) ? secondaryValue : [secondaryValue];
|
|
91
|
+
fields.forEach((field, index) => {
|
|
92
|
+
setFieldValue(field, values[index]);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/form/lib.ts
|
|
97
|
+
var EMPTY_ENTRY = {};
|
|
98
|
+
function asRecord(value) {
|
|
99
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Drops a schema flag the expression parser could not resolve. workflow.schema.json types
|
|
103
|
+
* `optional`/`hidden`/`ignore` as ["string", "boolean"], so a flag whose expression depends
|
|
104
|
+
* on something unavailable at form-render time (a list `[index]` outside a row, `needs.`,
|
|
105
|
+
* `env.`, a secret `var.`) arrives as the raw `${{…}}` string. That string is truthy, which
|
|
106
|
+
* inverts each flag's documented `false` default. Returning undefined lets the caller apply
|
|
107
|
+
* that default instead of reading an expression it never evaluated as "yes".
|
|
108
|
+
*/
|
|
109
|
+
function resolvedFlag(value) {
|
|
110
|
+
return typeof value === "string" && value.includes("${{") ? void 0 : value;
|
|
111
|
+
}
|
|
112
|
+
function enforceOneMustBeTrue(items, options, promoteIndex) {
|
|
113
|
+
if (items.length === 0) return items;
|
|
114
|
+
const clampedIndex = Math.max(0, Math.min(promoteIndex, items.length - 1));
|
|
115
|
+
const oneMustBeTrueFields = Object.keys(options).filter((key) => typeof options[key] === "object" && options[key] !== null && "one_must_be_true" in options[key] && options[key].one_must_be_true);
|
|
116
|
+
for (const fieldKey of oneMustBeTrueFields) {
|
|
117
|
+
const fieldSchema = options[fieldKey];
|
|
118
|
+
if (typeof fieldSchema === "object" && fieldSchema && "options" in fieldSchema) {
|
|
119
|
+
const opts = fieldSchema.options;
|
|
120
|
+
const trueOption = typeof opts === "object" && opts && !Array.isArray(opts) && "onOption" in opts ? opts.onOption || true : true;
|
|
121
|
+
if (!items.some((item) => item[fieldKey] === trueOption)) items[clampedIndex][fieldKey] = trueOption;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return items;
|
|
125
|
+
}
|
|
126
|
+
function flattenGroups(schema) {
|
|
127
|
+
if (!schema || typeof schema !== "object") return {};
|
|
128
|
+
const fields = schema;
|
|
129
|
+
let flattenedFields = {};
|
|
130
|
+
Object.keys(fields).forEach((key) => {
|
|
131
|
+
const entry = fields[key];
|
|
132
|
+
if (entry?.type === "group") {
|
|
133
|
+
const flattenedGroup = flattenGroups(entry.options);
|
|
134
|
+
flattenedFields = {
|
|
135
|
+
...flattenedFields,
|
|
136
|
+
...flattenedGroup
|
|
137
|
+
};
|
|
138
|
+
} else if (entry?.type === "object") {
|
|
139
|
+
const flattenedGroup = flattenGroups(entry.options);
|
|
140
|
+
flattenedFields = {
|
|
141
|
+
...flattenedFields,
|
|
142
|
+
[key]: flattenedGroup
|
|
143
|
+
};
|
|
144
|
+
} else flattenedFields[key] = entry;
|
|
145
|
+
});
|
|
146
|
+
return flattenedFields;
|
|
147
|
+
}
|
|
148
|
+
/**Not a pure function. Edits 'obj' passed into function */
|
|
149
|
+
function impureSetValueFromPath(obj, path, value) {
|
|
150
|
+
const pathArray = path.split(".");
|
|
151
|
+
if (pathArray.length === 1) {
|
|
152
|
+
obj[pathArray[0]] = value;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
let current = obj;
|
|
156
|
+
for (let i = 0; i < pathArray.length - 1; i++) {
|
|
157
|
+
const segment = pathArray[i];
|
|
158
|
+
const arrayMatch = segment.match(/^(.+)\[(\d+)\]$/);
|
|
159
|
+
if (arrayMatch) {
|
|
160
|
+
const key = arrayMatch[1];
|
|
161
|
+
const index = Number(arrayMatch[2]);
|
|
162
|
+
if (!current[key]) current[key] = [];
|
|
163
|
+
const list = current[key];
|
|
164
|
+
if (!list[index]) list[index] = {};
|
|
165
|
+
current = list[index];
|
|
166
|
+
} else {
|
|
167
|
+
if (!current[segment]) current[segment] = {};
|
|
168
|
+
current = current[segment];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
current[pathArray[pathArray.length - 1]] = value;
|
|
172
|
+
}
|
|
173
|
+
function initializeValues(options, srcData = {}, ignoreDefaultStrings = false) {
|
|
174
|
+
if (!options || typeof options !== "object") return;
|
|
175
|
+
const schema = options;
|
|
176
|
+
const source = srcData;
|
|
177
|
+
const data = structuredClone(source);
|
|
178
|
+
return Object.keys(schema).reduce((acc, field) => {
|
|
179
|
+
if (field.startsWith("$")) return acc;
|
|
180
|
+
const fieldSchema = schema[field] ?? EMPTY_ENTRY;
|
|
181
|
+
if (fieldSchema.type === "group") {
|
|
182
|
+
const values = initializeValues(fieldSchema.options, data);
|
|
183
|
+
if (!values) return acc;
|
|
184
|
+
Object.keys(values).forEach((key) => {
|
|
185
|
+
acc[key] = data[key] ?? values[key];
|
|
186
|
+
});
|
|
187
|
+
return acc;
|
|
188
|
+
}
|
|
189
|
+
if (fieldSchema.type === "step") {
|
|
190
|
+
if (schema["$meta"]?.wizard?.flatten !== false) {
|
|
191
|
+
const values = initializeValues(fieldSchema.options, data);
|
|
192
|
+
if (!values) return acc;
|
|
193
|
+
Object.keys(values).forEach((key) => {
|
|
194
|
+
acc[key] = data[key] ?? values[key];
|
|
195
|
+
});
|
|
196
|
+
} else acc[field] = initializeValues(fieldSchema.options, asRecord(data[field]));
|
|
197
|
+
return acc;
|
|
198
|
+
}
|
|
199
|
+
if (fieldSchema.type === "object") {
|
|
200
|
+
acc[field] = initializeValues(fieldSchema.options, asRecord(data[field]));
|
|
201
|
+
return acc;
|
|
202
|
+
}
|
|
203
|
+
if (fieldSchema.type === "list") {
|
|
204
|
+
const listData = data[field];
|
|
205
|
+
if (fieldSchema.options === "string") {
|
|
206
|
+
acc[field] = Array.isArray(listData) ? [...listData] : [];
|
|
207
|
+
return acc;
|
|
208
|
+
}
|
|
209
|
+
const arr = [];
|
|
210
|
+
if (Array.isArray(listData)) for (let i = 0; i < listData.length; i++) arr.push(initializeValues(fieldSchema.options, asRecord(listData[i])));
|
|
211
|
+
acc[field] = arr;
|
|
212
|
+
return acc;
|
|
213
|
+
}
|
|
214
|
+
if (data[field] !== void 0) {
|
|
215
|
+
acc[field] = data[field];
|
|
216
|
+
if ((fieldSchema.type === "dropdown" || fieldSchema.type === "storage") && fieldSchema.secondaryField && fieldSchema.options && Array.isArray(fieldSchema.options)) {
|
|
217
|
+
const option = findSecondaryOption(fieldSchema.options, data[field]);
|
|
218
|
+
applySecondaryField(fieldSchema.secondaryField, option?.secondaryValue, (secondaryField, secondaryValue) => {
|
|
219
|
+
if (!(fieldSchema.type === "storage" && Object.prototype.hasOwnProperty.call(options, secondaryField) && source[secondaryField] !== void 0)) impureSetValueFromPath(acc, secondaryField, secondaryValue);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return acc;
|
|
223
|
+
}
|
|
224
|
+
if (fieldSchema.type === "label") return acc;
|
|
225
|
+
if (fieldSchema.optional && fieldSchema.default === void 0) return acc;
|
|
226
|
+
acc[field] = "";
|
|
227
|
+
if (fieldSchema.autoselect) acc[field] = void 0;
|
|
228
|
+
if (fieldSchema.type === "boolean") {
|
|
229
|
+
const boolOptions = asRecord(fieldSchema.options);
|
|
230
|
+
if (boolOptions["offOption"] && boolOptions["onOption"]) acc[field] = boolOptions["offOption"];
|
|
231
|
+
else acc[field] = false;
|
|
232
|
+
}
|
|
233
|
+
if (fieldSchema.type === "dropdown") {
|
|
234
|
+
if (fieldSchema.options && Array.isArray(fieldSchema.options) && fieldSchema.options.length > 0) acc[field] = fieldSchema.options[0].value;
|
|
235
|
+
if (fieldSchema.type === "dropdown" && fieldSchema.secondaryField && fieldSchema.options && Array.isArray(fieldSchema.options)) {
|
|
236
|
+
const option = fieldSchema.options.find((option) => option.value === data[field]);
|
|
237
|
+
const secondaryField = Array.isArray(fieldSchema.secondaryField) ? fieldSchema.secondaryField : [fieldSchema.secondaryField];
|
|
238
|
+
const secondaryValue = Array.isArray(option?.secondaryValue) ? option?.secondaryValue : [option?.secondaryValue];
|
|
239
|
+
secondaryField.forEach((field, index) => {
|
|
240
|
+
impureSetValueFromPath(data, field, secondaryValue[index]);
|
|
241
|
+
impureSetValueFromPath(acc, field, secondaryValue[index]);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (fieldSchema.type === "multi-dropdown" || fieldSchema.type === "checkbox-group") acc[field] = [];
|
|
246
|
+
if (fieldSchema.default !== void 0) {
|
|
247
|
+
const dflt = fieldSchema.default;
|
|
248
|
+
const isPwResource = typeof dflt === "string" && dflt.startsWith("pw://");
|
|
249
|
+
acc[field] = fieldSchema.type === "string" || ignoreDefaultStrings && !isPwResource && (fieldSchema.type === "textarea" || fieldSchema.type === "compute-clusters" || fieldSchema.type === "compute-resources") ? "" : dflt;
|
|
250
|
+
}
|
|
251
|
+
if (fieldSchema.prefillDefault && fieldSchema.default !== void 0) acc[field] = fieldSchema.default;
|
|
252
|
+
return acc;
|
|
253
|
+
}, data);
|
|
254
|
+
}
|
|
255
|
+
//#endregion
|
|
256
|
+
export { resolvedFlag as a, FieldWrapper as c, useFieldLabelledByProps as d, useFieldRequired as f, initializeValues as i, FieldProvider as l, flattenGroups as n, applySecondaryField as o, impureSetValueFromPath as r, findSecondaryOption as s, enforceOneMustBeTrue as t, useFieldControlProps as u };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, DisplayIcon, ErrorIcon, FilterIcon, MenuIcon, SearchIcon, XIcon } from "../icons.js";
|
|
2
|
-
import { c as useStrings, n as useLink, r as useNavigation } from "./Provider-
|
|
3
|
-
import { n as TOOLTIP_ID, r as TooltipInfo } from "./Tooltip-
|
|
4
|
-
import { c as PageHeader, f as rowContextMenuProps, g as useRowMenuActive, l as MoreButton } from "./PageHeader-
|
|
5
|
-
import { n as Table } from "./Table-
|
|
2
|
+
import { c as useStrings, n as useLink, r as useNavigation } from "./Provider-CbFVFB7O.js";
|
|
3
|
+
import { n as TOOLTIP_ID, r as TooltipInfo } from "./Tooltip-n9w7Tkt1.js";
|
|
4
|
+
import { c as PageHeader, f as rowContextMenuProps, g as useRowMenuActive, l as MoreButton } from "./PageHeader-FhtphHGc.js";
|
|
5
|
+
import { n as Table } from "./Table-CutP1bRt.js";
|
|
6
6
|
import cx from "classnames";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Children, Fragment as Fragment$1, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
@@ -91,6 +91,7 @@ function OverflowMenu({ items }) {
|
|
|
91
91
|
as: "div",
|
|
92
92
|
className: "relative inline-block text-left",
|
|
93
93
|
children: [/* @__PURE__ */ jsx(MenuButton, {
|
|
94
|
+
"aria-label": t.moreActions,
|
|
94
95
|
className: "inline-flex items-center justify-center h-9 w-9 rounded-md border theme-border link hover:theme-hover transition-colors",
|
|
95
96
|
"data-tooltip-id": TOOLTIP_ID,
|
|
96
97
|
"data-tooltip-content": t.moreActions,
|
|
@@ -264,9 +265,13 @@ function ListError({ error, noun = "data" }) {
|
|
|
264
265
|
});
|
|
265
266
|
}
|
|
266
267
|
function ListSkeleton({ rows = 6 }) {
|
|
267
|
-
|
|
268
|
+
const { loading } = useStrings();
|
|
269
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
270
|
+
role: "status",
|
|
271
|
+
"aria-label": loading,
|
|
268
272
|
className: "divide-y border-b border-(--theme-border) divide-(--theme-border)",
|
|
269
|
-
children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("div", {
|
|
273
|
+
children: [Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("div", {
|
|
274
|
+
"aria-hidden": "true",
|
|
270
275
|
className: "flex items-center gap-3 px-4 py-2.5 animate-pulse",
|
|
271
276
|
children: [
|
|
272
277
|
/* @__PURE__ */ jsx("div", { className: "h-5 w-5 rounded bg-(--theme-muted-panel-bg)" }),
|
|
@@ -276,7 +281,10 @@ function ListSkeleton({ rows = 6 }) {
|
|
|
276
281
|
}),
|
|
277
282
|
/* @__PURE__ */ jsx("div", { className: "ml-auto h-3 w-20 rounded bg-(--theme-muted-panel-bg)" })
|
|
278
283
|
]
|
|
279
|
-
}, i))
|
|
284
|
+
}, i)), /* @__PURE__ */ jsx("span", {
|
|
285
|
+
className: "sr-only",
|
|
286
|
+
children: loading
|
|
287
|
+
})]
|
|
280
288
|
});
|
|
281
289
|
}
|
|
282
290
|
/** Prevents the name column from being crushed under table-auto layout during horizontal overflow. */
|
|
@@ -428,12 +436,13 @@ function ListRow({ href, items, goTo, openMenu, pinnedActions, selected, selecti
|
|
|
428
436
|
"data-tooltip-id": "global-tooltip",
|
|
429
437
|
"data-tooltip-content": action.label,
|
|
430
438
|
"data-tooltip-place": "bottom",
|
|
431
|
-
disabled: action.disabled,
|
|
439
|
+
"aria-disabled": action.disabled,
|
|
432
440
|
onClick: (e) => {
|
|
433
441
|
e.stopPropagation();
|
|
442
|
+
if (action.disabled) return;
|
|
434
443
|
action.onSelect();
|
|
435
444
|
},
|
|
436
|
-
className: cx("rounded p-1 cursor-pointer text-(--theme-muted-text-color) transition-colors hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) disabled:cursor-not-allowed disabled:opacity-20 [&>svg]:h-4 [&>svg]:w-4", alwaysShowActions || menuActive ? "opacity-100" : "opacity-0 group-hover:opacity-100 focus-visible:opacity-100"),
|
|
445
|
+
className: cx("rounded p-1 cursor-pointer text-(--theme-muted-text-color) transition-colors hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) aria-disabled:cursor-not-allowed aria-disabled:opacity-20 aria-disabled:hover:bg-transparent aria-disabled:hover:text-(--theme-muted-text-color) [&>svg]:h-4 [&>svg]:w-4", alwaysShowActions || menuActive ? "opacity-100" : "opacity-0 group-hover:opacity-100 focus-visible:opacity-100"),
|
|
437
446
|
children: action.icon
|
|
438
447
|
}, action.key))
|
|
439
448
|
}), /* @__PURE__ */ jsx(MoreButton, {
|
|
@@ -695,8 +704,8 @@ function AnchoredPopover({ icon, label, active, shortcut, panelClassName, childr
|
|
|
695
704
|
const open = useCallback(() => {
|
|
696
705
|
const r = btnRef.current?.getBoundingClientRect();
|
|
697
706
|
if (r) setPos({
|
|
698
|
-
right: Math.max(8, window.innerWidth - r.right),
|
|
699
|
-
top: r.bottom + 4
|
|
707
|
+
right: Math.max(8, Math.round(window.innerWidth - r.right)),
|
|
708
|
+
top: Math.round(r.bottom) + 4
|
|
700
709
|
});
|
|
701
710
|
}, []);
|
|
702
711
|
useEffect(() => {
|
|
@@ -740,6 +749,7 @@ function AnchoredPopover({ icon, label, active, shortcut, panelClassName, childr
|
|
|
740
749
|
className: cx(listControlButtonClasses, active && "border-(--theme-link) text-(--theme-app)"),
|
|
741
750
|
children: [icon, active && /* @__PURE__ */ jsx("span", { className: "absolute right-0 top-0 h-1.5 w-1.5 rounded-full bg-(--theme-link)" })]
|
|
742
751
|
}), pos && createPortal(/* @__PURE__ */ jsx("div", {
|
|
752
|
+
role: "none",
|
|
743
753
|
className: "fixed inset-0 z-50",
|
|
744
754
|
onMouseDown: close,
|
|
745
755
|
onContextMenu: (e) => {
|
|
@@ -994,10 +1004,17 @@ function FilterFacetRow({ view, facet, open, onEnter, onLeave }) {
|
|
|
994
1004
|
const selected = view.filters[facet.key] ?? [];
|
|
995
1005
|
return /* @__PURE__ */ jsxs("div", {
|
|
996
1006
|
className: "relative",
|
|
1007
|
+
role: "none",
|
|
997
1008
|
onMouseEnter: onEnter,
|
|
998
1009
|
onMouseLeave: onLeave,
|
|
999
|
-
|
|
1000
|
-
|
|
1010
|
+
onFocus: onEnter,
|
|
1011
|
+
onBlur: onLeave,
|
|
1012
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
1013
|
+
type: "button",
|
|
1014
|
+
"aria-expanded": open,
|
|
1015
|
+
"aria-haspopup": "menu",
|
|
1016
|
+
onClick: onEnter,
|
|
1017
|
+
className: "flex w-full cursor-default items-center justify-between gap-3 px-3 py-1.5 text-[13px] text-(--theme-app) hover:bg-(--theme-muted-panel-bg)",
|
|
1001
1018
|
children: [/* @__PURE__ */ jsx("span", { children: facet.label }), /* @__PURE__ */ jsxs("span", {
|
|
1002
1019
|
className: "flex items-center gap-1.5",
|
|
1003
1020
|
children: [selected.length > 0 && /* @__PURE__ */ jsx("span", {
|
|
@@ -1260,8 +1277,11 @@ function HoverCardSurface({ x, y, widthClassName, relayoutKey, onKeepOpen, onLea
|
|
|
1260
1277
|
]);
|
|
1261
1278
|
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
1262
1279
|
ref,
|
|
1280
|
+
role: "none",
|
|
1263
1281
|
onMouseEnter: onKeepOpen,
|
|
1264
1282
|
onMouseLeave: onLeave,
|
|
1283
|
+
onFocus: onKeepOpen,
|
|
1284
|
+
onBlur: onLeave,
|
|
1265
1285
|
className: cx("fixed z-[9999] rounded-xl border border-(--theme-border) bg-(--theme-panel-bg) p-3 shadow-xl backdrop-blur-xl", widthClassName),
|
|
1266
1286
|
style: {
|
|
1267
1287
|
left: pos?.left ?? x,
|
|
@@ -16,12 +16,21 @@ interface BreadcrumbContextType {
|
|
|
16
16
|
setTitleActionSlot: (el: HTMLElement | null) => void;
|
|
17
17
|
rightActionSlot: HTMLElement | null;
|
|
18
18
|
setRightActionSlot: (el: HTMLElement | null) => void;
|
|
19
|
+
/** Pathname whose breadcrumbs a page set itself, so layouts leave it alone. */
|
|
20
|
+
claimedPath: React.MutableRefObject<string | null>;
|
|
19
21
|
}
|
|
20
22
|
export declare const useBreadcrumb: () => BreadcrumbContextType;
|
|
21
23
|
export declare function BreadcrumbProvider({ children, }: {
|
|
22
24
|
children: React.ReactNode;
|
|
23
25
|
}): React.JSX.Element;
|
|
24
26
|
export declare function useSetBreadcrumbs(getBreadcrumbs: (() => IBreadcrumbItem[]) | IBreadcrumbItem[]): void;
|
|
27
|
+
/**
|
|
28
|
+
* For layout routes that derive breadcrumbs from the URL: applies them only
|
|
29
|
+
* while no page under the layout has set its own for the current path.
|
|
30
|
+
* Without this, a layout re-running its effect (for example when the
|
|
31
|
+
* organization's display name loads) overwrote the page's breadcrumbs.
|
|
32
|
+
*/
|
|
33
|
+
export declare function useSetDefaultBreadcrumbs(getBreadcrumbs: (() => IBreadcrumbItem[]) | IBreadcrumbItem[]): void;
|
|
25
34
|
/** For pages that render their own header instead of the breadcrumb strip. */
|
|
26
35
|
export declare function useClearBreadcrumbs(): void;
|
|
27
36
|
export declare function useHideBreadcrumbs(hidden: boolean): void;
|
|
@@ -4,16 +4,16 @@ interface IControlledCollapsiblePanelProps {
|
|
|
4
4
|
children: React.ReactNode;
|
|
5
5
|
open: boolean | undefined;
|
|
6
6
|
setOpen?: React.Dispatch<React.SetStateAction<boolean>>;
|
|
7
|
-
onClick?: () => void;
|
|
8
|
-
wrapperElement?: React.ElementType;
|
|
7
|
+
onClick?: (() => void) | undefined;
|
|
8
|
+
wrapperElement?: React.ElementType | undefined;
|
|
9
9
|
shown?: boolean;
|
|
10
10
|
setShown?: (shown: boolean) => void;
|
|
11
11
|
customizedButton?: React.ReactNode;
|
|
12
|
-
className?: string;
|
|
12
|
+
className?: string | undefined;
|
|
13
13
|
}
|
|
14
14
|
export declare function ControlledCollapsiblePanel({ title, children, open, setOpen, onClick, wrapperElement, customizedButton, className, }: IControlledCollapsiblePanelProps): React.JSX.Element;
|
|
15
15
|
export declare function UncontrolledCollapsiblePanel({ title, children, onClick, wrapperElement, initialState, className, customizedButton, }: Omit<IControlledCollapsiblePanelProps, 'setOpen' | 'open'> & {
|
|
16
|
-
initialState?: boolean;
|
|
16
|
+
initialState?: boolean | undefined;
|
|
17
17
|
}): React.JSX.Element;
|
|
18
18
|
type MaybeCollapsibleProps = {
|
|
19
19
|
className?: string;
|