@parallelworks/ui 0.77.0 → 0.78.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 +30 -5
- package/dist/access/AccessDrawer.d.ts +28 -7
- package/dist/access/AccessDrawer.js +216 -35
- package/dist/access/AccessList.d.ts +19 -1
- package/dist/access/AccessList.js +220 -9
- package/dist/access/GrantView.d.ts +3 -1
- package/dist/access/GrantView.js +17 -4
- package/dist/access/PrincipalPicker.js +5 -5
- package/dist/access/focus.js +1 -1
- package/dist/access/index.d.ts +2 -2
- package/dist/access/index.js +2 -2
- package/dist/access/strings.d.ts +18 -0
- package/dist/access/strings.js +20 -2
- package/dist/access/types.d.ts +26 -0
- package/dist/ai/components/AllocationSelector.js +1 -1
- package/dist/ai/components/AttachmentManager.js +5 -5
- package/dist/ai/components/AttachmentUpload.js +2 -2
- package/dist/ai/components/BranchNavigator.js +1 -1
- package/dist/ai/components/ChatActivity.js +1 -1
- package/dist/ai/components/ChatEmptyState.js +3 -3
- package/dist/ai/components/ChatInput.js +3 -5
- package/dist/ai/components/ChatLayout.js +1 -1
- package/dist/ai/components/ChatMessage.js +1 -1
- package/dist/ai/components/ChatMessageList.js +2 -2
- package/dist/ai/components/ChatSidebar.js +3 -3
- package/dist/ai/components/ChatThread.js +4 -4
- package/dist/ai/components/ComposerAddMenu.js +9 -20
- package/dist/ai/components/ModelSelector.js +3 -3
- package/dist/ai/components/PastedText.js +5 -5
- package/dist/ai/components/SessionView.js +1 -1
- package/dist/ai/components/ShareDialog.js +3 -3
- package/dist/ai/components/SlashMenu.d.ts +31 -4
- package/dist/ai/components/SlashMenu.js +36 -63
- package/dist/ai/components/agent/ActivityLine.js +1 -1
- package/dist/ai/components/agent/AgentMessageParts.js +13 -13
- package/dist/ai/components/conversationActions.js +3 -3
- package/dist/ai/core/ChatProvider.js +1 -1
- package/dist/ai/core/config.js +1 -1
- package/dist/ai/ui/ConversationSidebar.js +3 -3
- package/dist/ai/ui/sidebar.js +3 -3
- package/dist/assets/yaml.worker-DOBV2lND.js +884 -0
- package/dist/components/ActionMenu.d.ts +38 -9
- package/dist/components/ActionMenu.js +48 -22
- package/dist/components/Avatar.d.ts +66 -6
- package/dist/components/Avatar.js +130 -18
- package/dist/components/Breadcrumbs.d.ts +4 -0
- package/dist/components/Breadcrumbs.js +26 -10
- package/dist/components/Button.d.ts +3 -2
- package/dist/components/Button.js +11 -1
- package/dist/components/Callout.d.ts +3 -2
- package/dist/components/Callout.js +3 -2
- package/dist/components/Card.d.ts +33 -9
- package/dist/components/Card.js +24 -8
- package/dist/components/Checkbox.d.ts +3 -1
- package/dist/components/Checkbox.js +4 -2
- package/dist/components/ColorInput.js +1 -1
- package/dist/components/Combobox.d.ts +23 -0
- package/dist/components/Combobox.js +252 -86
- package/dist/components/ConfirmModal.d.ts +26 -2
- package/dist/components/ConfirmModal.js +81 -15
- package/dist/components/ContextMenu.d.ts +29 -2
- package/dist/components/ContextMenu.js +60 -8
- package/dist/components/CopyButton.d.ts +21 -8
- package/dist/components/CopyButton.js +29 -9
- package/dist/components/CreateModal.d.ts +16 -4
- package/dist/components/CreateModal.js +27 -16
- package/dist/components/DatePicker.d.ts +31 -1
- package/dist/components/DatePicker.js +178 -47
- package/dist/components/DescriptionList.d.ts +13 -3
- package/dist/components/DescriptionList.js +43 -11
- package/dist/components/Disclosure.d.ts +10 -2
- package/dist/components/Disclosure.js +18 -7
- package/dist/components/Drawer.js +5 -5
- package/dist/components/EmptyState.d.ts +12 -4
- package/dist/components/EmptyState.js +18 -10
- package/dist/components/ErrorPage.d.ts +40 -0
- package/dist/components/ErrorPage.js +101 -0
- package/dist/components/ExternalLink.d.ts +4 -1
- package/dist/components/ExternalLink.js +4 -5
- package/dist/components/Field.d.ts +21 -6
- package/dist/components/Field.js +32 -16
- package/dist/components/FileButton.d.ts +19 -0
- package/dist/components/FileButton.js +32 -0
- package/dist/components/HoverCard.d.ts +26 -6
- package/dist/components/HoverCard.js +11 -5
- package/dist/components/IconButton.js +4 -2
- package/dist/components/InfoTip.js +3 -3
- package/dist/components/Input.d.ts +33 -3
- package/dist/components/Input.js +149 -14
- package/dist/components/Kbd.d.ts +40 -0
- package/dist/components/Kbd.js +168 -0
- package/dist/components/Listbox.d.ts +103 -0
- package/dist/components/Listbox.js +190 -0
- package/dist/components/Loader.d.ts +8 -2
- package/dist/components/Loader.js +16 -1
- package/dist/components/Markdown.js +1 -1
- package/dist/components/MarkdownImpl.js +1 -1
- package/dist/components/Menu.d.ts +20 -2
- package/dist/components/Menu.js +48 -19
- package/dist/components/MenuEntries.d.ts +38 -2
- package/dist/components/MenuEntries.js +266 -39
- package/dist/components/Meter.d.ts +50 -11
- package/dist/components/Meter.js +71 -21
- package/dist/components/Modal.d.ts +9 -3
- package/dist/components/Modal.js +68 -29
- package/dist/components/OneTimeCodeInput.js +1 -1
- package/dist/components/PageHeader.js +111 -7
- package/dist/components/PageHeaderAction.d.ts +8 -3
- package/dist/components/PageHeaderAction.js +122 -34
- package/dist/components/Pagination.d.ts +13 -1
- package/dist/components/Pagination.js +90 -19
- package/dist/components/Popover.d.ts +13 -2
- package/dist/components/Popover.js +20 -21
- package/dist/components/Provider.d.ts +140 -3
- package/dist/components/Provider.js +142 -12
- package/dist/components/RefreshButton.d.ts +13 -6
- package/dist/components/RefreshButton.js +17 -9
- package/dist/components/RunStatusIcon.d.ts +16 -7
- package/dist/components/RunStatusIcon.js +21 -8
- package/dist/components/Section.d.ts +11 -4
- package/dist/components/Section.js +33 -22
- package/dist/components/SegmentedControl.d.ts +16 -3
- package/dist/components/SegmentedControl.js +7 -3
- package/dist/components/Select.d.ts +19 -3
- package/dist/components/Select.js +114 -68
- package/dist/components/SelectionCopy.d.ts +10 -0
- package/dist/components/SelectionCopy.js +105 -0
- package/dist/components/SettingModeOption.js +1 -1
- package/dist/components/SettingsCard.js +1 -1
- package/dist/components/Skeleton.js +1 -1
- package/dist/components/StatusBadge.d.ts +55 -10
- package/dist/components/StatusBadge.js +91 -15
- package/dist/components/StickyBar.js +1 -1
- package/dist/components/Table.d.ts +22 -4
- package/dist/components/Table.js +46 -24
- package/dist/components/Tabs.d.ts +9 -4
- package/dist/components/Tabs.js +9 -4
- package/dist/components/Tag.d.ts +49 -0
- package/dist/components/Tag.js +199 -0
- package/dist/components/ThemeEditor.js +1 -1
- package/dist/components/Toast.js +1 -1
- package/dist/components/ToggleGroup.d.ts +4 -1
- package/dist/components/ToggleGroup.js +30 -13
- package/dist/components/Tooltip.d.ts +9 -3
- package/dist/components/Tooltip.js +55 -39
- package/dist/components/buttonClasses.d.ts +5 -2
- package/dist/components/buttonClasses.js +11 -10
- package/dist/components/chart.d.ts +69 -0
- package/dist/components/chart.js +145 -0
- package/dist/components/comboboxItems.d.ts +7 -1
- package/dist/components/comboboxItems.js +6 -2
- package/dist/components/dismiss.d.ts +5 -1
- package/dist/components/dismiss.js +6 -2
- package/dist/components/floating.d.ts +4 -4
- package/dist/components/floating.js +5 -5
- package/dist/components/headerActionsFit.d.ts +37 -0
- package/dist/components/headerActionsFit.js +81 -0
- package/dist/components/pageHeaderStore.d.ts +3 -0
- package/dist/components/pageHeaderStore.js +3 -0
- package/dist/components/pathBreaks.js +2 -2
- package/dist/components/popupContainer.d.ts +17 -0
- package/dist/components/popupContainer.js +69 -0
- package/dist/components/relativeTime.d.ts +21 -10
- package/dist/components/relativeTime.js +50 -22
- package/dist/components/segmented.d.ts +18 -4
- package/dist/components/segmented.js +48 -6
- package/dist/components/typedDate.d.ts +5 -0
- package/dist/components/typedDate.js +50 -0
- package/dist/components/useClosingValue.d.ts +4 -0
- package/dist/components/useClosingValue.js +12 -0
- package/dist/components/useCopy.d.ts +6 -0
- package/dist/components/useCopy.js +3 -3
- package/dist/components/useNarrow.d.ts +2 -0
- package/dist/components/useNarrow.js +16 -0
- package/dist/editor/Editor.js +1 -1
- package/dist/editor/FormCodePanel.js +1 -1
- package/dist/editor/Monaco.js +1 -1
- package/dist/editor/workers.js +1 -1
- package/dist/file-explorer/FileExplorer.js +16 -15
- package/dist/file-explorer/FileExplorerContext.js +2 -2
- package/dist/file-explorer/FilePreview/Viewer.js +3 -3
- package/dist/file-explorer/FilePreview/index.js +2 -2
- package/dist/file-explorer/FileRowsWindow.js +3 -3
- package/dist/file-explorer/FileTable.js +1 -1
- package/dist/file-explorer/LoadMoreRow.js +1 -1
- package/dist/file-explorer/TreeView.js +5 -5
- package/dist/file-explorer/helpers.js +2 -2
- package/dist/file-explorer/toasts.js +2 -2
- package/dist/form/Fields/CheckboxGroupField.js +1 -1
- package/dist/form/Fields/DropdownField.js +1 -1
- package/dist/form/Fields/DurationField.js +2 -2
- package/dist/form/Fields/MultiDropdownField.js +1 -1
- package/dist/form/Fields/NumberField.js +1 -1
- package/dist/form/Fields/ObjectField.js +1 -1
- package/dist/form/Fields/RangeField.js +1 -1
- package/dist/form/Fields/StringField.js +1 -1
- package/dist/form/Form.js +3 -3
- package/dist/form/FormLayout.js +1 -1
- package/dist/form/Wizard/WizardContainer.js +1 -1
- package/dist/form/Wizard/WizardNavigation.js +1 -1
- package/dist/form/Wizard/WizardStepContent.js +1 -1
- package/dist/form/fieldRegistry.js +1 -1
- package/dist/form/formEditing.js +1 -1
- package/dist/format.d.ts +17 -7
- package/dist/format.js +39 -16
- package/dist/graph/AnnotationBanner.js +2 -2
- package/dist/graph/Connectors.js +5 -5
- package/dist/graph/DependencyGraph.js +10 -9
- package/dist/graph/GraphEditor.js +4 -4
- package/dist/graph/GraphEditorDialogs.js +13 -12
- package/dist/graph/GraphNode.js +1 -1
- package/dist/graph/InputDialog.js +5 -5
- package/dist/graph/InputsEditor.js +7 -7
- package/dist/graph/MatrixGroup.js +2 -2
- package/dist/graph/ProblemsButton.js +3 -3
- package/dist/graph/Reveal.js +1 -1
- package/dist/graph/RunWarningsList.js +1 -1
- package/dist/graph/ShortcutsButton.js +25 -8
- package/dist/graph/StepSummaries.js +1 -1
- package/dist/graph/TreeView.js +2 -2
- package/dist/graph/WorkflowSettingsDialog.js +3 -3
- package/dist/graph/editorFields.js +3 -3
- package/dist/graph/editorPrimitives.js +1 -1
- package/dist/graph/editorRows.js +5 -5
- package/dist/graph/fieldProblems.js +2 -2
- package/dist/graph/inputRefs.js +7 -6
- package/dist/graph/stepWith.js +2 -2
- package/dist/index.d.ts +30 -21
- package/dist/index.js +20 -12
- package/dist/list/ActionToolbar.d.ts +4 -0
- package/dist/list/ActionToolbar.js +35 -12
- package/dist/list/ListFilterBar.d.ts +42 -0
- package/dist/list/ListFilterBar.js +789 -0
- package/dist/list/ListPage.d.ts +42 -4
- package/dist/list/ListPage.js +56 -22
- package/dist/list/ListTable.d.ts +27 -3
- package/dist/list/ListTable.js +48 -23
- package/dist/list/ListToolbar.d.ts +31 -0
- package/dist/list/ListToolbar.js +43 -0
- package/dist/list/ListViewControls.d.ts +8 -4
- package/dist/list/ListViewControls.js +22 -14
- package/dist/list/UserHoverCard.d.ts +8 -2
- package/dist/list/UserHoverCard.js +26 -13
- package/dist/list/filterModel.d.ts +122 -0
- package/dist/list/filterModel.js +308 -0
- package/dist/list/index.d.ts +6 -2
- package/dist/list/index.js +6 -2
- package/dist/list/listSearch.d.ts +1 -1
- package/dist/list/listSearch.js +8 -4
- package/dist/list/listView.d.ts +24 -2
- package/dist/list/listView.js +47 -45
- package/dist/list/rowMenu.d.ts +10 -5
- package/dist/list/rowMenu.js +17 -7
- package/dist/list/useListFilters.d.ts +68 -0
- package/dist/list/useListFilters.js +252 -0
- package/dist/logviewer/LogViewer.js +4 -4
- package/dist/styles/theme.css +94 -0
- package/dist/styles.css +1 -1
- package/package.json +11 -11
- package/dist/assets/yaml.worker-k9AdOqzf.js +0 -1441
- package/dist/components/fullscreen.d.ts +0 -4
- package/dist/components/fullscreen.js +0 -18
|
@@ -27,6 +27,9 @@ export interface ToggleGroupProps<T extends string> {
|
|
|
27
27
|
} | undefined;
|
|
28
28
|
size?: 'sm' | 'md' | undefined;
|
|
29
29
|
disabled?: boolean | undefined;
|
|
30
|
+
/** Names an element that says more about the group, such as a live summary
|
|
31
|
+
* of what the filter lets through. */
|
|
32
|
+
'aria-describedby'?: string | undefined;
|
|
30
33
|
testId?: string;
|
|
31
34
|
}
|
|
32
35
|
/** Options that narrow a list, such as run statuses or job states, as a row of
|
|
@@ -39,4 +42,4 @@ export interface ToggleGroupProps<T extends string> {
|
|
|
39
42
|
* value, such as a time range, what to group by, or which view of the same
|
|
40
43
|
* data to show. A filter that may be off, or takes several values, is a
|
|
41
44
|
* `ToggleGroup`. */
|
|
42
|
-
export declare function ToggleGroup<T extends string>({ label, options, value, onValueChange, multiple, all, size, disabled, testId, }: ToggleGroupProps<T>): import("react").JSX.Element;
|
|
45
|
+
export declare function ToggleGroup<T extends string>({ label, options, value, onValueChange, multiple, all, size, disabled, 'aria-describedby': describedBy, testId, }: ToggleGroupProps<T>): import("react").JSX.Element;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { buttonClasses } from "./buttonClasses.js";
|
|
3
|
-
import {
|
|
3
|
+
import { CheckIcon } from "../icons.js";
|
|
4
|
+
import { useLocale, useStrings } from "./Provider.js";
|
|
4
5
|
import { formatCount } from "../format.js";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { Toggle } from "@base-ui/react/toggle";
|
|
@@ -17,12 +18,13 @@ var ALL = "\0all";
|
|
|
17
18
|
* value, such as a time range, what to group by, or which view of the same
|
|
18
19
|
* data to show. A filter that may be off, or takes several values, is a
|
|
19
20
|
* `ToggleGroup`. */
|
|
20
|
-
function ToggleGroup$1({ label, options, value, onValueChange, multiple = true, all = false, size = "sm", disabled = false, testId }) {
|
|
21
|
+
function ToggleGroup$1({ label, options, value, onValueChange, multiple = true, all = false, size = "sm", disabled = false, "aria-describedby": describedBy, testId }) {
|
|
21
22
|
const strings = useStrings();
|
|
22
23
|
const allCount = typeof all === "object" ? all.count : void 0;
|
|
23
24
|
const pressed = all && value.length === 0 ? [ALL] : value;
|
|
24
25
|
return /* @__PURE__ */ jsxs(ToggleGroup, {
|
|
25
26
|
"aria-label": label,
|
|
27
|
+
"aria-describedby": describedBy,
|
|
26
28
|
"data-testid": testId,
|
|
27
29
|
className: "flex flex-wrap items-center gap-1",
|
|
28
30
|
multiple,
|
|
@@ -35,18 +37,26 @@ function ToggleGroup$1({ label, options, value, onValueChange, multiple = true,
|
|
|
35
37
|
}
|
|
36
38
|
onValueChange(options.filter((option) => next.includes(option.value)).map((option) => option.value));
|
|
37
39
|
},
|
|
38
|
-
children: [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
children: [
|
|
41
|
+
all && /* @__PURE__ */ jsx(Chip, {
|
|
42
|
+
value: ALL,
|
|
43
|
+
label: strings.common.all,
|
|
44
|
+
count: allCount,
|
|
45
|
+
size
|
|
46
|
+
}),
|
|
47
|
+
all && options.length > 0 && /* @__PURE__ */ jsx("span", {
|
|
48
|
+
"aria-hidden": "true",
|
|
49
|
+
className: "mx-0.5 h-5 w-px shrink-0 bg-(--theme-border)"
|
|
50
|
+
}),
|
|
51
|
+
options.map((option) => /* @__PURE__ */ jsx(Chip, {
|
|
52
|
+
...option,
|
|
53
|
+
size
|
|
54
|
+
}, option.value))
|
|
55
|
+
]
|
|
47
56
|
});
|
|
48
57
|
}
|
|
49
58
|
function Chip({ value, label, icon, count, disabled, testId, size }) {
|
|
59
|
+
const locale = useLocale();
|
|
50
60
|
return /* @__PURE__ */ jsxs(Toggle, {
|
|
51
61
|
value,
|
|
52
62
|
disabled,
|
|
@@ -56,11 +66,18 @@ function Chip({ value, label, icon, count, disabled, testId, size }) {
|
|
|
56
66
|
size
|
|
57
67
|
})),
|
|
58
68
|
children: [
|
|
59
|
-
icon,
|
|
69
|
+
icon && /* @__PURE__ */ jsx("span", {
|
|
70
|
+
className: "inline-flex shrink-0 transition-opacity group-not-aria-pressed:opacity-55",
|
|
71
|
+
children: icon
|
|
72
|
+
}),
|
|
60
73
|
label,
|
|
61
74
|
count !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
62
75
|
className: "tabular-nums text-(--theme-muted-text-color) group-aria-pressed:text-(--theme-app)",
|
|
63
|
-
children: formatCount(count)
|
|
76
|
+
children: formatCount(count, locale)
|
|
77
|
+
}),
|
|
78
|
+
/* @__PURE__ */ jsx(CheckIcon, {
|
|
79
|
+
"aria-hidden": "true",
|
|
80
|
+
className: "hidden shrink-0 group-aria-pressed:block"
|
|
64
81
|
})
|
|
65
82
|
]
|
|
66
83
|
});
|
|
@@ -14,12 +14,18 @@ export interface TooltipProps extends Omit<BaseTooltip.Trigger.Props, 'content'
|
|
|
14
14
|
/** The anchor. It receives the trigger's props and ref, so it must pass them to its element. */
|
|
15
15
|
children: ReactElement;
|
|
16
16
|
side?: TooltipSide;
|
|
17
|
-
/** Keys shown beside the content,
|
|
17
|
+
/** Keys shown beside the content as keycaps, written as `Kbd` takes them, such as
|
|
18
|
+
* `Mod+F`: Command on an Apple keyboard, Control elsewhere. */
|
|
18
19
|
shortcut?: string | undefined;
|
|
19
20
|
disabled?: boolean | undefined;
|
|
20
21
|
/** Opens only while the anchor's text is clipped, such as a truncated label. */
|
|
21
22
|
overflowOnly?: boolean;
|
|
23
|
+
/** Also the anchor's accessible description, for a hint that adds to its name
|
|
24
|
+
* rather than repeating it, such as what Make default changes. Assistive
|
|
25
|
+
* technology reads it with the anchor whether or not the tooltip is open. */
|
|
26
|
+
describesAnchor?: boolean | undefined;
|
|
22
27
|
}
|
|
23
28
|
/** A visual hint for sighted pointer and keyboard users. The anchor still needs
|
|
24
|
-
* its own accessible name;
|
|
25
|
-
|
|
29
|
+
* its own accessible name; `describesAnchor` also gives assistive technology the
|
|
30
|
+
* hint. Use InfoTip for content everyone must reach, such as on a touch screen. */
|
|
31
|
+
export declare function Tooltip({ content, children, side, shortcut, disabled, overflowOnly, describesAnchor, ...anchorProps }: TooltipProps): import("react").JSX.Element;
|
|
@@ -1,54 +1,51 @@
|
|
|
1
|
-
import { positionerClassName,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { Fragment as Fragment$1,
|
|
1
|
+
import { positionerClassName, tipClassName } from "./floating.js";
|
|
2
|
+
import { usePopupContainer } from "./popupContainer.js";
|
|
3
|
+
import { Kbd } from "./Kbd.js";
|
|
4
|
+
import { cloneElement, createContext, use, useId, useState } from "react";
|
|
5
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Tooltip } from "@base-ui/react/tooltip";
|
|
7
7
|
//#region src/components/Tooltip.tsx
|
|
8
8
|
var TooltipHandleContext = createContext(null);
|
|
9
|
-
function KbdShortcut({ keys }) {
|
|
10
|
-
const parts = keys.split("+").map((part) => part.trim()).filter(Boolean);
|
|
11
|
-
return /* @__PURE__ */ jsx("span", {
|
|
12
|
-
className: "inline-flex items-center gap-1 align-middle",
|
|
13
|
-
children: keyedByContent(parts, (p) => p).map(({ key, item: part }, idx) => /* @__PURE__ */ jsxs(Fragment$1, { children: [idx > 0 && /* @__PURE__ */ jsx("span", {
|
|
14
|
-
className: "opacity-60 text-[11px]",
|
|
15
|
-
children: "+"
|
|
16
|
-
}), /* @__PURE__ */ jsx("kbd", {
|
|
17
|
-
className: "inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded border border-current/30 bg-current/10 font-sans text-[11px] font-semibold leading-none",
|
|
18
|
-
children: part
|
|
19
|
-
})] }, key))
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
9
|
function TooltipPopup({ content, shortcut, side }) {
|
|
23
|
-
const
|
|
10
|
+
const portal = usePopupContainer();
|
|
24
11
|
return /* @__PURE__ */ jsx(Tooltip.Portal, {
|
|
25
|
-
|
|
12
|
+
...portal,
|
|
26
13
|
children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
|
|
27
14
|
side,
|
|
28
|
-
sideOffset:
|
|
15
|
+
sideOffset: 6,
|
|
29
16
|
className: positionerClassName,
|
|
30
|
-
children: /* @__PURE__ */
|
|
31
|
-
className:
|
|
32
|
-
children:
|
|
17
|
+
children: /* @__PURE__ */ jsx(Tooltip.Popup, {
|
|
18
|
+
className: tipClassName,
|
|
19
|
+
children: shortcut ? /* @__PURE__ */ jsxs("span", {
|
|
33
20
|
className: "inline-flex items-center gap-2",
|
|
34
|
-
children: [content, /* @__PURE__ */ jsx(
|
|
35
|
-
|
|
21
|
+
children: [content, /* @__PURE__ */ jsx(Kbd, {
|
|
22
|
+
keys: shortcut,
|
|
23
|
+
size: "xs"
|
|
24
|
+
})]
|
|
25
|
+
}) : content
|
|
36
26
|
})
|
|
37
27
|
})
|
|
38
28
|
});
|
|
39
29
|
}
|
|
30
|
+
/** How long the pointer rests on an anchor before its tooltip opens, in milliseconds.
|
|
31
|
+
* Once one is open, the next opens at once. An anchor's own `delay` overrides it,
|
|
32
|
+
* such as 0 on a collapsed rail where the tooltip is the only label. */
|
|
33
|
+
var OPEN_DELAY = 400;
|
|
40
34
|
/** One popup serves every Tooltip below it, so each anchor costs only a trigger.
|
|
41
35
|
* UIProvider mounts it; nothing else needs to. */
|
|
42
36
|
function TooltipProvider({ children }) {
|
|
43
37
|
const [handle] = useState(() => Tooltip.createHandle());
|
|
44
|
-
return /* @__PURE__ */ jsxs(Tooltip.Provider, {
|
|
45
|
-
|
|
46
|
-
children
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
return /* @__PURE__ */ jsxs(Tooltip.Provider, {
|
|
39
|
+
delay: OPEN_DELAY,
|
|
40
|
+
children: [/* @__PURE__ */ jsx(TooltipHandleContext, {
|
|
41
|
+
value: handle,
|
|
42
|
+
children
|
|
43
|
+
}), /* @__PURE__ */ jsx(Tooltip.Root, {
|
|
44
|
+
handle,
|
|
45
|
+
onOpenChange: skipUnclipped,
|
|
46
|
+
children: ({ payload }) => payload && /* @__PURE__ */ jsx(TooltipPopup, { ...payload })
|
|
47
|
+
})]
|
|
48
|
+
});
|
|
52
49
|
}
|
|
53
50
|
/** An overflowOnly anchor opens only while its text is cut off. */
|
|
54
51
|
function skipUnclipped(open, details) {
|
|
@@ -56,26 +53,45 @@ function skipUnclipped(open, details) {
|
|
|
56
53
|
if (open && anchor instanceof HTMLElement && anchor.hasAttribute("data-overflow-only") && anchor.scrollWidth <= anchor.clientWidth) details.cancel();
|
|
57
54
|
}
|
|
58
55
|
/** A visual hint for sighted pointer and keyboard users. The anchor still needs
|
|
59
|
-
* its own accessible name;
|
|
60
|
-
|
|
56
|
+
* its own accessible name; `describesAnchor` also gives assistive technology the
|
|
57
|
+
* hint. Use InfoTip for content everyone must reach, such as on a touch screen. */
|
|
58
|
+
function Tooltip$1({ content, children, side = "top", shortcut, disabled = false, overflowOnly = false, describesAnchor = false, ...anchorProps }) {
|
|
61
59
|
const handle = use(TooltipHandleContext);
|
|
60
|
+
const descriptionId = useId();
|
|
62
61
|
const payload = {
|
|
63
62
|
content,
|
|
64
63
|
shortcut,
|
|
65
64
|
side
|
|
66
65
|
};
|
|
66
|
+
const described = describesAnchor && !disabled && !!content;
|
|
67
|
+
const anchor = children;
|
|
68
|
+
const describedBy = [
|
|
69
|
+
anchor.props["aria-describedby"],
|
|
70
|
+
anchorProps["aria-describedby"],
|
|
71
|
+
descriptionId
|
|
72
|
+
].filter(Boolean).join(" ");
|
|
67
73
|
const trigger = /* @__PURE__ */ jsx(Tooltip.Trigger, {
|
|
68
74
|
...anchorProps,
|
|
75
|
+
...!handle && anchorProps.delay === void 0 && { delay: OPEN_DELAY },
|
|
69
76
|
handle: handle ?? void 0,
|
|
70
77
|
payload,
|
|
71
78
|
disabled: disabled || !content,
|
|
72
79
|
"data-overflow-only": overflowOnly || void 0,
|
|
73
|
-
render: children
|
|
80
|
+
render: described ? cloneElement(anchor, { "aria-describedby": describedBy }) : children
|
|
81
|
+
});
|
|
82
|
+
const description = described && /* @__PURE__ */ jsx("span", {
|
|
83
|
+
id: descriptionId,
|
|
84
|
+
hidden: true,
|
|
85
|
+
children: content
|
|
74
86
|
});
|
|
75
|
-
if (handle) return trigger;
|
|
87
|
+
if (handle) return description ? /* @__PURE__ */ jsxs(Fragment$1, { children: [trigger, description] }) : trigger;
|
|
76
88
|
return /* @__PURE__ */ jsxs(Tooltip.Root, {
|
|
77
89
|
onOpenChange: skipUnclipped,
|
|
78
|
-
children: [
|
|
90
|
+
children: [
|
|
91
|
+
trigger,
|
|
92
|
+
description,
|
|
93
|
+
/* @__PURE__ */ jsx(TooltipPopup, { ...payload })
|
|
94
|
+
]
|
|
79
95
|
});
|
|
80
96
|
}
|
|
81
97
|
//#endregion
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/** `primary` is the one action a view leads to; `secondary` sits beside it;
|
|
2
2
|
* `outline` and `ghost` are toolbar and inline actions, bordered or not;
|
|
3
|
-
* `danger` confirms what can't be undone
|
|
4
|
-
|
|
3
|
+
* `danger` confirms what can't be undone; `danger-outline` is a destructive
|
|
4
|
+
* action that isn't the view's confirmation, such as Revoke or Disable on a row. */
|
|
5
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger' | 'danger-outline';
|
|
6
|
+
/** `md` (32px) lines up with inputs and is the default; `lg` (40px) is for a
|
|
7
|
+
* standalone page's one action, such as signing in or approving a device. */
|
|
5
8
|
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
6
9
|
export interface ButtonStyle {
|
|
7
10
|
variant?: ButtonVariant | undefined;
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
//#region src/components/buttonClasses.ts
|
|
3
|
-
var base = "relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-medium no-underline transition-
|
|
3
|
+
var base = "relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-medium no-underline transition-[color,background-color,border-color,box-shadow,translate] duration-150 hover:not-disabled:not-aria-disabled:-translate-y-px hover:not-disabled:not-aria-disabled:shadow-(--theme-shadow-sm) active:not-disabled:not-aria-disabled:translate-y-0 active:not-disabled:not-aria-disabled:shadow-none motion-reduce:hover:not-disabled:not-aria-disabled:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--theme-focus) disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50";
|
|
4
4
|
var variants = {
|
|
5
5
|
primary: "bg-(--theme-accent) text-(--theme-accent-text) hover:not-disabled:not-aria-disabled:bg-(--theme-accent-hover)",
|
|
6
6
|
secondary: "border border-(--theme-border) bg-(--theme-panel-bg) text-(--theme-app) hover:not-disabled:not-aria-disabled:bg-(--theme-hover)",
|
|
7
7
|
outline: "border border-(--theme-border) text-(--theme-muted-text-color) hover:not-disabled:not-aria-disabled:bg-(--theme-muted-panel-bg) hover:not-disabled:not-aria-disabled:text-(--theme-app) aria-pressed:border-(--theme-link) aria-pressed:text-(--theme-app) data-selected:border-(--theme-link) data-selected:text-(--theme-app) data-popup-open:bg-(--theme-muted-panel-bg) data-popup-open:text-(--theme-app)",
|
|
8
8
|
ghost: "text-(--theme-muted-text-color) hover:not-disabled:not-aria-disabled:bg-(--theme-muted-panel-bg) hover:not-disabled:not-aria-disabled:text-(--theme-app) aria-pressed:bg-(--theme-muted-panel-bg) aria-pressed:text-(--theme-link) data-selected:bg-(--theme-muted-panel-bg) data-selected:text-(--theme-link) data-popup-open:bg-(--theme-muted-panel-bg) data-popup-open:text-(--theme-app)",
|
|
9
|
-
danger: "bg-(--theme-error-solid) text-white hover:not-disabled:not-aria-disabled:bg-(--theme-error-solid)/90"
|
|
9
|
+
danger: "bg-(--theme-error-solid) text-white hover:not-disabled:not-aria-disabled:bg-(--theme-error-solid)/90",
|
|
10
|
+
"danger-outline": "border border-(--theme-error)/40 text-(--theme-error-text) hover:not-disabled:not-aria-disabled:border-(--theme-error)/60 hover:not-disabled:not-aria-disabled:bg-(--theme-error-muted) data-popup-open:bg-(--theme-error-muted)"
|
|
10
11
|
};
|
|
11
12
|
var sizes = {
|
|
12
|
-
xs: "h-6 px-2 text-xs [&_svg]:size-3",
|
|
13
|
-
sm: "h-7 px-2.5 text-xs [&_svg]:size-3.5",
|
|
14
|
-
md: "h-8 px-3 text-sm [&_svg]:size-4",
|
|
15
|
-
lg: "h-10 px-4 text-base [&_svg]:size-5"
|
|
13
|
+
xs: "h-6 px-2 text-xs [:where(&)_svg]:size-3",
|
|
14
|
+
sm: "h-7 px-2.5 text-xs [:where(&)_svg]:size-3.5",
|
|
15
|
+
md: "h-8 px-3 text-sm [:where(&)_svg]:size-4",
|
|
16
|
+
lg: "h-10 px-4 text-base [:where(&)_svg]:size-5"
|
|
16
17
|
};
|
|
17
18
|
var squares = {
|
|
18
|
-
xs: "size-6 text-xs [&_svg]:size-3",
|
|
19
|
-
sm: "size-7 text-xs [&_svg]:size-3.5",
|
|
20
|
-
md: "size-8 text-sm [&_svg]:size-4",
|
|
21
|
-
lg: "size-10 text-base [&_svg]:size-5"
|
|
19
|
+
xs: "size-6 text-xs [:where(&)_svg]:size-3",
|
|
20
|
+
sm: "size-7 text-xs [:where(&)_svg]:size-3.5",
|
|
21
|
+
md: "size-8 text-sm [:where(&)_svg]:size-4",
|
|
22
|
+
lg: "size-10 text-base [:where(&)_svg]:size-5"
|
|
22
23
|
};
|
|
23
24
|
/** The one look for anything pressed: a button, or a link or popup trigger
|
|
24
25
|
* that acts as one. `Button` and `IconButton` apply it; use it directly on a
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
/** A series' mark color for palette slot 1–8: the theme's category hue, between the slot's
|
|
3
|
+
* soft fill and its text and twice as saturated, so a bar or a line stands out from the page
|
|
4
|
+
* in light and dark alike and keeps the hue the slot has everywhere else. */
|
|
5
|
+
export declare function seriesSlotColor(slot: number): string;
|
|
6
|
+
/** A series' color by its key, any CSS color for a fill, a stroke or a style: the same key
|
|
7
|
+
* gets the same color on every chart, as `categoryOf` gives a name its avatar color. */
|
|
8
|
+
export declare function seriesColor(key: string): string;
|
|
9
|
+
/** Colors for a chart's series, each key its `seriesColor` unless another key took that slot
|
|
10
|
+
* first, when it moves to the next free one: up to eight series never share a color. */
|
|
11
|
+
export declare function seriesColors(keys: readonly string[]): Record<string, string>;
|
|
12
|
+
export type SeriesSwatchShape = 'square' | 'dot' | 'line';
|
|
13
|
+
/** A series' color as a mark, for a legend or a tooltip's row. Only seen: the series' name
|
|
14
|
+
* beside it says which it is. */
|
|
15
|
+
export declare function SeriesSwatch({ color, shape, className, }: {
|
|
16
|
+
color: string;
|
|
17
|
+
shape?: SeriesSwatchShape | undefined;
|
|
18
|
+
className?: string | undefined;
|
|
19
|
+
}): import("react").JSX.Element;
|
|
20
|
+
/** Which series is in focus, from hovering a mark or the legend, and how strongly every other
|
|
21
|
+
* series draws while it is: their marks fade so the one in focus reads alone. */
|
|
22
|
+
export declare function useSeriesHighlight(): {
|
|
23
|
+
highlighted: string | null;
|
|
24
|
+
highlight: (key: string | null) => void;
|
|
25
|
+
/** 1 for the series in focus or when none is, 0.3 for the rest. */
|
|
26
|
+
opacity: (key: string) => number;
|
|
27
|
+
};
|
|
28
|
+
/** A series' opacity while `highlighted` is in focus: full for it, or for all when none is. */
|
|
29
|
+
export declare function seriesOpacity(key: string, highlighted: string | null | undefined): number;
|
|
30
|
+
export interface ChartLegendItem {
|
|
31
|
+
key: string;
|
|
32
|
+
label: ReactNode;
|
|
33
|
+
color: string;
|
|
34
|
+
}
|
|
35
|
+
/** A chart's legend: each series' swatch and name. With `onHighlight` hovering or focusing a
|
|
36
|
+
* name puts its series in focus, and pressing one keeps it there until pressed again. */
|
|
37
|
+
export declare function ChartLegendList({ items, highlighted, onHighlight, shape, className, }: {
|
|
38
|
+
items: readonly ChartLegendItem[];
|
|
39
|
+
highlighted?: string | null | undefined;
|
|
40
|
+
onHighlight?: ((key: string | null) => void) | undefined;
|
|
41
|
+
shape?: SeriesSwatchShape | undefined;
|
|
42
|
+
className?: string | undefined;
|
|
43
|
+
}): import("react").JSX.Element;
|
|
44
|
+
export interface ChartTooltipItem {
|
|
45
|
+
key: string;
|
|
46
|
+
name: ReactNode;
|
|
47
|
+
value: number;
|
|
48
|
+
color: string;
|
|
49
|
+
}
|
|
50
|
+
/** What a chart's tooltip shows for a point: its label, then each series' swatch, name and
|
|
51
|
+
* value, largest first, the series in focus in bold, and a total when there is more than one.
|
|
52
|
+
* A charting library's tooltip renders it as its content. */
|
|
53
|
+
export declare function ChartTooltipContent({ label, items, formatValue, total, highlighted, hideZero, sort, className, style, }: {
|
|
54
|
+
label?: ReactNode;
|
|
55
|
+
items: readonly ChartTooltipItem[];
|
|
56
|
+
/** Formats each value and the total, such as a currency; numbers in the host's locale
|
|
57
|
+
* (`UIProvider locale`) by default. */
|
|
58
|
+
formatValue?: ((n: number) => string) | undefined;
|
|
59
|
+
/** Adds a total row; on by default when more than one series shows. */
|
|
60
|
+
total?: boolean | undefined;
|
|
61
|
+
highlighted?: string | null | undefined;
|
|
62
|
+
/** Leaves out series whose value is zero; on by default. */
|
|
63
|
+
hideZero?: boolean | undefined;
|
|
64
|
+
/** Lists the largest value first; on by default. */
|
|
65
|
+
sort?: boolean | undefined;
|
|
66
|
+
className?: string | undefined;
|
|
67
|
+
/** Places it, such as beside the point it describes. */
|
|
68
|
+
style?: CSSProperties | undefined;
|
|
69
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { cx } from "../cx.js";
|
|
2
|
+
import { useLocale, useStrings } from "./Provider.js";
|
|
3
|
+
import { CATEGORY_CLASSES, categoryOf } from "./category.js";
|
|
4
|
+
import { useCallback, useMemo, useState } from "react";
|
|
5
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/chart.tsx
|
|
7
|
+
var SLOTS = CATEGORY_CLASSES.length;
|
|
8
|
+
/** A series' mark color for palette slot 1–8: the theme's category hue, between the slot's
|
|
9
|
+
* soft fill and its text and twice as saturated, so a bar or a line stands out from the page
|
|
10
|
+
* in light and dark alike and keeps the hue the slot has everywhere else. */
|
|
11
|
+
function seriesSlotColor(slot) {
|
|
12
|
+
const n = ((slot - 1) % SLOTS + SLOTS) % SLOTS + 1;
|
|
13
|
+
return `oklch(from color-mix(in oklch, var(--theme-category-${n}), var(--theme-category-${n}-text)) l calc(c * 2) h)`;
|
|
14
|
+
}
|
|
15
|
+
/** A series' color by its key, any CSS color for a fill, a stroke or a style: the same key
|
|
16
|
+
* gets the same color on every chart, as `categoryOf` gives a name its avatar color. */
|
|
17
|
+
function seriesColor(key) {
|
|
18
|
+
return seriesSlotColor(categoryOf(key));
|
|
19
|
+
}
|
|
20
|
+
/** Colors for a chart's series, each key its `seriesColor` unless another key took that slot
|
|
21
|
+
* first, when it moves to the next free one: up to eight series never share a color. */
|
|
22
|
+
function seriesColors(keys) {
|
|
23
|
+
const taken = /* @__PURE__ */ new Set();
|
|
24
|
+
const colors = {};
|
|
25
|
+
for (const key of keys) {
|
|
26
|
+
if (key in colors) continue;
|
|
27
|
+
let slot = categoryOf(key);
|
|
28
|
+
if (taken.size < SLOTS) while (taken.has(slot)) slot = slot % SLOTS + 1;
|
|
29
|
+
taken.add(slot);
|
|
30
|
+
colors[key] = seriesSlotColor(slot);
|
|
31
|
+
}
|
|
32
|
+
return colors;
|
|
33
|
+
}
|
|
34
|
+
/** A series' color as a mark, for a legend or a tooltip's row. Only seen: the series' name
|
|
35
|
+
* beside it says which it is. */
|
|
36
|
+
function SeriesSwatch({ color, shape = "square", className }) {
|
|
37
|
+
return /* @__PURE__ */ jsx("span", {
|
|
38
|
+
"aria-hidden": "true",
|
|
39
|
+
className: cx("inline-block shrink-0", shape === "line" ? "h-0.5 w-3 rounded-full" : "size-2.5", shape === "dot" && "rounded-full", shape === "square" && "rounded-[3px]", className),
|
|
40
|
+
style: { background: color }
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/** Which series is in focus, from hovering a mark or the legend, and how strongly every other
|
|
44
|
+
* series draws while it is: their marks fade so the one in focus reads alone. */
|
|
45
|
+
function useSeriesHighlight() {
|
|
46
|
+
const [highlighted, highlight] = useState(null);
|
|
47
|
+
return {
|
|
48
|
+
highlighted,
|
|
49
|
+
highlight,
|
|
50
|
+
opacity: useCallback((key) => seriesOpacity(key, highlighted), [highlighted])
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** A series' opacity while `highlighted` is in focus: full for it, or for all when none is. */
|
|
54
|
+
function seriesOpacity(key, highlighted) {
|
|
55
|
+
return highlighted == null || highlighted === key ? 1 : .3;
|
|
56
|
+
}
|
|
57
|
+
/** A chart's legend: each series' swatch and name. With `onHighlight` hovering or focusing a
|
|
58
|
+
* name puts its series in focus, and pressing one keeps it there until pressed again. */
|
|
59
|
+
function ChartLegendList({ items, highlighted, onHighlight, shape, className }) {
|
|
60
|
+
const [pinned, setPinned] = useState(null);
|
|
61
|
+
const leave = () => onHighlight?.(pinned);
|
|
62
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
63
|
+
className: cx("m-0 flex list-none flex-wrap items-center gap-x-3 gap-y-1 p-0 text-xs text-(--theme-app)", className),
|
|
64
|
+
children: items.map((item) => {
|
|
65
|
+
const faded = highlighted != null && highlighted !== item.key;
|
|
66
|
+
const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SeriesSwatch, {
|
|
67
|
+
color: item.color,
|
|
68
|
+
shape
|
|
69
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
70
|
+
className: "min-w-0 truncate",
|
|
71
|
+
children: item.label
|
|
72
|
+
})] });
|
|
73
|
+
return /* @__PURE__ */ jsx("li", {
|
|
74
|
+
className: cx("flex min-w-0 items-center transition-opacity motion-reduce:transition-none", faded && "opacity-50"),
|
|
75
|
+
children: onHighlight ? /* @__PURE__ */ jsx("button", {
|
|
76
|
+
type: "button",
|
|
77
|
+
"aria-pressed": pinned === item.key,
|
|
78
|
+
onPointerEnter: () => onHighlight(item.key),
|
|
79
|
+
onPointerLeave: leave,
|
|
80
|
+
onFocus: () => onHighlight(item.key),
|
|
81
|
+
onBlur: leave,
|
|
82
|
+
onClick: () => {
|
|
83
|
+
const next = pinned === item.key ? null : item.key;
|
|
84
|
+
setPinned(next);
|
|
85
|
+
onHighlight(next ?? item.key);
|
|
86
|
+
},
|
|
87
|
+
className: "-mx-1 flex min-w-0 cursor-pointer items-center gap-1.5 rounded px-1 py-0.5 hover:bg-(--theme-muted-panel-bg) focus-visible:outline-2 focus-visible:outline-(--theme-focus) aria-pressed:font-medium",
|
|
88
|
+
children: body
|
|
89
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
90
|
+
className: "flex min-w-0 items-center gap-1.5",
|
|
91
|
+
children: body
|
|
92
|
+
})
|
|
93
|
+
}, item.key);
|
|
94
|
+
})
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/** What a chart's tooltip shows for a point: its label, then each series' swatch, name and
|
|
98
|
+
* value, largest first, the series in focus in bold, and a total when there is more than one.
|
|
99
|
+
* A charting library's tooltip renders it as its content. */
|
|
100
|
+
function ChartTooltipContent({ label, items, formatValue, total, highlighted, hideZero = true, sort = true, className, style }) {
|
|
101
|
+
const { chart: t } = useStrings();
|
|
102
|
+
const locale = useLocale();
|
|
103
|
+
const number = useMemo(() => new Intl.NumberFormat(locale, { maximumFractionDigits: 2 }), [locale]);
|
|
104
|
+
const format = formatValue ?? ((n) => number.format(n));
|
|
105
|
+
let rows = hideZero ? items.filter((item) => item.value !== 0) : [...items];
|
|
106
|
+
if (sort) rows = [...rows].sort((a, b) => b.value - a.value);
|
|
107
|
+
const sum = rows.reduce((acc, item) => acc + item.value, 0);
|
|
108
|
+
const showTotal = total ?? rows.length > 1;
|
|
109
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
110
|
+
className: cx("min-w-40 rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) p-3 text-xs text-(--theme-app) shadow-(--theme-shadow-lg)", className),
|
|
111
|
+
style,
|
|
112
|
+
children: [
|
|
113
|
+
label != null && label !== "" && /* @__PURE__ */ jsx("div", {
|
|
114
|
+
className: "mb-1.5 font-semibold",
|
|
115
|
+
children: label
|
|
116
|
+
}),
|
|
117
|
+
/* @__PURE__ */ jsx("ul", {
|
|
118
|
+
className: "m-0 list-none space-y-1 p-0",
|
|
119
|
+
children: rows.map((item) => /* @__PURE__ */ jsxs("li", {
|
|
120
|
+
className: cx("flex items-center gap-2", highlighted === item.key ? "font-semibold" : highlighted != null && "text-(--theme-muted-text-color)"),
|
|
121
|
+
children: [
|
|
122
|
+
/* @__PURE__ */ jsx(SeriesSwatch, { color: item.color }),
|
|
123
|
+
/* @__PURE__ */ jsx("span", {
|
|
124
|
+
className: "min-w-0 flex-1 truncate",
|
|
125
|
+
children: item.name
|
|
126
|
+
}),
|
|
127
|
+
/* @__PURE__ */ jsx("span", {
|
|
128
|
+
className: "ml-2 tabular-nums",
|
|
129
|
+
children: format(item.value)
|
|
130
|
+
})
|
|
131
|
+
]
|
|
132
|
+
}, item.key))
|
|
133
|
+
}),
|
|
134
|
+
showTotal && /* @__PURE__ */ jsxs("div", {
|
|
135
|
+
className: "mt-1.5 flex justify-between gap-4 border-t border-(--theme-border) pt-1.5 font-medium",
|
|
136
|
+
children: [/* @__PURE__ */ jsx("span", { children: t.total }), /* @__PURE__ */ jsx("span", {
|
|
137
|
+
className: "tabular-nums",
|
|
138
|
+
children: format(sum)
|
|
139
|
+
})]
|
|
140
|
+
})
|
|
141
|
+
]
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { ChartLegendList, ChartTooltipContent, SeriesSwatch, seriesColor, seriesColors, seriesOpacity, seriesSlotColor, useSeriesHighlight };
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
/** The end of an option's row: its hint, then the check while it is chosen, on the label's
|
|
3
|
+
* line rather than the middle of a row with a description under it. */
|
|
4
|
+
export declare const pickerEndClassName = "ml-auto flex h-[1lh] shrink-0 items-center gap-2 self-start pl-2";
|
|
5
|
+
export declare const pickerHintClassName = "text-xs tabular-nums text-(--theme-muted-text-color)";
|
|
2
6
|
/** An option's row in a Select's or a Combobox's list, so both lists look alike: the icon, the
|
|
3
7
|
* label over its description, and the check at the end. */
|
|
4
8
|
export declare const pickerItemClassName: string;
|
|
@@ -13,6 +17,8 @@ export interface ComboboxItem<Value = string> {
|
|
|
13
17
|
icon?: ReactNode;
|
|
14
18
|
/** Beside the label, such as a tag that marks the option out. */
|
|
15
19
|
badge?: ReactNode;
|
|
20
|
+
/** Short muted text at the row's end, such as a key or a count; read after the label. */
|
|
21
|
+
hint?: string | undefined;
|
|
16
22
|
disabled?: boolean | undefined;
|
|
17
23
|
}
|
|
18
24
|
export interface ComboboxGroup<Value = string> {
|
|
@@ -29,7 +35,7 @@ export type ComboboxLeaf<Value = string> = ComboboxItem<Value> | (Value & string
|
|
|
29
35
|
/** Items, groups under headings, or both: items between groups list where they sit, without a heading. */
|
|
30
36
|
export type ComboboxItems<Value = string> = readonly (ComboboxLeaf<Value> | ComboboxGroup<Value>)[];
|
|
31
37
|
/** How an option is named and described: by its label, with its description read after it. */
|
|
32
|
-
export declare function optionNaming(id: string, item: Pick<ComboboxItem<unknown>, 'description' | 'accessibleDescription'>): {
|
|
38
|
+
export declare function optionNaming(id: string, item: Pick<ComboboxItem<unknown>, 'description' | 'accessibleDescription' | 'hint'>): {
|
|
33
39
|
'aria-labelledby': string;
|
|
34
40
|
'aria-describedby': string | undefined;
|
|
35
41
|
};
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { cx } from "../cx.js";
|
|
2
2
|
import { panelItemClassName } from "./floating.js";
|
|
3
3
|
//#region src/components/comboboxItems.ts
|
|
4
|
+
/** The end of an option's row: its hint, then the check while it is chosen, on the label's
|
|
5
|
+
* line rather than the middle of a row with a description under it. */
|
|
6
|
+
var pickerEndClassName = "ml-auto flex h-[1lh] shrink-0 items-center gap-2 self-start pl-2";
|
|
7
|
+
var pickerHintClassName = "text-xs tabular-nums text-(--theme-muted-text-color)";
|
|
4
8
|
/** An option's row in a Select's or a Combobox's list, so both lists look alike: the icon, the
|
|
5
9
|
* label over its description, and the check at the end. */
|
|
6
10
|
var pickerItemClassName = cx(panelItemClassName, "data-selected:font-medium");
|
|
7
11
|
/** How an option is named and described: by its label, with its description read after it. */
|
|
8
12
|
function optionNaming(id, item) {
|
|
9
13
|
return {
|
|
10
|
-
"aria-labelledby": `${id}label`,
|
|
14
|
+
"aria-labelledby": item.hint ? `${id}label ${id}hint` : `${id}label`,
|
|
11
15
|
"aria-describedby": item.accessibleDescription || item.description ? `${id}description` : void 0
|
|
12
16
|
};
|
|
13
17
|
}
|
|
@@ -19,4 +23,4 @@ function comboboxLeaves(items) {
|
|
|
19
23
|
return items.flatMap((item) => isComboboxGroup(item) ? item.items : [item]);
|
|
20
24
|
}
|
|
21
25
|
//#endregion
|
|
22
|
-
export { comboboxLeaves, isComboboxGroup, optionNaming, pickerItemClassName };
|
|
26
|
+
export { comboboxLeaves, isComboboxGroup, optionNaming, pickerEndClassName, pickerHintClassName, pickerItemClassName };
|
|
@@ -5,7 +5,11 @@ interface CloseDetails {
|
|
|
5
5
|
}
|
|
6
6
|
/** The `onOpenChange` of a modal or drawer that the host opens and closes:
|
|
7
7
|
* Escape and a press outside close it unless it's not `dismissible`, and a
|
|
8
|
-
* press on a toast never does, since the toast sits above the backdrop.
|
|
8
|
+
* press on a toast never does, since the toast sits above the backdrop.
|
|
9
|
+
*
|
|
10
|
+
* An Escape whose default a layer inside already prevented is that layer's,
|
|
11
|
+
* such as a picker of the host's own or an editor's suggestions: it closes
|
|
12
|
+
* them, and the next Escape closes the dialog. */
|
|
9
13
|
export declare function closeHandler(dismissible: boolean, onClose: () => void): (next: boolean, details: CloseDetails) => void;
|
|
10
14
|
/** The row of a dialog's actions along its bottom edge, ruled off from its body. */
|
|
11
15
|
export declare const dialogFooterClassName = "flex shrink-0 items-center justify-end gap-2 border-t border-(--theme-border) px-4 py-3";
|
|
@@ -2,11 +2,15 @@ import { pressedToast } from "./Toast.js";
|
|
|
2
2
|
//#region src/components/dismiss.ts
|
|
3
3
|
/** The `onOpenChange` of a modal or drawer that the host opens and closes:
|
|
4
4
|
* Escape and a press outside close it unless it's not `dismissible`, and a
|
|
5
|
-
* press on a toast never does, since the toast sits above the backdrop.
|
|
5
|
+
* press on a toast never does, since the toast sits above the backdrop.
|
|
6
|
+
*
|
|
7
|
+
* An Escape whose default a layer inside already prevented is that layer's,
|
|
8
|
+
* such as a picker of the host's own or an editor's suggestions: it closes
|
|
9
|
+
* them, and the next Escape closes the dialog. */
|
|
6
10
|
function closeHandler(dismissible, onClose) {
|
|
7
11
|
return (next, details) => {
|
|
8
12
|
if (next) return;
|
|
9
|
-
if (
|
|
13
|
+
if (details.reason === "escape-key" && (!dismissible || details.event?.defaultPrevented) || details.reason === "outside-press" && pressedToast(details.event)) {
|
|
10
14
|
details.cancel();
|
|
11
15
|
return;
|
|
12
16
|
}
|
|
@@ -7,11 +7,11 @@ export declare const panelClassName = "rounded-lg border border-(--theme-border)
|
|
|
7
7
|
export declare const panelListClassName = "p-1";
|
|
8
8
|
/** A row in a panel, inside its `panelListClassName` gutter; its text lines up with a field's. */
|
|
9
9
|
export declare const panelItemClassName = "flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-left outline-none data-highlighted:bg-(--theme-hover) data-highlighted:text-(--theme-app) data-disabled:cursor-not-allowed data-disabled:opacity-50";
|
|
10
|
-
/** A tooltip's or
|
|
11
|
-
|
|
12
|
-
export declare const
|
|
10
|
+
/** A tooltip's, infotip's or popover tip's surface: a small panel in the page's colors, so a
|
|
11
|
+
* hint reads as part of the page rather than a dark patch over it. */
|
|
12
|
+
export declare const tipClassName = "max-w-64 rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) px-2.5 py-1.5 text-xs text-(--theme-app) shadow-(--theme-shadow-lg) whitespace-pre-line break-words data-instant:transition-none origin-(--transform-origin) transition-[transform,opacity] duration-100 data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0 motion-reduce:data-starting-style:scale-100 motion-reduce:data-ending-style:scale-100";
|
|
13
13
|
/** A hover card's surface; the card sets its own width and padding. */
|
|
14
|
-
export declare const cardClassName = "overflow-hidden rounded-
|
|
14
|
+
export declare const cardClassName = "overflow-hidden rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) text-(--theme-app) shadow-(--theme-shadow-lg) outline-none origin-(--transform-origin) transition-[transform,opacity] duration-100 data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0 motion-reduce:data-starting-style:scale-100 motion-reduce:data-ending-style:scale-100";
|
|
15
15
|
/** Where a popup opens: under an element, such as the button that opened it, or
|
|
16
16
|
* at a pointer event's point, which then moves with the element it landed on. */
|
|
17
17
|
export type FloatingAnchor = Element | {
|