prime-ui-kit 0.9.1 → 0.9.3
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 -12
- package/dist/chunks/{chunk-NHOWNIAR.js → chunk-6JTZOA5I.js} +1472 -671
- package/dist/chunks/{chunk-DB2Y3XXA.js → chunk-OAE4IQX2.js} +2845 -1732
- package/dist/chunks/{chunk-KCQFOORX.js → chunk-U5SR2LZR.js} +17 -4
- package/dist/color-picker.js +2 -2
- package/dist/components/button/Button.d.ts +19 -2
- package/dist/components/card/Card.d.ts +1 -1
- package/dist/components/code-block/CodeBlock.d.ts +1 -1
- package/dist/components/color-picker/ColorPicker.d.ts +1 -1
- package/dist/components/data-table/DataTable.d.ts +6 -1
- package/dist/components/data-table/Row.d.ts +3 -1
- package/dist/components/data-table/rows.d.ts +4 -0
- package/dist/components/data-table/types.d.ts +5 -0
- package/dist/components/digit-input/DigitInput.d.ts +6 -1
- package/dist/components/dnd/Dnd.d.ts +1 -1
- package/dist/components/dnd/dragSession.d.ts +9 -0
- package/dist/components/dnd/useDropTarget.d.ts +5 -0
- package/dist/components/dnd/useFlipList.d.ts +3 -3
- package/dist/components/drawer/Drawer.d.ts +8 -5
- package/dist/components/dropdown/Dropdown.d.ts +17 -0
- package/dist/components/index.d.ts +9 -2
- package/dist/components/input/Input.d.ts +16 -1
- package/dist/components/input/passwordStrength.d.ts +9 -0
- package/dist/components/kanban/Kanban.d.ts +129 -0
- package/dist/components/modal/Modal.d.ts +5 -2
- package/dist/components/page-toolbar/PageToolbar.d.ts +53 -0
- package/dist/components/progress-bar/ProgressBar.d.ts +16 -1
- package/dist/components/segmented-control/SegmentedControl.d.ts +5 -2
- package/dist/components/sparkline/Sparkline.d.ts +26 -0
- package/dist/components/tabs/Tabs.d.ts +5 -2
- package/dist/hooks/useEdgeOverflow.d.ts +16 -0
- package/dist/hooks/useMediaQuery.d.ts +7 -0
- package/dist/hooks/useSwipeDismiss.d.ts +34 -0
- package/dist/icons/registry.d.ts +2 -0
- package/dist/index.css +2977 -1306
- package/dist/index.d.ts +1 -0
- package/dist/index.js +17 -3
- package/dist/internal/CheckMark.d.ts +12 -0
- package/dist/internal/MorphText.d.ts +12 -0
- package/dist/internal/RollingNumber.d.ts +14 -0
- package/dist/internal/overlay/FloatingPanel.d.ts +3 -1
- package/dist/internal/overlay/useFloatingLayer.d.ts +11 -1
- package/dist/internal/surfaceDepth.d.ts +25 -0
- package/dist/internal/swatch.d.ts +4 -1
- package/dist/internal/touchTarget.d.ts +4 -0
- package/dist/layout/app-header/AppHeader.d.ts +110 -0
- package/dist/layout/app-shell/AppShell.d.ts +16 -11
- package/dist/layout/bottom-nav/BottomNav.d.ts +80 -0
- package/dist/layout/index.d.ts +5 -1
- package/dist/motion/celebrate.d.ts +18 -0
- package/dist/tokens/layers.d.ts +37 -0
- package/dist/tokens/naming.d.ts +1 -1
- package/dist/tokens/primitives.d.ts +4 -0
- package/dist/tokens/semantic.d.ts +122 -56
- package/dist/tokens/themes/dark.d.ts +10 -14
- package/package.json +3 -2
- package/src/components/accordion/COMPONENT.md +5 -5
- package/src/components/avatar/COMPONENT.md +1 -1
- package/src/components/badge/COMPONENT.md +2 -2
- package/src/components/banner/COMPONENT.md +1 -1
- package/src/components/button/COMPONENT.md +26 -5
- package/src/components/button/examples/download.tsx +45 -0
- package/src/components/button/examples/hold-to-confirm.tsx +23 -0
- package/src/components/button/examples/label-morph.tsx +33 -0
- package/src/components/card/COMPONENT.md +4 -2
- package/src/components/card/examples/narrow.tsx +2 -2
- package/src/components/card/examples/panel-chart.tsx +1 -1
- package/src/components/card/examples/variants.tsx +1 -1
- package/src/components/checkbox/examples/examples.module.css +5 -3
- package/src/components/code-block/COMPONENT.md +6 -6
- package/src/components/code-block/examples/overview.tsx +1 -1
- package/src/components/code-block/examples/variants.tsx +1 -1
- package/src/components/color-picker/COMPONENT.md +1 -1
- package/src/components/color-swatches/COMPONENT.md +5 -5
- package/src/components/command-menu/COMPONENT.md +1 -1
- package/src/components/crossfade/COMPONENT.md +1 -1
- package/src/components/crossfade/examples/overview.tsx +3 -3
- package/src/components/data-table/COMPONENT.md +24 -10
- package/src/components/data-table/examples/columns-visibility.tsx +167 -0
- package/src/components/digit-input/COMPONENT.md +15 -13
- package/src/components/digit-input/examples/examples.module.css +8 -0
- package/src/components/digit-input/examples/in-form.tsx +2 -5
- package/src/components/digit-input/examples/on-complete.tsx +7 -6
- package/src/components/digit-input/examples/sizes.tsx +1 -1
- package/src/components/divider/COMPONENT.md +1 -1
- package/src/components/dnd/COMPONENT.md +3 -3
- package/src/components/dnd/examples/examples.module.css +4 -4
- package/src/components/drawer/COMPONENT.md +17 -9
- package/src/components/drawer/examples/date-sheet.tsx +41 -0
- package/src/components/drawer/examples/examples.module.css +5 -0
- package/src/components/drawer/examples/placement.tsx +4 -2
- package/src/components/dropdown/COMPONENT.md +20 -6
- package/src/components/dropdown/examples/checkbox-items.tsx +48 -0
- package/src/components/dropdown/examples/examples.module.css +1 -1
- package/src/components/empty-page/COMPONENT.md +1 -1
- package/src/components/empty-page/examples/examples.module.css +1 -1
- package/src/components/example-frame/COMPONENT.md +1 -1
- package/src/components/input/COMPONENT.md +10 -1
- package/src/components/input/examples/password-strength.tsx +12 -0
- package/src/components/kanban/COMPONENT.md +181 -0
- package/src/components/kanban/examples/controlled.tsx +78 -0
- package/src/components/kanban/examples/examples.module.css +31 -0
- package/src/components/kanban/examples/limits.tsx +58 -0
- package/src/components/kanban/examples/narrow.tsx +76 -0
- package/src/components/kanban/examples/overview.tsx +130 -0
- package/src/components/kanban/examples/states.tsx +75 -0
- package/src/components/kanban/examples/structure.tsx +76 -0
- package/src/components/login-form/COMPONENT.md +5 -5
- package/src/components/login-form/examples/register.tsx +2 -2
- package/src/components/login-form/examples/reset-password.tsx +2 -2
- package/src/components/modal/COMPONENT.md +11 -8
- package/src/components/modal/examples/examples.module.css +2 -2
- package/src/components/notification/COMPONENT.md +2 -2
- package/src/components/page-content/COMPONENT.md +1 -1
- package/src/components/page-content/examples/examples.module.css +1 -1
- package/src/components/page-toolbar/COMPONENT.md +142 -0
- package/src/components/page-toolbar/examples/examples.module.css +16 -0
- package/src/components/page-toolbar/examples/narrow.tsx +103 -0
- package/src/components/page-toolbar/examples/overview.tsx +113 -0
- package/src/components/page-toolbar/examples/save-changes.tsx +40 -0
- package/src/components/page-toolbar/examples/without-search.tsx +60 -0
- package/src/components/popover/COMPONENT.md +5 -4
- package/src/components/progress-bar/COMPONENT.md +6 -2
- package/src/components/progress-bar/examples/examples.module.css +7 -0
- package/src/components/progress-bar/examples/milestone.tsx +43 -0
- package/src/components/progress-bar/examples/steps.tsx +35 -0
- package/src/components/progress-circle/COMPONENT.md +1 -1
- package/src/components/scroll-container/COMPONENT.md +1 -1
- package/src/components/segmented-control/COMPONENT.md +8 -8
- package/src/components/segmented-control/examples/full-width.tsx +1 -1
- package/src/components/select/COMPONENT.md +2 -1
- package/src/components/skeleton/COMPONENT.md +1 -1
- package/src/components/skeleton/examples/with-crossfade.tsx +3 -3
- package/src/components/smart-filter/COMPONENT.md +2 -0
- package/src/components/sparkline/COMPONENT.md +98 -0
- package/src/components/sparkline/examples/examples.module.css +13 -0
- package/src/components/sparkline/examples/overview.tsx +27 -0
- package/src/components/sparkline/examples/period.tsx +46 -0
- package/src/components/spinner/COMPONENT.md +1 -1
- package/src/components/tabs/COMPONENT.md +24 -22
- package/src/components/tabs/examples/closable.tsx +1 -1
- package/src/components/tabs/examples/examples.module.css +14 -0
- package/src/components/tabs/examples/orientation.tsx +87 -33
- package/src/components/tooltip/COMPONENT.md +8 -6
- package/src/components/tooltip/examples/examples.module.css +2 -2
- package/src/layout/app-header/COMPONENT.md +178 -0
- package/src/layout/app-header/examples/breadcrumbs.tsx +36 -0
- package/src/layout/app-header/examples/examples.module.css +47 -0
- package/src/layout/app-header/examples/in-app-shell.tsx +70 -0
- package/src/layout/app-header/examples/narrow.tsx +29 -0
- package/src/layout/app-header/examples/overview.tsx +36 -0
- package/src/layout/app-shell/COMPONENT.md +35 -29
- package/src/layout/app-shell/examples/examples.module.css +17 -2
- package/src/layout/app-shell/examples/footer.tsx +59 -0
- package/src/layout/app-shell/examples/overview.tsx +19 -8
- package/src/layout/bottom-nav/COMPONENT.md +153 -0
- package/src/layout/bottom-nav/examples/examples.module.css +39 -0
- package/src/layout/bottom-nav/examples/floating.tsx +89 -0
- package/src/layout/bottom-nav/examples/icon-only.tsx +41 -0
- package/src/layout/bottom-nav/examples/in-app-shell.tsx +64 -0
- package/src/layout/bottom-nav/examples/overview.tsx +44 -0
- package/src/layout/bottom-nav/examples/router.tsx +31 -0
- package/src/layout/bottom-nav/examples/structure.tsx +47 -0
- package/src/layout/sidebar/COMPONENT.md +14 -13
- package/src/layout/sidebar/examples/examples.module.css +5 -5
- package/src/styles/globals.css +125 -2
- package/src/styles/theme-dark.css +39 -13
- package/src/styles/theme-light.css +84 -16
- package/src/styles/tokens.css +2 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/** A glass capsule over the page: the client list scrolls under its blur, with labels or icons alone — `floating`, `iconOnly`. */
|
|
2
|
+
import {
|
|
3
|
+
AppHeader,
|
|
4
|
+
AppShell,
|
|
5
|
+
Avatar,
|
|
6
|
+
BottomNav,
|
|
7
|
+
Icon,
|
|
8
|
+
PageContent,
|
|
9
|
+
Switch,
|
|
10
|
+
Typography,
|
|
11
|
+
} from "prime-ui-kit";
|
|
12
|
+
import * as React from "react";
|
|
13
|
+
|
|
14
|
+
import styles from "./examples.module.css";
|
|
15
|
+
|
|
16
|
+
const SECTIONS = [
|
|
17
|
+
{ id: "home", label: "Главная", icon: "nav.home" },
|
|
18
|
+
{ id: "clients", label: "Клиенты", icon: "object.users" },
|
|
19
|
+
{ id: "inbox", label: "Входящие", icon: "object.inbox" },
|
|
20
|
+
{ id: "settings", label: "Настройки", icon: "action.settings" },
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
const CLIENTS = [
|
|
24
|
+
{ name: "ООО «Север»", initials: "СЕ", color: "blue", deals: "4 сделки" },
|
|
25
|
+
{ name: "ИП Котов", initials: "КО", color: "green", deals: "1 сделка" },
|
|
26
|
+
{ name: "ООО «Вектор»", initials: "ВЕ", color: "orange", deals: "7 сделок" },
|
|
27
|
+
{ name: "АО «Меридиан»", initials: "МЕ", color: "purple", deals: "2 сделки" },
|
|
28
|
+
{ name: "ООО «Полюс»", initials: "ПО", color: "red", deals: "5 сделок" },
|
|
29
|
+
{ name: "ИП Белова", initials: "БЕ", color: "teal", deals: "3 сделки" },
|
|
30
|
+
{ name: "ООО «Гранит»", initials: "ГР", color: "yellow", deals: "6 сделок" },
|
|
31
|
+
{ name: "АО «Ладога»", initials: "ЛА", color: "sky", deals: "2 сделки" },
|
|
32
|
+
] as const;
|
|
33
|
+
|
|
34
|
+
export default function BottomNavFloatingExample() {
|
|
35
|
+
const [section, setSection] = React.useState<string>("clients");
|
|
36
|
+
const [iconOnly, setIconOnly] = React.useState(false);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className={styles.phone}>
|
|
40
|
+
<AppShell.Root fillViewport className={styles.shell}>
|
|
41
|
+
<AppHeader.Root>
|
|
42
|
+
<AppHeader.Start>
|
|
43
|
+
<AppHeader.Title>Клиенты</AppHeader.Title>
|
|
44
|
+
</AppHeader.Start>
|
|
45
|
+
<AppHeader.Actions>
|
|
46
|
+
<Switch.Root checked={iconOnly} onCheckedChange={setIconOnly}>
|
|
47
|
+
<Switch.Label>Только иконки</Switch.Label>
|
|
48
|
+
</Switch.Root>
|
|
49
|
+
</AppHeader.Actions>
|
|
50
|
+
</AppHeader.Root>
|
|
51
|
+
<AppShell.Main>
|
|
52
|
+
<PageContent.Section>
|
|
53
|
+
<PageContent.Body>
|
|
54
|
+
{CLIENTS.map((client) => (
|
|
55
|
+
<div key={client.name} className={styles.client}>
|
|
56
|
+
<Avatar.Root color={client.color} aria-hidden="true">
|
|
57
|
+
<Avatar.Fallback>{client.initials}</Avatar.Fallback>
|
|
58
|
+
</Avatar.Root>
|
|
59
|
+
<div>
|
|
60
|
+
<Typography variant="body-m">{client.name}</Typography>
|
|
61
|
+
<Typography variant="body-s" tone="muted">
|
|
62
|
+
{client.deals}
|
|
63
|
+
</Typography>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
))}
|
|
67
|
+
</PageContent.Body>
|
|
68
|
+
</PageContent.Section>
|
|
69
|
+
</AppShell.Main>
|
|
70
|
+
<AppShell.Footer>
|
|
71
|
+
<BottomNav.Root floating iconOnly={iconOnly}>
|
|
72
|
+
{SECTIONS.map((item) => (
|
|
73
|
+
<BottomNav.Item
|
|
74
|
+
key={item.id}
|
|
75
|
+
current={item.id === section}
|
|
76
|
+
onClick={() => setSection(item.id)}
|
|
77
|
+
>
|
|
78
|
+
<BottomNav.ItemIcon>
|
|
79
|
+
<Icon name={item.icon} />
|
|
80
|
+
</BottomNav.ItemIcon>
|
|
81
|
+
{item.label}
|
|
82
|
+
</BottomNav.Item>
|
|
83
|
+
))}
|
|
84
|
+
</BottomNav.Root>
|
|
85
|
+
</AppShell.Footer>
|
|
86
|
+
</AppShell.Root>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Icons alone: the labels are hidden but still name the sections for screen readers — `iconOnly`. */
|
|
2
|
+
import { BottomNav, Icon, Typography } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import styles from "./examples.module.css";
|
|
6
|
+
|
|
7
|
+
const SECTIONS = [
|
|
8
|
+
{ id: "home", label: "Главная", icon: "nav.home" },
|
|
9
|
+
{ id: "orders", label: "Заказы", icon: "object.package" },
|
|
10
|
+
{ id: "inbox", label: "Входящие", icon: "object.inbox" },
|
|
11
|
+
{ id: "profile", label: "Профиль", icon: "object.user" },
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
export default function BottomNavIconOnlyExample() {
|
|
15
|
+
const [section, setSection] = React.useState<string>("home");
|
|
16
|
+
const current = SECTIONS.find((item) => item.id === section) ?? SECTIONS[0];
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className={styles.phone}>
|
|
20
|
+
<div className={styles.screen}>
|
|
21
|
+
<Typography as="h2" variant="title-m">
|
|
22
|
+
{current.label}
|
|
23
|
+
</Typography>
|
|
24
|
+
</div>
|
|
25
|
+
<BottomNav.Root iconOnly>
|
|
26
|
+
{SECTIONS.map((item) => (
|
|
27
|
+
<BottomNav.Item
|
|
28
|
+
key={item.id}
|
|
29
|
+
current={item.id === section}
|
|
30
|
+
onClick={() => setSection(item.id)}
|
|
31
|
+
>
|
|
32
|
+
<BottomNav.ItemIcon>
|
|
33
|
+
<Icon name={item.icon} />
|
|
34
|
+
</BottomNav.ItemIcon>
|
|
35
|
+
{item.label}
|
|
36
|
+
</BottomNav.Item>
|
|
37
|
+
))}
|
|
38
|
+
</BottomNav.Root>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** The app frame on a phone: the AppHeader, the page and the bar in the footer, which leaves once the panel is 640px wide — `AppShell.Footer`. */
|
|
2
|
+
import {
|
|
3
|
+
AppHeader,
|
|
4
|
+
AppShell,
|
|
5
|
+
BottomNav,
|
|
6
|
+
Button,
|
|
7
|
+
Icon,
|
|
8
|
+
PageContent,
|
|
9
|
+
Typography,
|
|
10
|
+
} from "prime-ui-kit";
|
|
11
|
+
|
|
12
|
+
import styles from "./examples.module.css";
|
|
13
|
+
|
|
14
|
+
const SECTIONS = [
|
|
15
|
+
{ label: "Главная", icon: "nav.home" },
|
|
16
|
+
{ label: "Заказы", icon: "object.package" },
|
|
17
|
+
{ label: "Клиенты", icon: "object.users" },
|
|
18
|
+
{ label: "Ещё", icon: "action.more" },
|
|
19
|
+
] as const;
|
|
20
|
+
|
|
21
|
+
const ORDERS = ["№ 4821 · ООО «Север»", "№ 4820 · ИП Котов", "№ 4819 · ООО «Вектор»"];
|
|
22
|
+
|
|
23
|
+
export default function BottomNavInAppShellExample() {
|
|
24
|
+
return (
|
|
25
|
+
<div className={styles.phone}>
|
|
26
|
+
<AppShell.Root fillViewport className={styles.shell}>
|
|
27
|
+
<AppHeader.Root>
|
|
28
|
+
<AppHeader.Start>
|
|
29
|
+
<AppHeader.Title>Заказы</AppHeader.Title>
|
|
30
|
+
</AppHeader.Start>
|
|
31
|
+
</AppHeader.Root>
|
|
32
|
+
<AppShell.Main>
|
|
33
|
+
<PageContent.Section>
|
|
34
|
+
<PageContent.Body>
|
|
35
|
+
{ORDERS.map((order) => (
|
|
36
|
+
<Typography key={order} variant="body-m">
|
|
37
|
+
{order}
|
|
38
|
+
</Typography>
|
|
39
|
+
))}
|
|
40
|
+
<Button.Root variant="soft" tone="neutral">
|
|
41
|
+
<Button.Icon>
|
|
42
|
+
<Icon name="action.add" />
|
|
43
|
+
</Button.Icon>
|
|
44
|
+
Новый заказ
|
|
45
|
+
</Button.Root>
|
|
46
|
+
</PageContent.Body>
|
|
47
|
+
</PageContent.Section>
|
|
48
|
+
</AppShell.Main>
|
|
49
|
+
<AppShell.Footer>
|
|
50
|
+
<BottomNav.Root>
|
|
51
|
+
{SECTIONS.map((item, index) => (
|
|
52
|
+
<BottomNav.Item key={item.label} current={index === 1}>
|
|
53
|
+
<BottomNav.ItemIcon>
|
|
54
|
+
<Icon name={item.icon} />
|
|
55
|
+
</BottomNav.ItemIcon>
|
|
56
|
+
{item.label}
|
|
57
|
+
</BottomNav.Item>
|
|
58
|
+
))}
|
|
59
|
+
</BottomNav.Root>
|
|
60
|
+
</AppShell.Footer>
|
|
61
|
+
</AppShell.Root>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Four sections of the app, the current one in the primary color and a tap moves it — `current`, `BottomNav.ItemIcon`. */
|
|
2
|
+
import { BottomNav, Icon, Typography } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import styles from "./examples.module.css";
|
|
6
|
+
|
|
7
|
+
const SECTIONS = [
|
|
8
|
+
{ id: "home", label: "Главная", icon: "nav.home", summary: "Выручка за неделю — 1,2 млн ₽" },
|
|
9
|
+
{ id: "orders", label: "Заказы", icon: "object.package", summary: "37 заказов ждут отгрузки" },
|
|
10
|
+
{ id: "clients", label: "Клиенты", icon: "object.users", summary: "214 активных клиентов" },
|
|
11
|
+
{ id: "settings", label: "Настройки", icon: "action.settings", summary: "Профиль и уведомления" },
|
|
12
|
+
] as const;
|
|
13
|
+
|
|
14
|
+
export default function BottomNavOverviewExample() {
|
|
15
|
+
const [section, setSection] = React.useState<string>("orders");
|
|
16
|
+
const current = SECTIONS.find((item) => item.id === section) ?? SECTIONS[0];
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className={styles.phone}>
|
|
20
|
+
<div className={styles.screen}>
|
|
21
|
+
<Typography as="h2" variant="title-m">
|
|
22
|
+
{current.label}
|
|
23
|
+
</Typography>
|
|
24
|
+
<Typography variant="body-m" tone="secondary">
|
|
25
|
+
{current.summary}
|
|
26
|
+
</Typography>
|
|
27
|
+
</div>
|
|
28
|
+
<BottomNav.Root>
|
|
29
|
+
{SECTIONS.map((item) => (
|
|
30
|
+
<BottomNav.Item
|
|
31
|
+
key={item.id}
|
|
32
|
+
current={item.id === section}
|
|
33
|
+
onClick={() => setSection(item.id)}
|
|
34
|
+
>
|
|
35
|
+
<BottomNav.ItemIcon>
|
|
36
|
+
<Icon name={item.icon} />
|
|
37
|
+
</BottomNav.ItemIcon>
|
|
38
|
+
{item.label}
|
|
39
|
+
</BottomNav.Item>
|
|
40
|
+
))}
|
|
41
|
+
</BottomNav.Root>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** A router link as the item: the router sets `aria-current` and the item shows as current; render it inside a router — `asChild`. */
|
|
2
|
+
import { BottomNav, Icon } from "prime-ui-kit";
|
|
3
|
+
import { NavLink } from "react-router-dom";
|
|
4
|
+
|
|
5
|
+
import styles from "./examples.module.css";
|
|
6
|
+
|
|
7
|
+
const LINKS = [
|
|
8
|
+
{ to: "/app-shell", label: "Каркас", icon: "nav.layoutGrid" },
|
|
9
|
+
{ to: "/bottom-nav", label: "Навигация", icon: "nav.menu" },
|
|
10
|
+
{ to: "/sidebar", label: "Сайдбар", icon: "nav.sidebarExpand" },
|
|
11
|
+
] as const;
|
|
12
|
+
|
|
13
|
+
export default function BottomNavRouterExample() {
|
|
14
|
+
return (
|
|
15
|
+
<div className={styles.phone}>
|
|
16
|
+
<div className={styles.screen} />
|
|
17
|
+
<BottomNav.Root>
|
|
18
|
+
{LINKS.map((link) => (
|
|
19
|
+
<BottomNav.Item key={link.to} asChild>
|
|
20
|
+
<NavLink to={link.to}>
|
|
21
|
+
<BottomNav.ItemIcon>
|
|
22
|
+
<Icon name={link.icon} />
|
|
23
|
+
</BottomNav.ItemIcon>
|
|
24
|
+
{link.label}
|
|
25
|
+
</NavLink>
|
|
26
|
+
</BottomNav.Item>
|
|
27
|
+
))}
|
|
28
|
+
</BottomNav.Root>
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Counts on the icons and a section that is not available yet — `BottomNav.ItemCount`, `disabled`. */
|
|
2
|
+
import { BottomNav, Icon, Typography } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
import styles from "./examples.module.css";
|
|
5
|
+
|
|
6
|
+
export default function BottomNavStructureExample() {
|
|
7
|
+
return (
|
|
8
|
+
<div className={styles.phone}>
|
|
9
|
+
<div className={styles.screen}>
|
|
10
|
+
<Typography as="h2" variant="title-m">
|
|
11
|
+
Главная
|
|
12
|
+
</Typography>
|
|
13
|
+
<Typography variant="body-m" tone="secondary">
|
|
14
|
+
12 новых заказов и 3 сообщения от клиентов.
|
|
15
|
+
</Typography>
|
|
16
|
+
</div>
|
|
17
|
+
<BottomNav.Root>
|
|
18
|
+
<BottomNav.Item current>
|
|
19
|
+
<BottomNav.ItemIcon>
|
|
20
|
+
<Icon name="nav.home" />
|
|
21
|
+
</BottomNav.ItemIcon>
|
|
22
|
+
Главная
|
|
23
|
+
</BottomNav.Item>
|
|
24
|
+
<BottomNav.Item>
|
|
25
|
+
<BottomNav.ItemIcon>
|
|
26
|
+
<Icon name="object.package" />
|
|
27
|
+
</BottomNav.ItemIcon>
|
|
28
|
+
<BottomNav.ItemCount>12</BottomNav.ItemCount>
|
|
29
|
+
Заказы
|
|
30
|
+
</BottomNav.Item>
|
|
31
|
+
<BottomNav.Item>
|
|
32
|
+
<BottomNav.ItemIcon>
|
|
33
|
+
<Icon name="object.message" />
|
|
34
|
+
</BottomNav.ItemIcon>
|
|
35
|
+
<BottomNav.ItemCount color="blue">3</BottomNav.ItemCount>
|
|
36
|
+
Сообщения
|
|
37
|
+
</BottomNav.Item>
|
|
38
|
+
<BottomNav.Item disabled>
|
|
39
|
+
<BottomNav.ItemIcon>
|
|
40
|
+
<Icon name="object.chart" />
|
|
41
|
+
</BottomNav.ItemIcon>
|
|
42
|
+
Отчёты
|
|
43
|
+
</BottomNav.Item>
|
|
44
|
+
</BottomNav.Root>
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Sidebar
|
|
2
2
|
|
|
3
|
-
**Category:**
|
|
3
|
+
**Category:** navigation
|
|
4
4
|
**Kind:** layout
|
|
5
5
|
|
|
6
6
|
> App side navigation in three modes — expanded, compact, hidden — and an off-canvas panel on narrow screens.
|
|
@@ -22,7 +22,8 @@ same place. Structure it by what people do, not by how the backend is split.
|
|
|
22
22
|
tooltip), so start sibling labels differently («Продажи» and «Проекты» both read «Про»).
|
|
23
23
|
- **Fold only what is secondary.** Make a group `collapsible` when the list is long (about 12+
|
|
24
24
|
items) or the group is used rarely; keep the main group open and fixed. `defaultOpen={false}`
|
|
25
|
-
only for rarely used groups — a group with the current page opens by itself
|
|
25
|
+
only for rarely used groups — a group with the current page opens by itself (on the compact rail
|
|
26
|
+
it stays folded; its `…` row marks the page).
|
|
26
27
|
- **One level of nesting.** `Sidebar.Sub` is one section with 2–6 views of the same objects
|
|
27
28
|
(Сделки → Новые · В работе · Закрытые). The parent only discloses; an overview page is the first
|
|
28
29
|
child («Все сделки»). Never a sub-list inside a sub-list — split the section or use page tabs.
|
|
@@ -128,7 +129,7 @@ useSidebar() state hook for custom parts inside Root
|
|
|
128
129
|
| `…rest` | `HTMLAttributes<HTMLElement>` | — | `children` (Groups, Items, Subs), `className` and the other attributes. |
|
|
129
130
|
|
|
130
131
|
### Sidebar.Group
|
|
131
|
-
`ref` → `HTMLDivElement`. `<div role="group">` named by its label. With `collapsible` the heading is a disclosure button (`aria-expanded`, `aria-controls`) with a chevron at its end; the items fold away (inert). On the compact rail the heading keeps its height and layout: its text slides toward the edge, scales down and is cut by the rail with a fade, so the first letters still name the section. An open group keeps its items on the rail; a folded one stays folded and becomes one `…` row (named by the label, `aria-haspopup="dialog"`) whose items open in a flyout, like a sub-list. A folded group with a count that needs attention inside shows its dot (after the heading, or on the `…` row).
|
|
132
|
+
`ref` → `HTMLDivElement`. `<div role="group">` named by its label. With `collapsible` the heading is a disclosure button (`aria-expanded`, `aria-controls`) with a chevron at its end; the items fold away (inert). On the compact rail the heading keeps its height and layout: its text slides toward the edge, scales down and is cut by the rail with a fade, so the first letters still name the section, and it still folds and unfolds the group. An open group keeps its items on the rail; a folded one stays folded and becomes one `…` row (named by the label, `aria-haspopup="dialog"`) whose items open in a flyout, like a sub-list. A folded group with a count that needs attention inside shows its dot (after the heading, or on the `…` row).
|
|
132
133
|
|
|
133
134
|
| Prop | Type | Default | Description |
|
|
134
135
|
|---|---|---|---|
|
|
@@ -136,7 +137,7 @@ useSidebar() state hook for custom parts inside Root
|
|
|
136
137
|
| `collapsible` | `boolean` | `false` | The heading shows and hides the items. Needs `label`. |
|
|
137
138
|
| `open` | `boolean` | — | Items shown (controlled). |
|
|
138
139
|
| `onOpenChange` | `(open: boolean) => void` | — | Called with the new open state (click, keyboard, a current page moving inside). |
|
|
139
|
-
| `defaultOpen` | `boolean` | `true` | Initial state (uncontrolled).
|
|
140
|
+
| `defaultOpen` | `boolean` | `true` | Initial state (uncontrolled). Off the compact rail a closed group opens by itself when the current page moves into it; on the rail it stays folded and its `…` row marks the page. |
|
|
140
141
|
| `…rest` | `Omit<HTMLAttributes<HTMLDivElement>, "role">` | — | `children` (Items, Subs), `className` and the other div attributes. |
|
|
141
142
|
|
|
142
143
|
### Sidebar.Item
|
|
@@ -178,7 +179,7 @@ useSidebar() state hook for custom parts inside Root
|
|
|
178
179
|
| `…rest` | `Omit<HTMLAttributes<HTMLSpanElement>, "children">` | — | `className` and the other span attributes. |
|
|
179
180
|
|
|
180
181
|
### Sidebar.ItemAction
|
|
181
|
-
`ref` → `HTMLButtonElement`. A row action (create, add): a ghost icon `Button` one tier down with a tooltip, next to the item element — never inside it. It shows on hover and focus of the row while the trail (count, hint) steps aside; hidden on the compact rail.
|
|
182
|
+
`ref` → `HTMLButtonElement`. A row action (create, add): a ghost icon `Button` one tier down with a tooltip, next to the item element — never inside it. It shows on hover and focus of the row, always on touch screens, while the trail (count, hint) steps aside; hidden on the compact rail.
|
|
182
183
|
|
|
183
184
|
| Prop | Type | Default | Description |
|
|
184
185
|
|---|---|---|---|
|
|
@@ -242,7 +243,7 @@ Hook for custom parts inside `Sidebar.Root` (throws outside). Returns the fields
|
|
|
242
243
|
| `size · navId · labels` | `ControlSize · string · SidebarLabels` | — | Tier, id of the `<nav>` (for `aria-controls` on your own menu button), resolved strings. |
|
|
243
244
|
|
|
244
245
|
## Variants
|
|
245
|
-
The rail
|
|
246
|
+
The rail is a surface beside the page, one layer above it on the surface ladder (`data-depth`): white on the light gray page, one step lighter than the near-black page in dark; no border or card. Items are transparent rows with `text-secondary`, `fill-subtle` on hover; the current item takes the rail's fill two ladder steps off it (`fill-muted-hover`) with primary text.
|
|
246
247
|
|
|
247
248
|
### mode (Root)
|
|
248
249
|
| Value | Looks like | Use when | Default |
|
|
@@ -289,7 +290,7 @@ The rail width does not depend on `size`.
|
|
|
289
290
|
| `current` (Item) | surface fill + raised shadow, primary text and icon | the current page | off |
|
|
290
291
|
| `disabled` (Item) | `text-disabled`, no hover, `cursor: not-allowed` | an unavailable section | off |
|
|
291
292
|
|
|
292
|
-
Put `<Sidebar.Toggle variant="header" />` next to `Sidebar.Brand` in the header, or `Sidebar.Toggle` in the footer for a rail without a brand; on phones (`offCanvas="auto"`) or always (`offCanvas="always"`) pair it with
|
|
293
|
+
Put `<Sidebar.Toggle variant="header" />` next to `Sidebar.Brand` in the header, or `Sidebar.Toggle` in the footer for a rail without a brand; on phones (`offCanvas="auto"`) or always (`offCanvas="always"`) pair it with `AppHeader.MenuButton` (`open` / `onOpenChange`). One current item at a time; give every top-level item an icon when the rail can go compact (child items need none).
|
|
293
294
|
|
|
294
295
|
## States
|
|
295
296
|
| State | Driven by | DOM |
|
|
@@ -297,7 +298,7 @@ Put `<Sidebar.Toggle variant="header" />` next to `Sidebar.Brand` in the header,
|
|
|
297
298
|
| mode | `mode` / `defaultMode` | Root `data-mode`, `data-panel-mode` (the last visible mode while hidden); `<nav inert>` while hidden |
|
|
298
299
|
| off-canvas | `offCanvas="always"`, or `"auto"` + viewport < 768px | Root `data-off-canvas`, `data-state="open" \| "closed"`; `<nav inert>` while closed |
|
|
299
300
|
| current | `current` or a router's `aria-current` | Item `aria-current="page"`, `data-state="active"` |
|
|
300
|
-
| active path | a child of a Sub (or an item of a Group) is current | SubTrigger `data-active-path`; a closed Sub
|
|
301
|
+
| active path | a child of a Sub (or an item of a Group) is current | SubTrigger (or the `…` row of a folded Group) `data-active-path`; a closed Sub opens, a closed Group opens off the compact rail |
|
|
301
302
|
| group open | Group `open` / `defaultOpen` (`collapsible`) | heading `aria-expanded`; region `data-state`, `inert` while closed |
|
|
302
303
|
| sub open | Sub `open` / `defaultOpen` | SubTrigger `aria-expanded`; SubContent `data-state`, `inert` while closed |
|
|
303
304
|
| flyout | hover / click / keyboard on a SubTrigger, or on the `…` row of a folded group, in compact mode | the row `aria-haspopup="dialog"`, `aria-expanded`; a Popover `role="dialog"` |
|
|
@@ -310,18 +311,18 @@ Leaving the narrow viewport closes the off-canvas panel; navigating from an `hre
|
|
|
310
311
|
## Layout & spacing
|
|
311
312
|
- Panel padding: `--prime-space-3` block, `--prime-space-2` inline; regions 8 apart; groups 16 apart, items 4 apart.
|
|
312
313
|
- Item horizontal padding is derived from the compact width so icons and the brand logo sit on one axis in every mode (the account avatar joins that axis on the rail).
|
|
313
|
-
- Header is one row of the item height + 8. The header toggle (xs, 28) sits at its end, 8 from the rail edge; in compact mode it moves half past the edge, scales to 3/4, turns round and gets a
|
|
314
|
+
- Header is one row of the item height + 8. The header toggle (xs, 28) sits at its end, 8 from the rail edge; in compact mode it moves half past the edge, scales to 3/4, turns round and gets a ring in the rail color. The root clips with `clip-path`, reaching past the edge by the toggle's half-width and ring beside the header only; everywhere else the panel ends exactly at the spacer edge.
|
|
314
315
|
- Collapsible group: heading 28 high with the chevron (14) at its end, aligned with the item trail; items start 4 below. A folded group's attention dot sits before the chevron.
|
|
315
|
-
- On the rail a heading keeps its 28 and its layout: the text slides 8 toward the edge, scales to 0.85 and is cut at the rail box with a 12 fade into the
|
|
316
|
+
- On the rail a heading keeps its 28 and its layout: the text slides 8 toward the edge, scales to 0.85 and is cut at the rail box with a 12 fade into the rail. A folded group adds one `…` row under its heading. The items and the row share one place: folding or unfolding on the rail glides the group's height one way (list ↔ row) while the two cross-fade, so the rows below never move back.
|
|
316
317
|
- Sub-list: a 1px `border-default` guide line on the parent icon's centre; every child branches off it with an 8 elbow and a 6 bend; child labels line up with the parent label.
|
|
317
|
-
- Trail (count, key hint, trailing icon) sits at the row end; a row action (one tier down) appears there on hover / focus and the trail moves aside.
|
|
318
|
+
- Trail (count, key hint, trailing icon) sits at the row end; a row action (one tier down) appears there on hover / focus (always on touch screens) and the trail moves aside.
|
|
318
319
|
- Footer: items 4 apart; the account is set 8 apart below them. It is its own card-like row: the
|
|
319
320
|
avatar of the tier (xs 20, s 24, m·l 32, xl 40) sits in an even frame — the inset before it, the
|
|
320
321
|
gap to the text and the air above and below are one value, the tier gap (xs 4, s·m·l 8, xl 12),
|
|
321
322
|
so the row is the avatar + 2 × gap high (48 at m). On the compact rail the start inset becomes the
|
|
322
323
|
one that centres the avatar on the icon axis, as part of the rail motion.
|
|
323
324
|
- Compact flyout: the kit Popover (flush) to the right, aligned with the parent row, with the metrics of a kit menu — rows of the tier's menu item height (32 at m), the panel padding, no title (the row names it), no guide line; current child is a `fill-subtle-active` wash.
|
|
324
|
-
- Motion: two layers on one clock. `Sidebar.Root` is the spacer: it reserves the rail width in the page, paints the
|
|
325
|
+
- Motion: two layers on one clock. `Sidebar.Root` is the spacer: it reserves the rail width in the page, paints the rail and clips the panel to its own box; its width is the only layout that moves (the page column follows). The `<nav>` panel inside is positioned at the expanded width in every mode and never lays out again, so nothing re-wraps and nothing switches at the end. Every part is a plain CSS transition over `base` with the `standard` (ease-in-out) easing, started by the same mode change and ending with the rail: text fades through its fill colour (paint-only, no compositor layer per label), chevrons through their stroke, trailing boxes (a coloured count, a key hint) through `opacity`; coloured counts turn into dots; the account avatar slides onto the icon axis; the header toggle rides the edge by `translate` / `scale`. Rows stay full width: a row with a fill or a ring (current, on the active path, hovered, open, focused) draws them on a pseudo-element whose end edge travels to the icon box and clips its content there, so it always ends rail padding before the moving edge and is a rounded square around the icon at rest. Group headings keep their height and layout: their text slides toward the edge and scales down by transform while the moving cut ends it with a fade; the text box narrows only once the rail has closed (under the cut, never seen), so the dot and the chevron after it stay in place and fade. The `…` row of a folded group grows in and out on the same clock (grid track height), as do the attention dots (opacity and scale). Hidden keeps the look of the last visible mode and is clipped as one piece; the header toggle stays at its place and fades, and coming back from hidden it fades in at its final place. Collapsible groups that open for the rail and sub-lists that close for it move on the same clock (grid track height); chevrons rotate (base). All durations are tokens: under reduced motion every mode change is instant.
|
|
325
326
|
- Layers of a row on the rail (compact tooltips, the sub-list flyout, a `Dropdown` around `Sidebar.Account`) anchor to the visible part of the row — the icon box — not to its full-width box. The brand has no compact tooltip: the logo speaks for itself and a tooltip would cover the edge toggle.
|
|
326
327
|
- Off-canvas panel width: min(sidebar width, 100% − `--prime-space-12`).
|
|
327
328
|
- Inside `AppShell.Nav` the rail takes the full height. The root is `height: 100%` and the panel is
|
|
@@ -344,7 +345,7 @@ Leaving the narrow viewport closes the off-canvas panel; navigating from an `hre
|
|
|
344
345
|
- The current item has `aria-current="page"`; in compact mode the label shows as a tooltip, so icon-only items keep a visible name.
|
|
345
346
|
- A collapsible group heading and a SubTrigger are buttons with `aria-expanded` and `aria-controls`; folded content is `inert`.
|
|
346
347
|
- On the compact rail a SubTrigger and the `…` row of a folded group have `aria-haspopup="dialog"`; the flyout is a non-modal dialog named by the parent (the `…` row by the group label).
|
|
347
|
-
- On the rail a group heading
|
|
348
|
+
- On the rail a collapsible group heading stays the same disclosure button (folding it there brings the `…` row); hovering it shows the whole name in a tooltip.
|
|
348
349
|
- An attention dot is decorative: the count it stands for is read inside.
|
|
349
350
|
- A row action is its own button next to the item (never nested), named by `label` with a tooltip.
|
|
350
351
|
- The account avatar is hidden from screen readers; the name and the muted line name the button.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* Layout for the Sidebar examples: small "app windows" (
|
|
1
|
+
/* Layout for the Sidebar examples: small "app windows" (the page with a rail one layer above it). Semantic tokens only. */
|
|
2
2
|
|
|
3
3
|
.stage {
|
|
4
4
|
box-sizing: border-box;
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
height: calc(var(--prime-space-24) * 4);
|
|
8
8
|
overflow: hidden;
|
|
9
9
|
border-radius: var(--prime-card-radius);
|
|
10
|
-
background: var(--prime-color-
|
|
11
|
-
/* The
|
|
10
|
+
background: var(--prime-color-layer-current);
|
|
11
|
+
/* The window is a page on the preview's page: a hairline keeps its edge visible. */
|
|
12
12
|
box-shadow:
|
|
13
13
|
0 0 0 var(--prime-border-width) var(--prime-color-border-subtle),
|
|
14
14
|
var(--prime-shadow-raised);
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
height: calc(var(--prime-space-24) * 2);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/* Content plane next to the rail, like AppShell:
|
|
27
|
+
/* Content plane next to the rail, like AppShell: the page itself, edge to edge. */
|
|
28
28
|
.content {
|
|
29
29
|
box-sizing: border-box;
|
|
30
30
|
flex: 1 1 auto;
|
|
31
31
|
min-width: 0;
|
|
32
32
|
padding: var(--prime-space-4);
|
|
33
|
-
background: var(--prime-color-
|
|
33
|
+
background: var(--prime-color-layer-current);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/* The product mark inside `Sidebar.BrandLogo`: an accent tile with a glyph. */
|
package/src/styles/globals.css
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
:root {
|
|
9
9
|
font-family: var(--prime-font-family-sans);
|
|
10
10
|
color: var(--prime-color-text-primary);
|
|
11
|
-
background: var(--prime-color-bg
|
|
11
|
+
background: var(--prime-color-layer-0-bg);
|
|
12
12
|
text-rendering: optimizeLegibility;
|
|
13
13
|
font-kerning: normal;
|
|
14
14
|
font-feature-settings: "cv11", "ss01";
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
body {
|
|
26
|
-
background: var(--prime-color-bg
|
|
26
|
+
background: var(--prime-color-layer-0-bg);
|
|
27
27
|
color: var(--prime-color-text-primary);
|
|
28
28
|
font-size: var(--prime-text-body-m-size);
|
|
29
29
|
line-height: var(--prime-text-body-m-line-height);
|
|
@@ -88,6 +88,129 @@ input::-moz-focus-inner {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
/*
|
|
92
|
+
* Surface depth (foundation §4). The page (and the AppShell panel) is layer 0; every surface (Card,
|
|
93
|
+
* Sidebar, Accordion, DataTable…) sets `data-depth` one above the surface around it, floating layers set
|
|
94
|
+
* `floating`. Each depth points the context variables at its row of `--prime-color-layer-*`:
|
|
95
|
+
* layer-current the surface's own fill layer-nested a surface placed on it
|
|
96
|
+
* field-bg(-hover/-focus), fill-muted(-hover) controls on it: one step from the surface
|
|
97
|
+
* control-selected the selected thumb on a track of it
|
|
98
|
+
* layer-shadow a whisper only on a card that sits on the page
|
|
99
|
+
* A theme island (`data-theme`) starts again at layer 0.
|
|
100
|
+
*/
|
|
101
|
+
:root,
|
|
102
|
+
[data-theme],
|
|
103
|
+
[data-depth="0"] {
|
|
104
|
+
--prime-color-layer-current: var(--prime-color-layer-0-bg);
|
|
105
|
+
--prime-color-layer-nested: var(--prime-color-layer-1-bg);
|
|
106
|
+
--prime-color-field-bg: var(--prime-color-layer-0-fill);
|
|
107
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-0-fill-hover);
|
|
108
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-0-bg);
|
|
109
|
+
--prime-color-fill-muted: var(--prime-color-layer-0-fill);
|
|
110
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-0-fill-hover);
|
|
111
|
+
--prime-color-control-selected: var(--prime-color-layer-0-selected);
|
|
112
|
+
--prime-layer-shadow: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
[data-depth="1"] {
|
|
116
|
+
--prime-color-layer-current: var(--prime-color-layer-1-bg);
|
|
117
|
+
--prime-color-layer-nested: var(--prime-color-layer-2-bg);
|
|
118
|
+
--prime-color-field-bg: var(--prime-color-layer-1-fill);
|
|
119
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-1-fill-hover);
|
|
120
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-1-bg);
|
|
121
|
+
--prime-color-fill-muted: var(--prime-color-layer-1-fill);
|
|
122
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-1-fill-hover);
|
|
123
|
+
--prime-color-control-selected: var(--prime-color-layer-1-selected);
|
|
124
|
+
--prime-layer-shadow: var(--prime-shadow-raised);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
[data-depth="2"] {
|
|
128
|
+
--prime-color-layer-current: var(--prime-color-layer-2-bg);
|
|
129
|
+
--prime-color-layer-nested: var(--prime-color-layer-3-bg);
|
|
130
|
+
--prime-color-field-bg: var(--prime-color-layer-2-fill);
|
|
131
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-2-fill-hover);
|
|
132
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-2-bg);
|
|
133
|
+
--prime-color-fill-muted: var(--prime-color-layer-2-fill);
|
|
134
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-2-fill-hover);
|
|
135
|
+
--prime-color-control-selected: var(--prime-color-layer-2-selected);
|
|
136
|
+
--prime-layer-shadow: none;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
[data-depth="3"] {
|
|
140
|
+
--prime-color-layer-current: var(--prime-color-layer-3-bg);
|
|
141
|
+
--prime-color-layer-nested: var(--prime-color-layer-4-bg);
|
|
142
|
+
--prime-color-field-bg: var(--prime-color-layer-3-fill);
|
|
143
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-3-fill-hover);
|
|
144
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-3-bg);
|
|
145
|
+
--prime-color-fill-muted: var(--prime-color-layer-3-fill);
|
|
146
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-3-fill-hover);
|
|
147
|
+
--prime-color-control-selected: var(--prime-color-layer-3-selected);
|
|
148
|
+
--prime-layer-shadow: none;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* The deepest layer: a surface nested in it keeps its color (deeper nesting is not supported). */
|
|
152
|
+
[data-depth="4"] {
|
|
153
|
+
--prime-color-layer-current: var(--prime-color-layer-4-bg);
|
|
154
|
+
--prime-color-layer-nested: var(--prime-color-layer-4-bg);
|
|
155
|
+
--prime-color-field-bg: var(--prime-color-layer-4-fill);
|
|
156
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-4-fill-hover);
|
|
157
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-4-bg);
|
|
158
|
+
--prime-color-fill-muted: var(--prime-color-layer-4-fill);
|
|
159
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-4-fill-hover);
|
|
160
|
+
--prime-color-control-selected: var(--prime-color-layer-4-selected);
|
|
161
|
+
--prime-layer-shadow: none;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Floating layers (menus, popovers, modals, drawers): one step above a card, depth comes from the
|
|
165
|
+
shadow; two layers can nest inside. */
|
|
166
|
+
[data-depth="floating"] {
|
|
167
|
+
--prime-color-layer-current: var(--prime-color-layer-floating-bg);
|
|
168
|
+
--prime-color-layer-nested: var(--prime-color-layer-floating1-bg);
|
|
169
|
+
--prime-color-field-bg: var(--prime-color-layer-floating-fill);
|
|
170
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-floating-fill-hover);
|
|
171
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-floating-bg);
|
|
172
|
+
--prime-color-fill-muted: var(--prime-color-layer-floating-fill);
|
|
173
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-floating-fill-hover);
|
|
174
|
+
--prime-color-control-selected: var(--prime-color-layer-floating-selected);
|
|
175
|
+
--prime-layer-shadow: none;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
[data-depth="floating-1"] {
|
|
179
|
+
--prime-color-layer-current: var(--prime-color-layer-floating1-bg);
|
|
180
|
+
--prime-color-layer-nested: var(--prime-color-layer-floating2-bg);
|
|
181
|
+
--prime-color-field-bg: var(--prime-color-layer-floating1-fill);
|
|
182
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-floating1-fill-hover);
|
|
183
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-floating1-bg);
|
|
184
|
+
--prime-color-fill-muted: var(--prime-color-layer-floating1-fill);
|
|
185
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-floating1-fill-hover);
|
|
186
|
+
--prime-color-control-selected: var(--prime-color-layer-floating1-selected);
|
|
187
|
+
--prime-layer-shadow: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
[data-depth="floating-2"] {
|
|
191
|
+
--prime-color-layer-current: var(--prime-color-layer-floating2-bg);
|
|
192
|
+
--prime-color-layer-nested: var(--prime-color-layer-floating2-bg);
|
|
193
|
+
--prime-color-field-bg: var(--prime-color-layer-floating2-fill);
|
|
194
|
+
--prime-color-field-bg-hover: var(--prime-color-layer-floating2-fill-hover);
|
|
195
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-floating2-bg);
|
|
196
|
+
--prime-color-fill-muted: var(--prime-color-layer-floating2-fill);
|
|
197
|
+
--prime-color-fill-muted-hover: var(--prime-color-layer-floating2-fill-hover);
|
|
198
|
+
--prime-color-control-selected: var(--prime-color-layer-floating2-selected);
|
|
199
|
+
--prime-layer-shadow: none;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* A host off the ladder (a tinted banner, an accent wash, an image): its own fill stays, controls
|
|
203
|
+
on it take translucent washes, which read on any color. */
|
|
204
|
+
[data-depth="tinted"] {
|
|
205
|
+
--prime-color-field-bg: var(--prime-color-fill-subtle-active);
|
|
206
|
+
--prime-color-field-bg-hover: var(--prime-color-fill-strong);
|
|
207
|
+
--prime-color-field-bg-focus: var(--prime-color-layer-floating-bg);
|
|
208
|
+
--prime-color-fill-muted: var(--prime-color-fill-subtle-active);
|
|
209
|
+
--prime-color-fill-muted-hover: var(--prime-color-fill-strong);
|
|
210
|
+
--prime-color-control-selected: var(--prime-color-layer-floating-bg);
|
|
211
|
+
--prime-layer-shadow: none;
|
|
212
|
+
}
|
|
213
|
+
|
|
91
214
|
/* Theme switches are instant: a running color transition would start from the old theme and blink. */
|
|
92
215
|
[data-theme-switching],
|
|
93
216
|
[data-theme-switching] *,
|