@arbor-education/design-system.components 0.23.1 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/components/sidebarNav/SidebarNav.d.ts +46 -0
  3. package/dist/components/sidebarNav/SidebarNav.d.ts.map +1 -0
  4. package/dist/components/sidebarNav/SidebarNav.js +102 -0
  5. package/dist/components/sidebarNav/SidebarNav.js.map +1 -0
  6. package/dist/components/sidebarNav/SidebarNav.stories.d.ts +61 -0
  7. package/dist/components/sidebarNav/SidebarNav.stories.d.ts.map +1 -0
  8. package/dist/components/sidebarNav/SidebarNav.stories.js +253 -0
  9. package/dist/components/sidebarNav/SidebarNav.stories.js.map +1 -0
  10. package/dist/components/sidebarNav/SidebarNav.test.d.ts +2 -0
  11. package/dist/components/sidebarNav/SidebarNav.test.d.ts.map +1 -0
  12. package/dist/components/sidebarNav/SidebarNav.test.js +240 -0
  13. package/dist/components/sidebarNav/SidebarNav.test.js.map +1 -0
  14. package/dist/components/sidebarNav/SidebarNavContext.d.ts +13 -0
  15. package/dist/components/sidebarNav/SidebarNavContext.d.ts.map +1 -0
  16. package/dist/components/sidebarNav/SidebarNavContext.js +15 -0
  17. package/dist/components/sidebarNav/SidebarNavContext.js.map +1 -0
  18. package/dist/components/sidebarNav/SidebarNavGroup.d.ts +10 -0
  19. package/dist/components/sidebarNav/SidebarNavGroup.d.ts.map +1 -0
  20. package/dist/components/sidebarNav/SidebarNavGroup.js +16 -0
  21. package/dist/components/sidebarNav/SidebarNavGroup.js.map +1 -0
  22. package/dist/components/sidebarNav/SidebarNavItem.d.ts +32 -0
  23. package/dist/components/sidebarNav/SidebarNavItem.d.ts.map +1 -0
  24. package/dist/components/sidebarNav/SidebarNavItem.js +43 -0
  25. package/dist/components/sidebarNav/SidebarNavItem.js.map +1 -0
  26. package/dist/components/sidebarNav/SidebarNavItemFavourite.d.ts +8 -0
  27. package/dist/components/sidebarNav/SidebarNavItemFavourite.d.ts.map +1 -0
  28. package/dist/components/sidebarNav/SidebarNavItemFavourite.js +14 -0
  29. package/dist/components/sidebarNav/SidebarNavItemFavourite.js.map +1 -0
  30. package/dist/components/sidebarNav/SidebarNavPanel.d.ts +4 -0
  31. package/dist/components/sidebarNav/SidebarNavPanel.d.ts.map +1 -0
  32. package/dist/components/sidebarNav/SidebarNavPanel.js +9 -0
  33. package/dist/components/sidebarNav/SidebarNavPanel.js.map +1 -0
  34. package/dist/components/sidebarNav/SidebarNavPanelNav.d.ts +10 -0
  35. package/dist/components/sidebarNav/SidebarNavPanelNav.d.ts.map +1 -0
  36. package/dist/components/sidebarNav/SidebarNavPanelNav.js +21 -0
  37. package/dist/components/sidebarNav/SidebarNavPanelNav.js.map +1 -0
  38. package/dist/components/sidebarNav/SidebarNavRail.d.ts +6 -0
  39. package/dist/components/sidebarNav/SidebarNavRail.d.ts.map +1 -0
  40. package/dist/components/sidebarNav/SidebarNavRail.js +7 -0
  41. package/dist/components/sidebarNav/SidebarNavRail.js.map +1 -0
  42. package/dist/components/sidebarNav/SidebarNavRailItem.d.ts +10 -0
  43. package/dist/components/sidebarNav/SidebarNavRailItem.d.ts.map +1 -0
  44. package/dist/components/sidebarNav/SidebarNavRailItem.js +24 -0
  45. package/dist/components/sidebarNav/SidebarNavRailItem.js.map +1 -0
  46. package/dist/components/sidebarNav/SidebarNavRailList.d.ts +4 -0
  47. package/dist/components/sidebarNav/SidebarNavRailList.d.ts.map +1 -0
  48. package/dist/components/sidebarNav/SidebarNavRailList.js +7 -0
  49. package/dist/components/sidebarNav/SidebarNavRailList.js.map +1 -0
  50. package/dist/components/sidebarNav/SidebarNavRailSlot.d.ts +6 -0
  51. package/dist/components/sidebarNav/SidebarNavRailSlot.d.ts.map +1 -0
  52. package/dist/components/sidebarNav/SidebarNavRailSlot.js +7 -0
  53. package/dist/components/sidebarNav/SidebarNavRailSlot.js.map +1 -0
  54. package/dist/components/sidebarNav/SidebarNavSeparator.d.ts +6 -0
  55. package/dist/components/sidebarNav/SidebarNavSeparator.d.ts.map +1 -0
  56. package/dist/components/sidebarNav/SidebarNavSeparator.js +8 -0
  57. package/dist/components/sidebarNav/SidebarNavSeparator.js.map +1 -0
  58. package/dist/components/sidebarNav/SidebarNavTitle.d.ts +4 -0
  59. package/dist/components/sidebarNav/SidebarNavTitle.d.ts.map +1 -0
  60. package/dist/components/sidebarNav/SidebarNavTitle.js +7 -0
  61. package/dist/components/sidebarNav/SidebarNavTitle.js.map +1 -0
  62. package/dist/components/sidebarNav/SidebarNavTooltip.d.ts +7 -0
  63. package/dist/components/sidebarNav/SidebarNavTooltip.d.ts.map +1 -0
  64. package/dist/components/sidebarNav/SidebarNavTooltip.js +9 -0
  65. package/dist/components/sidebarNav/SidebarNavTooltip.js.map +1 -0
  66. package/dist/components/sidebarNav/SidebarNavTrigger.d.ts +8 -0
  67. package/dist/components/sidebarNav/SidebarNavTrigger.d.ts.map +1 -0
  68. package/dist/components/sidebarNav/SidebarNavTrigger.js +15 -0
  69. package/dist/components/sidebarNav/SidebarNavTrigger.js.map +1 -0
  70. package/dist/components/sidebarNav/index.d.ts +4 -0
  71. package/dist/components/sidebarNav/index.d.ts.map +1 -0
  72. package/dist/components/sidebarNav/index.js +3 -0
  73. package/dist/components/sidebarNav/index.js.map +1 -0
  74. package/dist/components/sidebarNav/resolvePanelItemProps.d.ts +4 -0
  75. package/dist/components/sidebarNav/resolvePanelItemProps.d.ts.map +1 -0
  76. package/dist/components/sidebarNav/resolvePanelItemProps.js +43 -0
  77. package/dist/components/sidebarNav/resolvePanelItemProps.js.map +1 -0
  78. package/dist/components/sidebarNav/resolvePanelItemProps.test.d.ts +2 -0
  79. package/dist/components/sidebarNav/resolvePanelItemProps.test.d.ts.map +1 -0
  80. package/dist/components/sidebarNav/resolvePanelItemProps.test.js +52 -0
  81. package/dist/components/sidebarNav/resolvePanelItemProps.test.js.map +1 -0
  82. package/dist/components/sidebarNav/types.d.ts +100 -0
  83. package/dist/components/sidebarNav/types.d.ts.map +1 -0
  84. package/dist/components/sidebarNav/types.js +4 -0
  85. package/dist/components/sidebarNav/types.js.map +1 -0
  86. package/dist/components/sidebarNav/useControllableBoolean.d.ts +9 -0
  87. package/dist/components/sidebarNav/useControllableBoolean.d.ts.map +1 -0
  88. package/dist/components/sidebarNav/useControllableBoolean.js +14 -0
  89. package/dist/components/sidebarNav/useControllableBoolean.js.map +1 -0
  90. package/dist/index.css +287 -10
  91. package/dist/index.css.map +1 -1
  92. package/dist/index.d.ts +3 -0
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +2 -0
  95. package/dist/index.js.map +1 -1
  96. package/package.json +7 -4
  97. package/src/components/sidebarNav/SidebarNav.stories.tsx +484 -0
  98. package/src/components/sidebarNav/SidebarNav.test.tsx +611 -0
  99. package/src/components/sidebarNav/SidebarNav.tsx +230 -0
  100. package/src/components/sidebarNav/SidebarNavContext.tsx +28 -0
  101. package/src/components/sidebarNav/SidebarNavGroup.tsx +59 -0
  102. package/src/components/sidebarNav/SidebarNavItem.tsx +160 -0
  103. package/src/components/sidebarNav/SidebarNavItemFavourite.tsx +49 -0
  104. package/src/components/sidebarNav/SidebarNavPanel.tsx +20 -0
  105. package/src/components/sidebarNav/SidebarNavPanelNav.tsx +55 -0
  106. package/src/components/sidebarNav/SidebarNavRail.tsx +20 -0
  107. package/src/components/sidebarNav/SidebarNavRailItem.tsx +84 -0
  108. package/src/components/sidebarNav/SidebarNavRailList.tsx +11 -0
  109. package/src/components/sidebarNav/SidebarNavRailSlot.tsx +15 -0
  110. package/src/components/sidebarNav/SidebarNavSeparator.tsx +19 -0
  111. package/src/components/sidebarNav/SidebarNavTitle.tsx +13 -0
  112. package/src/components/sidebarNav/SidebarNavTooltip.tsx +24 -0
  113. package/src/components/sidebarNav/SidebarNavTrigger.tsx +52 -0
  114. package/src/components/sidebarNav/index.ts +6 -0
  115. package/src/components/sidebarNav/resolvePanelItemProps.test.ts +57 -0
  116. package/src/components/sidebarNav/resolvePanelItemProps.ts +50 -0
  117. package/src/components/sidebarNav/sidebarNav.scss +283 -0
  118. package/src/components/sidebarNav/types.ts +126 -0
  119. package/src/components/sidebarNav/useControllableBoolean.ts +20 -0
  120. package/src/index.scss +1 -0
  121. package/src/index.ts +12 -0
  122. 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
+ }
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);