@node-core/ui-components 0.0.1 → 1.0.1-df203d0fe21ee5d80d258c60dc821e8ac0601ce4

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 (186) hide show
  1. package/Common/AlertBox/index.module.css +76 -0
  2. package/Common/AlertBox/index.stories.tsx +73 -0
  3. package/Common/AlertBox/index.tsx +24 -0
  4. package/Common/AvatarGroup/Avatar/index.module.css +40 -0
  5. package/Common/AvatarGroup/Avatar/index.stories.tsx +22 -0
  6. package/Common/AvatarGroup/Avatar/index.tsx +67 -0
  7. package/Common/AvatarGroup/Overlay/index.module.css +31 -0
  8. package/Common/AvatarGroup/Overlay/index.stories.tsx +33 -0
  9. package/Common/AvatarGroup/Overlay/index.tsx +37 -0
  10. package/Common/AvatarGroup/__tests__/index.test.jsx +55 -0
  11. package/Common/AvatarGroup/index.module.css +25 -0
  12. package/Common/AvatarGroup/index.stories.tsx +56 -0
  13. package/Common/AvatarGroup/index.tsx +87 -0
  14. package/Common/Badge/index.module.css +38 -0
  15. package/Common/Badge/index.stories.tsx +38 -0
  16. package/Common/Badge/index.tsx +35 -0
  17. package/Common/BadgeGroup/index.module.css +77 -0
  18. package/Common/BadgeGroup/index.stories.tsx +35 -0
  19. package/Common/BadgeGroup/index.tsx +35 -0
  20. package/Common/Banner/index.module.css +42 -0
  21. package/Common/Banner/index.stories.tsx +29 -0
  22. package/Common/Banner/index.tsx +18 -0
  23. package/Common/BaseActiveLink/__tests__/index.test.jsx +52 -0
  24. package/Common/BaseActiveLink/index.tsx +34 -0
  25. package/Common/BaseButton/index.module.css +142 -0
  26. package/Common/BaseButton/index.stories.tsx +67 -0
  27. package/Common/BaseButton/index.tsx +59 -0
  28. package/Common/BaseCodeBox/index.module.css +84 -0
  29. package/Common/BaseCodeBox/index.stories.tsx +39 -0
  30. package/Common/BaseCodeBox/index.tsx +133 -0
  31. package/Common/BaseCrossLink/index.module.css +51 -0
  32. package/Common/BaseCrossLink/index.stories.tsx +38 -0
  33. package/Common/BaseCrossLink/index.tsx +46 -0
  34. package/Common/BaseLinkTabs/index.module.css +43 -0
  35. package/Common/BaseLinkTabs/index.stories.tsx +34 -0
  36. package/Common/BaseLinkTabs/index.tsx +53 -0
  37. package/Common/BasePagination/Ellipsis/index.module.css +10 -0
  38. package/Common/BasePagination/Ellipsis/index.stories.tsx +10 -0
  39. package/Common/BasePagination/Ellipsis/index.tsx +11 -0
  40. package/Common/BasePagination/PaginationListItem/__tests__/index.test.jsx +58 -0
  41. package/Common/BasePagination/PaginationListItem/index.module.css +27 -0
  42. package/Common/BasePagination/PaginationListItem/index.stories.tsx +40 -0
  43. package/Common/BasePagination/PaginationListItem/index.tsx +39 -0
  44. package/Common/BasePagination/PrevNextArrow.tsx +15 -0
  45. package/Common/BasePagination/__tests__/index.test.jsx +180 -0
  46. package/Common/BasePagination/index.module.css +39 -0
  47. package/Common/BasePagination/index.stories.tsx +67 -0
  48. package/Common/BasePagination/index.tsx +77 -0
  49. package/Common/BasePagination/useGetPageElements.tsx +132 -0
  50. package/Common/Blockquote/index.module.css +29 -0
  51. package/Common/Blockquote/index.stories.tsx +45 -0
  52. package/Common/Blockquote/index.tsx +11 -0
  53. package/Common/Breadcrumbs/BreadcrumbHomeLink/index.module.css +5 -0
  54. package/Common/Breadcrumbs/BreadcrumbHomeLink/index.tsx +30 -0
  55. package/Common/Breadcrumbs/BreadcrumbItem/index.module.css +41 -0
  56. package/Common/Breadcrumbs/BreadcrumbItem/index.tsx +42 -0
  57. package/Common/Breadcrumbs/BreadcrumbLink/index.module.css +22 -0
  58. package/Common/Breadcrumbs/BreadcrumbLink/index.tsx +37 -0
  59. package/Common/Breadcrumbs/BreadcrumbRoot/index.module.css +9 -0
  60. package/Common/Breadcrumbs/BreadcrumbRoot/index.tsx +20 -0
  61. package/Common/Breadcrumbs/BreadcrumbTruncatedItem/index.tsx +9 -0
  62. package/Common/Breadcrumbs/index.stories.tsx +94 -0
  63. package/Common/Breadcrumbs/index.tsx +81 -0
  64. package/Common/CodeTabs/index.module.css +56 -0
  65. package/Common/CodeTabs/index.stories.tsx +74 -0
  66. package/Common/CodeTabs/index.tsx +16 -0
  67. package/Common/GlowingBackdrop/index.module.css +32 -0
  68. package/Common/GlowingBackdrop/index.stories.tsx +10 -0
  69. package/Common/GlowingBackdrop/index.tsx +13 -0
  70. package/Common/LanguageDropDown/index.module.css +53 -0
  71. package/Common/LanguageDropDown/index.stories.tsx +19 -0
  72. package/Common/LanguageDropDown/index.tsx +56 -0
  73. package/Common/Modal/index.module.css +79 -0
  74. package/Common/Modal/index.stories.tsx +32 -0
  75. package/Common/Modal/index.tsx +48 -0
  76. package/Common/NodejsLogo/index.module.css +6 -0
  77. package/Common/NodejsLogo/index.stories.tsx +14 -0
  78. package/Common/NodejsLogo/index.tsx +26 -0
  79. package/Common/Notification/index.module.css +20 -0
  80. package/Common/Notification/index.stories.tsx +36 -0
  81. package/Common/Notification/index.tsx +34 -0
  82. package/Common/Preview/index.module.css +79 -0
  83. package/Common/Preview/index.stories.tsx +44 -0
  84. package/Common/Preview/index.tsx +25 -0
  85. package/Common/ProgressionSidebar/ProgressionSidebarGroup/index.module.css +47 -0
  86. package/Common/ProgressionSidebar/ProgressionSidebarGroup/index.tsx +35 -0
  87. package/Common/ProgressionSidebar/ProgressionSidebarIcon/index.tsx +16 -0
  88. package/Common/ProgressionSidebar/ProgressionSidebarItem/index.module.css +39 -0
  89. package/Common/ProgressionSidebar/ProgressionSidebarItem/index.tsx +32 -0
  90. package/Common/ProgressionSidebar/index.module.css +30 -0
  91. package/Common/ProgressionSidebar/index.stories.tsx +79 -0
  92. package/Common/ProgressionSidebar/index.tsx +59 -0
  93. package/Common/Select/__tests__/index.test.jsx +67 -0
  94. package/Common/Select/index.module.css +161 -0
  95. package/Common/Select/index.stories.tsx +111 -0
  96. package/Common/Select/index.tsx +187 -0
  97. package/Common/Separator/index.module.css +16 -0
  98. package/Common/Separator/index.stories.tsx +32 -0
  99. package/Common/Separator/index.tsx +27 -0
  100. package/Common/Skeleton/index.module.css +30 -0
  101. package/Common/Skeleton/index.tsx +39 -0
  102. package/Common/Tabs/__tests__/index.test.jsx +52 -0
  103. package/Common/Tabs/index.module.css +54 -0
  104. package/Common/Tabs/index.stories.tsx +50 -0
  105. package/Common/Tabs/index.tsx +54 -0
  106. package/Common/ThemeToggle/__tests__/index.test.jsx +35 -0
  107. package/Common/ThemeToggle/index.module.css +15 -0
  108. package/Common/ThemeToggle/index.stories.tsx +10 -0
  109. package/Common/ThemeToggle/index.tsx +15 -0
  110. package/Common/Tooltip/index.module.css +43 -0
  111. package/Common/Tooltip/index.stories.tsx +73 -0
  112. package/Common/Tooltip/index.tsx +48 -0
  113. package/Containers/Article/index.module.css +70 -0
  114. package/Containers/Article/index.stories.tsx +39 -0
  115. package/Containers/Article/index.tsx +9 -0
  116. package/Containers/Footer/index.module.css +46 -0
  117. package/Containers/Footer/index.stories.tsx +27 -0
  118. package/Containers/Footer/index.tsx +95 -0
  119. package/Containers/MetaBar/__tests__/index.test.jsx +63 -0
  120. package/Containers/MetaBar/index.module.css +91 -0
  121. package/Containers/MetaBar/index.stories.tsx +80 -0
  122. package/Containers/MetaBar/index.tsx +72 -0
  123. package/Containers/NavBar/NavItem/index.module.css +60 -0
  124. package/Containers/NavBar/NavItem/index.stories.tsx +38 -0
  125. package/Containers/NavBar/NavItem/index.tsx +44 -0
  126. package/Containers/NavBar/index.module.css +125 -0
  127. package/Containers/NavBar/index.stories.tsx +45 -0
  128. package/Containers/NavBar/index.tsx +94 -0
  129. package/Containers/Sidebar/SidebarGroup/index.module.css +26 -0
  130. package/Containers/Sidebar/SidebarGroup/index.stories.tsx +36 -0
  131. package/Containers/Sidebar/SidebarGroup/index.tsx +30 -0
  132. package/Containers/Sidebar/SidebarItem/index.module.css +35 -0
  133. package/Containers/Sidebar/SidebarItem/index.stories.tsx +15 -0
  134. package/Containers/Sidebar/SidebarItem/index.tsx +26 -0
  135. package/Containers/Sidebar/index.module.css +31 -0
  136. package/Containers/Sidebar/index.stories.tsx +84 -0
  137. package/Containers/Sidebar/index.tsx +58 -0
  138. package/Icons/HexagonGrid.stories.tsx +10 -0
  139. package/Icons/HexagonGrid.tsx +1434 -0
  140. package/Icons/InstallationMethod/Choco.tsx +78 -0
  141. package/Icons/InstallationMethod/Devbox.tsx +21 -0
  142. package/Icons/InstallationMethod/Docker.tsx +20 -0
  143. package/Icons/InstallationMethod/FNM.tsx +132 -0
  144. package/Icons/InstallationMethod/Homebrew.tsx +69 -0
  145. package/Icons/InstallationMethod/N.tsx +32 -0
  146. package/Icons/InstallationMethod/NVM.tsx +63 -0
  147. package/Icons/InstallationMethod/Volta.tsx +34 -0
  148. package/Icons/InstallationMethod/index.ts +10 -0
  149. package/Icons/Logos/JsGreen.tsx +24 -0
  150. package/Icons/Logos/JsWhite.tsx +37 -0
  151. package/Icons/Logos/Nodejs.tsx +188 -0
  152. package/Icons/Logos/NodejsStackedBlack.tsx +98 -0
  153. package/Icons/Logos/NodejsStackedDark.tsx +124 -0
  154. package/Icons/Logos/NodejsStackedLight.tsx +123 -0
  155. package/Icons/Logos/NodejsStackedWhite.tsx +98 -0
  156. package/Icons/Logos/index.ts +17 -0
  157. package/Icons/OperatingSystem/AIX.tsx +46 -0
  158. package/Icons/OperatingSystem/Apple.tsx +23 -0
  159. package/Icons/OperatingSystem/Linux.tsx +969 -0
  160. package/Icons/OperatingSystem/Microsoft.tsx +19 -0
  161. package/Icons/OperatingSystem/index.ts +6 -0
  162. package/Icons/PackageManager/Npm.tsx +21 -0
  163. package/Icons/PackageManager/Pnpm.tsx +22 -0
  164. package/Icons/PackageManager/Yarn.tsx +22 -0
  165. package/Icons/PackageManager/index.ts +5 -0
  166. package/Icons/Social/Bluesky.tsx +19 -0
  167. package/Icons/Social/Discord.tsx +20 -0
  168. package/Icons/Social/GitHub.tsx +16 -0
  169. package/Icons/Social/LinkedIn.tsx +16 -0
  170. package/Icons/Social/Mastodon.tsx +36 -0
  171. package/Icons/Social/Slack.tsx +31 -0
  172. package/Icons/Social/X.tsx +16 -0
  173. package/Icons/Social/index.ts +9 -0
  174. package/LICENSE +21 -0
  175. package/package.json +89 -5
  176. package/stylelint/__tests__/index.test.mjs +80 -0
  177. package/stylelint/one-utility-class-per-line.mjs +64 -0
  178. package/stylelint/utils.mjs +53 -0
  179. package/styles/animations.css +47 -0
  180. package/styles/base.css +17 -0
  181. package/styles/effects.css +12 -0
  182. package/styles/index.css +38 -0
  183. package/styles/markdown.css +173 -0
  184. package/styles/theme.css +175 -0
  185. package/types.ts +25 -0
  186. package/README.md +0 -1
