@arbor-education/design-system.components 0.23.2 → 0.24.1
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/CHANGELOG.md +12 -0
- package/CONTRIBUTING.md +24 -22
- package/dist/components/sidebarNav/SidebarNav.d.ts +46 -0
- package/dist/components/sidebarNav/SidebarNav.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNav.js +102 -0
- package/dist/components/sidebarNav/SidebarNav.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNav.stories.d.ts +61 -0
- package/dist/components/sidebarNav/SidebarNav.stories.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNav.stories.js +253 -0
- package/dist/components/sidebarNav/SidebarNav.stories.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNav.test.d.ts +2 -0
- package/dist/components/sidebarNav/SidebarNav.test.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNav.test.js +240 -0
- package/dist/components/sidebarNav/SidebarNav.test.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavContext.d.ts +13 -0
- package/dist/components/sidebarNav/SidebarNavContext.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavContext.js +15 -0
- package/dist/components/sidebarNav/SidebarNavContext.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavGroup.d.ts +10 -0
- package/dist/components/sidebarNav/SidebarNavGroup.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavGroup.js +16 -0
- package/dist/components/sidebarNav/SidebarNavGroup.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavItem.d.ts +32 -0
- package/dist/components/sidebarNav/SidebarNavItem.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavItem.js +43 -0
- package/dist/components/sidebarNav/SidebarNavItem.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavItemFavourite.d.ts +8 -0
- package/dist/components/sidebarNav/SidebarNavItemFavourite.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavItemFavourite.js +14 -0
- package/dist/components/sidebarNav/SidebarNavItemFavourite.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavPanel.d.ts +4 -0
- package/dist/components/sidebarNav/SidebarNavPanel.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavPanel.js +9 -0
- package/dist/components/sidebarNav/SidebarNavPanel.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavPanelNav.d.ts +10 -0
- package/dist/components/sidebarNav/SidebarNavPanelNav.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavPanelNav.js +21 -0
- package/dist/components/sidebarNav/SidebarNavPanelNav.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRail.d.ts +6 -0
- package/dist/components/sidebarNav/SidebarNavRail.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRail.js +7 -0
- package/dist/components/sidebarNav/SidebarNavRail.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRailItem.d.ts +10 -0
- package/dist/components/sidebarNav/SidebarNavRailItem.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRailItem.js +24 -0
- package/dist/components/sidebarNav/SidebarNavRailItem.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRailList.d.ts +4 -0
- package/dist/components/sidebarNav/SidebarNavRailList.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRailList.js +7 -0
- package/dist/components/sidebarNav/SidebarNavRailList.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRailSlot.d.ts +6 -0
- package/dist/components/sidebarNav/SidebarNavRailSlot.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavRailSlot.js +7 -0
- package/dist/components/sidebarNav/SidebarNavRailSlot.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavSeparator.d.ts +6 -0
- package/dist/components/sidebarNav/SidebarNavSeparator.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavSeparator.js +8 -0
- package/dist/components/sidebarNav/SidebarNavSeparator.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavTitle.d.ts +4 -0
- package/dist/components/sidebarNav/SidebarNavTitle.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavTitle.js +7 -0
- package/dist/components/sidebarNav/SidebarNavTitle.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavTooltip.d.ts +7 -0
- package/dist/components/sidebarNav/SidebarNavTooltip.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavTooltip.js +9 -0
- package/dist/components/sidebarNav/SidebarNavTooltip.js.map +1 -0
- package/dist/components/sidebarNav/SidebarNavTrigger.d.ts +8 -0
- package/dist/components/sidebarNav/SidebarNavTrigger.d.ts.map +1 -0
- package/dist/components/sidebarNav/SidebarNavTrigger.js +15 -0
- package/dist/components/sidebarNav/SidebarNavTrigger.js.map +1 -0
- package/dist/components/sidebarNav/index.d.ts +4 -0
- package/dist/components/sidebarNav/index.d.ts.map +1 -0
- package/dist/components/sidebarNav/index.js +3 -0
- package/dist/components/sidebarNav/index.js.map +1 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.d.ts +4 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.d.ts.map +1 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.js +43 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.js.map +1 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.test.d.ts +2 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.test.d.ts.map +1 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.test.js +52 -0
- package/dist/components/sidebarNav/resolvePanelItemProps.test.js.map +1 -0
- package/dist/components/sidebarNav/types.d.ts +100 -0
- package/dist/components/sidebarNav/types.d.ts.map +1 -0
- package/dist/components/sidebarNav/types.js +4 -0
- package/dist/components/sidebarNav/types.js.map +1 -0
- package/dist/components/sidebarNav/useControllableBoolean.d.ts +9 -0
- package/dist/components/sidebarNav/useControllableBoolean.d.ts.map +1 -0
- package/dist/components/sidebarNav/useControllableBoolean.js +14 -0
- package/dist/components/sidebarNav/useControllableBoolean.js.map +1 -0
- package/dist/index.css +275 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/sidebarNav/SidebarNav.stories.tsx +484 -0
- package/src/components/sidebarNav/SidebarNav.test.tsx +611 -0
- package/src/components/sidebarNav/SidebarNav.tsx +230 -0
- package/src/components/sidebarNav/SidebarNavContext.tsx +28 -0
- package/src/components/sidebarNav/SidebarNavGroup.tsx +59 -0
- package/src/components/sidebarNav/SidebarNavItem.tsx +160 -0
- package/src/components/sidebarNav/SidebarNavItemFavourite.tsx +49 -0
- package/src/components/sidebarNav/SidebarNavPanel.tsx +20 -0
- package/src/components/sidebarNav/SidebarNavPanelNav.tsx +55 -0
- package/src/components/sidebarNav/SidebarNavRail.tsx +20 -0
- package/src/components/sidebarNav/SidebarNavRailItem.tsx +84 -0
- package/src/components/sidebarNav/SidebarNavRailList.tsx +11 -0
- package/src/components/sidebarNav/SidebarNavRailSlot.tsx +15 -0
- package/src/components/sidebarNav/SidebarNavSeparator.tsx +19 -0
- package/src/components/sidebarNav/SidebarNavTitle.tsx +13 -0
- package/src/components/sidebarNav/SidebarNavTooltip.tsx +24 -0
- package/src/components/sidebarNav/SidebarNavTrigger.tsx +52 -0
- package/src/components/sidebarNav/index.ts +6 -0
- package/src/components/sidebarNav/resolvePanelItemProps.test.ts +57 -0
- package/src/components/sidebarNav/resolvePanelItemProps.ts +50 -0
- package/src/components/sidebarNav/sidebarNav.scss +283 -0
- package/src/components/sidebarNav/types.ts +126 -0
- package/src/components/sidebarNav/useControllableBoolean.ts +20 -0
- package/src/docs/Contributing.mdx +7 -0
- package/src/index.scss +1 -0
- package/src/index.ts +12 -0
- package/src/tokens.scss +14 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { IconName } from 'Components/icon/allowedIcons';
|
|
2
|
+
import type { Icon } from 'Components/icon/Icon';
|
|
3
|
+
import type { AnchorHTMLAttributes } from 'react';
|
|
4
|
+
|
|
5
|
+
export type SidebarNavLinkProps = Omit<
|
|
6
|
+
AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
7
|
+
'href' | 'children' | 'className'
|
|
8
|
+
> & Record<`data-${string}`, string | number | boolean | undefined>;
|
|
9
|
+
|
|
10
|
+
export type SidebarNavRenderLinkArgs = {
|
|
11
|
+
href: string;
|
|
12
|
+
className: string;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
ariaCurrent?: 'page';
|
|
15
|
+
ariaLabel?: string;
|
|
16
|
+
onClick?: React.MouseEventHandler;
|
|
17
|
+
linkProps?: SidebarNavLinkProps;
|
|
18
|
+
linkElementProps?: Omit<
|
|
19
|
+
AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
20
|
+
'href' | 'className' | 'children'
|
|
21
|
+
>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type SidebarNavItemNodeFavouriteFields
|
|
25
|
+
= | { canFavourite?: false; favouriteTooltip?: never }
|
|
26
|
+
| { canFavourite: true; favouriteTooltip: string };
|
|
27
|
+
|
|
28
|
+
type SidebarNavItemNodeLinkFields = {
|
|
29
|
+
href: string;
|
|
30
|
+
onClick?: React.MouseEventHandler;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type SidebarNavItemNodeButtonFields = {
|
|
34
|
+
href?: never;
|
|
35
|
+
onClick: React.MouseEventHandler;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type SidebarNavItemNode = {
|
|
39
|
+
type: 'item';
|
|
40
|
+
id: string;
|
|
41
|
+
label: string;
|
|
42
|
+
current?: boolean;
|
|
43
|
+
linkProps?: SidebarNavLinkProps;
|
|
44
|
+
isPressed?: boolean;
|
|
45
|
+
onFavouriteClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
46
|
+
} & SidebarNavItemNodeFavouriteFields
|
|
47
|
+
& (SidebarNavItemNodeLinkFields | SidebarNavItemNodeButtonFields);
|
|
48
|
+
|
|
49
|
+
export type SidebarNavGroupNode = {
|
|
50
|
+
type: 'group';
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
children: SidebarNavNode[];
|
|
54
|
+
defaultExpanded?: boolean;
|
|
55
|
+
expanded?: boolean;
|
|
56
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type SidebarNavNode = SidebarNavItemNode | SidebarNavGroupNode;
|
|
60
|
+
|
|
61
|
+
export type SidebarNavRailSeparatorConfig = {
|
|
62
|
+
type: 'separator';
|
|
63
|
+
id: string;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type SidebarNavIconColor = Icon.Props['color'];
|
|
67
|
+
|
|
68
|
+
type SidebarNavRailItemBase = {
|
|
69
|
+
type?: 'item';
|
|
70
|
+
id: string;
|
|
71
|
+
label: string;
|
|
72
|
+
onClick?: React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export type SidebarNavRailItemStandard = SidebarNavRailItemBase & {
|
|
76
|
+
iconName: IconName;
|
|
77
|
+
href?: string;
|
|
78
|
+
current?: boolean;
|
|
79
|
+
badgeContent?: React.ReactNode;
|
|
80
|
+
iconColor?: SidebarNavIconColor;
|
|
81
|
+
renderItem?: never;
|
|
82
|
+
opensPanel?: false;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export type SidebarNavRailItemPanelTrigger = SidebarNavRailItemBase & {
|
|
86
|
+
opensPanel: true;
|
|
87
|
+
iconName: IconName;
|
|
88
|
+
iconColor?: SidebarNavIconColor;
|
|
89
|
+
renderItem?: never;
|
|
90
|
+
href?: never;
|
|
91
|
+
badgeContent?: never;
|
|
92
|
+
current?: never;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export type SidebarNavRailItemCustom = SidebarNavRailItemBase & {
|
|
96
|
+
renderItem: (item: SidebarNavRailItemCustom) => React.ReactNode;
|
|
97
|
+
iconName?: never;
|
|
98
|
+
iconColor?: never;
|
|
99
|
+
href?: never;
|
|
100
|
+
opensPanel?: never;
|
|
101
|
+
badgeContent?: never;
|
|
102
|
+
current?: never;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export type SidebarNavRailItemConfig
|
|
106
|
+
= | SidebarNavRailItemStandard
|
|
107
|
+
| SidebarNavRailItemPanelTrigger
|
|
108
|
+
| SidebarNavRailItemCustom;
|
|
109
|
+
|
|
110
|
+
export type SidebarNavRailEntry = SidebarNavRailItemConfig | SidebarNavRailSeparatorConfig;
|
|
111
|
+
|
|
112
|
+
export function isSidebarNavRailSeparator(
|
|
113
|
+
entry: SidebarNavRailEntry,
|
|
114
|
+
): entry is SidebarNavRailSeparatorConfig {
|
|
115
|
+
return 'type' in entry && entry.type === 'separator';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type SidebarNavProps = {
|
|
119
|
+
expanded?: boolean;
|
|
120
|
+
defaultExpanded?: boolean;
|
|
121
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
122
|
+
renderLink?: (args: SidebarNavRenderLinkArgs) => React.ReactElement;
|
|
123
|
+
railItems?: SidebarNavRailEntry[];
|
|
124
|
+
panelTitle?: string;
|
|
125
|
+
panelNavItems?: SidebarNavNode[];
|
|
126
|
+
} & React.HTMLAttributes<HTMLDivElement>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export function useControllableBoolean(args: {
|
|
4
|
+
value?: boolean;
|
|
5
|
+
defaultValue: boolean;
|
|
6
|
+
onChange?: (next: boolean) => void;
|
|
7
|
+
}) {
|
|
8
|
+
const { value, defaultValue, onChange } = args;
|
|
9
|
+
const [uncontrolled, setUncontrolled] = useState(defaultValue);
|
|
10
|
+
const isControlled = typeof value === 'boolean';
|
|
11
|
+
|
|
12
|
+
const current = isControlled ? (value as boolean) : uncontrolled;
|
|
13
|
+
|
|
14
|
+
const set = useCallback((next: boolean) => {
|
|
15
|
+
if (!isControlled) setUncontrolled(next);
|
|
16
|
+
onChange?.(next);
|
|
17
|
+
}, [isControlled, onChange]);
|
|
18
|
+
|
|
19
|
+
return useMemo(() => ({ value: current, set }), [current, set]);
|
|
20
|
+
}
|
|
@@ -205,6 +205,13 @@ Never push directly to `main` — all work goes through a branch and PR.
|
|
|
205
205
|
- **Under 400 lines** of meaningful code change — if it's bigger, split it.
|
|
206
206
|
- **Fill in the PR template** — every section, no placeholders.
|
|
207
207
|
|
|
208
|
+
### Changesets
|
|
209
|
+
|
|
210
|
+
- **Every PR requires a changeset.** These should be generated by running `yarn changeset`, which takes you through a prompt to specify the change level and to give a brief description of your change
|
|
211
|
+
- **Do not let an AI create a changeset file for you.** AI Agents have a propensity to directly write their own changeset files, which often hallucinate the structure of the files, or the name of the changeset project, which can result in stray changeset files not being added to the changelog on releases. Generate **all** changeset files via `yarn changeset`.
|
|
212
|
+
- **Do not use backticks or quotes in your changeset description** - these break the release automation
|
|
213
|
+
- Until we are on v1.0.0 as our first wide release, we are not using proper semver. For the time being, use minor version bumps for breaking changes and patch for all other changes, including new functionality.
|
|
214
|
+
|
|
208
215
|
For the full details and the reasoning behind these rules, see [CONTRIBUTING.md](https://github.com/arbor-education/design-system.components/blob/main/CONTRIBUTING.md) on GitHub.
|
|
209
216
|
|
|
210
217
|
---
|
package/src/index.scss
CHANGED
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
@use "components/toggle/toggle.scss";
|
|
56
56
|
@use "components/dataViewCard/dataViewCard.scss";
|
|
57
57
|
@use "components/treeRow/treeRow.scss";
|
|
58
|
+
@use "components/sidebarNav/sidebarNav.scss";
|
|
58
59
|
|
|
59
60
|
// stylelint-disable-next-line at-rule-disallowed-list -- plain CSS import (font face), exempt from Sass @import deprecation
|
|
60
61
|
@import "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap";
|
package/src/index.ts
CHANGED
|
@@ -46,6 +46,18 @@ export { Row } from 'Components/row/Row';
|
|
|
46
46
|
export { SearchBar } from 'Components/searchBar/SearchBar';
|
|
47
47
|
export { Section } from 'Components/section/Section';
|
|
48
48
|
export { Separator } from 'Components/separator/Separator';
|
|
49
|
+
export { SidebarNav } from 'Components/sidebarNav/SidebarNav';
|
|
50
|
+
export type {
|
|
51
|
+
SidebarNavProps,
|
|
52
|
+
SidebarNavNode,
|
|
53
|
+
SidebarNavGroupNode,
|
|
54
|
+
SidebarNavItemNode,
|
|
55
|
+
SidebarNavRailItemConfig,
|
|
56
|
+
SidebarNavRailEntry,
|
|
57
|
+
SidebarNavRailSeparatorConfig,
|
|
58
|
+
SidebarNavRenderLinkArgs,
|
|
59
|
+
} from 'Components/sidebarNav/types';
|
|
60
|
+
export { isSidebarNavRailSeparator } from 'Components/sidebarNav/types';
|
|
49
61
|
export { SingleUser } from 'Components/singleUser/SingleUser';
|
|
50
62
|
export { Slideover } from 'Components/slideover/Slideover';
|
|
51
63
|
export { SlideoverManager } from 'Components/slideoverManager/SlideoverManager';
|
package/src/tokens.scss
CHANGED
|
@@ -966,6 +966,20 @@
|
|
|
966
966
|
--section-subsection-heading-spacing-horizontal: var(--spacing-small);
|
|
967
967
|
--section-subsection-spacing-vertical: var(--spacing-small);
|
|
968
968
|
--sidebar-bg: var(--color-mono-white);
|
|
969
|
+
--sidebar-nav-rail-width: 3.625rem;
|
|
970
|
+
--sidebar-nav-rail-item-size: 2.625rem;
|
|
971
|
+
--sidebar-nav-rail-item-color-icon: var(--color-grey-600);
|
|
972
|
+
--sidebar-nav-rail-item-color-icon-hover: var(--color-grey-900);
|
|
973
|
+
--sidebar-nav-rail-item-color-background-hover: var(--color-grey-050);
|
|
974
|
+
--sidebar-nav-rail-item-color-icon-selected: var(--color-brand-600);
|
|
975
|
+
--sidebar-nav-rail-item-color-background-selected: var(--color-brand-050);
|
|
976
|
+
--sidebar-nav-panel-width: 14.375rem;
|
|
977
|
+
--sidebar-nav-panel-gap: 0.125rem;
|
|
978
|
+
--sidebar-nav-title-min-height: 3.875rem;
|
|
979
|
+
--sidebar-nav-title-padding-block: var(--spacing-xsmall);
|
|
980
|
+
--sidebar-nav-title-padding-inline-end: var(--spacing-large);
|
|
981
|
+
--sidebar-nav-title-padding-inline-start: 1.25rem;
|
|
982
|
+
--sidebar-nav-help-menu-min-width: 17.5rem;
|
|
969
983
|
--tooltip-color-text: var(--color-mono-white);
|
|
970
984
|
--tooltip-color-background: var(--color-grey-900);
|
|
971
985
|
--tooltip-spacing-vertical: var(--spacing-medium);
|