@parallelworks/ui 0.51.0 → 0.53.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/README.md +197 -17
- package/dist/ai/agent/toolStrings.d.ts +2 -0
- package/dist/ai/agent/toolStrings.js +20 -18
- package/dist/ai/ai.css +17 -3
- package/dist/ai/components/AllocationSelector.js +5 -1
- package/dist/ai/components/AttachmentManager.js +51 -42
- package/dist/ai/components/AttachmentUpload.d.ts +4 -2
- package/dist/ai/components/AttachmentUpload.js +9 -9
- package/dist/ai/components/BlockedGroupBanner.js +8 -14
- package/dist/ai/components/BranchNavigator.js +11 -12
- package/dist/ai/components/ChatEmptyState.js +12 -19
- package/dist/ai/components/ChatInput.d.ts +4 -3
- package/dist/ai/components/ChatInput.js +27 -13
- package/dist/ai/components/ChatMessage.js +45 -121
- package/dist/ai/components/ChatMessageList.d.ts +5 -2
- package/dist/ai/components/ChatMessageList.js +89 -51
- package/dist/ai/components/ChatSidebar.js +11 -7
- package/dist/ai/components/ChatThread.js +1 -13
- package/dist/ai/components/DragOverlay.js +3 -3
- package/dist/ai/components/MessageAttachments.d.ts +10 -0
- package/dist/ai/components/MessageAttachments.js +78 -0
- package/dist/ai/components/ModelSelector.js +3 -3
- package/dist/ai/components/PastedText.js +2 -2
- package/dist/ai/components/ProviderIssueBanner.js +19 -23
- package/dist/ai/components/ShareDialog.js +2 -2
- package/dist/ai/components/agent/ActivityLine.d.ts +0 -2
- package/dist/ai/components/agent/ActivityLine.js +8 -51
- package/dist/ai/components/agent/AgentMessageParts.js +114 -53
- package/dist/ai/core/ChatProvider.d.ts +16 -5
- package/dist/ai/core/ChatProvider.js +41 -8
- package/dist/ai/core/config.js +4 -3
- package/dist/ai/index.d.ts +1 -1
- package/dist/ai/index.js +3 -3
- package/dist/ai/strings.d.ts +29 -3
- package/dist/ai/strings.js +80 -26
- package/dist/ai/types.d.ts +4 -0
- package/dist/ai/ui/Notice.d.ts +2 -2
- package/dist/ai/ui/Notice.js +29 -62
- package/dist/ai/ui/sidebar.d.ts +5 -3
- package/dist/ai/ui/sidebar.js +22 -10
- package/dist/components/ActionMenu.d.ts +1 -0
- package/dist/components/ActionMenu.js +6 -1
- package/dist/components/AppLink.d.ts +26 -0
- package/dist/components/AppLink.js +51 -0
- package/dist/components/Avatar.d.ts +2 -1
- package/dist/components/Avatar.js +4 -2
- package/dist/components/Button.d.ts +15 -5
- package/dist/components/Button.js +47 -40
- package/dist/components/Callout.d.ts +31 -7
- package/dist/components/Callout.js +50 -19
- package/dist/components/Card.d.ts +11 -6
- package/dist/components/Card.js +14 -8
- package/dist/components/Checkbox.js +2 -1
- package/dist/components/ColorInput.js +5 -3
- package/dist/components/Combobox.js +49 -19
- package/dist/components/ConfirmModal.d.ts +19 -8
- package/dist/components/ConfirmModal.js +31 -53
- package/dist/components/CopyButton.d.ts +38 -0
- package/dist/components/CopyButton.js +68 -0
- package/dist/components/CreateModal.js +118 -111
- package/dist/components/DatePicker.js +12 -8
- package/dist/components/DescriptionList.d.ts +25 -5
- package/dist/components/DescriptionList.js +56 -22
- package/dist/components/Disclosure.js +1 -1
- package/dist/components/Drawer.js +10 -16
- package/dist/components/Field.d.ts +16 -5
- package/dist/components/Field.js +63 -8
- package/dist/components/IconButton.d.ts +14 -5
- package/dist/components/IconButton.js +25 -14
- package/dist/components/InfoTip.d.ts +12 -1
- package/dist/components/InfoTip.js +13 -2
- package/dist/components/Input.d.ts +14 -8
- package/dist/components/Input.js +46 -31
- package/dist/components/Loader.js +1 -1
- package/dist/components/MarkdownImpl.d.ts +1 -0
- package/dist/components/MarkdownImpl.js +1 -0
- package/dist/components/MenuEntries.d.ts +4 -0
- package/dist/components/MenuEntries.js +11 -12
- package/dist/components/Meter.js +5 -4
- package/dist/components/Modal.d.ts +28 -4
- package/dist/components/Modal.js +37 -14
- package/dist/components/Overview.d.ts +20 -12
- package/dist/components/Overview.js +14 -9
- package/dist/components/PageHeader.d.ts +47 -65
- package/dist/components/PageHeader.js +275 -153
- package/dist/components/PageHeaderAction.d.ts +67 -0
- package/dist/components/PageHeaderAction.js +107 -0
- package/dist/components/Pagination.js +6 -16
- package/dist/components/Popover.d.ts +4 -1
- package/dist/components/Popover.js +5 -3
- package/dist/components/Provider.d.ts +79 -19
- package/dist/components/Provider.js +140 -130
- package/dist/components/Radio.js +2 -1
- package/dist/components/RefreshButton.js +7 -8
- package/dist/components/RequiredMark.js +1 -1
- package/dist/components/Section.js +1 -1
- package/dist/components/Select.d.ts +4 -9
- package/dist/components/Select.js +24 -11
- package/dist/components/SettingModeOption.d.ts +1 -1
- package/dist/components/SettingModeOption.js +7 -1
- package/dist/components/SettingsCard.d.ts +5 -3
- package/dist/components/SettingsCard.js +27 -20
- package/dist/components/Slider.js +1 -1
- package/dist/components/StatusBadge.js +2 -2
- package/dist/components/Switch.js +5 -4
- package/dist/components/Table.d.ts +30 -20
- package/dist/components/Table.js +50 -73
- package/dist/components/Tabs.d.ts +3 -7
- package/dist/components/Tabs.js +6 -10
- package/dist/components/ThemeEditor.js +18 -8
- package/dist/components/Toast.d.ts +11 -3
- package/dist/components/Toast.js +45 -20
- package/dist/components/buttonClasses.js +1 -1
- package/dist/components/comboboxItems.d.ts +4 -0
- package/dist/components/comboboxItems.js +6 -1
- package/dist/components/dismiss.d.ts +12 -0
- package/dist/components/dismiss.js +19 -0
- package/dist/components/fieldBox.d.ts +4 -0
- package/dist/components/fieldBox.js +7 -3
- package/dist/components/floating.d.ts +3 -3
- package/dist/components/floating.js +1 -1
- package/dist/components/focus.d.ts +5 -0
- package/dist/components/focus.js +21 -1
- package/dist/components/markdownCodeBreaks.js +3 -4
- package/dist/components/pageHeaderStore.d.ts +41 -0
- package/dist/components/pageHeaderStore.js +67 -0
- package/dist/components/pathBreaks.d.ts +8 -0
- package/dist/components/pathBreaks.js +28 -0
- package/dist/components/segmented.js +1 -1
- package/dist/components/shortcutKey.d.ts +2 -1
- package/dist/components/shortcutKey.js +19 -2
- package/dist/components/splitter.js +1 -1
- package/dist/components/useCssIsDark.js +40 -18
- package/dist/components/useTheme.js +9 -10
- package/dist/dev.d.ts +9 -0
- package/dist/dev.js +14 -0
- package/dist/editor/Editor.d.ts +3 -2
- package/dist/editor/Editor.js +24 -5
- package/dist/editor/EditorField.d.ts +2 -1
- package/dist/editor/EditorField.js +11 -29
- package/dist/editor/FormCodePanel.d.ts +7 -3
- package/dist/editor/FormCodePanel.js +14 -7
- package/dist/editor/Monaco.d.ts +22 -6
- package/dist/editor/Monaco.js +177 -113
- package/dist/editor/editorModel.d.ts +1 -1
- package/dist/editor/editorModel.js +1 -1
- package/dist/editor/index.d.ts +6 -5
- package/dist/editor/index.js +5 -4
- package/dist/editor/languages.d.ts +24 -0
- package/dist/editor/languages.js +31 -0
- package/dist/editor/monacoFeatures.d.ts +7 -0
- package/dist/editor/monacoFeatures.js +19 -0
- package/dist/editor/themes.d.ts +8 -5
- package/dist/editor/themes.js +65 -32
- package/dist/editor/workers.d.ts +3 -3
- package/dist/editor/workers.js +8 -4
- package/dist/editor/yaml.d.ts +6 -2
- package/dist/editor/yaml.js +11 -2
- package/dist/editor/yamlLanguage.js +55 -38
- package/dist/file-explorer/FileExplorer.d.ts +18 -4
- package/dist/file-explorer/FileExplorer.js +204 -142
- package/dist/file-explorer/FileExplorerContext.js +1 -1
- package/dist/file-explorer/FilePreview/StreamedBadge.js +3 -1
- package/dist/file-explorer/FilePreview/Viewer.js +14 -10
- package/dist/file-explorer/FilePreview/index.js +4 -4
- package/dist/file-explorer/FileRow.d.ts +6 -2
- package/dist/file-explorer/FileRow.js +35 -17
- package/dist/file-explorer/FileRowsWindow.d.ts +2 -1
- package/dist/file-explorer/FileRowsWindow.js +36 -4
- package/dist/file-explorer/FileTable.d.ts +3 -1
- package/dist/file-explorer/FileTable.js +6 -3
- package/dist/file-explorer/TreeView.d.ts +5 -1
- package/dist/file-explorer/TreeView.js +86 -39
- package/dist/file-explorer/helpers.d.ts +2 -1
- package/dist/file-explorer/helpers.js +24 -23
- package/dist/file-explorer/lib/utils.d.ts +3 -0
- package/dist/file-explorer/lib/utils.js +6 -1
- package/dist/file-explorer/toasts.js +27 -19
- package/dist/file-explorer/treeRows.d.ts +6 -0
- package/dist/file-explorer/treeRows.js +19 -1
- package/dist/file-explorer/useNearEnd.js +3 -6
- package/dist/form/Fields/CheckboxGroupField.js +12 -5
- package/dist/form/Fields/DurationField.js +1 -1
- package/dist/form/Fields/LabelField.js +1 -1
- package/dist/form/Fields/ObjectField.d.ts +1 -1
- package/dist/form/Fields/ObjectField.js +3 -2
- package/dist/form/Fields/StringField.js +16 -29
- package/dist/form/Fields/TextAreaField.js +3 -4
- package/dist/form/Form.js +3 -8
- package/dist/form/Wizard/WizardNavigation.js +0 -3
- package/dist/form/Wizard/utils.js +2 -1
- package/dist/form/fieldFrame.d.ts +1 -1
- package/dist/form/fieldFrame.js +2 -2
- package/dist/form/types/fieldComponentTypes.d.ts +2 -1
- package/dist/graph/AnnotationBanner.d.ts +1 -2
- package/dist/graph/AnnotationBanner.js +30 -32
- package/dist/graph/Connectors.js +4 -1
- package/dist/graph/DependencyGraph.js +2 -2
- package/dist/graph/GraphEditor.js +11 -9
- package/dist/graph/GraphEditorDialogs.js +1 -1
- package/dist/graph/GraphNode.js +7 -4
- package/dist/graph/InputDialog.js +1 -1
- package/dist/graph/InputsEditor.js +14 -11
- package/dist/graph/MatrixGroup.js +9 -3
- package/dist/graph/Reveal.js +18 -10
- package/dist/graph/ShortcutsButton.d.ts +11 -2
- package/dist/graph/ShortcutsButton.js +14 -3
- package/dist/graph/TreeView.js +35 -18
- package/dist/graph/WorkflowSettingsDialog.js +1 -1
- package/dist/graph/editorFields.js +1 -1
- package/dist/graph/editorRows.js +16 -10
- package/dist/graph/editorStrings.d.ts +7 -0
- package/dist/graph/editorStrings.js +8 -1
- package/dist/graph/inputRefs.js +1 -1
- package/dist/graph/settingsViews.js +11 -18
- package/dist/graph/stepWith.js +1 -1
- package/dist/icons.d.ts +2 -0
- package/dist/icons.js +4 -2
- package/dist/index.d.ts +12 -12
- package/dist/index.js +16 -16
- package/dist/list/ActionToolbar.d.ts +42 -6
- package/dist/list/ActionToolbar.js +298 -101
- package/dist/list/ListPage.d.ts +15 -23
- package/dist/list/ListPage.js +42 -43
- package/dist/list/ListTable.d.ts +37 -7
- package/dist/list/ListTable.js +52 -12
- package/dist/list/ListViewControls.js +1 -1
- package/dist/list/UserHoverCard.js +7 -15
- package/dist/list/index.d.ts +2 -2
- package/dist/list/index.js +2 -2
- package/dist/list/listSearch.js +12 -10
- package/dist/list/listView.d.ts +10 -1
- package/dist/list/listView.js +15 -1
- package/dist/logviewer/LogViewer.d.ts +4 -2
- package/dist/logviewer/LogViewer.js +87 -69
- package/dist/logviewer/logviewer.css +3 -2
- package/dist/reducedMotion.d.ts +5 -0
- package/dist/reducedMotion.js +20 -0
- package/dist/safeUrl.d.ts +1 -1
- package/dist/safeUrl.js +4 -2
- package/dist/styles.css +1 -1
- package/package.json +5 -2
- package/dist/components/Breadcrumbs.d.ts +0 -37
- package/dist/components/Breadcrumbs.js +0 -90
- package/dist/components/CopyToClipboard.d.ts +0 -17
- package/dist/components/CopyToClipboard.js +0 -66
- package/dist/components/Sort.d.ts +0 -9
- package/dist/components/Sort.js +0 -42
- package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +0 -6
- package/dist/file-explorer/FilePreview/CodePreviewEditor.js +0 -64
|
@@ -1,28 +1,66 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
|
-
import { CheckIcon, CopyIcon } from "../icons.js";
|
|
3
2
|
import { useStrings } from "./Provider.js";
|
|
4
|
-
import { useCopy } from "./useCopy.js";
|
|
5
|
-
import { IconButton } from "./IconButton.js";
|
|
6
3
|
import { InfoTip } from "./InfoTip.js";
|
|
4
|
+
import { CopyButton } from "./CopyButton.js";
|
|
5
|
+
import { withPathBreaks } from "./pathBreaks.js";
|
|
7
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { useId, useRef } from "react";
|
|
7
|
+
import { createContext, useContext, useId, useRef } from "react";
|
|
9
8
|
//#region src/components/DescriptionList.tsx
|
|
10
9
|
var variantClasses = {
|
|
11
10
|
plain: "*:py-1",
|
|
12
11
|
divided: "divide-y divide-(--theme-border) *:py-2",
|
|
13
12
|
card: "panel divide-y divide-(--theme-border) px-4 *:py-2"
|
|
14
13
|
};
|
|
14
|
+
var columns = (stacked) => cx("grid grid-cols-[minmax(0,1fr)]", !stacked && "@sm/dl:grid-cols-[fit-content(40%)_minmax(0,1fr)] @sm/dl:gap-x-6");
|
|
15
|
+
var InGroup = createContext(false);
|
|
16
|
+
var titleClassName = "col-span-full m-0 mb-1 text-sm font-semibold text-(--theme-app)";
|
|
15
17
|
/** Names and their values, such as the details of a record in a drawer or a card. The
|
|
16
18
|
* label column is as wide as its longest label, up to two fifths of the list, so a
|
|
17
19
|
* long label wraps rather than squeezing the values; each label sits over its value
|
|
18
|
-
* when the list is narrow.
|
|
19
|
-
|
|
20
|
+
* when the list is narrow. Lists side by side in one panel share their label column
|
|
21
|
+
* inside a `DescriptionListGroup`. */
|
|
22
|
+
function DescriptionList({ variant = "plain", title, headingLevel = 3, stacked = false, className, children, ...props }) {
|
|
23
|
+
const grouped = useContext(InGroup);
|
|
24
|
+
const titleId = useId();
|
|
25
|
+
const Heading = `h${headingLevel}`;
|
|
26
|
+
const list = /* @__PURE__ */ jsx("dl", {
|
|
27
|
+
...props,
|
|
28
|
+
className: cx("m-0 text-sm", grouped ? "col-span-full grid grid-cols-subgrid" : columns(stacked), variantClasses[variant]),
|
|
29
|
+
children
|
|
30
|
+
});
|
|
31
|
+
const named = title !== void 0 ? {
|
|
32
|
+
role: "group",
|
|
33
|
+
"aria-labelledby": titleId
|
|
34
|
+
} : {};
|
|
35
|
+
const heading = title !== void 0 && /* @__PURE__ */ jsx(Heading, {
|
|
36
|
+
id: titleId,
|
|
37
|
+
className: titleClassName,
|
|
38
|
+
children: title
|
|
39
|
+
});
|
|
40
|
+
if (grouped) return /* @__PURE__ */ jsxs("div", {
|
|
41
|
+
...named,
|
|
42
|
+
className: cx("col-span-full grid grid-cols-subgrid", className),
|
|
43
|
+
children: [heading, list]
|
|
44
|
+
});
|
|
45
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
46
|
+
...named,
|
|
47
|
+
className: cx("@container/dl min-w-0", className),
|
|
48
|
+
children: [heading, list]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Description lists in one panel, such as a record's Overview, Actor and Target, that
|
|
52
|
+
* share one label column: it fits the longest label across all of them, so their
|
|
53
|
+
* values start at one edge down the panel. Each list keeps its own title and variant;
|
|
54
|
+
* all of them stack together when the panel is narrow. */
|
|
55
|
+
function DescriptionListGroup({ stacked = false, className, children }) {
|
|
20
56
|
return /* @__PURE__ */ jsx("div", {
|
|
21
57
|
className: cx("@container/dl min-w-0", className),
|
|
22
|
-
children: /* @__PURE__ */ jsx("
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
58
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
59
|
+
className: cx(columns(stacked), "gap-y-6"),
|
|
60
|
+
children: /* @__PURE__ */ jsx(InGroup, {
|
|
61
|
+
value: true,
|
|
62
|
+
children
|
|
63
|
+
})
|
|
26
64
|
})
|
|
27
65
|
});
|
|
28
66
|
}
|
|
@@ -46,7 +84,7 @@ function DescriptionListItem({ label, children, tooltip, mono = false, copy = fa
|
|
|
46
84
|
children: isEmpty(children) ? /* @__PURE__ */ jsx(EmptyValue, {}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
47
85
|
"data-value": true,
|
|
48
86
|
className: cx("min-w-0 leading-5 wrap-anywhere", mono && "font-mono text-[0.8125rem]"),
|
|
49
|
-
children
|
|
87
|
+
children: withPathBreaks(children)
|
|
50
88
|
}), copy !== false && /* @__PURE__ */ jsx(CopyValue, {
|
|
51
89
|
text: copy === true ? void 0 : copy,
|
|
52
90
|
label,
|
|
@@ -70,25 +108,21 @@ function EmptyValue() {
|
|
|
70
108
|
});
|
|
71
109
|
}
|
|
72
110
|
function CopyValue({ text, label, labelId }) {
|
|
73
|
-
const { common: t } = useStrings();
|
|
74
|
-
const { copy, copied } = useCopy();
|
|
75
111
|
const buttonId = useId();
|
|
76
112
|
const button = useRef(null);
|
|
77
|
-
const
|
|
113
|
+
const shown = () => {
|
|
78
114
|
const value = button.current?.closest("dd")?.querySelector("[data-value]");
|
|
79
|
-
|
|
80
|
-
copy(text ?? shown ?? "", typeof label === "string" ? { label } : void 0);
|
|
115
|
+
return value?.innerText ?? value?.textContent ?? "";
|
|
81
116
|
};
|
|
82
|
-
return /* @__PURE__ */ jsx(
|
|
117
|
+
return /* @__PURE__ */ jsx(CopyButton, {
|
|
83
118
|
ref: button,
|
|
84
119
|
id: buttonId,
|
|
85
120
|
size: "xs",
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
onClick,
|
|
121
|
+
text: text ?? shown,
|
|
122
|
+
label: typeof label === "string" ? label : void 0,
|
|
123
|
+
"aria-labelledby": typeof label === "string" ? void 0 : `${buttonId} ${labelId}`,
|
|
90
124
|
className: "-my-0.5"
|
|
91
125
|
});
|
|
92
126
|
}
|
|
93
127
|
//#endregion
|
|
94
|
-
export { DescriptionListItem, DescriptionList as default };
|
|
128
|
+
export { DescriptionListGroup, DescriptionListItem, DescriptionList as default };
|
|
@@ -17,7 +17,7 @@ function Disclosure({ summary, open, onOpenChange, defaultOpen = false, disabled
|
|
|
17
17
|
disabled,
|
|
18
18
|
className,
|
|
19
19
|
children: [/* @__PURE__ */ jsxs(Collapsible.Trigger, {
|
|
20
|
-
className: cx("group/disclosure flex min-w-0 items-start gap-2 text-left", disabled ? "cursor-default" : "cursor-pointer", summaryClassName),
|
|
20
|
+
className: cx("group/disclosure flex min-w-0 items-start gap-2 rounded-sm text-left focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-focus)", disabled ? "cursor-default" : "cursor-pointer", summaryClassName),
|
|
21
21
|
children: [summary, !disabled && /* @__PURE__ */ jsx(ChevronRightIcon, {
|
|
22
22
|
"aria-hidden": "true",
|
|
23
23
|
className: "mt-1 h-3.5 w-3.5 shrink-0 opacity-70 transition-transform group-data-panel-open/disclosure:rotate-90 motion-reduce:transition-none"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { CloseIcon } from "../icons.js";
|
|
3
|
-
import { pressedToast } from "./Toast.js";
|
|
4
3
|
import { useStrings } from "./Provider.js";
|
|
4
|
+
import { IconButton } from "./IconButton.js";
|
|
5
|
+
import { closeHandler } from "./dismiss.js";
|
|
5
6
|
import { useSplitter } from "./splitter.js";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
import { useLayoutEffect, useRef, useState } from "react";
|
|
@@ -30,14 +31,7 @@ function Drawer$1({ open, onClose, title, description, footer, side = "right", w
|
|
|
30
31
|
});
|
|
31
32
|
const header = title !== void 0 || description !== void 0 || closeButton;
|
|
32
33
|
const area = contained ? "absolute inset-0" : "fixed inset-x-0 bottom-0 top-(--app-inset-top,0px)";
|
|
33
|
-
const onOpenChange = (
|
|
34
|
-
if (next) return;
|
|
35
|
-
if (!dismissible && details.reason === "escape-key" || details.reason === "outside-press" && pressedToast(details.event)) {
|
|
36
|
-
details.cancel();
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
onClose();
|
|
40
|
-
};
|
|
34
|
+
const onOpenChange = closeHandler(dismissible, onClose);
|
|
41
35
|
return /* @__PURE__ */ jsxs(Drawer.Root, {
|
|
42
36
|
open,
|
|
43
37
|
onOpenChange,
|
|
@@ -70,24 +64,24 @@ function Drawer$1({ open, onClose, title, description, footer, side = "right", w
|
|
|
70
64
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
71
65
|
className: "min-w-0 flex-1",
|
|
72
66
|
children: [title !== void 0 && /* @__PURE__ */ jsx(Drawer.Title, {
|
|
73
|
-
className: "
|
|
67
|
+
className: "m-0 text-sm font-semibold wrap-break-word",
|
|
74
68
|
children: title
|
|
75
69
|
}), description !== void 0 && /* @__PURE__ */ jsx(Drawer.Description, {
|
|
76
70
|
className: "mt-0.5 text-xs text-(--theme-muted-text-color)",
|
|
77
71
|
children: description
|
|
78
72
|
})]
|
|
79
|
-
}), closeButton && /* @__PURE__ */ jsx(Drawer.Close, {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
})]
|
|
73
|
+
}), closeButton && /* @__PURE__ */ jsx(Drawer.Close, { render: /* @__PURE__ */ jsx(IconButton, {
|
|
74
|
+
icon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
75
|
+
label: common.close,
|
|
76
|
+
className: "-my-1 -me-1.5"
|
|
77
|
+
}) })]
|
|
84
78
|
}),
|
|
85
79
|
/* @__PURE__ */ jsx("div", {
|
|
86
80
|
className: cx("relative flex min-h-0 flex-1 flex-col overflow-y-auto", padded && "p-4", className),
|
|
87
81
|
children
|
|
88
82
|
}),
|
|
89
83
|
footer && /* @__PURE__ */ jsx("div", {
|
|
90
|
-
className: "flex shrink-0 justify-end gap-2 border-t border-(--theme-border) px-
|
|
84
|
+
className: cx("flex shrink-0 items-center justify-end gap-2 border-t border-(--theme-border) px-5 py-3", "px-4"),
|
|
91
85
|
children: footer
|
|
92
86
|
})
|
|
93
87
|
]
|
|
@@ -17,11 +17,21 @@ export declare const FieldRowContext: import("react").Context<boolean>;
|
|
|
17
17
|
/** The surrounding Field's control props, for a control drawn further down than the Field's
|
|
18
18
|
* own children. Null outside a Field. */
|
|
19
19
|
export declare function useFieldControl(): FieldControlProps | null;
|
|
20
|
+
/** The label's id, for a control that isn't a Base UI one and so isn't named by the label's
|
|
21
|
+
* `for`, such as a button that opens a picker. */
|
|
22
|
+
export declare function useFieldLabelId(): string | undefined;
|
|
20
23
|
export type FieldLayout = 'stacked' | 'inline';
|
|
21
24
|
export interface FieldProps {
|
|
22
25
|
label: ReactNode;
|
|
23
|
-
/** Beside the label and outside it, so it stays out of the control's name
|
|
26
|
+
/** Beside the label and outside it, so it stays out of the control's name, such as a count. For
|
|
27
|
+
* help text, use `help`. */
|
|
24
28
|
hint?: ReactNode;
|
|
29
|
+
/** More about the field, behind a ? beside the label. It is read with the control as part of
|
|
30
|
+
* its description, so the ? is hidden from assistive technology and Tab passes over it. It
|
|
31
|
+
* opens on hover or press of the ?, and while the control has keyboard focus, until Escape.
|
|
32
|
+
* `[text](url)` links and line breaks show as such; a link keeps the ? in the Tab order, as
|
|
33
|
+
* the keyboard's way to it. */
|
|
34
|
+
help?: string | undefined;
|
|
25
35
|
/** Buttons at the far end of the label's row that act on the field, such as one that
|
|
26
36
|
* switches its control to a typed expression. */
|
|
27
37
|
actions?: ReactNode;
|
|
@@ -47,9 +57,10 @@ export interface FieldProps {
|
|
|
47
57
|
/** The control's id; one is made up when left out. */
|
|
48
58
|
id?: string | undefined;
|
|
49
59
|
className?: string | undefined;
|
|
50
|
-
/** The control, or a function that places the control props on it.
|
|
51
|
-
* as Select, Combobox, NumberInput,
|
|
52
|
-
*
|
|
60
|
+
/** The control, or a function that places the control props on it. Any control of this
|
|
61
|
+
* package, such as Input, Select, Combobox, NumberInput, Switch or DatePicker, takes its label,
|
|
62
|
+
* description and invalid state from the Field on its own; a native element needs the
|
|
63
|
+
* function. A value shown but not edited goes in a `FieldValue`. */
|
|
53
64
|
children: ReactNode | ((control: FieldControlProps) => ReactNode);
|
|
54
65
|
}
|
|
55
66
|
/** An error in the look a Field gives its own, for a control outside a Field, or for a part of
|
|
@@ -61,7 +72,7 @@ export declare function ErrorText({ id, children }: {
|
|
|
61
72
|
}): import("react").JSX.Element | null;
|
|
62
73
|
/** A control with its label, help and error, tied to it for assistive technology. One frame
|
|
63
74
|
* for every field, in a form or standing alone. */
|
|
64
|
-
export declare function Field({ label, hint, actions, description, error, invalid, required, disabled, layout, compact, size, group, id: ownId, className, children, }: FieldProps): import("react").JSX.Element;
|
|
75
|
+
export declare function Field({ label, hint, help, actions, description, error, invalid, required, disabled, layout, compact, size, group, id: ownId, className, children, }: FieldProps): import("react").JSX.Element;
|
|
65
76
|
/** One checkbox or radio and its label inside a Field, such as an option of a group. A bare
|
|
66
77
|
* `<label>` there would take the Field's label as its own, so every option read as the field. */
|
|
67
78
|
export declare function FieldOption({ disabled, className, children, }: {
|
package/dist/components/Field.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { EyeIcon, EyeOffIcon, WarningIcon } from "../icons.js";
|
|
3
3
|
import { useStrings } from "./Provider.js";
|
|
4
|
+
import { focusCameFromKeyboard, trackFocusModality } from "./focus.js";
|
|
5
|
+
import { InfoTip, formatInfoTipContent } from "./InfoTip.js";
|
|
4
6
|
import { RequiredMark } from "./RequiredMark.js";
|
|
5
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
import { createContext, use, useId } from "react";
|
|
8
|
+
import { createContext, use, useEffect, useId, useState } from "react";
|
|
7
9
|
import { Field } from "@base-ui/react/field";
|
|
8
10
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
9
11
|
//#region src/components/Field.tsx
|
|
@@ -15,7 +17,12 @@ var FieldRowContext = createContext(false);
|
|
|
15
17
|
/** The surrounding Field's control props, for a control drawn further down than the Field's
|
|
16
18
|
* own children. Null outside a Field. */
|
|
17
19
|
function useFieldControl() {
|
|
18
|
-
return use(ControlContext);
|
|
20
|
+
return use(ControlContext)?.control ?? null;
|
|
21
|
+
}
|
|
22
|
+
/** The label's id, for a control that isn't a Base UI one and so isn't named by the label's
|
|
23
|
+
* `for`, such as a button that opens a picker. */
|
|
24
|
+
function useFieldLabelId() {
|
|
25
|
+
return use(ControlContext)?.labelId;
|
|
19
26
|
}
|
|
20
27
|
var labelSizes = {
|
|
21
28
|
sm: {
|
|
@@ -48,14 +55,19 @@ function ErrorText({ id, children }) {
|
|
|
48
55
|
}
|
|
49
56
|
/** A control with its label, help and error, tied to it for assistive technology. One frame
|
|
50
57
|
* for every field, in a form or standing alone. */
|
|
51
|
-
function Field$1({ label, hint, actions, description, error, invalid, required = false, disabled = false, layout = "stacked", compact = false, size = "md", group = false, id: ownId, className, children }) {
|
|
58
|
+
function Field$1({ label, hint, help, actions, description, error, invalid, required = false, disabled = false, layout = "stacked", compact = false, size = "md", group = false, id: ownId, className, children }) {
|
|
52
59
|
const uid = useId();
|
|
53
60
|
const id = ownId ?? `${uid}control`;
|
|
54
61
|
const labelId = `${uid}label`;
|
|
55
62
|
const descriptionId = description ? `${uid}description` : void 0;
|
|
63
|
+
const helpId = help ? `${uid}help` : void 0;
|
|
56
64
|
const errorId = error ? `${uid}error` : void 0;
|
|
57
65
|
const isInvalid = Boolean(error) || Boolean(invalid);
|
|
58
|
-
const describedBy = [
|
|
66
|
+
const describedBy = [
|
|
67
|
+
descriptionId,
|
|
68
|
+
helpId,
|
|
69
|
+
errorId
|
|
70
|
+
].filter(Boolean).join(" ");
|
|
59
71
|
const control = {
|
|
60
72
|
id,
|
|
61
73
|
...group && { "aria-labelledby": labelId },
|
|
@@ -63,26 +75,61 @@ function Field$1({ label, hint, actions, description, error, invalid, required =
|
|
|
63
75
|
...isInvalid && { "aria-invalid": true },
|
|
64
76
|
...required && { "aria-required": true }
|
|
65
77
|
};
|
|
78
|
+
const controlContext = {
|
|
79
|
+
control,
|
|
80
|
+
labelId
|
|
81
|
+
};
|
|
66
82
|
const inline = layout === "inline";
|
|
67
83
|
const inRow = use(FieldRowContext) && !inline && !group;
|
|
68
84
|
const labelSize = labelSizes[size];
|
|
85
|
+
const [helpOpen, setHelpOpen] = useState(false);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (help) trackFocusModality();
|
|
88
|
+
}, [help]);
|
|
89
|
+
const helpTip = help && /* @__PURE__ */ jsx(InfoTip, {
|
|
90
|
+
text: help,
|
|
91
|
+
describesControl: true,
|
|
92
|
+
open: Boolean(helpOpen),
|
|
93
|
+
onOpenChange: (open) => setHelpOpen(open && "pointer"),
|
|
94
|
+
keepSide: helpOpen === "focus"
|
|
95
|
+
});
|
|
96
|
+
const helpFocus = help ? {
|
|
97
|
+
onFocus: () => {
|
|
98
|
+
if (focusCameFromKeyboard()) setHelpOpen("focus");
|
|
99
|
+
},
|
|
100
|
+
onBlur: (event) => {
|
|
101
|
+
if (!event.currentTarget.contains(event.relatedTarget)) setHelpOpen(false);
|
|
102
|
+
},
|
|
103
|
+
onKeyDown: (event) => {
|
|
104
|
+
if (event.key === "Escape" && helpOpen) {
|
|
105
|
+
event.stopPropagation();
|
|
106
|
+
setHelpOpen(false);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} : {};
|
|
69
110
|
const labelBox = cx(labelClassName, labelSize.text, inline && cx(labelSize.inlineHeight, "shrink-0", compact ? "mr-2 w-fit" : "w-52 pr-3"), inRow && "row-start-1 self-end");
|
|
70
111
|
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
71
112
|
/* @__PURE__ */ jsxs("span", { children: [label, required && /* @__PURE__ */ jsx(RequiredMark, {})] }),
|
|
113
|
+
helpTip,
|
|
72
114
|
hint,
|
|
73
115
|
actions && /* @__PURE__ */ jsx("span", {
|
|
74
116
|
className: actionsClassName,
|
|
75
117
|
children: actions
|
|
76
118
|
})
|
|
77
119
|
] });
|
|
120
|
+
const placed = typeof children === "function" ? children(control) : children;
|
|
78
121
|
const body = /* @__PURE__ */ jsxs("div", {
|
|
79
122
|
className: cx("flex w-full min-w-0 flex-col gap-1", inRow && "row-start-2"),
|
|
123
|
+
...helpFocus,
|
|
80
124
|
children: [
|
|
81
125
|
/* @__PURE__ */ jsx(FieldRowContext, {
|
|
82
126
|
value: false,
|
|
83
127
|
children: /* @__PURE__ */ jsx(ControlContext, {
|
|
84
|
-
value:
|
|
85
|
-
children:
|
|
128
|
+
value: controlContext,
|
|
129
|
+
children: inline ? /* @__PURE__ */ jsx("div", {
|
|
130
|
+
className: cx("grid items-center", labelSize.inlineHeight),
|
|
131
|
+
children: placed
|
|
132
|
+
}) : placed
|
|
86
133
|
})
|
|
87
134
|
}),
|
|
88
135
|
description && /* @__PURE__ */ jsx(Field.Description, {
|
|
@@ -90,6 +137,11 @@ function Field$1({ label, hint, actions, description, error, invalid, required =
|
|
|
90
137
|
className: "text-xs leading-relaxed text-(--theme-muted-text-color)",
|
|
91
138
|
children: description
|
|
92
139
|
}),
|
|
140
|
+
help && /* @__PURE__ */ jsx(Field.Description, {
|
|
141
|
+
id: helpId,
|
|
142
|
+
hidden: true,
|
|
143
|
+
children: formatInfoTipContent(help)
|
|
144
|
+
}),
|
|
93
145
|
error && /* @__PURE__ */ jsxs(Field.Error, {
|
|
94
146
|
id: errorId,
|
|
95
147
|
match: true,
|
|
@@ -128,11 +180,12 @@ function Field$1({ label, hint, actions, description, error, invalid, required =
|
|
|
128
180
|
className: labelBox,
|
|
129
181
|
children: [
|
|
130
182
|
/* @__PURE__ */ jsxs(Field.Label, {
|
|
131
|
-
htmlFor: id,
|
|
183
|
+
...typeof children === "function" || ownId !== void 0 ? { htmlFor: id } : {},
|
|
132
184
|
id: labelId,
|
|
133
185
|
"data-field-label": true,
|
|
134
186
|
children: [label, required && /* @__PURE__ */ jsx(RequiredMark, {})]
|
|
135
187
|
}),
|
|
188
|
+
helpTip,
|
|
136
189
|
hint,
|
|
137
190
|
actions && /* @__PURE__ */ jsx("span", {
|
|
138
191
|
className: actionsClassName,
|
|
@@ -177,8 +230,10 @@ function RevealToggle({ revealed, onRevealedChange, disabled }) {
|
|
|
177
230
|
* DescriptionList. */
|
|
178
231
|
function FieldValue({ size = "md", className, children, ...props }) {
|
|
179
232
|
const control = useFieldControl();
|
|
233
|
+
const labelId = useFieldLabelId();
|
|
180
234
|
return /* @__PURE__ */ jsx("output", {
|
|
181
235
|
id: control?.id,
|
|
236
|
+
"aria-labelledby": labelId,
|
|
182
237
|
"aria-describedby": control?.["aria-describedby"],
|
|
183
238
|
...props,
|
|
184
239
|
className: cx("flex min-w-0 items-center break-words text-(--theme-app)", size === "sm" ? "min-h-7 text-xs" : "min-h-9 text-sm", className),
|
|
@@ -186,4 +241,4 @@ function FieldValue({ size = "md", className, children, ...props }) {
|
|
|
186
241
|
});
|
|
187
242
|
}
|
|
188
243
|
//#endregion
|
|
189
|
-
export { ErrorText, Field$1 as Field, FieldOption, FieldRowContext, FieldValue, RevealToggle, useFieldControl };
|
|
244
|
+
export { ErrorText, Field$1 as Field, FieldOption, FieldRowContext, FieldValue, RevealToggle, useFieldControl, useFieldLabelId };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
|
+
import { type AppLinkProps } from './AppLink.js';
|
|
2
3
|
import { type ButtonSize, type ButtonVariant } from './buttonClasses.js';
|
|
3
|
-
|
|
4
|
+
interface IconButtonOwnProps {
|
|
4
5
|
icon: ReactNode;
|
|
5
6
|
/** The accessible name, also shown as the tooltip. */
|
|
6
7
|
label: string;
|
|
@@ -8,13 +9,21 @@ export interface IconButtonProps extends ComponentPropsWithRef<'button'> {
|
|
|
8
9
|
size?: ButtonSize;
|
|
9
10
|
/** A toggle's state: set, it reads as pressed (`aria-pressed`). */
|
|
10
11
|
pressed?: boolean | undefined;
|
|
11
|
-
/** A dot in the corner, such as for filters narrowing what the page shows.
|
|
12
|
+
/** A dot in the corner, such as for filters narrowing what the page shows. It
|
|
13
|
+
* is only seen, so say what it means in `label` too, such as "Filters (2 on)". */
|
|
12
14
|
dot?: boolean;
|
|
13
15
|
/** A single key, such as F, that presses the button from anywhere on the page
|
|
14
16
|
* outside a text field. Also shown in the tooltip. */
|
|
15
17
|
shortcut?: string | undefined;
|
|
16
18
|
}
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
/** With `href` it is a link that looks like the button, for navigation. */
|
|
20
|
+
export type IconButtonProps = IconButtonOwnProps & ((ComponentPropsWithRef<'button'> & {
|
|
21
|
+
href?: undefined;
|
|
22
|
+
}) | (Omit<AppLinkProps, 'href'> & {
|
|
23
|
+
href: string;
|
|
24
|
+
}));
|
|
25
|
+
/** A button that shows only an icon, named by its tooltip, or with `href` a
|
|
26
|
+
* link that looks like one. It can be a popup's trigger: it passes the
|
|
27
|
+
* trigger's props and ref on, and hides its tooltip while the popup is open. */
|
|
20
28
|
export declare function IconButton({ icon, label, variant, size, pressed, dot, shortcut, className, ref, ...props }: IconButtonProps): import("react").JSX.Element;
|
|
29
|
+
export {};
|
|
@@ -1,37 +1,48 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { buttonClasses } from "./buttonClasses.js";
|
|
3
3
|
import { Tooltip } from "./Tooltip.js";
|
|
4
|
+
import { AppLink } from "./AppLink.js";
|
|
4
5
|
import { useShortcutKey } from "./shortcutKey.js";
|
|
5
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { useCallback, useRef } from "react";
|
|
7
8
|
//#region src/components/IconButton.tsx
|
|
8
|
-
/** A button that shows only an icon, named by its tooltip
|
|
9
|
-
*
|
|
10
|
-
* the popup is open. */
|
|
9
|
+
/** A button that shows only an icon, named by its tooltip, or with `href` a
|
|
10
|
+
* link that looks like one. It can be a popup's trigger: it passes the
|
|
11
|
+
* trigger's props and ref on, and hides its tooltip while the popup is open. */
|
|
11
12
|
function IconButton({ icon, label, variant = "ghost", size = "sm", pressed, dot = false, shortcut, className, ref, ...props }) {
|
|
12
13
|
const button = useRef(null);
|
|
13
14
|
const setButton = useCallback((node) => {
|
|
14
15
|
button.current = node;
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const forward = ref;
|
|
17
|
+
if (typeof forward === "function") forward(node);
|
|
18
|
+
else if (forward) forward.current = node;
|
|
17
19
|
}, [ref]);
|
|
20
|
+
const shared = {
|
|
21
|
+
"aria-label": label,
|
|
22
|
+
className: cx(buttonClasses({
|
|
23
|
+
variant,
|
|
24
|
+
size,
|
|
25
|
+
iconOnly: true
|
|
26
|
+
}), className)
|
|
27
|
+
};
|
|
28
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [icon, dot && /* @__PURE__ */ jsx("span", { className: "absolute right-0 top-0 h-1.5 w-1.5 rounded-full bg-(--theme-link)" })] });
|
|
18
29
|
useShortcutKey(shortcut, () => button.current?.click());
|
|
19
30
|
return /* @__PURE__ */ jsx(Tooltip, {
|
|
20
31
|
content: label,
|
|
21
32
|
shortcut: shortcut?.toUpperCase(),
|
|
22
33
|
disabled: props["aria-expanded"] === true && !!props["aria-haspopup"],
|
|
23
|
-
children: /* @__PURE__ */
|
|
34
|
+
children: props.href !== void 0 ? /* @__PURE__ */ jsx(AppLink, {
|
|
35
|
+
...shared,
|
|
36
|
+
ref: setButton,
|
|
37
|
+
...props,
|
|
38
|
+
children: content
|
|
39
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
24
40
|
type: "button",
|
|
25
|
-
"aria-label": label,
|
|
26
41
|
"aria-pressed": pressed,
|
|
42
|
+
...shared,
|
|
27
43
|
ref: setButton,
|
|
28
|
-
className: cx(buttonClasses({
|
|
29
|
-
variant,
|
|
30
|
-
size,
|
|
31
|
-
iconOnly: true
|
|
32
|
-
}), className),
|
|
33
44
|
...props,
|
|
34
|
-
children:
|
|
45
|
+
children: content
|
|
35
46
|
})
|
|
36
47
|
});
|
|
37
48
|
}
|
|
@@ -8,8 +8,19 @@ interface InfoTipProps {
|
|
|
8
8
|
className?: string | undefined;
|
|
9
9
|
/** Replaces the info icon as the trigger, such as a status label the text explains. */
|
|
10
10
|
children?: ReactNode;
|
|
11
|
+
/** The text is also a control's description, which assistive technology reads with the
|
|
12
|
+
* control, so the ? is hidden from it and skipped by Tab rather than offering the text twice.
|
|
13
|
+
* Text with a link keeps the ? reachable, as the only way to the link from the keyboard. */
|
|
14
|
+
describesControl?: boolean | undefined;
|
|
15
|
+
/** Opens it from outside as well as on hover and press, such as while the described control
|
|
16
|
+
* has keyboard focus. Pair it with `onOpenChange`. */
|
|
17
|
+
open?: boolean | undefined;
|
|
18
|
+
onOpenChange?: ((open: boolean) => void) | undefined;
|
|
19
|
+
/** Stays on `side` rather than flipping where it doesn't fit, as while the control it
|
|
20
|
+
* describes is typed in, which a flipped tip would cover. */
|
|
21
|
+
keepSide?: boolean | undefined;
|
|
11
22
|
}
|
|
12
23
|
/** Extra detail behind an info trigger. A popover that also opens on hover, so
|
|
13
24
|
* touch and screen reader users can reach it and its links. */
|
|
14
|
-
export declare function InfoTip({ text, side, className, children }: InfoTipProps): import("react").JSX.Element | null;
|
|
25
|
+
export declare function InfoTip({ text, side, className, children, describesControl, open, onOpenChange, keepSide, }: InfoTipProps): import("react").JSX.Element | null;
|
|
15
26
|
export {};
|
|
@@ -28,21 +28,32 @@ function formatInfoTipContent(content) {
|
|
|
28
28
|
if (!content) return null;
|
|
29
29
|
return keyedByContent(content.split(/<br\s*\/?>|\n/i), (l) => l).map(({ key, item: line }, idx) => /* @__PURE__ */ jsxs(Fragment$1, { children: [idx > 0 && /* @__PURE__ */ jsx("br", {}), formatLine(line)] }, key));
|
|
30
30
|
}
|
|
31
|
+
var hasLink = (content) => new RegExp(linkRegex.source).test(content);
|
|
31
32
|
/** Extra detail behind an info trigger. A popover that also opens on hover, so
|
|
32
33
|
* touch and screen reader users can reach it and its links. */
|
|
33
|
-
function InfoTip({ text, side = "top", className, children }) {
|
|
34
|
+
function InfoTip({ text, side = "top", className, children, describesControl = false, open, onOpenChange, keepSide = false }) {
|
|
34
35
|
const t = useStrings().common;
|
|
35
36
|
if (!text) return children ? /* @__PURE__ */ jsx("span", {
|
|
36
37
|
className,
|
|
37
38
|
children
|
|
38
39
|
}) : null;
|
|
40
|
+
const hidden = describesControl && !hasLink(text);
|
|
39
41
|
return /* @__PURE__ */ jsx(Popover, {
|
|
40
42
|
variant: "tip",
|
|
41
43
|
openOnHover: true,
|
|
42
44
|
side,
|
|
45
|
+
keepSide,
|
|
46
|
+
...open === void 0 ? {} : { open },
|
|
47
|
+
...onOpenChange ? { onOpenChange } : {},
|
|
48
|
+
...describesControl && { initialFocus: "none" },
|
|
49
|
+
...hidden && { finalFocus: false },
|
|
43
50
|
trigger: /* @__PURE__ */ jsx("button", {
|
|
44
51
|
type: "button",
|
|
45
|
-
|
|
52
|
+
...hidden && {
|
|
53
|
+
tabIndex: -1,
|
|
54
|
+
"aria-hidden": true
|
|
55
|
+
},
|
|
56
|
+
"aria-label": children || hidden ? void 0 : t.moreInfo,
|
|
46
57
|
className: cx("inline-flex items-center cursor-help", !children && "tooltip", className),
|
|
47
58
|
children: children ?? /* @__PURE__ */ jsx(HelpIcon, { "aria-hidden": "true" })
|
|
48
59
|
}),
|
|
@@ -1,30 +1,36 @@
|
|
|
1
|
-
import type { InputHTMLAttributes, ReactNode, TextareaHTMLAttributes } from 'react';
|
|
1
|
+
import type { InputHTMLAttributes, ReactNode, Ref, TextareaHTMLAttributes } from 'react';
|
|
2
2
|
import { type FieldControlProps } from './Field.js';
|
|
3
3
|
import { type FieldBoxSize } from './fieldBox.js';
|
|
4
4
|
interface FramedProps {
|
|
5
|
-
/** Without a label the box stands alone
|
|
5
|
+
/** Without a label the box stands alone: name it with `aria-label`, or place it in a Field. */
|
|
6
6
|
label?: ReactNode;
|
|
7
7
|
/** Beside the label and outside it, so it stays out of the field's name. */
|
|
8
8
|
hint?: ReactNode;
|
|
9
|
+
/** More about the field, behind a ? beside the label; see Field's `help`. */
|
|
10
|
+
help?: string | undefined;
|
|
9
11
|
/** Help under the field. */
|
|
10
12
|
description?: ReactNode;
|
|
11
13
|
error?: ReactNode;
|
|
12
14
|
mono?: boolean;
|
|
13
|
-
/** `sm` for dense places such as toolbars and table cells. */
|
|
15
|
+
/** `sm` for dense places such as toolbars and table cells. With a label, the label matches. */
|
|
14
16
|
size?: FieldBoxSize | undefined;
|
|
15
17
|
}
|
|
16
18
|
export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>, FramedProps {
|
|
19
|
+
ref?: Ref<HTMLInputElement> | undefined;
|
|
17
20
|
}
|
|
18
21
|
export interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement>, FramedProps {
|
|
22
|
+
ref?: Ref<HTMLTextAreaElement> | undefined;
|
|
19
23
|
}
|
|
20
24
|
/** The Field around a control when it has a label; the control alone when it doesn't. */
|
|
21
|
-
export declare function framed({ label, hint, description, error }: Omit<FramedProps, 'mono'
|
|
25
|
+
export declare function framed({ label, hint, help, description, error, size }: Omit<FramedProps, 'mono'>, { id, required, disabled, }: {
|
|
22
26
|
id?: string | undefined;
|
|
23
27
|
required?: boolean | undefined;
|
|
24
28
|
disabled?: boolean | undefined;
|
|
25
29
|
}, control: (props: Partial<FieldControlProps>) => ReactNode): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
26
|
-
/** A single-line text field. `type="password"` adds a button that shows what was typed.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
/** A single-line text field. `type="password"` adds a button that shows what was typed. Placed in
|
|
31
|
+
* a Field, it takes the Field's label, description and invalid state. */
|
|
32
|
+
export declare function Input({ label, hint, help, description, error, className, mono, size, type, ref, ...props }: InputProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
33
|
+
/** A multi-line text field that grows by hand. Placed in a Field, it takes the Field's label,
|
|
34
|
+
* description and invalid state. */
|
|
35
|
+
export declare function Textarea({ label, hint, help, description, error, className, mono, size, ref, ...props }: TextareaProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
|
|
30
36
|
export {};
|