@ciridae/ui 1.0.4 → 1.0.9
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 +3 -2
- package/dist/chat/conversation-source.d.ts +1 -3
- package/dist/chat/message-text.js +6 -6
- package/dist/chat/use-chat-conversation.d.ts +7 -2
- package/dist/chat/use-chat-conversation.js +2 -1
- package/dist/components/activity-feed.d.ts +0 -1
- package/dist/components/activity-feed.js +6 -7
- package/dist/components/agent-work.d.ts +5 -1
- package/dist/components/agent-work.js +27 -13
- package/dist/components/app-frame.d.ts +3 -17
- package/dist/components/app-frame.js +11 -30
- package/dist/components/app-navigation.d.ts +5 -6
- package/dist/components/app-navigation.js +70 -40
- package/dist/components/badge.d.ts +0 -4
- package/dist/components/badge.js +17 -27
- package/dist/components/bulk-action-bar.js +2 -2
- package/dist/components/button.js +41 -50
- package/dist/components/calendar.js +5 -8
- package/dist/components/centered-page.js +4 -4
- package/dist/components/chart.js +3 -4
- package/dist/components/chat-client-source.js +55 -34
- package/dist/components/chat-page.js +1 -1
- package/dist/components/chat-sheet.d.ts +30 -20
- package/dist/components/chat-sheet.js +112 -54
- package/dist/components/chat.d.ts +27 -56
- package/dist/components/chat.js +153 -132
- package/dist/components/checkbox-item.js +4 -4
- package/dist/components/checkbox-list.js +6 -6
- package/dist/components/chip.js +2 -2
- package/dist/components/collapsible.js +3 -3
- package/dist/components/color-theme.d.ts +3 -6
- package/dist/components/color-theme.js +10 -11
- package/dist/components/column-settings.js +3 -3
- package/dist/components/command-menu.d.ts +1 -2
- package/dist/components/command-menu.js +56 -77
- package/dist/components/command-palette.js +5 -2
- package/dist/components/copyable-id.js +5 -5
- package/dist/components/data-display.d.ts +1 -7
- package/dist/components/data-display.js +32 -55
- package/dist/components/data-grid.d.ts +4 -7
- package/dist/components/data-grid.js +106 -90
- package/dist/components/date-range-picker.js +4 -5
- package/dist/components/document-viewer.js +23 -23
- package/dist/components/drawer.d.ts +2 -1
- package/dist/components/drawer.js +45 -20
- package/dist/components/dropzone.js +13 -13
- package/dist/components/editable-field.d.ts +2 -7
- package/dist/components/editable-field.js +14 -27
- package/dist/components/email-input.js +2 -3
- package/dist/components/environment-frame.js +7 -7
- package/dist/components/expandable-text.js +2 -2
- package/dist/components/feedback-screenshot.js +7 -7
- package/dist/components/feedback-sheet.js +8 -8
- package/dist/components/filter-bar.js +41 -27
- package/dist/components/form-controls.d.ts +3 -6
- package/dist/components/form-controls.js +15 -22
- package/dist/components/form-layout.d.ts +6 -6
- package/dist/components/form-layout.js +10 -16
- package/dist/components/glass-menu.d.ts +2 -0
- package/dist/components/glass-menu.js +14 -18
- package/dist/components/gradient-edge.d.ts +0 -1
- package/dist/components/gradient-edge.js +8 -9
- package/dist/components/icon.js +1 -1
- package/dist/components/input.js +18 -17
- package/dist/components/keycap.d.ts +2 -6
- package/dist/components/keycap.js +4 -12
- package/dist/components/layout.js +11 -10
- package/dist/components/lightbox.js +8 -8
- package/dist/components/link.js +1 -1
- package/dist/components/locale.d.ts +23 -7
- package/dist/components/locale.js +19 -7
- package/dist/components/log-entry.d.ts +2 -14
- package/dist/components/log-entry.js +11 -22
- package/dist/components/log-list.js +1 -1
- package/dist/components/mention-input.js +13 -14
- package/dist/components/menu.d.ts +7 -4
- package/dist/components/menu.js +23 -10
- package/dist/components/meter.d.ts +2 -3
- package/dist/components/meter.js +12 -16
- package/dist/components/navigation.d.ts +0 -7
- package/dist/components/navigation.js +3 -12
- package/dist/components/notification-tray.js +7 -7
- package/dist/components/overlays.d.ts +5 -2
- package/dist/components/overlays.js +24 -24
- package/dist/components/panel.js +3 -3
- package/dist/components/progress.js +2 -2
- package/dist/components/radio-card.d.ts +1 -1
- package/dist/components/radio-card.js +9 -9
- package/dist/components/record.d.ts +2 -4
- package/dist/components/record.js +19 -32
- package/dist/components/scroll-area.js +10 -10
- package/dist/components/segmented-bar.js +9 -9
- package/dist/components/select.d.ts +3 -5
- package/dist/components/select.js +26 -44
- package/dist/components/settings.js +1 -1
- package/dist/components/shell-skeleton.js +1 -1
- package/dist/components/shell.d.ts +1 -1
- package/dist/components/shell.js +69 -24
- package/dist/components/side-panel.js +3 -3
- package/dist/components/sidebar.d.ts +0 -5
- package/dist/components/sidebar.js +25 -33
- package/dist/components/single-line-text.js +3 -4
- package/dist/components/site-banner.js +4 -4
- package/dist/components/skeleton.js +19 -22
- package/dist/components/skeletons.d.ts +0 -3
- package/dist/components/skeletons.js +5 -10
- package/dist/components/stages.d.ts +6 -3
- package/dist/components/stages.js +77 -105
- package/dist/components/stat-card.d.ts +2 -5
- package/dist/components/stat-card.js +23 -31
- package/dist/components/status-banner.js +6 -6
- package/dist/components/status.js +3 -3
- package/dist/components/steps.js +2 -2
- package/dist/components/switch.js +1 -1
- package/dist/components/tabs.js +15 -18
- package/dist/components/theme-customizer.d.ts +5 -8
- package/dist/components/theme-customizer.js +9 -41
- package/dist/components/theme-toggle.d.ts +0 -1
- package/dist/components/theme-toggle.js +6 -11
- package/dist/components/toast.d.ts +1 -7
- package/dist/components/toast.js +19 -22
- package/dist/components/user-chip.js +8 -8
- package/dist/components/wizard.js +6 -4
- package/dist/preset.d.ts +1 -2
- package/dist/preset.js +41 -89
- package/dist/styled-system/css/conditions.mjs +1 -1
- package/dist/styled-system/css/css.mjs +1 -1
- package/dist/styled-system/styles.css +820 -1297
- package/dist/styled-system/tokens/index.mjs +78 -1926
- package/dist/styled-system/tokens/tokens.d.ts +18 -33
- package/dist/styled-system/types/conditions.d.ts +0 -74
- package/dist/styled-system/types/prop-type.d.ts +15 -40
- package/dist/styled-system/types/style-props.d.ts +705 -705
- package/dist/theme/color.d.ts +0 -1
- package/dist/theme/color.js +0 -16
- package/dist/theme/derive.d.ts +3 -3
- package/dist/theme/derive.js +9 -32
- package/dist/theme/index.d.ts +1 -2
- package/dist/theme/index.js +3 -5
- package/dist/theme/options.d.ts +2 -4
- package/dist/theme/options.js +0 -1
- package/dist/theme/{palettes.d.ts → palette.d.ts} +12 -23
- package/dist/theme/palette.js +127 -0
- package/dist/theme/tokens.d.ts +8 -13
- package/dist/theme/tokens.js +39 -92
- package/package.json +1 -1
- package/dist/theme/palettes.js +0 -254
|
@@ -35,14 +35,14 @@ export function openMentionPicker(input, char) {
|
|
|
35
35
|
*/
|
|
36
36
|
export const mentionChip = css({
|
|
37
37
|
display: "inline",
|
|
38
|
-
paddingBlock: "1px",
|
|
38
|
+
paddingBlock: "[1px]",
|
|
39
39
|
paddingInline: "control.trackInset",
|
|
40
|
-
marginInline: "1px",
|
|
40
|
+
marginInline: "[1px]",
|
|
41
41
|
// Tinted from the text it sits in, so it reads on the field and on either side's bubble.
|
|
42
42
|
border: "1px solid color-mix(in srgb, currentColor 16%, transparent)",
|
|
43
43
|
borderRadius: "control",
|
|
44
|
-
background: "color-mix(in srgb, currentColor 7%, transparent)",
|
|
45
|
-
color: "inherit",
|
|
44
|
+
background: "[color-mix(in srgb, currentColor 7%, transparent)]",
|
|
45
|
+
color: "[inherit]",
|
|
46
46
|
fontWeight: "medium",
|
|
47
47
|
textDecoration: "none",
|
|
48
48
|
whiteSpace: "nowrap",
|
|
@@ -53,13 +53,13 @@ export const mentionChip = css({
|
|
|
53
53
|
display: "inline-flex",
|
|
54
54
|
verticalAlign: "-0.125em",
|
|
55
55
|
marginInlineEnd: "control.trackInset",
|
|
56
|
-
opacity: "0.7",
|
|
56
|
+
opacity: "[0.7]",
|
|
57
57
|
"& > svg": { fontSize: "icon.compact" },
|
|
58
58
|
},
|
|
59
59
|
"& > [data-mark]:empty": { display: "none" },
|
|
60
60
|
"&[href]": {
|
|
61
61
|
cursor: "pointer",
|
|
62
|
-
_hover: { background: "color-mix(in srgb, currentColor 12%, transparent)" },
|
|
62
|
+
_hover: { background: "[color-mix(in srgb, currentColor 12%, transparent)]" },
|
|
63
63
|
},
|
|
64
64
|
_focusVisible: { focusRing: "outer" },
|
|
65
65
|
});
|
|
@@ -234,31 +234,30 @@ const field = css({
|
|
|
234
234
|
"&[data-empty]::before": {
|
|
235
235
|
content: "attr(aria-placeholder)",
|
|
236
236
|
position: "absolute",
|
|
237
|
-
inset: "
|
|
238
|
-
padding: "inherit",
|
|
237
|
+
inset: "none",
|
|
238
|
+
padding: "[inherit]",
|
|
239
239
|
overflow: "hidden",
|
|
240
240
|
color: "fg.muted",
|
|
241
241
|
whiteSpace: "nowrap",
|
|
242
242
|
textOverflow: "ellipsis",
|
|
243
243
|
pointerEvents: "none",
|
|
244
244
|
},
|
|
245
|
-
"&[aria-disabled=true]": { cursor: "default", opacity: "0.5" },
|
|
245
|
+
"&[aria-disabled=true]": { cursor: "default", opacity: "[0.5]" },
|
|
246
246
|
});
|
|
247
|
-
/* The picker: a flush menu over the caret on the popovers' glass, its rows edge to edge. */
|
|
248
247
|
const picker = css({
|
|
249
248
|
zIndex: "popover",
|
|
250
249
|
display: "grid",
|
|
251
250
|
minWidth: "overlay.menu",
|
|
252
|
-
maxWidth: "min(token(sizes.overlay.popover), calc(100vw - 2 * token(spacing.layout.controlGap)))",
|
|
251
|
+
maxWidth: "[min(token(sizes.overlay.popover), calc(100vw - 2 * token(spacing.layout.controlGap)))]",
|
|
253
252
|
maxHeight: "search.dropdownPreview",
|
|
254
253
|
overflowY: "auto",
|
|
255
|
-
border: "1px solid token(colors.border.
|
|
254
|
+
border: "1px solid token(colors.border.popover)",
|
|
256
255
|
borderRadius: "action",
|
|
257
256
|
background: "bg.popover",
|
|
258
|
-
backdropFilter: "blur(token(blurs.popover))",
|
|
257
|
+
backdropFilter: "[blur(token(blurs.popover))]",
|
|
259
258
|
color: "fg.primary",
|
|
260
259
|
boxShadow: "soft",
|
|
261
|
-
outline: "
|
|
260
|
+
outline: "0",
|
|
262
261
|
});
|
|
263
262
|
const pickerRow = css({
|
|
264
263
|
display: "flex",
|
|
@@ -12,12 +12,14 @@ export type MenuItem = {
|
|
|
12
12
|
variant?: "default" | "danger";
|
|
13
13
|
/** Shows a check mark, for the active choice in a set. */
|
|
14
14
|
checked?: boolean;
|
|
15
|
-
/** Muted at the row's end, such as what a choice covers. */
|
|
16
15
|
meta?: string;
|
|
17
16
|
/** The hotkey that does what the item does, at the row's end; the host binds it. */
|
|
18
17
|
shortcut?: Hotkey;
|
|
19
18
|
onSelect?: () => void;
|
|
20
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Makes the item a link to this address; it closes the menu as it navigates. Disabled or
|
|
21
|
+
* loading, it goes nowhere.
|
|
22
|
+
*/
|
|
21
23
|
href?: string;
|
|
22
24
|
/**
|
|
23
25
|
* The link element, such as a router's `<Link to="...">`; the item's content and
|
|
@@ -59,12 +61,13 @@ export type MenuProps = Omit<ComponentProps<typeof BaseMenu.Root>, "children"> &
|
|
|
59
61
|
items: readonly MenuItem[];
|
|
60
62
|
/** Which edge of the trigger the menu lines up with; `end` keeps a right-hand menu inside its container. */
|
|
61
63
|
align?: "start" | "end";
|
|
62
|
-
/** How far the menu floats from its trigger, in px. Defaults to the kit's 4. */
|
|
63
64
|
sideOffset?: number;
|
|
64
65
|
/** Makes the menu exactly as wide as its trigger rather than at least `overlay.menu`. */
|
|
65
66
|
matchTriggerWidth?: boolean;
|
|
67
|
+
/** A tooltip on an icon-only trigger, beside it where the line ends. */
|
|
68
|
+
triggerTooltip?: string;
|
|
66
69
|
};
|
|
67
|
-
export declare function Menu({ trigger, items, align, sideOffset, matchTriggerWidth, ...rootProps }: MenuProps): import("react").JSX.Element;
|
|
70
|
+
export declare function Menu({ trigger, items, align, sideOffset, matchTriggerWidth, triggerTooltip, ...rootProps }: MenuProps): import("react").JSX.Element;
|
|
68
71
|
export type OverflowMenuProps = Omit<MenuProps, "trigger" | "align"> & {
|
|
69
72
|
/** The button's accessible name, such as "Record actions" or "More for INV-4821". */
|
|
70
73
|
label: string;
|
package/dist/components/menu.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
3
|
+
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
3
4
|
import { CaretRightIcon, CheckIcon, DotsThreeIcon } from "@phosphor-icons/react";
|
|
4
5
|
import { css, cx } from "#primitives/css";
|
|
5
6
|
import { IconButton } from "./button.js";
|
|
6
|
-
import { glassMenuDivider, glassMenuRow, glassMenuSurface } from "./glass-menu.js";
|
|
7
|
+
import { glassMenuDivider, glassMenuOffsetFromTrigger, glassMenuRow, glassMenuSurface, } from "./glass-menu.js";
|
|
7
8
|
import { HotkeyLayer } from "./hotkeys.js";
|
|
8
9
|
import { directional, icon, Spinner } from "./icon.js";
|
|
9
10
|
import { ShortcutHint } from "./keycap.js";
|
|
11
|
+
import { TooltipChip } from "./overlays.js";
|
|
10
12
|
import { singleLineTextClass } from "./single-line-text.js";
|
|
11
13
|
const popup = css(glassMenuSurface, { minWidth: "overlay.menu" });
|
|
12
14
|
// As wide as its trigger, such as a switcher whose menu hangs under a full-width button.
|
|
13
15
|
const triggerWidthPopup = css(glassMenuSurface, { width: "var(--anchor-width)" });
|
|
14
16
|
// A submenu joins its parent: the corner it opens from goes square, so the two read as one panel.
|
|
15
17
|
const submenuPopup = css({
|
|
16
|
-
"&:is([data-side=right], [data-side=inline-end])": { borderStartStartRadius: "
|
|
17
|
-
"&:is([data-side=left], [data-side=inline-start])": { borderStartEndRadius: "
|
|
18
|
+
"&:is([data-side=right], [data-side=inline-end])": { borderStartStartRadius: "none" },
|
|
19
|
+
"&:is([data-side=left], [data-side=inline-start])": { borderStartEndRadius: "none" },
|
|
18
20
|
});
|
|
19
21
|
/** The positioner is the positioned element, so it carries the stacking order. */
|
|
20
22
|
const positioner = css({ zIndex: "popover" });
|
|
@@ -23,7 +25,7 @@ const positioner = css({ zIndex: "popover" });
|
|
|
23
25
|
const itemStyle = css.raw(glassMenuRow, {
|
|
24
26
|
"&[data-popup-open]": {
|
|
25
27
|
background: "bg.hover",
|
|
26
|
-
boxShadow: "inset 0 0 0 1px token(colors.border.menuHover)",
|
|
28
|
+
boxShadow: "[inset 0 0 0 1px token(colors.border.menuHover)]",
|
|
27
29
|
},
|
|
28
30
|
"& > [data-label]": { flex: "1", minWidth: "0" },
|
|
29
31
|
"& > [data-trailing]": { color: "fg.muted" },
|
|
@@ -79,13 +81,16 @@ const itemMeta = css({
|
|
|
79
81
|
fontSize: "caption",
|
|
80
82
|
});
|
|
81
83
|
const separator = css(glassMenuDivider);
|
|
82
|
-
export function Menu({ trigger, items, align = "start", sideOffset =
|
|
83
|
-
|
|
84
|
+
export function Menu({ trigger, items, align = "start", sideOffset = glassMenuOffsetFromTrigger, matchTriggerWidth = false, triggerTooltip, ...rootProps }) {
|
|
85
|
+
const menuTrigger = _jsx(BaseMenu.Trigger, { render: trigger });
|
|
86
|
+
return (_jsxs(BaseMenu.Root, { ...rootProps, children: [triggerTooltip === undefined ? (menuTrigger) : (_jsx(BaseTooltip.Provider, { children: _jsxs(BaseTooltip.Root, { children: [_jsx(BaseTooltip.Trigger, { render: menuTrigger }), _jsx(TooltipChip, { content: triggerTooltip, side: "inline-end" })] }) })), _jsx(BaseMenu.Portal, { children: _jsx(HotkeyLayer, { children: _jsx(BaseMenu.Positioner, { className: positioner, sideOffset: sideOffset, align: align, children: _jsx(BaseMenu.Popup, { className: matchTriggerWidth ? triggerWidthPopup : popup, "data-ciridae-ui": "", children: _jsx(MenuItems, { items: items }) }) }) }) })] }));
|
|
84
87
|
}
|
|
85
88
|
/** The "more" button: an `IconButton` with three dots that opens a `Menu` of `items`. */
|
|
86
89
|
export function OverflowMenu({ label, size = "medium", variant = "raised", align = "end", disabled, ref, ...props }) {
|
|
87
90
|
return (_jsx(Menu, { ...props, align: align, trigger: _jsx(IconButton, { ref: ref, "aria-label": label, size: size, variant: variant, disabled: disabled, children: _jsx(DotsThreeIcon, { className: icon({ size: size === "large" ? "medium" : "small" }), weight: "bold" }) }) }));
|
|
88
91
|
}
|
|
92
|
+
/** Pulls a submenu up by the sheet's padding and border, so its first row meets the row that opened it. */
|
|
93
|
+
const submenuAlignOffsetToFirstRow = -5;
|
|
89
94
|
function MenuItems({ items }) {
|
|
90
95
|
return items.map((menuItem, index) => {
|
|
91
96
|
if ("separator" in menuItem)
|
|
@@ -97,13 +102,21 @@ function MenuItems({ items }) {
|
|
|
97
102
|
return (_jsxs("div", { className: header, role: "presentation", children: [menuItem.icon, _jsxs("span", { className: headerCopy, children: [_jsx("span", { children: menuItem.label }), menuItem.detail && _jsx("span", { children: menuItem.detail })] })] }, index));
|
|
98
103
|
}
|
|
99
104
|
if (menuItem.items) {
|
|
100
|
-
return (_jsxs(BaseMenu.SubmenuRoot, { children: [_jsxs(BaseMenu.SubmenuTrigger, { className: item, disabled: menuItem.disabled, children: [menuItem.icon && _jsx("span", { className: iconSlot, children: menuItem.icon }), _jsx("span", { "data-label": "", className: singleLineTextClass, children: menuItem.label }), _jsx(CaretRightIcon, { "data-trailing": "", className: cx(icon({ size: "small" }), directional) })] }), _jsx(BaseMenu.Portal, { children: _jsx(BaseMenu.Positioner, { className: positioner, sideOffset: 0, align: "start", alignOffset:
|
|
105
|
+
return (_jsxs(BaseMenu.SubmenuRoot, { children: [_jsxs(BaseMenu.SubmenuTrigger, { className: item, disabled: menuItem.disabled, children: [menuItem.icon && _jsx("span", { className: iconSlot, children: menuItem.icon }), _jsx("span", { "data-label": "", className: singleLineTextClass, children: menuItem.label }), _jsx(CaretRightIcon, { "data-trailing": "", className: cx(icon({ size: "small" }), directional) })] }), _jsx(BaseMenu.Portal, { children: _jsx(BaseMenu.Positioner, { className: positioner, sideOffset: 0, align: "start", alignOffset: submenuAlignOffsetToFirstRow, children: _jsx(BaseMenu.Popup, { className: cx(popup, submenuPopup), "data-ciridae-ui": "", children: _jsx(MenuItems, { items: menuItem.items }) }) }) })] }, index));
|
|
101
106
|
}
|
|
102
107
|
const content = (_jsxs(_Fragment, { children: [(menuItem.loading || menuItem.icon) && (_jsx("span", { className: iconSlot, children: menuItem.loading ? _jsx(Spinner, { "aria-hidden": "true" }) : menuItem.icon })), _jsx("span", { "data-label": "", className: singleLineTextClass, children: menuItem.label }), menuItem.meta !== undefined && (_jsx("span", { "data-trailing": "", className: itemMeta, children: menuItem.meta })), menuItem.shortcut && _jsx(ShortcutHint, { "data-trailing": "", boxed: true, hotkey: menuItem.shortcut }), menuItem.checked && _jsx(CheckIcon, { "data-trailing": "", className: icon({ size: "small" }) })] }));
|
|
103
108
|
const className = menuItem.variant === "danger" ? dangerItem : item;
|
|
104
|
-
|
|
105
|
-
|
|
109
|
+
const disabledOrLoading = menuItem.disabled || menuItem.loading;
|
|
110
|
+
// Base UI's link item has no disabled state, so a disabled or loading link draws as a
|
|
111
|
+
// disabled item, which goes nowhere.
|
|
112
|
+
if (!disabledOrLoading && (menuItem.href !== undefined || menuItem.render !== undefined)) {
|
|
113
|
+
return (_jsx(BaseMenu.LinkItem, { className: className, href: menuItem.href, render: menuItem.render, closeOnClick: true, onClick: menuItem.onSelect, children: content }, index));
|
|
106
114
|
}
|
|
107
|
-
|
|
115
|
+
// A checked item marks the one chosen among its siblings, as the stage and workspace menus
|
|
116
|
+
// use it, so assistive tech hears it as a radio item and whether it is the chosen one.
|
|
117
|
+
const choice = menuItem.checked === undefined
|
|
118
|
+
? {}
|
|
119
|
+
: { role: "menuitemradio", "aria-checked": menuItem.checked };
|
|
120
|
+
return (_jsx(BaseMenu.Item, { className: className, disabled: disabledOrLoading, onClick: menuItem.onSelect, ...choice, children: content }, index));
|
|
108
121
|
});
|
|
109
122
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Tone } from "./badge.js";
|
|
2
2
|
import type { ComponentProps, HTMLAttributes, ReactNode } from "react";
|
|
3
3
|
export type MeterProps = Omit<ComponentProps<"span">, "children"> & {
|
|
4
|
+
/** Held between 0 and `max`, for the track and for assistive tech alike. */
|
|
4
5
|
value: number;
|
|
5
|
-
/** 1 by default, so a share can be passed as is. */
|
|
6
|
+
/** 1 by default, so a share can be passed as is. Must be above 0. */
|
|
6
7
|
max?: number;
|
|
7
8
|
/** `info` by default; `warning` once it nears the limit, say. */
|
|
8
9
|
tone?: Tone;
|
|
@@ -12,11 +13,9 @@ export type MeterProps = Omit<ComponentProps<"span">, "children"> & {
|
|
|
12
13
|
valueLabel?: ReactNode;
|
|
13
14
|
};
|
|
14
15
|
export declare function Meter({ value, max, tone, label, valueLabel, className, ...props }: MeterProps): import("react").JSX.Element;
|
|
15
|
-
/** A button with `onClick`, otherwise a plain row; either way it takes the caller's attributes. */
|
|
16
16
|
export type BudgetRowProps = Omit<HTMLAttributes<HTMLElement>, "children"> & Pick<MeterProps, "value" | "max" | "tone" | "valueLabel"> & {
|
|
17
17
|
icon: ReactNode;
|
|
18
18
|
name: string;
|
|
19
|
-
/** Under the name, such as "$184K of $200K of approved budget". */
|
|
20
19
|
detail: ReactNode;
|
|
21
20
|
};
|
|
22
21
|
export declare function BudgetRow({ icon, name, detail, value, max, tone, valueLabel, className, ...props }: BudgetRowProps): import("react").JSX.Element;
|
package/dist/components/meter.js
CHANGED
|
@@ -2,8 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
/*
|
|
3
3
|
* A measured amount against its limit, such as a budget spent: a thin track filled to
|
|
4
4
|
* `value / max`, with the figure above it at the end. Past the limit the track stays full. It is
|
|
5
|
-
* phrasing content, so it can sit inside a row's button.
|
|
6
|
-
* fill as the chart's progress bar does, a gradient over the hue's track.
|
|
5
|
+
* phrasing content, so it can sit inside a row's button.
|
|
7
6
|
*/
|
|
8
7
|
import { css, cva, cx } from "#primitives/css";
|
|
9
8
|
const meter = css({
|
|
@@ -16,7 +15,7 @@ const meter = css({
|
|
|
16
15
|
fontVariantNumeric: "tabular-nums",
|
|
17
16
|
});
|
|
18
17
|
const track = cva({
|
|
19
|
-
base: { width: "
|
|
18
|
+
base: { width: "full", height: "[6px]", borderRadius: "control", overflow: "hidden" },
|
|
20
19
|
variants: {
|
|
21
20
|
tone: {
|
|
22
21
|
neutral: { background: "bg.hover" },
|
|
@@ -28,32 +27,29 @@ const track = cva({
|
|
|
28
27
|
},
|
|
29
28
|
});
|
|
30
29
|
const fill = cva({
|
|
31
|
-
base: { display: "block", height: "
|
|
30
|
+
base: { display: "block", height: "full", borderRadius: "control" },
|
|
32
31
|
variants: {
|
|
33
32
|
tone: {
|
|
34
33
|
neutral: { background: "fg.subtle" },
|
|
35
|
-
info: { background: "token(gradients.chart.progress)" },
|
|
34
|
+
info: { background: "[token(gradients.chart.progress)]" },
|
|
36
35
|
success: { background: "accent.green" },
|
|
37
|
-
warning: { background: "token(gradients.chart.atRisk)" },
|
|
36
|
+
warning: { background: "[token(gradients.chart.atRisk)]" },
|
|
38
37
|
danger: { background: "accent.red" },
|
|
39
38
|
},
|
|
40
39
|
},
|
|
41
40
|
});
|
|
42
41
|
export function Meter({ value, max = 1, tone = "info", label, valueLabel, className, ...props }) {
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
if (max <= 0)
|
|
43
|
+
throw new Error(`Meter needs a max above 0, got ${max}`);
|
|
44
|
+
const valueWithinRange = Math.min(Math.max(value, 0), max);
|
|
45
|
+
return (_jsxs("span", { role: "meter", "aria-label": label, "aria-valuenow": valueWithinRange, "aria-valuemin": 0, "aria-valuemax": max, "aria-valuetext": typeof valueLabel === "string" ? valueLabel : undefined, ...props, className: cx(meter, className), "data-ciridae-ui": "", children: [valueLabel, _jsx("span", { className: track({ tone }), children: _jsx("span", { className: fill({ tone }), style: { width: `${(valueWithinRange / max) * 100}%` } }) })] }));
|
|
45
46
|
}
|
|
46
|
-
/*
|
|
47
|
-
* Budget row: a job's spend against its budget as a row, the kit's Budget row: the icon on the
|
|
48
|
-
* raised tile, the name over what is spent of what, and a 170px meter at the end. A row with
|
|
49
|
-
* `onClick` is a button that opens the job. Rows in a list part with a hairline above each.
|
|
50
|
-
*/
|
|
51
47
|
const budgetRow = css({
|
|
52
48
|
display: "flex",
|
|
53
49
|
alignItems: "center",
|
|
54
50
|
justifyContent: "space-between",
|
|
55
51
|
gap: "meter.rowGap",
|
|
56
|
-
width: "
|
|
52
|
+
width: "full",
|
|
57
53
|
paddingBlock: "panel.default",
|
|
58
54
|
paddingInline: "panel.comfortable",
|
|
59
55
|
border: "0",
|
|
@@ -87,7 +83,7 @@ const budgetTile = css({
|
|
|
87
83
|
height: "tile.icon",
|
|
88
84
|
border: "1px solid transparent",
|
|
89
85
|
borderRadius: "action",
|
|
90
|
-
background: "token(gradients.raised)",
|
|
86
|
+
background: "[token(gradients.raised)]",
|
|
91
87
|
fontSize: "icon.medium",
|
|
92
88
|
"--edge": "token(gradients.border.raised)",
|
|
93
89
|
});
|
|
@@ -95,7 +91,7 @@ const budgetCopy = css({ display: "grid", gap: "layout.tightGap", minWidth: "0"
|
|
|
95
91
|
const budgetName = css({ fontSize: "body" });
|
|
96
92
|
const budgetDetail = css({ color: "fg.secondary", fontSize: "code" });
|
|
97
93
|
// Fluid under 170px, so the job's name keeps a readable line on a phone.
|
|
98
|
-
const budgetMeter = css({ width: "min(170px, 40%)", flexShrink: "0" });
|
|
94
|
+
const budgetMeter = css({ width: "[min(170px, 40%)]", flexShrink: "0" });
|
|
99
95
|
export function BudgetRow({ icon, name, detail, value, max, tone, valueLabel, className, ...props }) {
|
|
100
96
|
const content = (_jsxs(_Fragment, { children: [_jsxs("span", { className: budgetLeading, children: [_jsx("span", { className: budgetTile, "data-ciridae-ui": "", "data-edge": "gradient", children: icon }), _jsxs("span", { className: budgetCopy, children: [_jsx("span", { className: budgetName, children: name }), _jsx("span", { className: budgetDetail, children: detail })] })] }), _jsx(Meter, { className: budgetMeter, value: value, max: max, tone: tone, label: name, valueLabel: valueLabel })] }));
|
|
101
97
|
return props.onClick ? (_jsx("button", { type: "button", ...props, className: cx(budgetRow, className), "data-ciridae-ui": "", children: content })) : (_jsx("div", { ...props, className: cx(budgetRow, className), "data-ciridae-ui": "", children: content }));
|
|
@@ -4,11 +4,8 @@ export type PaginationProps = Omit<ComponentProps<"nav">, "children"> & {
|
|
|
4
4
|
page: number;
|
|
5
5
|
pages: number;
|
|
6
6
|
onPageChange: (page: number) => void;
|
|
7
|
-
/** At the bar's start, such as a `Select` of how many rows a page shows. */
|
|
8
7
|
pageSizeSelect?: ReactNode;
|
|
9
|
-
/** Before the pager, such as "Showing 1 to 25 of 1,284". */
|
|
10
8
|
summary?: ReactNode;
|
|
11
|
-
/** A button per page between Previous and Next, for a short run of pages. */
|
|
12
9
|
numbered?: boolean;
|
|
13
10
|
labels?: Partial<CiridaeLabels["pagination"]>;
|
|
14
11
|
};
|
|
@@ -19,7 +16,6 @@ export type EmptyStateProps = Omit<ComponentProps<"section">, "title"> & {
|
|
|
19
16
|
description?: ReactNode;
|
|
20
17
|
/** The main way forward: a primary medium button on a page, a secondary small one in a card. */
|
|
21
18
|
action?: ReactNode;
|
|
22
|
-
/** A second way forward before `action`, such as a secondary medium button on a page. */
|
|
23
19
|
secondaryAction?: ReactNode;
|
|
24
20
|
/**
|
|
25
21
|
* `block` is a page's or panel's empty state; `bare` the same, tighter, for a table or card
|
|
@@ -29,10 +25,7 @@ export type EmptyStateProps = Omit<ComponentProps<"section">, "title"> & {
|
|
|
29
25
|
};
|
|
30
26
|
export declare function EmptyState({ icon, title, description, action, secondaryAction, variant, className, ...props }: EmptyStateProps): import("react").JSX.Element;
|
|
31
27
|
export type EmptyTileProps = Omit<ComponentProps<"div">, "children"> & {
|
|
32
|
-
/** What the tile would count, as its stat tile names it. */
|
|
33
28
|
label: ReactNode;
|
|
34
|
-
/** Why there is no figure, such as "No invoices this period". */
|
|
35
29
|
note?: ReactNode;
|
|
36
30
|
};
|
|
37
|
-
/** A stat tile with no figure: its label, a dash in the figure's place, and why. */
|
|
38
31
|
export declare function EmptyTile({ label, note, className, ...props }: EmptyTileProps): import("react").JSX.Element;
|
|
@@ -6,11 +6,7 @@ import { icon } from "./icon.js";
|
|
|
6
6
|
import { Heading } from "./layout.js";
|
|
7
7
|
import { useCiridaeLocale } from "./locale.js";
|
|
8
8
|
import { cardSurface } from "./panel.js";
|
|
9
|
-
/*
|
|
10
|
-
* The bar under a table, the kit's Pagination. Full: the page size at the start, then the summary
|
|
11
|
-
* and the pager at the end, inset 12px. Simple, with no page size: the summary at the start, the
|
|
12
|
-
* pager at the end, flush.
|
|
13
|
-
*/
|
|
9
|
+
/* Full is inset 12px; simple, with no page size, is flush. */
|
|
14
10
|
const pagination = css({
|
|
15
11
|
display: "flex",
|
|
16
12
|
alignItems: "center",
|
|
@@ -19,7 +15,7 @@ const pagination = css({
|
|
|
19
15
|
minHeight: "control.row",
|
|
20
16
|
paddingInline: "panel.default",
|
|
21
17
|
lineHeight: "tight",
|
|
22
|
-
"&[data-type=simple]": { paddingInline: "
|
|
18
|
+
"&[data-type=simple]": { paddingInline: "none" },
|
|
23
19
|
});
|
|
24
20
|
const paginationEnd = css({
|
|
25
21
|
display: "flex",
|
|
@@ -34,7 +30,6 @@ const paginationSummary = css({
|
|
|
34
30
|
letterSpacing: "compact",
|
|
35
31
|
fontVariantNumeric: "tabular-nums",
|
|
36
32
|
});
|
|
37
|
-
// Simple: the summary and the pager are the bar's own ends.
|
|
38
33
|
const summaryAndPagerAsBarEnds = css({ display: "contents" });
|
|
39
34
|
const pager = css({ display: "flex", alignItems: "center", gap: "layout.tightGap" });
|
|
40
35
|
const pagerAlone = css({ marginInlineStart: "auto" });
|
|
@@ -50,14 +45,12 @@ const emptyState = cva({
|
|
|
50
45
|
base: { display: "grid", placeItems: "center", textAlign: "center" },
|
|
51
46
|
variants: {
|
|
52
47
|
variant: {
|
|
53
|
-
// A page or panel with nothing in it yet: no frame, with room around it.
|
|
54
48
|
block: {
|
|
55
49
|
justifyItems: "center",
|
|
56
50
|
gap: "layout.clusterGap",
|
|
57
51
|
paddingBlock: "emptyState.pageBlock",
|
|
58
52
|
paddingInline: "panel.roomy",
|
|
59
53
|
},
|
|
60
|
-
// Inside a table or a card that frames it already: tighter, its copy wrapping to the card.
|
|
61
54
|
bare: {
|
|
62
55
|
justifyItems: "center",
|
|
63
56
|
gap: "layout.contentGap",
|
|
@@ -117,7 +110,6 @@ export function EmptyState({ icon, title, description, action, secondaryAction,
|
|
|
117
110
|
}
|
|
118
111
|
return (_jsxs("section", { ...props, "data-ciridae-ui": "", "data-variant": variant, className: cx(emptyState({ variant }), className), children: [icon && (_jsx("span", { className: emptyRing, "aria-hidden": "true", children: icon })), _jsxs("div", { className: emptyCopy, children: [_jsx(Heading, { level: 2, size: "small", className: emptyTitle, children: title }), description && _jsx("p", { className: emptyDescription, children: description })] }), (action || secondaryAction) && (_jsxs("div", { className: emptyActions, children: [secondaryAction, action] }))] }));
|
|
119
112
|
}
|
|
120
|
-
// A dashboard tile with nothing to count, worn like the stat tile it stands in for.
|
|
121
113
|
const emptyTile = css(cardSurface, {
|
|
122
114
|
display: "grid",
|
|
123
115
|
alignContent: "start",
|
|
@@ -131,10 +123,9 @@ const emptyTile = css(cardSurface, {
|
|
|
131
123
|
letterSpacing: "compact",
|
|
132
124
|
lineHeight: "tight",
|
|
133
125
|
});
|
|
134
|
-
const emptyTileLabel = css({ color: "fg.
|
|
126
|
+
const emptyTileLabel = css({ color: "fg.primary" });
|
|
135
127
|
const emptyTileValue = css({ color: "fg.primary", fontSize: "body" });
|
|
136
128
|
const emptyTileNote = css({ color: "fg.subtle" });
|
|
137
|
-
/** A stat tile with no figure: its label, a dash in the figure's place, and why. */
|
|
138
129
|
export function EmptyTile({ label, note, className, ...props }) {
|
|
139
130
|
return (_jsxs("div", { ...props, className: cx(emptyTile, className), "data-ciridae-ui": "", children: [_jsx("span", { className: emptyTileLabel, children: label }), _jsx("span", { className: emptyTileValue, children: "\u2014" }), note && _jsx("span", { className: emptyTileNote, children: note })] }));
|
|
140
131
|
}
|
|
@@ -42,17 +42,17 @@ const popup = css({
|
|
|
42
42
|
display: "flex",
|
|
43
43
|
flexDirection: "column",
|
|
44
44
|
width: "overlay.tray",
|
|
45
|
-
maxWidth: "calc(100vw - token(spacing.layout.pageGap) * 2)",
|
|
45
|
+
maxWidth: "[calc(100vw - token(spacing.layout.pageGap) * 2)]",
|
|
46
46
|
padding: "none",
|
|
47
47
|
overflow: "hidden",
|
|
48
|
-
border: "1px solid token(colors.border.
|
|
48
|
+
border: "1px solid token(colors.border.popover)",
|
|
49
49
|
borderRadius: "action",
|
|
50
50
|
background: "bg.popover",
|
|
51
|
-
backdropFilter: "blur(token(blurs.popover))",
|
|
51
|
+
backdropFilter: "[blur(token(blurs.popover))]",
|
|
52
52
|
color: "fg.primary",
|
|
53
53
|
textStyle: "body",
|
|
54
54
|
boxShadow: "soft",
|
|
55
|
-
outline: "
|
|
55
|
+
outline: "0",
|
|
56
56
|
});
|
|
57
57
|
const header = css({
|
|
58
58
|
display: "flex",
|
|
@@ -109,7 +109,7 @@ const openButton = css({
|
|
|
109
109
|
border: "0",
|
|
110
110
|
background: "transparent",
|
|
111
111
|
cursor: "pointer",
|
|
112
|
-
outline: "
|
|
112
|
+
outline: "0",
|
|
113
113
|
_focusVisible: { focusRing: "inset" },
|
|
114
114
|
});
|
|
115
115
|
const rowBody = css({
|
|
@@ -117,7 +117,7 @@ const rowBody = css({
|
|
|
117
117
|
display: "grid",
|
|
118
118
|
flex: "1",
|
|
119
119
|
minWidth: "0",
|
|
120
|
-
gap: "2px",
|
|
120
|
+
gap: "[2px]",
|
|
121
121
|
pointerEvents: "none",
|
|
122
122
|
"& button": { pointerEvents: "auto" },
|
|
123
123
|
});
|
|
@@ -168,7 +168,7 @@ const footer = css({
|
|
|
168
168
|
letterSpacing: "compact",
|
|
169
169
|
textAlign: "start",
|
|
170
170
|
cursor: "pointer",
|
|
171
|
-
outline: "
|
|
171
|
+
outline: "0",
|
|
172
172
|
_hover: { background: "bg.rowHover", color: "fg.primary" },
|
|
173
173
|
_focusVisible: { focusRing: "inset" },
|
|
174
174
|
});
|
|
@@ -103,7 +103,10 @@ export declare function Popover({ trigger, anchor, children, density, width, ali
|
|
|
103
103
|
export type TooltipProps = Omit<ComponentProps<typeof BaseTooltip.Root>, "children"> & {
|
|
104
104
|
children: ReactElement;
|
|
105
105
|
content: ReactNode;
|
|
106
|
-
/** A count or shortcut after the content, quieter than it. */
|
|
107
106
|
meta?: ReactNode;
|
|
107
|
+
/** Where it sits against its trigger; above it by default. `inline-end` follows the direction. */
|
|
108
|
+
side?: ComponentProps<typeof BaseTooltip.Positioner>["side"];
|
|
108
109
|
};
|
|
109
|
-
|
|
110
|
+
/** The tooltip's floating chip, for a tooltip trigger composed by hand, such as a menu's. */
|
|
111
|
+
export declare function TooltipChip({ content, meta, side, }: Pick<TooltipProps, "content" | "meta" | "side">): import("react").JSX.Element;
|
|
112
|
+
export declare function Tooltip({ children, content, meta, side, ...rootProps }: TooltipProps): import("react").JSX.Element;
|
|
@@ -8,7 +8,7 @@ import { useCallback, useRef, useState, } from "react";
|
|
|
8
8
|
import { css, cx } from "#primitives/css";
|
|
9
9
|
import { Button, ButtonSizeContext, IconButton } from "./button.js";
|
|
10
10
|
import { DialogHeightResetContext } from "./dialog-height-context.js";
|
|
11
|
-
import { glassMenuSurface } from "./glass-menu.js";
|
|
11
|
+
import { glassMenuOffsetFromTrigger, glassMenuSurface } from "./glass-menu.js";
|
|
12
12
|
import { HotkeyLayer } from "./hotkeys.js";
|
|
13
13
|
import { icon } from "./icon.js";
|
|
14
14
|
import { heading } from "./layout.js";
|
|
@@ -32,33 +32,30 @@ const dialogLayout = css.raw({
|
|
|
32
32
|
// A dialog's own inset, not the page margin, so page density changes leave it alone.
|
|
33
33
|
padding: "panel.comfortable",
|
|
34
34
|
});
|
|
35
|
-
/*
|
|
36
|
-
* A dialog is a glass shell, 4px round its sheet, holding the sheet itself. `--dialog-sheet` is
|
|
37
|
-
* the sheet's width; the shell adds its inset and edge. Dark blurs the shell and light the sheet.
|
|
38
|
-
*/
|
|
35
|
+
/* `--dialog-sheet` is the sheet's width; the shell adds its inset and edge. Dark blurs the shell and light the sheet. */
|
|
39
36
|
const dialogShell = css.raw({
|
|
40
37
|
"--dialog-sheet": "token(sizes.overlay.dialog)",
|
|
41
38
|
zIndex: "dialog",
|
|
42
39
|
position: "fixed",
|
|
43
|
-
top: "50%",
|
|
44
|
-
left: "50%",
|
|
40
|
+
top: "[50%]",
|
|
41
|
+
left: "[50%]",
|
|
45
42
|
display: "grid",
|
|
46
43
|
gridTemplateRows: "minmax(0, 1fr)",
|
|
47
|
-
width: "calc(100vw - token(spacing.layout.pageGap) * 2)",
|
|
48
|
-
maxWidth: "calc(var(--dialog-sheet) + 2 * (token(spacing.layout.tightGap) + token(sizes.border.hairline)))",
|
|
49
|
-
maxHeight: "calc(100dvh - token(spacing.layout.pageGap) * 2)",
|
|
44
|
+
width: "[calc(100vw - token(spacing.layout.pageGap) * 2)]",
|
|
45
|
+
maxWidth: "[calc(var(--dialog-sheet) + 2 * (token(spacing.layout.tightGap) + token(sizes.border.hairline)))]",
|
|
46
|
+
maxHeight: "[calc(100dvh - token(spacing.layout.pageGap) * 2)]",
|
|
50
47
|
padding: "layout.tightGap",
|
|
51
48
|
border: "1px solid token(colors.border.control)",
|
|
52
49
|
borderRadius: "shell",
|
|
53
50
|
background: "bg.modalShell",
|
|
54
|
-
backdropFilter: "blur(token(blurs.modalShell))",
|
|
55
|
-
outline: "
|
|
51
|
+
backdropFilter: "[blur(token(blurs.modalShell))]",
|
|
52
|
+
outline: "0",
|
|
56
53
|
transform: "translate(-50%, -50%)",
|
|
57
|
-
transitionProperty: "opacity, transform",
|
|
54
|
+
transitionProperty: "[opacity, transform]",
|
|
58
55
|
transitionDuration: "fast",
|
|
59
|
-
_motionReduce: { transition: "none" },
|
|
56
|
+
_motionReduce: { transition: "[none]" },
|
|
60
57
|
"&[data-starting-style], &[data-ending-style]": {
|
|
61
|
-
opacity: "0",
|
|
58
|
+
opacity: "[0]",
|
|
62
59
|
transform: "translate(-50%, calc(-50% + token(spacing.control.block)))",
|
|
63
60
|
},
|
|
64
61
|
});
|
|
@@ -67,7 +64,7 @@ const dialogSheetStyle = css.raw(dialogLayout, {
|
|
|
67
64
|
border: "1px solid token(colors.border.control)",
|
|
68
65
|
borderRadius: "inset",
|
|
69
66
|
background: "bg.modalSheet",
|
|
70
|
-
backdropFilter: "blur(token(blurs.modalSheet))",
|
|
67
|
+
backdropFilter: "[blur(token(blurs.modalSheet))]",
|
|
71
68
|
boxShadow: "soft",
|
|
72
69
|
color: "fg.primary",
|
|
73
70
|
textStyle: "body",
|
|
@@ -107,7 +104,7 @@ const dialogBody = css({
|
|
|
107
104
|
"&:has(> [data-wizard-state=result])": { alignContent: "center" },
|
|
108
105
|
gap: "layout.contentGap",
|
|
109
106
|
overflowY: "auto",
|
|
110
|
-
margin: "calc(token(spacing.control.block) * -1)",
|
|
107
|
+
margin: "[calc(token(spacing.control.block) * -1)]",
|
|
111
108
|
padding: "control.block",
|
|
112
109
|
});
|
|
113
110
|
const dialogLeadingActions = css({
|
|
@@ -115,7 +112,6 @@ const dialogLeadingActions = css({
|
|
|
115
112
|
gap: "layout.controlGap",
|
|
116
113
|
marginInlineEnd: "auto",
|
|
117
114
|
});
|
|
118
|
-
// Under a divider, its buttons at the default height and close together.
|
|
119
115
|
const dialogFooter = css({
|
|
120
116
|
display: "flex",
|
|
121
117
|
justifyContent: "flex-end",
|
|
@@ -242,7 +238,7 @@ const popoverWidths = {
|
|
|
242
238
|
const hoverOpenDelayMs = 300;
|
|
243
239
|
const hoverCloseDelayMs = 150;
|
|
244
240
|
export function Popover({ trigger, anchor, children, density = "regular", width, align, openOnHover = false, ...rootProps }) {
|
|
245
|
-
return (_jsxs(BasePopover.Root, { ...rootProps, children: [trigger && (_jsx(BasePopover.Trigger, { render: trigger, openOnHover: openOnHover, delay: hoverOpenDelayMs, closeDelay: hoverCloseDelayMs })), _jsx(BasePopover.Portal, { children: _jsx(HotkeyLayer, { enabled: !openOnHover, children: _jsx(BasePopover.Positioner, { className: positioner, sideOffset:
|
|
241
|
+
return (_jsxs(BasePopover.Root, { ...rootProps, children: [trigger && (_jsx(BasePopover.Trigger, { render: trigger, openOnHover: openOnHover, delay: hoverOpenDelayMs, closeDelay: hoverCloseDelayMs })), _jsx(BasePopover.Portal, { children: _jsx(HotkeyLayer, { enabled: !openOnHover, children: _jsx(BasePopover.Positioner, { className: positioner, sideOffset: glassMenuOffsetFromTrigger, align: align, anchor: anchor, children: _jsx(BasePopover.Popup, { className: cx(popoverPopups[density], width && popoverWidths[width]), "data-ciridae-ui": "", initialFocus: openOnHover ? (openType) => openType === "keyboard" : undefined, children: children }) }) }) })] }));
|
|
246
242
|
}
|
|
247
243
|
/* An inverted chip: the primary face, ink in light and white in dark, with the text in the canvas's. */
|
|
248
244
|
const tooltipPopup = css({
|
|
@@ -255,15 +251,19 @@ const tooltipPopup = css({
|
|
|
255
251
|
borderRadius: "keycap",
|
|
256
252
|
background: "fg.primary",
|
|
257
253
|
color: "bg.canvas",
|
|
258
|
-
_light: { background: "token(gradients.primary)", color: "fg.onAccent" },
|
|
254
|
+
_light: { background: "[token(gradients.primary)]", color: "fg.onAccent" },
|
|
259
255
|
fontSize: "code",
|
|
260
256
|
fontWeight: "medium",
|
|
261
257
|
lineHeight: "tight",
|
|
262
258
|
letterSpacing: "compact",
|
|
263
259
|
maxWidth: "overlay.tooltip",
|
|
264
|
-
textWrap: "pretty",
|
|
260
|
+
textWrap: "[pretty]",
|
|
265
261
|
});
|
|
266
|
-
const tooltipMeta = css({ flexShrink: "0", opacity: "0.6" });
|
|
267
|
-
|
|
268
|
-
|
|
262
|
+
const tooltipMeta = css({ flexShrink: "0", opacity: "[0.6]" });
|
|
263
|
+
/** The tooltip's floating chip, for a tooltip trigger composed by hand, such as a menu's. */
|
|
264
|
+
export function TooltipChip({ content, meta, side, }) {
|
|
265
|
+
return (_jsx(BaseTooltip.Portal, { children: _jsx(BaseTooltip.Positioner, { className: tooltipPositioner, side: side, sideOffset: 8, children: _jsxs(BaseTooltip.Popup, { className: tooltipPopup, "data-ciridae-ui": "", children: [content, meta !== undefined && _jsx("span", { className: tooltipMeta, children: meta })] }) }) }));
|
|
266
|
+
}
|
|
267
|
+
export function Tooltip({ children, content, meta, side, ...rootProps }) {
|
|
268
|
+
return (_jsx(BaseTooltip.Provider, { children: _jsxs(BaseTooltip.Root, { ...rootProps, children: [_jsx(BaseTooltip.Trigger, { render: children }), _jsx(TooltipChip, { content: content, meta: meta, side: side })] }) }));
|
|
269
269
|
}
|
package/dist/components/panel.js
CHANGED
|
@@ -15,7 +15,7 @@ export const cardSurface = css.raw({
|
|
|
15
15
|
minWidth: "0",
|
|
16
16
|
border: "1px solid token(colors.border.card)",
|
|
17
17
|
borderRadius: "action",
|
|
18
|
-
background: "token(gradients.card)",
|
|
18
|
+
background: "[token(gradients.card)]",
|
|
19
19
|
});
|
|
20
20
|
const card = css(cardSurface);
|
|
21
21
|
const panel = cva({
|
|
@@ -39,7 +39,7 @@ const panel = cva({
|
|
|
39
39
|
default: { gap: "layout.contentGap", padding: "panel.default" },
|
|
40
40
|
},
|
|
41
41
|
tone: {
|
|
42
|
-
panel: { borderColor: "border.panel", background: "token(gradients.panel)" },
|
|
42
|
+
panel: { borderColor: "border.panel", background: "[token(gradients.panel)]" },
|
|
43
43
|
outline: { borderColor: "border.control" },
|
|
44
44
|
},
|
|
45
45
|
},
|
|
@@ -65,7 +65,7 @@ const panelHeader = css({
|
|
|
65
65
|
gap: "layout.controlGap",
|
|
66
66
|
paddingInline: "none",
|
|
67
67
|
paddingBottom: "panel.comfortable",
|
|
68
|
-
marginBottom: "calc(token(spacing.layout.contentGap) * -1)",
|
|
68
|
+
marginBottom: "[calc(token(spacing.layout.contentGap) * -1)]",
|
|
69
69
|
},
|
|
70
70
|
});
|
|
71
71
|
const panelHeaderTitle = css(singleLineText, {
|
|
@@ -10,9 +10,9 @@ export function Progress({ value, label }) {
|
|
|
10
10
|
background: "border.control",
|
|
11
11
|
overflow: "hidden",
|
|
12
12
|
}), children: _jsx(BaseProgress.Indicator, { className: css({
|
|
13
|
-
height: "
|
|
13
|
+
height: "full",
|
|
14
14
|
background: "accent.green",
|
|
15
|
-
transitionProperty: "width",
|
|
15
|
+
transitionProperty: "[width]",
|
|
16
16
|
transitionDuration: "default",
|
|
17
17
|
}) }) })] }));
|
|
18
18
|
}
|
|
@@ -10,7 +10,7 @@ export type RadioCardGroupProps = Omit<ComponentProps<typeof BaseRadioGroup>, "d
|
|
|
10
10
|
onValueChange?: (value: string) => void;
|
|
11
11
|
};
|
|
12
12
|
export declare function RadioCardGroup({ name, label, defaultValue, value, onValueChange, className, ...props }: RadioCardGroupProps): import("react").JSX.Element;
|
|
13
|
-
export type RadioCardProps = Omit<ComponentProps<typeof BaseRadio.Root>, "children" | "className"> & {
|
|
13
|
+
export type RadioCardProps = Omit<ComponentProps<typeof BaseRadio.Root>, "children" | "className" | "title"> & {
|
|
14
14
|
value: string;
|
|
15
15
|
title: ReactNode;
|
|
16
16
|
detail?: ReactNode;
|