@@ -0,0 +1,125 @@
1
+ @reference "../../styles/index.css";
2
+
3
+ .container {
4
+ @apply border-neutral-200
5
+ bg-white
6
+ lg:flex
7
+ lg:h-16
8
+ lg:flex-row
9
+ lg:items-center
10
+ lg:gap-8
11
+ lg:border-b
12
+ lg:px-8
13
+ dark:border-neutral-900
14
+ dark:bg-neutral-950;
15
+ }
16
+
17
+ .nodeIconAndMobileItemsToggler {
18
+ @apply flex
19
+ h-16
20
+ shrink-0
21
+ items-center
22
+ border-b
23
+ border-neutral-200
24
+ px-4
25
+ lg:flex
26
+ lg:h-full
27
+ lg:items-center
28
+ lg:border-0
29
+ lg:px-0
30
+ dark:border-neutral-900;
31
+ }
32
+
33
+ .sidebarItemToggler {
34
+ @apply absolute
35
+ right-4
36
+ -z-10
37
+ -translate-y-[200%]
38
+ appearance-none
39
+ opacity-0;
40
+ }
41
+
42
+ .nodeIconWrapper {
43
+ @apply h-[30px]
44
+ flex-1;
45
+ }
46
+
47
+ .navInteractionIcon,
48
+ .sidebarItemToggler {
49
+ @apply size-6;
50
+ }
51
+
52
+ .sidebarItemTogglerLabel {
53
+ @apply block
54
+ cursor-pointer
55
+ lg:hidden;
56
+ }
57
+
58
+ .main {
59
+ @apply flex-1
60
+ flex-col
61
+ justify-between
62
+ gap-4
63
+ lg:flex
64
+ lg:flex-row
65
+ lg:items-center;
66
+ }
67
+
68
+ .navItems {
69
+ @apply flex
70
+ flex-col
71
+ gap-0
72
+ border-b
73
+ border-neutral-200
74
+ p-4
75
+ lg:flex-1
76
+ lg:flex-row
77
+ lg:gap-1
78
+ lg:border-0
79
+ lg:p-0
80
+ dark:border-neutral-900;
81
+ }
82
+
83
+ .actionsWrapper {
84
+ @apply flex
85
+ flex-row
86
+ flex-wrap
87
+ items-center
88
+ justify-between
89
+ gap-2
90
+ border-b
91
+ border-neutral-200
92
+ p-4
93
+ sm:flex-nowrap
94
+ lg:basis-96
95
+ lg:border-0
96
+ lg:p-0
97
+ dark:border-neutral-900;
98
+ }
99
+
100
+ span.searchButtonSkeleton {
101
+ @apply my-px
102
+ mr-2
103
+ flex-grow
104
+ rounded-xl;
105
+
106
+ &:empty {
107
+ @apply h-10;
108
+ }
109
+ }
110
+
111
+ .ghIconWrapper {
112
+ @apply size-9
113
+ rounded-md
114
+ p-2;
115
+
116
+ svg {
117
+ @apply fill-neutral-700
118
+ dark:fill-neutral-300;
119
+ }
120
+
121
+ &:hover {
122
+ @apply bg-neutral-100
123
+ dark:bg-neutral-900;
124
+ }
125
+ }
@@ -0,0 +1,45 @@
1
+ import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
+
3
+ import NavBar from '#ui/Containers/NavBar';
4
+
5
+ type Story = StoryObj<typeof NavBar>;
6
+ type Meta = MetaObj<typeof NavBar>;
7
+
8
+ export const Default: Story = {
9
+ args: {
10
+ as: 'a',
11
+ Logo: 'a',
12
+ pathname: '/',
13
+
14
+ children: <a>Some other child</a>,
15
+
16
+ navItems: [
17
+ {
18
+ text: 'Learn',
19
+ link: '/',
20
+ },
21
+ {
22
+ text: 'About',
23
+ link: '/about',
24
+ },
25
+ {
26
+ text: 'Docs',
27
+ link: '/docs',
28
+ },
29
+ {
30
+ text: 'Download',
31
+ link: '/download',
32
+ },
33
+ {
34
+ text: 'Blog',
35
+ link: '/blog',
36
+ },
37
+ {
38
+ text: 'Certification',
39
+ link: 'https://openjsf.org/certification',
40
+ },
41
+ ],
42
+ },
43
+ };
44
+
45
+ export default { component: NavBar } as Meta;
@@ -0,0 +1,94 @@
1
+ 'use client';
2
+
3
+ import Hamburger from '@heroicons/react/24/solid/Bars3Icon';
4
+ import XMark from '@heroicons/react/24/solid/XMarkIcon';
5
+ import * as Label from '@radix-ui/react-label';
6
+ import classNames from 'classnames';
7
+ import { useState } from 'react';
8
+ import type {
9
+ FC,
10
+ HTMLAttributeAnchorTarget,
11
+ PropsWithChildren,
12
+ ElementType,
13
+ } from 'react';
14
+
15
+ import NavItem from '#ui/Containers/NavBar/NavItem';
16
+ import type { FormattedMessage, LinkLike } from '#ui/types';
17
+
18
+ import style from './index.module.css';
19
+
20
+ const navInteractionIcons = {
21
+ show: <Hamburger className={style.navInteractionIcon} />,
22
+ close: <XMark className={style.navInteractionIcon} />,
23
+ };
24
+
25
+ type NavbarProps = {
26
+ navItems: Array<{
27
+ text: FormattedMessage;
28
+ link: string;
29
+ target?: HTMLAttributeAnchorTarget | undefined;
30
+ }>;
31
+ Logo: ElementType;
32
+ as: LinkLike;
33
+ pathname: string;
34
+ sidebarItemTogglerAriaLabel: string;
35
+ };
36
+
37
+ const NavBar: FC<PropsWithChildren<NavbarProps>> = ({
38
+ children,
39
+ Logo,
40
+ as: Component = 'a',
41
+ navItems,
42
+ pathname,
43
+ sidebarItemTogglerAriaLabel,
44
+ }) => {
45
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
46
+
47
+ return (
48
+ <nav className={style.container}>
49
+ <div className={style.nodeIconAndMobileItemsToggler}>
50
+ <Component className={style.nodeIconWrapper} href="/" aria-label="Home">
51
+ <Logo />
52
+ </Component>
53
+
54
+ <Label.Root
55
+ className={style.sidebarItemTogglerLabel}
56
+ htmlFor="sidebarItemToggler"
57
+ role="button"
58
+ aria-label={sidebarItemTogglerAriaLabel}
59
+ >
60
+ {navInteractionIcons[isMenuOpen ? 'close' : 'show']}
61
+ </Label.Root>
62
+ </div>
63
+
64
+ <input
65
+ className={classNames(['peer', style.sidebarItemToggler])}
66
+ id="sidebarItemToggler"
67
+ type="checkbox"
68
+ onChange={e => setIsMenuOpen(() => e.target.checked)}
69
+ aria-label={sidebarItemTogglerAriaLabel}
70
+ tabIndex={-1}
71
+ />
72
+
73
+ <div className={`${style.main} hidden peer-checked:flex`}>
74
+ <div className={style.navItems}>
75
+ {navItems.map(({ text, link, target }) => (
76
+ <NavItem
77
+ pathname={pathname}
78
+ as={Component}
79
+ key={link}
80
+ href={link}
81
+ target={target}
82
+ >
83
+ {text}
84
+ </NavItem>
85
+ ))}
86
+ </div>
87
+
88
+ <div className={style.actionsWrapper}>{children}</div>
89
+ </div>
90
+ </nav>
91
+ );
92
+ };
93
+
94
+ export default NavBar;
@@ -0,0 +1,26 @@
1
+ @reference "../../../styles/index.css";
2
+
3
+ .group {
4
+ @apply flex
5
+ w-full
6
+ flex-col
7
+ gap-2;
8
+ }
9
+
10
+ .groupName {
11
+ @apply px-2
12
+ py-1
13
+ text-xs
14
+ font-semibold
15
+ text-neutral-800
16
+ dark:text-neutral-600;
17
+ }
18
+
19
+ .itemList {
20
+ @apply m-0
21
+ flex
22
+ flex-col
23
+ items-start
24
+ gap-0.5
25
+ p-0;
26
+ }
@@ -0,0 +1,36 @@
1
+ import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
+
3
+ import SidebarGroup from '#ui/Containers/Sidebar/SidebarGroup';
4
+
5
+ type Story = StoryObj<typeof SidebarGroup>;
6
+ type Meta = MetaObj<typeof SidebarGroup>;
7
+
8
+ export const Default: Story = {
9
+ args: {
10
+ groupName: 'Example Group',
11
+ items: [
12
+ { label: 'Item 1', link: '/item1' },
13
+ { label: 'Item 2', link: '/item2' },
14
+ { label: 'Item 3', link: '/item3' },
15
+ ],
16
+ },
17
+ };
18
+
19
+ export const CustomGroup: Story = {
20
+ args: {
21
+ groupName: 'Custom Group',
22
+ items: [
23
+ { label: 'Custom Item 1', link: '/custom-item1' },
24
+ { label: 'Custom Item 2', link: '/custom-item2' },
25
+ ],
26
+ },
27
+ };
28
+
29
+ export const EmptyGroup: Story = {
30
+ args: {
31
+ groupName: 'Empty Group',
32
+ items: [],
33
+ },
34
+ };
35
+
36
+ export default { component: SidebarGroup } as Meta;
@@ -0,0 +1,30 @@
1
+ import type { ComponentProps, FC } from 'react';
2
+
3
+ import SidebarItem from '#ui/Containers/Sidebar/SidebarItem';
4
+ import type { FormattedMessage, LinkLike } from '#ui/types';
5
+
6
+ import styles from './index.module.css';
7
+
8
+ type SidebarGroupProps = {
9
+ groupName: FormattedMessage;
10
+ items: Array<Omit<ComponentProps<typeof SidebarItem>, 'as' | 'pathname'>>;
11
+ as?: LinkLike;
12
+ pathname?: string;
13
+ };
14
+
15
+ const SidebarGroup: FC<SidebarGroupProps> = ({
16
+ groupName,
17
+ items,
18
+ ...props
19
+ }) => (
20
+ <section className={styles.group}>
21
+ <label className={styles.groupName}>{groupName}</label>
22
+ <ul className={styles.itemList}>
23
+ {items.map(({ label, link }) => (
24
+ <SidebarItem key={link} label={label} link={link} {...props} />
25
+ ))}
26
+ </ul>
27
+ </section>
28
+ );
29
+
30
+ export default SidebarGroup;
@@ -0,0 +1,35 @@
1
+ @reference "../../../styles/index.css";
2
+
3
+ .sideBarItem {
4
+ @apply flex
5
+ w-full
6
+ list-none
7
+ text-neutral-800
8
+ dark:text-neutral-200;
9
+
10
+ a {
11
+ @apply inline-flex
12
+ items-center
13
+ gap-2
14
+ p-2;
15
+ }
16
+
17
+ .label {
18
+ @apply font-regular
19
+ w-full
20
+ text-sm;
21
+ }
22
+
23
+ .icon {
24
+ @apply size-3
25
+ text-neutral-500
26
+ dark:text-neutral-200;
27
+ }
28
+ }
29
+
30
+ .active {
31
+ @apply rounded-sm
32
+ bg-green-600
33
+ text-white
34
+ dark:text-white;
35
+ }
@@ -0,0 +1,15 @@
1
+ import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
+
3
+ import SidebarItem from '#ui/Containers/Sidebar/SidebarItem';
4
+
5
+ type Story = StoryObj<typeof SidebarItem>;
6
+ type Meta = MetaObj<typeof SidebarItem>;
7
+
8
+ export const Default: Story = {
9
+ args: {
10
+ label: 'Example Item',
11
+ link: '/example',
12
+ },
13
+ };
14
+
15
+ export default { component: SidebarItem } as Meta;
@@ -0,0 +1,26 @@
1
+ import { ArrowUpRightIcon } from '@heroicons/react/24/solid';
2
+ import type { FC } from 'react';
3
+
4
+ import ActiveLink from '#ui/Common/BaseActiveLink';
5
+ import type { FormattedMessage, LinkLike } from '#ui/types';
6
+
7
+ import styles from './index.module.css';
8
+
9
+ type SidebarItemProps = {
10
+ label: FormattedMessage;
11
+ link: string;
12
+ as?: LinkLike;
13
+ pathname?: string;
14
+ };
15
+
16
+ const SidebarItem: FC<SidebarItemProps> = ({ label, link, ...props }) => (
17
+ <li className={styles.sideBarItem}>
18
+ <ActiveLink href={link} activeClassName={styles.active} {...props}>
19
+ <span className={styles.label}>{label}</span>
20
+
21
+ {link.startsWith('http') && <ArrowUpRightIcon className={styles.icon} />}
22
+ </ActiveLink>
23
+ </li>
24
+ );
25
+
26
+ export default SidebarItem;
@@ -0,0 +1,31 @@
1
+ @reference "../../styles/index.css";
2
+
3
+ .wrapper {
4
+ @apply flex
5
+ w-full
6
+ flex-col
7
+ items-start
8
+ gap-8
9
+ overflow-auto
10
+ overflow-x-hidden
11
+ border-r-neutral-200
12
+ bg-white
13
+ px-4
14
+ py-6
15
+ sm:border-r
16
+ md:max-w-xs
17
+ lg:px-6
18
+ dark:border-r-neutral-900
19
+ dark:bg-neutral-950;
20
+
21
+ > section {
22
+ @apply hidden
23
+ sm:flex;
24
+ }
25
+
26
+ > span {
27
+ @apply flex
28
+ w-full
29
+ sm:hidden;
30
+ }
31
+ }
@@ -0,0 +1,84 @@
1
+ import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
+
3
+ import Sidebar from '#ui/Containers/Sidebar';
4
+
5
+ type Story = StoryObj<typeof Sidebar>;
6
+ type Meta = MetaObj<typeof Sidebar>;
7
+
8
+ export const Default: Story = {
9
+ args: {
10
+ groups: [
11
+ {
12
+ groupName: 'About Node.js',
13
+ items: [
14
+ {
15
+ link: '/item1',
16
+ label: 'About Node.js',
17
+ },
18
+ {
19
+ link: '/item2',
20
+ label: 'Project Governance',
21
+ },
22
+ {
23
+ link: '/item3',
24
+ label: 'Releases',
25
+ },
26
+ {
27
+ link: '/item4',
28
+ label: 'Branding',
29
+ },
30
+ {
31
+ link: '/item5',
32
+ label: 'Privacy Policy',
33
+ },
34
+ {
35
+ link: '/item6',
36
+ label: 'Security Reporting',
37
+ },
38
+ ],
39
+ },
40
+ {
41
+ groupName: 'Get Involved',
42
+ items: [
43
+ {
44
+ link: '/item7',
45
+ label: 'Get Involved',
46
+ },
47
+ {
48
+ link: '/item8',
49
+ label: 'Collab Summit',
50
+ },
51
+ {
52
+ link: '/item9',
53
+ label: 'Contribute',
54
+ },
55
+ {
56
+ link: '/item10',
57
+ label: 'Code of Conduct',
58
+ },
59
+ ],
60
+ },
61
+ {
62
+ groupName: 'Download',
63
+ items: [
64
+ {
65
+ link: '/item11',
66
+ label: 'Download',
67
+ },
68
+ {
69
+ link: '/item12',
70
+ label: 'Package Manager',
71
+ },
72
+ {
73
+ link: '/item13',
74
+ label: 'Node.js Releases',
75
+ },
76
+ ],
77
+ },
78
+ ],
79
+ title: 'Sidebar',
80
+ onSelect: console.log,
81
+ },
82
+ };
83
+
84
+ export default { component: Sidebar } as Meta;
@@ -0,0 +1,58 @@
1
+ import type { ComponentProps, FC } from 'react';
2
+
3
+ import Select from '#ui/Common/Select';
4
+ import SidebarGroup from '#ui/Containers/Sidebar/SidebarGroup';
5
+ import type { LinkLike } from '#ui/types';
6
+
7
+ import styles from './index.module.css';
8
+
9
+ type SidebarProps = {
10
+ groups: Array<Omit<ComponentProps<typeof SidebarGroup>, 'as' | 'pathname'>>;
11
+ pathname?: string;
12
+ title: string;
13
+ onSelect: (value: string) => void;
14
+ as?: LinkLike;
15
+ };
16
+
17
+ const SideBar: FC<SidebarProps> = ({
18
+ groups,
19
+ pathname,
20
+ title,
21
+ onSelect,
22
+ as,
23
+ }) => {
24
+ const selectItems = groups.map(({ items, groupName }) => ({
25
+ label: groupName,
26
+ items: items.map(({ label, link }) => ({ value: link, label })),
27
+ }));
28
+
29
+ const currentItem = selectItems
30
+ .map(item => item.items)
31
+ .flat()
32
+ .find(item => pathname === item.value);
33
+
34
+ return (
35
+ <aside className={styles.wrapper}>
36
+ {selectItems.length > 0 && (
37
+ <Select
38
+ label={title}
39
+ values={selectItems}
40
+ defaultValue={currentItem?.value}
41
+ onChange={onSelect}
42
+ />
43
+ )}
44
+
45
+ {groups.map(({ groupName, items }) => (
46
+ <SidebarGroup
47
+ key={groupName.toString()}
48
+ groupName={groupName}
49
+ items={items}
50
+ pathname={pathname}
51
+ as={as}
52
+ />
53
+ ))}
54
+ </aside>
55
+ );
56
+ };
57
+
58
+ export default SideBar;
@@ -0,0 +1,10 @@
1
+ import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
+
3
+ import HexagonGrid from '#ui/Icons/HexagonGrid';
4
+
5
+ type Story = StoryObj<typeof HexagonGrid>;
6
+ type Meta = MetaObj<typeof HexagonGrid>;
7
+
8
+ export const Default: Story = {};
9
+
10
+ export default { component: HexagonGrid } as Meta;