@ciridae/ui 1.0.5 → 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 +65 -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 +109 -51
- package/dist/components/chat.d.ts +27 -56
- package/dist/components/chat.js +151 -129
- 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 -12
- package/dist/components/editable-field.js +13 -26
- 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 +39 -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 +805 -1279
- package/dist/styled-system/tokens/index.mjs +74 -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 +38 -92
- package/package.json +1 -1
- package/dist/theme/palettes.js +0 -254
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/*
|
|
3
3
|
* The app's sidebar from data. `AppNavigation` draws its sections twice from the same list: as the
|
|
4
|
-
* expanded sidebar, and as the icon rail the shell shows under 1000px or while `collapsed
|
|
4
|
+
* expanded sidebar, and as the icon rail the shell shows under 1000px or while `collapsed`, where
|
|
5
|
+
* each icon shows its label in a tooltip beside it on hover and keyboard focus. A
|
|
5
6
|
* section can fold past `maxVisible` behind a More row, and unfolds on its own while the item it
|
|
6
7
|
* holds is open or, with `autoUnfold`, while the sidebar has room for every row. Pinned and recent
|
|
7
8
|
* records are sections like any other, which the caller builds from its own state.
|
|
8
|
-
* `WorkspaceSwitcher` heads the sidebar: the current workspace's mark and name, opening a menu of
|
|
9
|
-
* the others.
|
|
10
9
|
*/
|
|
11
10
|
import { CaretDownIcon, CaretLineRightIcon, CaretUpDownIcon, CaretUpIcon, } from "@phosphor-icons/react";
|
|
12
11
|
import { Fragment, useLayoutEffect, useRef, useState, } from "react";
|
|
13
12
|
import { css, cx } from "#primitives/css";
|
|
14
13
|
import { IconButton } from "./button.js";
|
|
15
|
-
import { icon } from "./icon.js";
|
|
14
|
+
import { directional, icon } from "./icon.js";
|
|
16
15
|
import { useCiridaeLocale } from "./locale.js";
|
|
17
16
|
import { Menu } from "./menu.js";
|
|
17
|
+
import { Tooltip } from "./overlays.js";
|
|
18
18
|
import { AppSidebar, AppSidebarFooter, AppSidebarNav, AppSidebarRail } from "./shell.js";
|
|
19
19
|
import { SidebarItem, SidebarPanel, SidebarRailRule, SidebarSection } from "./sidebar.js";
|
|
20
20
|
import { singleLineTextClass } from "./single-line-text.js";
|
|
21
21
|
const navCount = css({ color: "fg.subtle", fontSize: "code", fontVariantNumeric: "tabular-nums" });
|
|
22
|
-
// The rail's items, a section at a time: the sections stand apart by the rail's gap.
|
|
23
22
|
const railSection = css({
|
|
24
23
|
display: "flex",
|
|
25
24
|
flexDirection: "column",
|
|
@@ -35,7 +34,7 @@ const sectionFooter = css({
|
|
|
35
34
|
const foldScroll = css({
|
|
36
35
|
display: "grid",
|
|
37
36
|
gap: "control.trackInset",
|
|
38
|
-
maxHeight: "200px",
|
|
37
|
+
maxHeight: "[200px]",
|
|
39
38
|
overflowY: "auto",
|
|
40
39
|
});
|
|
41
40
|
// The kit draws the collapsed sidebar's expand button as its 32px round button, a step under
|
|
@@ -43,14 +42,13 @@ const foldScroll = css({
|
|
|
43
42
|
const expandButtonRail = css({
|
|
44
43
|
"& > button": { width: "control.roundRail", height: "control.roundRail" },
|
|
45
44
|
});
|
|
46
|
-
/** The tallest row, so an estimate of the folded rows' height never overshoots. */
|
|
47
|
-
const SIDEBAR_ROW_HEIGHT = 32;
|
|
48
45
|
/**
|
|
49
|
-
* Whether the sidebar has room to
|
|
50
|
-
*
|
|
51
|
-
* out of room, so it does not flicker at the
|
|
46
|
+
* Whether the sidebar has room to unfold every section: the free space between its navigation and
|
|
47
|
+
* its footer covers the `hiddenRows` its folds hide, less the More rows unfolding removes. Once it
|
|
48
|
+
* has, it loses it only when the navigation runs out of room, so it does not flicker at the
|
|
49
|
+
* threshold.
|
|
52
50
|
*/
|
|
53
|
-
export function useSidebarRoom(
|
|
51
|
+
export function useSidebarRoom(hiddenRows) {
|
|
54
52
|
const navRef = useRef(null);
|
|
55
53
|
const footerRef = useRef(null);
|
|
56
54
|
const [roomy, setRoomy] = useState(false);
|
|
@@ -63,28 +61,56 @@ export function useSidebarRoom(foldedRows) {
|
|
|
63
61
|
const free = footer.getBoundingClientRect().top - nav.getBoundingClientRect().bottom;
|
|
64
62
|
setRoomy((current) => current
|
|
65
63
|
? free >= 0 && nav.scrollHeight <= nav.clientHeight + 1
|
|
66
|
-
: free >=
|
|
64
|
+
: free >= measureHeightUnfoldingAdds(nav, hiddenRows));
|
|
67
65
|
};
|
|
68
66
|
measure();
|
|
69
67
|
const observer = new ResizeObserver(measure);
|
|
70
68
|
observer.observe(nav);
|
|
71
69
|
observer.observe(document.documentElement);
|
|
72
70
|
return () => observer.disconnect();
|
|
73
|
-
}, [
|
|
71
|
+
}, [hiddenRows]);
|
|
74
72
|
return { navRef, footerRef, roomy };
|
|
75
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* How much taller unfolding every section makes the navigation, from the rows it renders: each
|
|
76
|
+
* hidden row as tall as the tallest row shown, with the gap a section leaves between rows, less
|
|
77
|
+
* the More rows that unfolding removes.
|
|
78
|
+
*/
|
|
79
|
+
function measureHeightUnfoldingAdds(nav, hiddenRows) {
|
|
80
|
+
const moreRows = Array.from(nav.querySelectorAll("[data-navigation-more]"));
|
|
81
|
+
const moreRowSection = moreRows[0]?.parentElement;
|
|
82
|
+
// Without a More row, every section already shows all of its rows.
|
|
83
|
+
if (!moreRowSection)
|
|
84
|
+
return 0;
|
|
85
|
+
const rowGap = parseFloat(getComputedStyle(moreRowSection).rowGap);
|
|
86
|
+
const tallestRowHeight = Math.max(...Array.from(nav.querySelectorAll("[data-sidebar-row]"), (row) => row.getBoundingClientRect().height));
|
|
87
|
+
const moreRowsHeight = moreRows.reduce((total, row) => total + row.getBoundingClientRect().height + rowGap, 0);
|
|
88
|
+
return hiddenRows * (tallestRowHeight + rowGap) - moreRowsHeight;
|
|
89
|
+
}
|
|
76
90
|
function NavRow({ item, activeIds, renderLink, }) {
|
|
77
91
|
return (_jsx(SidebarItem, { size: item.size, icon: item.icon, active: activeIds.includes(item.id), trailing: item.count !== undefined && _jsx("span", { className: navCount, children: item.count }), href: item.href, render: item.render ?? renderLink?.(item), onClick: item.onSelect, action: item.action, children: item.label }));
|
|
78
92
|
}
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
/**
|
|
94
|
+
* How many of a section's rows its fold hides: none when it has no fold, or when it is unfolded
|
|
95
|
+
* because it was expanded or holds the active item past `maxVisible`.
|
|
96
|
+
*/
|
|
97
|
+
function countRowsHiddenByFold(section, activeIds, expanded) {
|
|
98
|
+
const { items, maxVisible } = section;
|
|
99
|
+
if (maxVisible === undefined || items.length <= maxVisible)
|
|
100
|
+
return 0;
|
|
101
|
+
const unfolded = expanded || items.slice(maxVisible).some((item) => activeIds.includes(item.id));
|
|
102
|
+
return unfolded ? 0 : items.length - maxVisible;
|
|
103
|
+
}
|
|
104
|
+
function SectionItems({ section, activeIds, renderLink, roomy, labels, expanded, onExpandedChange, }) {
|
|
81
105
|
const { items, maxVisible } = section;
|
|
82
106
|
const rows = (shown) => shown.map((item) => (_jsx(NavRow, { item: item, activeIds: activeIds, renderLink: renderLink }, item.id)));
|
|
83
107
|
if (maxVisible === undefined || items.length <= maxVisible || roomy)
|
|
84
108
|
return rows(items);
|
|
85
|
-
const unfolded =
|
|
109
|
+
const unfolded = countRowsHiddenByFold(section, activeIds, expanded) === 0;
|
|
110
|
+
// The open page keeps its section unfolded, so a Less row could not fold it.
|
|
111
|
+
const holdsActiveItem = items.slice(maxVisible).some((item) => activeIds.includes(item.id));
|
|
86
112
|
const Caret = unfolded ? CaretUpIcon : CaretDownIcon;
|
|
87
|
-
return (_jsxs(_Fragment, { children: [!unfolded ? (rows(items.slice(0, maxVisible))) : section.scrollWhenUnfolded ? (_jsx("div", { className: foldScroll, children: rows(items) })) : (rows(items)), _jsx(SidebarItem, { size: "compact", icon: _jsx(Caret, { className: icon({ size: "small" }) }), "aria-expanded": unfolded, onClick: () =>
|
|
113
|
+
return (_jsxs(_Fragment, { children: [!unfolded ? (rows(items.slice(0, maxVisible))) : section.scrollWhenUnfolded ? (_jsx("div", { className: foldScroll, children: rows(items) })) : (rows(items)), !holdsActiveItem && (_jsx(SidebarItem, { size: "compact", icon: _jsx(Caret, { className: icon({ size: "small" }) }), "aria-expanded": unfolded, onClick: () => onExpandedChange(!unfolded), "data-navigation-more": "", "data-sidebar-action": "", children: unfolded ? labels.less : labels.more }))] }));
|
|
88
114
|
}
|
|
89
115
|
/** Runs of sections: each main section alone, consecutive panel sections together. */
|
|
90
116
|
function sectionRuns(sections) {
|
|
@@ -105,23 +131,26 @@ export function AppNavigation({ sections, activeId: ownActiveId = null, renderLi
|
|
|
105
131
|
const locale = useCiridaeLocale();
|
|
106
132
|
const labels = { ...locale.labels.navigation, ...ownLabels };
|
|
107
133
|
const activeIds = ownActiveId === null ? [] : typeof ownActiveId === "string" ? [ownActiveId] : ownActiveId;
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
134
|
+
// The navigation owns which sections were expanded, so the room estimate counts only the rows
|
|
135
|
+
// that are still folded away.
|
|
136
|
+
const [expandedSectionIds, setExpandedSectionIds] = useState(() => new Set());
|
|
137
|
+
const setSectionExpanded = (sectionId, expanded) => setExpandedSectionIds((current) => {
|
|
138
|
+
const next = new Set(current);
|
|
139
|
+
if (expanded)
|
|
140
|
+
next.add(sectionId);
|
|
141
|
+
else
|
|
142
|
+
next.delete(sectionId);
|
|
143
|
+
return next;
|
|
144
|
+
});
|
|
145
|
+
const hiddenRows = sections.reduce((rows, section) => rows + countRowsHiddenByFold(section, activeIds, expandedSectionIds.has(section.id)), 0);
|
|
146
|
+
const room = useSidebarRoom(hiddenRows);
|
|
114
147
|
const roomy = autoUnfold && room.roomy;
|
|
115
|
-
const sectionBlock = (section) => (_jsxs(SidebarSection, { label: section.label, children: [_jsx(SectionItems, { section: section, activeIds: activeIds, renderLink: renderLink, roomy: roomy, labels: labels }), section.footer && _jsx("div", { className: sectionFooter, children: section.footer })] }, section.id));
|
|
148
|
+
const sectionBlock = (section) => (_jsxs(SidebarSection, { label: section.label, children: [_jsx(SectionItems, { section: section, activeIds: activeIds, renderLink: renderLink, roomy: roomy, labels: labels, expanded: expandedSectionIds.has(section.id), onExpandedChange: (expanded) => setSectionExpanded(section.id, expanded) }), section.footer && _jsx("div", { className: sectionFooter, children: section.footer })] }, section.id));
|
|
116
149
|
return (_jsxs(AppSidebar, { "aria-label": labels.navigation, collapsed: collapsed, ...props, children: [_jsxs(AppSidebarNav, { ref: room.navRef, children: [header, sectionRuns(sections).map((run) => run.panel ? (_jsx(SidebarPanel, { children: run.sections.map(sectionBlock) }, run.sections[0].id)) : (_jsx(Fragment, { children: run.sections.map(sectionBlock) }, run.sections[0].id)))] }), _jsxs(AppSidebarRail, { children: [railHeader, sections
|
|
117
150
|
.filter((section) => section.rail !== false && section.items.length > 0)
|
|
118
|
-
.map((section) => (_jsxs("div", { className: railSection, children: [section.label && _jsx(SidebarRailRule, {}), section.items.map((item) => (_jsx(SidebarItem, { "aria-label": item.label, icon: item.icon, active: activeIds.includes(item.id), href: item.href, render: item.render ?? renderLink?.(item), onClick: item.onSelect }, item.id)))] }, section.id)))] }), _jsxs(AppSidebarFooter, { ref: room.footerRef, children: [collapsed && onExpand && (_jsx(AppSidebarRail, { className: expandButtonRail, children: _jsx(IconButton, { "aria-label": locale.labels.common.expand, size: "medium", onClick: onExpand, children: _jsx(CaretLineRightIcon, { className: cx(icon({ size: "small" }),
|
|
151
|
+
.map((section) => (_jsxs("div", { className: railSection, children: [section.label && _jsx(SidebarRailRule, {}), section.items.map((item) => (_jsx(Tooltip, { content: item.label, side: "inline-end", children: _jsx(SidebarItem, { "aria-label": item.label, icon: item.icon, active: activeIds.includes(item.id), href: item.href, render: item.render ?? renderLink?.(item), onClick: item.onSelect }) }, item.id)))] }, section.id)))] }), _jsxs(AppSidebarFooter, { ref: room.footerRef, children: [collapsed && onExpand && (_jsx(AppSidebarRail, { className: expandButtonRail, children: _jsx(Tooltip, { content: locale.labels.common.expand, side: "inline-end", children: _jsx(IconButton, { "aria-label": locale.labels.common.expand, size: "medium", onClick: onExpand, children: _jsx(CaretLineRightIcon, { className: cx(icon({ size: "small" }), directional) }) }) }) })), footer] })] }));
|
|
119
152
|
}
|
|
120
|
-
/*
|
|
121
|
-
* A workspace's square mark with its initial: the primary face for the current one, the raised
|
|
122
|
-
* face with a quieter initial for the others. Its edge is a gradient, so it is drawn under the face
|
|
123
|
-
* through a transparent border.
|
|
124
|
-
*/
|
|
153
|
+
/* A workspace's mark: its edge is a gradient, so it is drawn under the face through a transparent border. */
|
|
125
154
|
const workspaceMark = css({
|
|
126
155
|
display: "inline-grid",
|
|
127
156
|
placeItems: "center",
|
|
@@ -130,29 +159,27 @@ const workspaceMark = css({
|
|
|
130
159
|
height: "workspace.mark",
|
|
131
160
|
border: "1px solid transparent",
|
|
132
161
|
borderRadius: "keycap",
|
|
133
|
-
background: "token(gradients.raised) padding-box, token(gradients.border.otherWorkspaceMark) border-box",
|
|
162
|
+
background: "[token(gradients.raised) padding-box, token(gradients.border.otherWorkspaceMark) border-box]",
|
|
134
163
|
color: "fg.label",
|
|
135
164
|
fontSize: "code",
|
|
136
165
|
fontWeight: "medium",
|
|
137
166
|
letterSpacing: "compact",
|
|
138
167
|
lineHeight: "tight",
|
|
139
168
|
"&[data-current]": {
|
|
140
|
-
background: "token(gradients.primary) padding-box, token(gradients.border.primary) border-box",
|
|
169
|
+
background: "[token(gradients.primary) padding-box, token(gradients.border.primary) border-box]",
|
|
141
170
|
color: "bg.canvas",
|
|
142
171
|
_light: { color: "fg.onAccent" },
|
|
143
172
|
},
|
|
144
173
|
"&[data-size=small]": { width: "control.mark", height: "control.mark", borderRadius: "control" },
|
|
145
174
|
});
|
|
146
|
-
/** A workspace's mark: its name's first letter on a square tile. */
|
|
147
175
|
export function WorkspaceMark({ name, current = false, size = "regular", className, }) {
|
|
148
176
|
return (_jsx("span", { "aria-hidden": "true", className: cx(workspaceMark, className), "data-ciridae-ui": "", "data-current": current || undefined, "data-size": size, children: name.trim().charAt(0).toLocaleUpperCase() }));
|
|
149
177
|
}
|
|
150
|
-
// The sidebar's first row: hovered it takes the nav row's wash, open a grey well in the canvas's edge.
|
|
151
178
|
const workspaceSwitcher = css({
|
|
152
179
|
display: "flex",
|
|
153
180
|
alignItems: "center",
|
|
154
181
|
gap: "layout.controlGap",
|
|
155
|
-
width: "
|
|
182
|
+
width: "full",
|
|
156
183
|
height: "control.default",
|
|
157
184
|
padding: "control.compactBlock",
|
|
158
185
|
border: "0",
|
|
@@ -168,12 +195,11 @@ const workspaceSwitcher = css({
|
|
|
168
195
|
cursor: "pointer",
|
|
169
196
|
transitionProperty: "background",
|
|
170
197
|
transitionDuration: "fast",
|
|
171
|
-
_hover: { background: "token(gradients.selected)", _light: { background: "bg.rowHover" } },
|
|
172
|
-
// Open, it keeps its open face under the pointer too.
|
|
198
|
+
_hover: { background: "[token(gradients.selected)]", _light: { background: "bg.rowHover" } },
|
|
173
199
|
"&[data-popup-open], &[data-popup-open]:hover": {
|
|
174
200
|
background: "bg.openTrigger",
|
|
175
201
|
_light: { background: "bg.openTrigger" },
|
|
176
|
-
boxShadow: "inset 0 0 0 1px token(colors.border.canvas)",
|
|
202
|
+
boxShadow: "[inset 0 0 0 1px token(colors.border.canvas)]",
|
|
177
203
|
},
|
|
178
204
|
_focusVisible: { focusRing: "outer" },
|
|
179
205
|
"& > [data-name]": { flex: "1" },
|
|
@@ -185,7 +211,6 @@ const workspaceSwitcher = css({
|
|
|
185
211
|
padding: "none",
|
|
186
212
|
},
|
|
187
213
|
});
|
|
188
|
-
/** The current workspace, opening a menu of every workspace the reader belongs to, current checked. */
|
|
189
214
|
export function WorkspaceSwitcher({ workspaces, currentId, onSelect, compact = false, }) {
|
|
190
215
|
const current = workspaces.find((workspace) => workspace.id === currentId);
|
|
191
216
|
const name = current?.name ?? "";
|
|
@@ -21,19 +21,15 @@ export type BadgeGlyphKind = "notReached" | "hereNow" | "terminal" | "contested"
|
|
|
21
21
|
export type BadgeGlyphProps = Omit<ComponentProps<"svg">, "children"> & {
|
|
22
22
|
kind: BadgeGlyphKind;
|
|
23
23
|
};
|
|
24
|
-
/** A badge's drawn glyph: a lifecycle position, a contested verdict, an unchanged outcome. */
|
|
25
24
|
export declare function BadgeGlyph({ kind, className, ...props }: BadgeGlyphProps): import("react").JSX.Element;
|
|
26
25
|
/** How strongly a value has been checked: none, by a model, by a person, against the world. */
|
|
27
26
|
export type AssuranceLevel = 0 | 1 | 2 | 3;
|
|
28
27
|
export type AssuranceGlyphProps = Omit<ComponentProps<"svg">, "children"> & {
|
|
29
28
|
level: AssuranceLevel;
|
|
30
29
|
};
|
|
31
|
-
/** A three-bar meter, lit to the level, so a value's assurance reads without color. */
|
|
32
30
|
export declare function AssuranceGlyph({ level, className, ...props }: AssuranceGlyphProps): import("react").JSX.Element;
|
|
33
|
-
/** Where a record sits in its stages. The glyph is fixed per position; the words name the stage. */
|
|
34
31
|
export type LifecycleState = "notReached" | "hereNow" | "done" | "blocked" | "agentWaiting" | "expired" | "terminal" | "awaiting";
|
|
35
32
|
export type LifecycleBadgeProps = Omit<BadgeProps, "tone" | "shape" | "appearance" | "icon"> & {
|
|
36
33
|
state: LifecycleState;
|
|
37
34
|
};
|
|
38
|
-
/** A lifecycle pill: the state picks the glyph and the hue; the words are the stage's name. */
|
|
39
35
|
export declare function LifecycleBadge({ state, ...props }: LifecycleBadgeProps): import("react").JSX.Element;
|
package/dist/components/badge.js
CHANGED
|
@@ -11,11 +11,7 @@ import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-run
|
|
|
11
11
|
import { useRender } from "@base-ui/react/use-render";
|
|
12
12
|
import { CheckIcon, ClockIcon, HourglassIcon, SparkleIcon, StopIcon } from "@phosphor-icons/react";
|
|
13
13
|
import { css, cva, cx } from "#primitives/css";
|
|
14
|
-
/*
|
|
15
|
-
* A tinted pill is its hue's glass, falling from light to its hue, inside that hue's gradient
|
|
16
|
-
* hairline, which the `[data-edge="gradient"]` ring draws from `--edge`. Neutral is the raised
|
|
17
|
-
* glass, warning the tinted button's warm glass, and ink the primary face.
|
|
18
|
-
*/
|
|
14
|
+
/* The `[data-edge="gradient"]` ring draws the hairline from `--edge`. */
|
|
19
15
|
const badge = cva({
|
|
20
16
|
base: {
|
|
21
17
|
display: "inline-flex",
|
|
@@ -47,11 +43,6 @@ const badge = cva({
|
|
|
47
43
|
_light: { background: "bg.card" },
|
|
48
44
|
},
|
|
49
45
|
},
|
|
50
|
-
/*
|
|
51
|
-
* `filled` is the tone's glass; `outline` the card's face inside the tone's edge, as an
|
|
52
|
-
* outcome that changed nothing; `bare` a fact told in passing: the icon and the words, muted,
|
|
53
|
-
* with no box, the tone on the icon alone.
|
|
54
|
-
*/
|
|
55
46
|
appearance: {
|
|
56
47
|
filled: {},
|
|
57
48
|
outline: {},
|
|
@@ -60,7 +51,7 @@ const badge = cva({
|
|
|
60
51
|
gap: "layout.tightGap",
|
|
61
52
|
paddingInline: "none",
|
|
62
53
|
border: "0",
|
|
63
|
-
borderRadius: "
|
|
54
|
+
borderRadius: "none",
|
|
64
55
|
background: "transparent",
|
|
65
56
|
flexShrink: "0",
|
|
66
57
|
_light: { background: "transparent" },
|
|
@@ -81,7 +72,7 @@ const badge = cva({
|
|
|
81
72
|
shape: "pill",
|
|
82
73
|
tone: "neutral",
|
|
83
74
|
css: {
|
|
84
|
-
background: "token(gradients.raised)",
|
|
75
|
+
background: "[token(gradients.raised)]",
|
|
85
76
|
color: "fg.label",
|
|
86
77
|
"--edge": "token(gradients.border.raised)",
|
|
87
78
|
},
|
|
@@ -91,7 +82,7 @@ const badge = cva({
|
|
|
91
82
|
shape: "pill",
|
|
92
83
|
tone: "info",
|
|
93
84
|
css: {
|
|
94
|
-
background: "token(gradients.infoGlass)",
|
|
85
|
+
background: "[token(gradients.infoGlass)]",
|
|
95
86
|
"--edge": "token(gradients.border.infoGlass)",
|
|
96
87
|
},
|
|
97
88
|
},
|
|
@@ -100,7 +91,7 @@ const badge = cva({
|
|
|
100
91
|
shape: "pill",
|
|
101
92
|
tone: "success",
|
|
102
93
|
css: {
|
|
103
|
-
background: "token(gradients.successGlass)",
|
|
94
|
+
background: "[token(gradients.successGlass)]",
|
|
104
95
|
"--edge": "token(gradients.border.successGlass)",
|
|
105
96
|
},
|
|
106
97
|
},
|
|
@@ -109,7 +100,7 @@ const badge = cva({
|
|
|
109
100
|
shape: "pill",
|
|
110
101
|
tone: "warning",
|
|
111
102
|
css: {
|
|
112
|
-
background: "token(gradients.tinted)",
|
|
103
|
+
background: "[token(gradients.tinted)]",
|
|
113
104
|
"--edge": "token(gradients.border.raised)",
|
|
114
105
|
_light: { "--edge": "token(gradients.border.tinted)" },
|
|
115
106
|
},
|
|
@@ -119,7 +110,7 @@ const badge = cva({
|
|
|
119
110
|
shape: "pill",
|
|
120
111
|
tone: "danger",
|
|
121
112
|
css: {
|
|
122
|
-
background: "token(gradients.dangerGlass)",
|
|
113
|
+
background: "[token(gradients.dangerGlass)]",
|
|
123
114
|
"--edge": "token(gradients.border.dangerGlass)",
|
|
124
115
|
},
|
|
125
116
|
},
|
|
@@ -128,7 +119,7 @@ const badge = cva({
|
|
|
128
119
|
shape: "pill",
|
|
129
120
|
tone: "ink",
|
|
130
121
|
css: {
|
|
131
|
-
background: "token(gradients.primary)",
|
|
122
|
+
background: "[token(gradients.primary)]",
|
|
132
123
|
color: "bg.canvas",
|
|
133
124
|
"--edge": "token(gradients.border.primary)",
|
|
134
125
|
_light: { color: "fg.onAccent" },
|
|
@@ -138,7 +129,7 @@ const badge = cva({
|
|
|
138
129
|
appearance: "outline",
|
|
139
130
|
shape: "pill",
|
|
140
131
|
css: {
|
|
141
|
-
background: "token(gradients.raised)",
|
|
132
|
+
background: "[token(gradients.raised)]",
|
|
142
133
|
color: "fg.primary",
|
|
143
134
|
"--edge": "token(gradients.border.raised)",
|
|
144
135
|
_light: { background: "bg.card", "--edge": "token(gradients.border.primary)" },
|
|
@@ -180,13 +171,14 @@ export function Badge({ tone = "neutral", shape = "pill", appearance = "filled",
|
|
|
180
171
|
},
|
|
181
172
|
});
|
|
182
173
|
}
|
|
183
|
-
/*
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
174
|
+
/* The glyphs are drawn in a 14px box (12px for the progress step's check and stop). */
|
|
175
|
+
const glyph = css({ flexShrink: "0", width: "[1em]", height: "[1em]", fontSize: "icon.small" });
|
|
176
|
+
const smallGlyph = css({
|
|
177
|
+
flexShrink: "0",
|
|
178
|
+
width: "[1em]",
|
|
179
|
+
height: "[1em]",
|
|
180
|
+
fontSize: "icon.compact",
|
|
181
|
+
});
|
|
190
182
|
export function BadgeGlyph({ kind, className, ...props }) {
|
|
191
183
|
const small = kind === "check" || kind === "stop";
|
|
192
184
|
return (_jsxs("svg", { "aria-hidden": "true", viewBox: small ? "0 0 12 12" : "0 0 14 14", fill: "none", ...props, className: cx(small ? smallGlyph : glyph, className), children: [kind === "notReached" && (_jsx("circle", { cx: "7", cy: "7", r: "3.875", stroke: "currentColor", strokeWidth: "1.25", strokeDasharray: "2 1.6" })), kind === "hereNow" && _jsx("circle", { cx: "7", cy: "7", r: "3", fill: "currentColor" }), kind === "terminal" && (_jsx("rect", { x: "3.5", y: "3.5", width: "7", height: "7", rx: "1.5", fill: "currentColor" })), kind === "contested" && (_jsx("circle", { cx: "7", cy: "7", r: "3.875", fill: "currentColor", stroke: "currentColor", strokeWidth: "1.25" })), kind === "noChange" && (_jsx("circle", { cx: "7", cy: "7", r: "3.375", stroke: "currentColor", strokeWidth: "1.25" })), kind === "check" && (_jsx("path", { d: "M2.4 6.2 4.6 8.5 9.7 3.4", stroke: "currentColor", strokeWidth: "0.857", strokeLinecap: "round", strokeLinejoin: "round" })), kind === "stop" && (_jsxs(_Fragment, { children: [_jsx("circle", { cx: "6", cy: "6", r: "3.95", stroke: "currentColor", strokeWidth: "0.857" }), _jsx("path", { d: "M4.1 6h3.8", stroke: "currentColor", strokeWidth: "0.857", strokeLinecap: "round" })] }))] }));
|
|
@@ -196,7 +188,6 @@ const ASSURANCE_BARS = [
|
|
|
196
188
|
{ x: 5.8, y: 4.5, height: 8 },
|
|
197
189
|
{ x: 9.5, y: 1.5, height: 11 },
|
|
198
190
|
];
|
|
199
|
-
/** A three-bar meter, lit to the level, so a value's assurance reads without color. */
|
|
200
191
|
export function AssuranceGlyph({ level, className, ...props }) {
|
|
201
192
|
return (_jsx("svg", { "aria-hidden": "true", viewBox: "0 0 14 14", fill: "currentColor", ...props, className: cx(glyph, className), children: ASSURANCE_BARS.map((bar, index) => (_jsx("rect", { x: bar.x, y: bar.y, width: "2.5", height: bar.height, rx: "0.75", opacity: index < level ? 1 : 0.28 }, bar.x))) }));
|
|
202
193
|
}
|
|
@@ -220,7 +211,6 @@ const LIFECYCLE_GLYPHS = {
|
|
|
220
211
|
terminal: _jsx(BadgeGlyph, { kind: "terminal" }),
|
|
221
212
|
awaiting: _jsx(HourglassIcon, { weight: "bold" }),
|
|
222
213
|
};
|
|
223
|
-
/** A lifecycle pill: the state picks the glyph and the hue; the words are the stage's name. */
|
|
224
214
|
export function LifecycleBadge({ state, ...props }) {
|
|
225
215
|
return _jsx(Badge, { ...props, tone: LIFECYCLE_TONES[state], icon: LIFECYCLE_GLYPHS[state] });
|
|
226
216
|
}
|
|
@@ -10,13 +10,13 @@ const bar = css({
|
|
|
10
10
|
justifyContent: "space-between",
|
|
11
11
|
flexWrap: "wrap",
|
|
12
12
|
gap: "layout.contentGap",
|
|
13
|
-
minHeight: "56px",
|
|
13
|
+
minHeight: "[56px]",
|
|
14
14
|
paddingBlock: "panel.compact",
|
|
15
15
|
paddingInlineStart: "panel.comfortable",
|
|
16
16
|
paddingInlineEnd: "panel.compact",
|
|
17
17
|
border: "1px solid token(colors.border.divider)",
|
|
18
18
|
borderRadius: "action",
|
|
19
|
-
background: "token(gradients.card)",
|
|
19
|
+
background: "[token(gradients.card)]",
|
|
20
20
|
fontSize: "body",
|
|
21
21
|
fontWeight: "medium",
|
|
22
22
|
letterSpacing: "compact",
|
|
@@ -8,9 +8,8 @@ import { formatForDisplay } from "./hotkeys.js";
|
|
|
8
8
|
import { icon as iconStyle, Spinner } from "./icon.js";
|
|
9
9
|
import { ShortcutHint } from "./keycap.js";
|
|
10
10
|
import { useCiridaeLocale } from "./locale.js";
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const tintedHover = "linear-gradient(token(colors.bg.hover), token(colors.bg.hover)), token(gradients.tinted)";
|
|
11
|
+
const raisedHoverLight = "[linear-gradient(token(colors.bg.hover), token(colors.bg.hover)), token(gradients.raised)]";
|
|
12
|
+
const tintedHover = "[linear-gradient(token(colors.bg.hover), token(colors.bg.hover)), token(gradients.tinted)]";
|
|
14
13
|
const action = cva({
|
|
15
14
|
base: {
|
|
16
15
|
display: "inline-flex",
|
|
@@ -20,7 +19,6 @@ const action = cva({
|
|
|
20
19
|
gap: "control.iconGap",
|
|
21
20
|
// The design lays a button's edge over its padding rather than inside it, so no border.
|
|
22
21
|
border: "0",
|
|
23
|
-
// Buttons are pills at both heights.
|
|
24
22
|
borderRadius: "pill",
|
|
25
23
|
height: "control.default",
|
|
26
24
|
paddingInline: "control.inline",
|
|
@@ -30,44 +28,41 @@ const action = cva({
|
|
|
30
28
|
letterSpacing: "compact",
|
|
31
29
|
lineHeight: "tight",
|
|
32
30
|
cursor: "pointer",
|
|
33
|
-
transitionProperty: "translate, background, color",
|
|
31
|
+
transitionProperty: "[translate, background, color]",
|
|
34
32
|
transitionDuration: "fast",
|
|
35
33
|
_focusVisible: { focusRing: "outer" },
|
|
36
34
|
"&:disabled, &[data-disabled]": {
|
|
37
35
|
opacity: "disabled",
|
|
38
36
|
cursor: "not-allowed",
|
|
39
37
|
// A control that cannot be pressed should not look like it is waiting to be.
|
|
40
|
-
translate: "none",
|
|
38
|
+
translate: "[none]",
|
|
41
39
|
},
|
|
42
40
|
},
|
|
43
41
|
variants: {
|
|
44
42
|
variant: {
|
|
45
43
|
/*
|
|
46
44
|
* Buttons cast no shadow: each face is told apart by its gradient fill and its gradient
|
|
47
|
-
* edge alone.
|
|
48
|
-
*
|
|
45
|
+
* edge alone. The primary face's hover lets a little of the surface through in both
|
|
46
|
+
* themes.
|
|
49
47
|
*/
|
|
50
48
|
primary: {
|
|
51
|
-
background: "token(gradients.primary)",
|
|
49
|
+
background: "[token(gradients.primary)]",
|
|
52
50
|
color: "bg.canvas",
|
|
53
51
|
_light: { color: "fg.onAccent" },
|
|
54
|
-
_hover: {
|
|
55
|
-
|
|
56
|
-
_light: { background: "token(gradients.primary)" },
|
|
57
|
-
},
|
|
58
|
-
_active: { translate: "0 1px" },
|
|
52
|
+
_hover: { background: "[token(gradients.primaryHover)]" },
|
|
53
|
+
_active: { translate: "[0 1px]" },
|
|
59
54
|
},
|
|
60
55
|
secondary: {
|
|
61
|
-
background: "token(gradients.raised)",
|
|
56
|
+
background: "[token(gradients.raised)]",
|
|
62
57
|
color: "fg.primary",
|
|
63
58
|
_hover: { background: "bg.raisedHover", _light: { background: raisedHoverLight } },
|
|
64
|
-
_active: { translate: "0 1px" },
|
|
59
|
+
_active: { translate: "[0 1px]" },
|
|
65
60
|
},
|
|
66
61
|
subtle: {
|
|
67
62
|
background: "bg.fill",
|
|
68
63
|
color: "fg.muted",
|
|
69
64
|
_hover: { color: "fg.primary" },
|
|
70
|
-
_active: { translate: "0 1px" },
|
|
65
|
+
_active: { translate: "[0 1px]" },
|
|
71
66
|
},
|
|
72
67
|
// White in dark, the secondary grey in light: the one face whose text follows the theme
|
|
73
68
|
// differently.
|
|
@@ -79,41 +74,41 @@ const action = cva({
|
|
|
79
74
|
},
|
|
80
75
|
// Warm glass with an amber edge and the warm accent for its text.
|
|
81
76
|
tinted: {
|
|
82
|
-
background: "token(gradients.tinted)",
|
|
77
|
+
background: "[token(gradients.tinted)]",
|
|
83
78
|
color: "accent.yellow",
|
|
84
79
|
_light: { color: "accent.bronze" },
|
|
85
80
|
_hover: { background: tintedHover },
|
|
86
|
-
_active: { translate: "0 1px" },
|
|
81
|
+
_active: { translate: "[0 1px]" },
|
|
87
82
|
},
|
|
88
83
|
// The secondary face with red text, for a destructive action that asks for confirmation:
|
|
89
84
|
// it names the risk without being the loudest thing on the page. The confirmation's own
|
|
90
85
|
// button is `danger`.
|
|
91
86
|
secondaryDanger: {
|
|
92
|
-
background: "token(gradients.raised)",
|
|
87
|
+
background: "[token(gradients.raised)]",
|
|
93
88
|
color: "accent.red",
|
|
94
89
|
_hover: { background: "bg.raisedHover", _light: { background: raisedHoverLight } },
|
|
95
|
-
_active: { translate: "0 1px" },
|
|
90
|
+
_active: { translate: "[0 1px]" },
|
|
96
91
|
},
|
|
97
92
|
danger: {
|
|
98
|
-
background: "token(gradients.danger)",
|
|
93
|
+
background: "[token(gradients.danger)]",
|
|
99
94
|
color: "fg.onAccent",
|
|
100
|
-
_hover: { filter: "brightness(1.05)" },
|
|
101
|
-
_active: { translate: "0 1px" },
|
|
95
|
+
_hover: { filter: "[brightness(1.05)]" },
|
|
96
|
+
_active: { translate: "[0 1px]" },
|
|
102
97
|
},
|
|
103
98
|
success: {
|
|
104
99
|
background: "accent.green",
|
|
105
100
|
color: "bg.canvas",
|
|
106
|
-
_hover: { filter: "brightness(1.05)" },
|
|
107
|
-
_active: { translate: "0 1px" },
|
|
101
|
+
_hover: { filter: "[brightness(1.05)]" },
|
|
102
|
+
_active: { translate: "[0 1px]" },
|
|
108
103
|
},
|
|
109
104
|
// Words only, in the text around it: no face, no height, underlined on hover.
|
|
110
105
|
link: {
|
|
111
106
|
background: "transparent",
|
|
112
107
|
color: "fg.primary",
|
|
113
|
-
fontFamily: "inherit",
|
|
114
|
-
fontWeight: "inherit",
|
|
115
|
-
letterSpacing: "inherit",
|
|
116
|
-
lineHeight: "inherit",
|
|
108
|
+
fontFamily: "[inherit]",
|
|
109
|
+
fontWeight: "[inherit]",
|
|
110
|
+
letterSpacing: "[inherit]",
|
|
111
|
+
lineHeight: "[inherit]",
|
|
117
112
|
_hover: { textDecoration: "underline" },
|
|
118
113
|
},
|
|
119
114
|
},
|
|
@@ -126,19 +121,18 @@ const action = cva({
|
|
|
126
121
|
medium: {},
|
|
127
122
|
large: { height: "control.field", paddingInline: "control.largeInline", fontSize: "heading" },
|
|
128
123
|
},
|
|
129
|
-
fullWidth: { true: { width: "
|
|
124
|
+
fullWidth: { true: { width: "full" } },
|
|
130
125
|
},
|
|
131
126
|
compoundVariants: [
|
|
132
127
|
{
|
|
133
128
|
variant: "link",
|
|
134
129
|
size: ["small", "medium", "large"],
|
|
135
|
-
css: { height: "auto", paddingInline: "none", fontSize: "inherit", flexShrink: "0" },
|
|
130
|
+
css: { height: "auto", paddingInline: "none", fontSize: "[inherit]", flexShrink: "0" },
|
|
136
131
|
},
|
|
137
132
|
],
|
|
138
133
|
// Small is the everyday button; medium and large are for a page's one main action.
|
|
139
134
|
defaultVariants: { variant: "primary", size: "small" },
|
|
140
135
|
});
|
|
141
|
-
// Each gradient face draws its own gradient edge; the flat faces draw a hairline or none.
|
|
142
136
|
const buttonEdges = {
|
|
143
137
|
primary: "primary",
|
|
144
138
|
secondary: "raised",
|
|
@@ -151,7 +145,7 @@ const buttonEdges = {
|
|
|
151
145
|
link: undefined,
|
|
152
146
|
};
|
|
153
147
|
// In the button's own color, quieter than its label.
|
|
154
|
-
const buttonHint = css({ color: "inherit", opacity: "0.6" });
|
|
148
|
+
const buttonHint = css({ color: "[inherit]", opacity: "[0.6]" });
|
|
155
149
|
/**
|
|
156
150
|
* The size a `Button` takes where it does not set its own, so the container decides: a dialog's
|
|
157
151
|
* footer holds the default 38px buttons, where everywhere else the small one is the everyday.
|
|
@@ -199,42 +193,40 @@ const round = cva({
|
|
|
199
193
|
border: "1px solid transparent",
|
|
200
194
|
borderRadius: "pill",
|
|
201
195
|
color: "fg.muted",
|
|
202
|
-
background: "token(gradients.raised)",
|
|
196
|
+
background: "[token(gradients.raised)]",
|
|
203
197
|
cursor: "pointer",
|
|
204
198
|
flexShrink: "0",
|
|
205
|
-
transitionProperty: "translate, background, color",
|
|
199
|
+
transitionProperty: "[translate, background, color]",
|
|
206
200
|
transitionDuration: "fast",
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
_active: { translate: "0 1px" },
|
|
201
|
+
_hover: { color: "fg.primary", background: "[token(gradients.raisedHover)]" },
|
|
202
|
+
_active: { translate: "[0 1px]" },
|
|
210
203
|
_focusVisible: { focusRing: "outer" },
|
|
211
204
|
// A round face fades further than other controls when it cannot be pressed.
|
|
212
205
|
"&:disabled, &[data-disabled]": {
|
|
213
206
|
opacity: "disabledRound",
|
|
214
207
|
cursor: "not-allowed",
|
|
215
|
-
translate: "none",
|
|
208
|
+
translate: "[none]",
|
|
216
209
|
},
|
|
217
210
|
},
|
|
218
211
|
variants: {
|
|
219
212
|
variant: {
|
|
220
213
|
raised: {},
|
|
221
|
-
// The bare icon button: no face until hovered, and disabled it fades as other controls do.
|
|
222
214
|
ghost: {
|
|
223
215
|
border: "0",
|
|
224
216
|
background: "transparent",
|
|
225
|
-
_hover: { background: "bg.hover"
|
|
226
|
-
_active: { translate: "none" },
|
|
217
|
+
_hover: { background: "bg.hover" },
|
|
218
|
+
_active: { translate: "[none]" },
|
|
227
219
|
"&:disabled, &[data-disabled]": { opacity: "disabled" },
|
|
228
220
|
},
|
|
229
221
|
// The primary face as a round button: a composer's send.
|
|
230
222
|
primary: {
|
|
231
|
-
background: "token(gradients.primary)",
|
|
223
|
+
background: "[token(gradients.primary)]",
|
|
232
224
|
color: "bg.canvas",
|
|
233
225
|
_light: { color: "fg.onAccent" },
|
|
234
226
|
_hover: {
|
|
235
227
|
color: "bg.canvas",
|
|
236
|
-
background: "
|
|
237
|
-
_light: { color: "fg.onAccent"
|
|
228
|
+
background: "[token(gradients.primaryHover)]",
|
|
229
|
+
_light: { color: "fg.onAccent" },
|
|
238
230
|
},
|
|
239
231
|
},
|
|
240
232
|
},
|
|
@@ -247,7 +239,6 @@ const round = cva({
|
|
|
247
239
|
medium: { width: "control.round", height: "control.round" },
|
|
248
240
|
large: { width: "control.default", height: "control.default" },
|
|
249
241
|
},
|
|
250
|
-
// A page's leading icon button is a rounded square rather than a circle.
|
|
251
242
|
shape: { round: {}, square: { borderRadius: "action" } },
|
|
252
243
|
},
|
|
253
244
|
compoundVariants: [
|
|
@@ -271,8 +262,8 @@ const badgeDot = css({
|
|
|
271
262
|
/* A count sits on the button's corner, where the dot alone would not say how many. */
|
|
272
263
|
const badgeCount = css({
|
|
273
264
|
position: "absolute",
|
|
274
|
-
top: "calc(token(spacing.layout.tightGap) * -1)",
|
|
275
|
-
insetInlineEnd: "calc(token(spacing.layout.tightGap) * -1)",
|
|
265
|
+
top: "[calc(token(spacing.layout.tightGap) * -1)]",
|
|
266
|
+
insetInlineEnd: "[calc(token(spacing.layout.tightGap) * -1)]",
|
|
276
267
|
display: "inline-flex",
|
|
277
268
|
alignItems: "center",
|
|
278
269
|
justifyContent: "center",
|
|
@@ -286,7 +277,7 @@ const badgeCount = css({
|
|
|
286
277
|
color: "bg.canvas",
|
|
287
278
|
fontSize: "avatar.small",
|
|
288
279
|
fontWeight: "medium",
|
|
289
|
-
lineHeight: "
|
|
280
|
+
lineHeight: "tight",
|
|
290
281
|
fontVariantNumeric: "tabular-nums",
|
|
291
282
|
});
|
|
292
283
|
/**
|