@node-core/ui-components 1.0.1-c0bc4dd7eb49f97f35ce0983849d17702404c76a → 1.0.1-da75492230302b0f459aab323d2f6fdac6269a06

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 (263) hide show
  1. package/Common/AlertBox/index.js +5 -0
  2. package/Common/AlertBox/index.module.css +2 -76
  3. package/Common/AvatarGroup/Avatar/index.js +11 -0
  4. package/Common/AvatarGroup/Avatar/index.module.css +2 -40
  5. package/Common/AvatarGroup/Overlay/index.js +6 -0
  6. package/Common/AvatarGroup/Overlay/index.module.css +2 -31
  7. package/Common/AvatarGroup/index.js +21 -0
  8. package/Common/AvatarGroup/index.module.css +2 -21
  9. package/Common/Badge/index.js +5 -0
  10. package/Common/Badge/index.module.css +2 -38
  11. package/Common/BadgeGroup/index.js +6 -0
  12. package/Common/BadgeGroup/index.module.css +2 -77
  13. package/Common/Banner/index.js +4 -0
  14. package/Common/Banner/index.module.css +2 -42
  15. package/Common/BaseActiveLink/index.js +14 -0
  16. package/Common/BaseButton/index.js +10 -0
  17. package/Common/BaseButton/index.module.css +2 -142
  18. package/Common/BaseCodeBox/index.js +50 -0
  19. package/Common/BaseCodeBox/index.module.css +2 -78
  20. package/Common/BaseCrossLink/index.js +12 -0
  21. package/Common/BaseCrossLink/index.module.css +2 -51
  22. package/Common/BaseLinkTabs/index.js +5 -0
  23. package/Common/BaseLinkTabs/index.module.css +2 -43
  24. package/Common/BasePagination/Ellipsis/index.js +4 -0
  25. package/Common/BasePagination/Ellipsis/index.module.css +2 -10
  26. package/Common/BasePagination/PaginationListItem/index.js +6 -0
  27. package/Common/BasePagination/PaginationListItem/index.module.css +2 -27
  28. package/Common/BasePagination/PrevNextArrow.js +7 -0
  29. package/Common/BasePagination/index.js +10 -0
  30. package/Common/BasePagination/index.module.css +2 -39
  31. package/Common/BasePagination/useGetPageElements.js +77 -0
  32. package/Common/Blockquote/index.js +4 -0
  33. package/Common/Blockquote/index.module.css +2 -29
  34. package/Common/Breadcrumbs/BreadcrumbHomeLink/index.js +9 -0
  35. package/Common/Breadcrumbs/BreadcrumbHomeLink/index.module.css +2 -5
  36. package/Common/Breadcrumbs/BreadcrumbItem/index.js +6 -0
  37. package/Common/Breadcrumbs/BreadcrumbItem/index.module.css +2 -41
  38. package/Common/Breadcrumbs/BreadcrumbLink/index.js +5 -0
  39. package/Common/Breadcrumbs/BreadcrumbLink/index.module.css +2 -22
  40. package/Common/Breadcrumbs/BreadcrumbRoot/index.js +4 -0
  41. package/Common/Breadcrumbs/BreadcrumbRoot/index.module.css +2 -9
  42. package/Common/Breadcrumbs/BreadcrumbTruncatedItem/index.js +4 -0
  43. package/Common/Breadcrumbs/index.js +22 -0
  44. package/Common/ChangeHistory/index.js +9 -0
  45. package/Common/ChangeHistory/index.module.css +2 -83
  46. package/Common/CodeTabs/index.js +5 -0
  47. package/Common/CodeTabs/index.module.css +2 -56
  48. package/Common/DataTag/index.js +18 -0
  49. package/Common/DataTag/index.module.css +2 -56
  50. package/Common/GlowingBackdrop/index.js +5 -0
  51. package/Common/GlowingBackdrop/index.module.css +2 -32
  52. package/Common/LanguageDropDown/index.js +11 -0
  53. package/Common/LanguageDropDown/index.module.css +2 -53
  54. package/Common/Modal/index.js +10 -0
  55. package/Common/Modal/index.module.css +2 -79
  56. package/Common/NodejsLogo/index.js +7 -0
  57. package/Common/NodejsLogo/index.module.css +2 -6
  58. package/Common/Notification/index.js +6 -0
  59. package/Common/Notification/index.module.css +2 -20
  60. package/Common/Preview/index.js +7 -0
  61. package/Common/Preview/index.module.css +2 -79
  62. package/Common/Select/index.js +47 -0
  63. package/Common/Select/index.module.css +2 -161
  64. package/Common/Separator/index.js +7 -0
  65. package/Common/Separator/index.module.css +2 -16
  66. package/Common/Skeleton/index.js +18 -0
  67. package/Common/Skeleton/index.module.css +2 -30
  68. package/Common/Tabs/index.js +6 -0
  69. package/Common/Tabs/index.module.css +2 -54
  70. package/Common/ThemeToggle/index.js +7 -0
  71. package/Common/ThemeToggle/index.module.css +2 -15
  72. package/Common/Tooltip/index.js +8 -0
  73. package/Common/Tooltip/index.module.css +2 -43
  74. package/Containers/Article/index.js +4 -0
  75. package/Containers/Article/index.module.css +2 -70
  76. package/Containers/Footer/index.js +21 -0
  77. package/Containers/Footer/index.module.css +2 -46
  78. package/Containers/MetaBar/index.js +12 -0
  79. package/Containers/MetaBar/index.module.css +2 -91
  80. package/Containers/NavBar/NavItem/index.js +7 -0
  81. package/Containers/NavBar/NavItem/index.module.css +2 -60
  82. package/Containers/NavBar/index.js +18 -0
  83. package/Containers/NavBar/index.module.css +2 -125
  84. package/Containers/Sidebar/ProgressionIcon/index.js +3 -0
  85. package/Containers/Sidebar/SidebarGroup/index.js +9 -0
  86. package/Containers/Sidebar/SidebarGroup/index.module.css +2 -64
  87. package/Containers/Sidebar/SidebarItem/index.js +11 -0
  88. package/Containers/Sidebar/SidebarItem/index.module.css +2 -56
  89. package/Containers/Sidebar/index.js +15 -0
  90. package/Containers/Sidebar/index.module.css +2 -30
  91. package/Icons/HexagonGrid.js +3 -0
  92. package/Icons/InstallationMethod/Choco.js +3 -0
  93. package/Icons/InstallationMethod/Devbox.js +3 -0
  94. package/Icons/InstallationMethod/Docker.js +3 -0
  95. package/Icons/InstallationMethod/FNM.js +3 -0
  96. package/Icons/InstallationMethod/Homebrew.js +3 -0
  97. package/Icons/InstallationMethod/N.js +5 -0
  98. package/Icons/InstallationMethod/NVM.js +3 -0
  99. package/Icons/InstallationMethod/Volta.js +3 -0
  100. package/Icons/InstallationMethod/{index.ts → index.js} +0 -1
  101. package/Icons/Logos/JsWhite.js +3 -0
  102. package/Icons/Logos/Nodejs.js +12 -0
  103. package/Icons/Logos/index.js +3 -0
  104. package/Icons/OperatingSystem/AIX.js +3 -0
  105. package/Icons/OperatingSystem/Apple.js +3 -0
  106. package/Icons/OperatingSystem/Linux.js +3 -0
  107. package/Icons/OperatingSystem/Microsoft.js +3 -0
  108. package/Icons/OperatingSystem/{index.ts → index.js} +0 -1
  109. package/Icons/PackageManager/Npm.js +3 -0
  110. package/Icons/PackageManager/Pnpm.js +3 -0
  111. package/Icons/PackageManager/Yarn.js +3 -0
  112. package/Icons/PackageManager/{index.ts → index.js} +0 -1
  113. package/Icons/Social/Bluesky.js +3 -0
  114. package/Icons/Social/Discord.js +3 -0
  115. package/Icons/Social/GitHub.js +3 -0
  116. package/Icons/Social/LinkedIn.js +3 -0
  117. package/Icons/Social/Mastodon.js +3 -0
  118. package/Icons/Social/Slack.js +3 -0
  119. package/Icons/Social/X.js +3 -0
  120. package/Icons/Social/{index.ts → index.js} +0 -1
  121. package/MDX/CodeTabs.js +25 -0
  122. package/Providers/NotificationProvider/index.js +16 -0
  123. package/Providers/NotificationProvider/index.module.css +2 -0
  124. package/package.json +6 -51
  125. package/stylelint/one-utility-class-per-line.mjs +34 -50
  126. package/stylelint/utils.mjs +19 -25
  127. package/styles/index.css +2 -38
  128. package/types.js +1 -0
  129. package/Common/AlertBox/index.stories.tsx +0 -73
  130. package/Common/AlertBox/index.tsx +0 -24
  131. package/Common/AvatarGroup/Avatar/index.stories.tsx +0 -22
  132. package/Common/AvatarGroup/Avatar/index.tsx +0 -67
  133. package/Common/AvatarGroup/Overlay/index.stories.tsx +0 -33
  134. package/Common/AvatarGroup/Overlay/index.tsx +0 -37
  135. package/Common/AvatarGroup/__tests__/index.test.jsx +0 -55
  136. package/Common/AvatarGroup/index.stories.tsx +0 -56
  137. package/Common/AvatarGroup/index.tsx +0 -83
  138. package/Common/Badge/index.stories.tsx +0 -38
  139. package/Common/Badge/index.tsx +0 -35
  140. package/Common/BadgeGroup/index.stories.tsx +0 -35
  141. package/Common/BadgeGroup/index.tsx +0 -35
  142. package/Common/Banner/index.stories.tsx +0 -29
  143. package/Common/Banner/index.tsx +0 -18
  144. package/Common/BaseActiveLink/__tests__/index.test.jsx +0 -52
  145. package/Common/BaseActiveLink/index.tsx +0 -34
  146. package/Common/BaseButton/index.stories.tsx +0 -67
  147. package/Common/BaseButton/index.tsx +0 -59
  148. package/Common/BaseCodeBox/index.stories.tsx +0 -39
  149. package/Common/BaseCodeBox/index.tsx +0 -122
  150. package/Common/BaseCrossLink/index.stories.tsx +0 -38
  151. package/Common/BaseCrossLink/index.tsx +0 -46
  152. package/Common/BaseLinkTabs/index.stories.tsx +0 -34
  153. package/Common/BaseLinkTabs/index.tsx +0 -53
  154. package/Common/BasePagination/Ellipsis/index.stories.tsx +0 -10
  155. package/Common/BasePagination/Ellipsis/index.tsx +0 -11
  156. package/Common/BasePagination/PaginationListItem/__tests__/index.test.jsx +0 -58
  157. package/Common/BasePagination/PaginationListItem/index.stories.tsx +0 -40
  158. package/Common/BasePagination/PaginationListItem/index.tsx +0 -39
  159. package/Common/BasePagination/PrevNextArrow.tsx +0 -15
  160. package/Common/BasePagination/__tests__/index.test.jsx +0 -180
  161. package/Common/BasePagination/index.stories.tsx +0 -67
  162. package/Common/BasePagination/index.tsx +0 -77
  163. package/Common/BasePagination/useGetPageElements.tsx +0 -132
  164. package/Common/Blockquote/index.stories.tsx +0 -45
  165. package/Common/Blockquote/index.tsx +0 -11
  166. package/Common/Breadcrumbs/BreadcrumbHomeLink/index.tsx +0 -30
  167. package/Common/Breadcrumbs/BreadcrumbItem/index.tsx +0 -42
  168. package/Common/Breadcrumbs/BreadcrumbLink/index.tsx +0 -37
  169. package/Common/Breadcrumbs/BreadcrumbRoot/index.tsx +0 -20
  170. package/Common/Breadcrumbs/BreadcrumbTruncatedItem/index.tsx +0 -9
  171. package/Common/Breadcrumbs/index.stories.tsx +0 -94
  172. package/Common/Breadcrumbs/index.tsx +0 -81
  173. package/Common/ChangeHistory/index.stories.tsx +0 -130
  174. package/Common/ChangeHistory/index.tsx +0 -67
  175. package/Common/CodeTabs/index.stories.tsx +0 -73
  176. package/Common/CodeTabs/index.tsx +0 -16
  177. package/Common/DataTag/index.stories.tsx +0 -40
  178. package/Common/DataTag/index.tsx +0 -39
  179. package/Common/GlowingBackdrop/index.stories.tsx +0 -10
  180. package/Common/GlowingBackdrop/index.tsx +0 -13
  181. package/Common/LanguageDropDown/index.stories.tsx +0 -19
  182. package/Common/LanguageDropDown/index.tsx +0 -56
  183. package/Common/Modal/index.stories.tsx +0 -32
  184. package/Common/Modal/index.tsx +0 -48
  185. package/Common/NodejsLogo/index.stories.tsx +0 -14
  186. package/Common/NodejsLogo/index.tsx +0 -26
  187. package/Common/Notification/index.stories.tsx +0 -36
  188. package/Common/Notification/index.tsx +0 -34
  189. package/Common/Preview/index.stories.tsx +0 -44
  190. package/Common/Preview/index.tsx +0 -25
  191. package/Common/Select/__tests__/index.test.jsx +0 -67
  192. package/Common/Select/index.stories.tsx +0 -111
  193. package/Common/Select/index.tsx +0 -187
  194. package/Common/Separator/index.stories.tsx +0 -32
  195. package/Common/Separator/index.tsx +0 -27
  196. package/Common/Skeleton/index.tsx +0 -39
  197. package/Common/Tabs/__tests__/index.test.jsx +0 -52
  198. package/Common/Tabs/index.stories.tsx +0 -50
  199. package/Common/Tabs/index.tsx +0 -54
  200. package/Common/ThemeToggle/__tests__/index.test.jsx +0 -35
  201. package/Common/ThemeToggle/index.stories.tsx +0 -10
  202. package/Common/ThemeToggle/index.tsx +0 -15
  203. package/Common/Tooltip/index.stories.tsx +0 -73
  204. package/Common/Tooltip/index.tsx +0 -48
  205. package/Containers/Article/index.stories.tsx +0 -39
  206. package/Containers/Article/index.tsx +0 -9
  207. package/Containers/DocSideBar/index.tsx +0 -0
  208. package/Containers/Footer/index.stories.tsx +0 -27
  209. package/Containers/Footer/index.tsx +0 -95
  210. package/Containers/MetaBar/__tests__/index.test.jsx +0 -63
  211. package/Containers/MetaBar/index.stories.tsx +0 -80
  212. package/Containers/MetaBar/index.tsx +0 -72
  213. package/Containers/NavBar/NavItem/index.stories.tsx +0 -38
  214. package/Containers/NavBar/NavItem/index.tsx +0 -44
  215. package/Containers/NavBar/index.stories.tsx +0 -45
  216. package/Containers/NavBar/index.tsx +0 -94
  217. package/Containers/Sidebar/ProgressionIcon/index.tsx +0 -16
  218. package/Containers/Sidebar/SidebarGroup/index.stories.tsx +0 -36
  219. package/Containers/Sidebar/SidebarGroup/index.tsx +0 -49
  220. package/Containers/Sidebar/SidebarItem/index.stories.tsx +0 -15
  221. package/Containers/Sidebar/SidebarItem/index.tsx +0 -43
  222. package/Containers/Sidebar/index.stories.tsx +0 -88
  223. package/Containers/Sidebar/index.tsx +0 -70
  224. package/Icons/HexagonGrid.stories.tsx +0 -10
  225. package/Icons/HexagonGrid.tsx +0 -1434
  226. package/Icons/InstallationMethod/Choco.tsx +0 -78
  227. package/Icons/InstallationMethod/Devbox.tsx +0 -21
  228. package/Icons/InstallationMethod/Docker.tsx +0 -20
  229. package/Icons/InstallationMethod/FNM.tsx +0 -132
  230. package/Icons/InstallationMethod/Homebrew.tsx +0 -69
  231. package/Icons/InstallationMethod/N.tsx +0 -32
  232. package/Icons/InstallationMethod/NVM.tsx +0 -63
  233. package/Icons/InstallationMethod/Volta.tsx +0 -34
  234. package/Icons/Logos/JsGreen.tsx +0 -24
  235. package/Icons/Logos/JsWhite.tsx +0 -37
  236. package/Icons/Logos/Nodejs.tsx +0 -372
  237. package/Icons/Logos/NodejsStackedBlack.tsx +0 -98
  238. package/Icons/Logos/NodejsStackedDark.tsx +0 -124
  239. package/Icons/Logos/NodejsStackedLight.tsx +0 -123
  240. package/Icons/Logos/NodejsStackedWhite.tsx +0 -98
  241. package/Icons/Logos/index.ts +0 -17
  242. package/Icons/OperatingSystem/AIX.tsx +0 -46
  243. package/Icons/OperatingSystem/Apple.tsx +0 -23
  244. package/Icons/OperatingSystem/Linux.tsx +0 -969
  245. package/Icons/OperatingSystem/Microsoft.tsx +0 -19
  246. package/Icons/PackageManager/Npm.tsx +0 -21
  247. package/Icons/PackageManager/Pnpm.tsx +0 -22
  248. package/Icons/PackageManager/Yarn.tsx +0 -22
  249. package/Icons/Social/Bluesky.tsx +0 -19
  250. package/Icons/Social/Discord.tsx +0 -20
  251. package/Icons/Social/GitHub.tsx +0 -16
  252. package/Icons/Social/LinkedIn.tsx +0 -16
  253. package/Icons/Social/Mastodon.tsx +0 -36
  254. package/Icons/Social/Slack.tsx +0 -31
  255. package/Icons/Social/X.tsx +0 -16
  256. package/MDX/CodeTabs.tsx +0 -47
  257. package/stylelint/__tests__/index.test.mjs +0 -80
  258. package/styles/animations.css +0 -47
  259. package/styles/base.css +0 -17
  260. package/styles/effects.css +0 -12
  261. package/styles/markdown.css +0 -173
  262. package/styles/theme.css +0 -175
  263. package/types.ts +0 -25
@@ -1,122 +0,0 @@
1
- 'use client';
2
-
3
- import { DocumentDuplicateIcon } from '@heroicons/react/24/outline';
4
- import classNames from 'classnames';
5
- import type { FC, PropsWithChildren, ReactElement } from 'react';
6
- import { Fragment, isValidElement, useRef } from 'react';
7
-
8
- import BaseButton from '#ui/Common/BaseButton';
9
- import type { LinkLike } from '#ui/types';
10
-
11
- import styles from './index.module.css';
12
-
13
- // Transforms a code element with plain text content into a more structured
14
- // format for rendering with line numbers
15
- const transformCode = <T extends ReactElement<PropsWithChildren>>(
16
- code: T,
17
- language: string
18
- ): ReactElement<HTMLElement> | T => {
19
- if (!isValidElement(code)) {
20
- // Early return when the `CodeBox` child is not a valid element since the
21
- // type is a ReactNode, and can assume any value
22
- return code;
23
- }
24
-
25
- const content = code.props?.children;
26
-
27
- if (code.type !== 'code' || typeof content !== 'string') {
28
- // There is no need to transform an element that is not a code element or
29
- // a content that is not a string
30
- return code;
31
- }
32
-
33
- // Note that since we use `.split` we will have an extra entry
34
- // being an empty string, so we need to remove it
35
- const lines = content.split('\n');
36
-
37
- const extraStyle = language.length === 0 ? { fontFamily: 'monospace' } : {};
38
-
39
- return (
40
- <code style={extraStyle}>
41
- {lines
42
- .flatMap((line, lineIndex) => {
43
- const columns = line.split(' ');
44
-
45
- return [
46
- <span key={lineIndex} className="line">
47
- {columns.map((column, columnIndex) => (
48
- <Fragment key={columnIndex}>
49
- <span>{column}</span>
50
- {columnIndex < columns.length - 1 && <span> </span>}
51
- </Fragment>
52
- ))}
53
- </span>,
54
- // Add a break line so the text content is formatted correctly
55
- // when copying to clipboard
56
- '\n',
57
- ];
58
- })
59
- // Here we remove that empty line from before and
60
- // the last flatMap entry which is an `\n`
61
- .slice(0, -2)}
62
- </code>
63
- );
64
- };
65
-
66
- interface CodeBoxProps {
67
- language: string;
68
- className?: string;
69
- onCopy: (text: string) => void;
70
- as?: LinkLike;
71
- buttonText: string;
72
- showCopyButton?: boolean;
73
- }
74
-
75
- const BaseCodeBox: FC<PropsWithChildren<CodeBoxProps>> = ({
76
- children,
77
- language,
78
- className,
79
- onCopy,
80
- buttonText,
81
- as = 'a',
82
- showCopyButton = true,
83
- }: PropsWithChildren<CodeBoxProps>) => {
84
- const containerRef = useRef<HTMLPreElement>(null);
85
-
86
- const handleCopy = (): void => {
87
- const text = containerRef.current?.textContent;
88
- if (text) {
89
- onCopy(text);
90
- }
91
- };
92
-
93
- return (
94
- <div className={styles.root}>
95
- <pre
96
- ref={containerRef}
97
- className={classNames(styles.content, className)}
98
- tabIndex={0}
99
- >
100
- {transformCode(children as ReactElement<PropsWithChildren>, language)}
101
- </pre>
102
- {language && (
103
- <div className={styles.footer}>
104
- <span className={styles.language}>{language}</span>
105
- {showCopyButton && (
106
- <BaseButton
107
- as={as}
108
- className={styles.action}
109
- kind="neutral"
110
- onClick={handleCopy}
111
- >
112
- <DocumentDuplicateIcon className={styles.icon} />
113
- {buttonText}
114
- </BaseButton>
115
- )}
116
- </div>
117
- )}
118
- </div>
119
- );
120
- };
121
-
122
- export default BaseCodeBox;
@@ -1,38 +0,0 @@
1
- import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
-
3
- import BaseCrossLink from '#ui/Common/BaseCrossLink';
4
-
5
- type Story = StoryObj<typeof BaseCrossLink>;
6
- type Meta = MetaObj<typeof BaseCrossLink>;
7
-
8
- export const Prev: Story = {
9
- args: {
10
- type: 'previous',
11
- text: 'How to install Node.js',
12
- link: 'https://nodejs.dev/en/learn/how-to-install-nodejs/',
13
- },
14
- decorators: [
15
- Story => (
16
- <div className="w-[305px]">
17
- <Story />
18
- </div>
19
- ),
20
- ],
21
- };
22
-
23
- export const Next: Story = {
24
- args: {
25
- type: 'next',
26
- text: 'How much JavaScript do you need to know to use Node.js?',
27
- link: 'https://nodejs.dev/en/learn/how-much-javascript-do-you-need-to-know-to-use-nodejs/',
28
- },
29
- decorators: [
30
- Story => (
31
- <div className="w-[305px]">
32
- <Story />
33
- </div>
34
- ),
35
- ],
36
- };
37
-
38
- export default { component: BaseCrossLink } as Meta;
@@ -1,46 +0,0 @@
1
- import classNames from 'classnames';
2
- import type { FC } from 'react';
3
-
4
- import PrevNextArrow from '#ui/Common/BasePagination/PrevNextArrow';
5
- import type { LinkLike, FormattedMessage } from '#ui/types';
6
-
7
- import styles from './index.module.css';
8
-
9
- export type CrossLinkProps = {
10
- type: 'previous' | 'next';
11
- text: FormattedMessage;
12
- label: string;
13
- link: string;
14
- as: LinkLike;
15
- };
16
-
17
- const BaseCrossLink: FC<CrossLinkProps> = ({
18
- type,
19
- label,
20
- text,
21
- link,
22
- as: Component = 'a',
23
- }) => {
24
- return (
25
- <Component className={styles.crossLink} href={link}>
26
- <span
27
- className={classNames(styles.header, {
28
- [styles.reverse]: type === 'next',
29
- })}
30
- >
31
- <PrevNextArrow className={styles.icon} type={type} />
32
- {label}
33
- </span>
34
-
35
- <span
36
- className={classNames(styles.content, {
37
- [styles.reverse]: type === 'next',
38
- })}
39
- >
40
- {text}
41
- </span>
42
- </Component>
43
- );
44
- };
45
-
46
- export default BaseCrossLink;
@@ -1,34 +0,0 @@
1
- import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
-
3
- import BaseLinkTabs from '#ui/Common/BaseLinkTabs';
4
-
5
- type Story = StoryObj<typeof BaseLinkTabs>;
6
- type Meta = MetaObj<typeof BaseLinkTabs>;
7
-
8
- export const Default: Story = {
9
- args: {
10
- label: 'Select Tab',
11
- tabs: [
12
- {
13
- key: 'package',
14
- label: 'Package Manager',
15
- link: '/package-manager',
16
- },
17
- {
18
- key: 'prebuilt',
19
- label: 'Prebuilt Installer',
20
- link: '/prebuilt-installer',
21
- },
22
- {
23
- key: 'source',
24
- label: 'Source Code',
25
- link: '/source-code',
26
- },
27
- ],
28
- activeTab: 'prebuilt',
29
- children: <p>Tab content goes here</p>,
30
- onSelect: console.log,
31
- },
32
- };
33
-
34
- export default { component: BaseLinkTabs } as Meta;
@@ -1,53 +0,0 @@
1
- import type { FC, PropsWithChildren } from 'react';
2
-
3
- import Select from '#ui/Common/Select';
4
- import type { LinkLike } from '#ui/types';
5
-
6
- import styles from './index.module.css';
7
-
8
- type LinkTab = { key: string; label: string; link: string };
9
-
10
- export type LinkTabsProps = PropsWithChildren<{
11
- label?: string;
12
- tabs: Array<LinkTab>;
13
- activeTab: string;
14
- as?: LinkLike;
15
- onSelect: (value: string) => void;
16
- }>;
17
-
18
- const BaseLinkTabs: FC<LinkTabsProps> = ({
19
- tabs,
20
- label,
21
- activeTab,
22
- children,
23
- as: Component = 'a',
24
- onSelect,
25
- }) => (
26
- <>
27
- <div className={styles.tabsList}>
28
- {tabs.map(tab => (
29
- <Component
30
- key={tab.key}
31
- href={tab.link}
32
- className={styles.tabsTrigger}
33
- data-state={tab.key === activeTab ? 'active' : 'inactive'}
34
- >
35
- {tab.label}
36
- </Component>
37
- ))}
38
- </div>
39
-
40
- <div className={styles.tabsSelect}>
41
- <Select
42
- label={label}
43
- defaultValue={tabs.find(tab => tab.key === activeTab)?.link}
44
- values={tabs.map(tab => ({ label: tab.label, value: tab.link }))}
45
- onChange={onSelect}
46
- />
47
- </div>
48
-
49
- {children}
50
- </>
51
- );
52
-
53
- export default BaseLinkTabs;
@@ -1,10 +0,0 @@
1
- import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
-
3
- import Ellipsis from '#ui/Common/BasePagination/Ellipsis';
4
-
5
- type Story = StoryObj<typeof Ellipsis>;
6
- type Meta = MetaObj<typeof Ellipsis>;
7
-
8
- export const Default: Story = {};
9
-
10
- export default { component: Ellipsis } as Meta;
@@ -1,11 +0,0 @@
1
- import type { FC } from 'react';
2
-
3
- import styles from './index.module.css';
4
-
5
- const Ellipsis: FC = () => (
6
- <span aria-hidden="true" className={styles.ellipsis}>
7
- ...
8
- </span>
9
- );
10
-
11
- export default Ellipsis;
@@ -1,58 +0,0 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'node:assert/strict';
3
-
4
- import { render, screen } from '@testing-library/react';
5
-
6
- import { isVisible } from '../../../../../../tests/utilities.mjs';
7
-
8
- import PaginationListItem from '#ui/Common/BasePagination/PaginationListItem';
9
-
10
- function renderPaginationListItem({
11
- url,
12
- pageNumber,
13
- currentPage,
14
- totalPages,
15
- }) {
16
- render(
17
- <PaginationListItem
18
- url={url}
19
- pageNumber={pageNumber}
20
- currentPage={currentPage}
21
- totalPages={totalPages}
22
- />
23
- );
24
- }
25
-
26
- describe('PaginationListItem', () => {
27
- it('Renders the list item correctly, including the corresponding ARIA attributes', () => {
28
- const pageNumber = 1;
29
- const totalPages = 10;
30
- const url = 'http://';
31
-
32
- renderPaginationListItem({
33
- url,
34
- currentPage: 1,
35
- pageNumber,
36
- totalPages,
37
- });
38
-
39
- const listItem = screen.getByRole('listitem');
40
-
41
- assert.ok(isVisible());
42
- assert.equal(listItem.getAttribute('aria-posinset'), String(pageNumber));
43
- assert.equal(listItem.getAttribute('aria-setsize'), String(totalPages));
44
-
45
- assert.equal(screen.getByRole('link').getAttribute('href'), url);
46
- });
47
-
48
- it('Assigns aria-current="page" attribute to the link when the current page is equal to the page number', () => {
49
- renderPaginationListItem({
50
- url: 'http://',
51
- currentPage: 1,
52
- pageNumber: 1,
53
- totalPages: 10,
54
- });
55
-
56
- assert.equal(screen.getByRole('link').getAttribute('aria-current'), 'page');
57
- });
58
- });
@@ -1,40 +0,0 @@
1
- import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
-
3
- import PaginationListItem from '#ui/Common/BasePagination/PaginationListItem';
4
-
5
- type Story = StoryObj<typeof PaginationListItem>;
6
- type Meta = MetaObj<typeof PaginationListItem>;
7
-
8
- export const Default: Story = {
9
- args: {
10
- url: '#',
11
- pageNumber: 1,
12
- currentPage: 2,
13
- totalPages: 2,
14
- },
15
- decorators: [
16
- Story => (
17
- <ul className="list-none">
18
- <Story />
19
- </ul>
20
- ),
21
- ],
22
- };
23
-
24
- export const CurrentPage: Story = {
25
- args: {
26
- url: '#',
27
- pageNumber: 1,
28
- currentPage: 1,
29
- totalPages: 1,
30
- },
31
- decorators: [
32
- Story => (
33
- <ul className="list-none">
34
- <Story />
35
- </ul>
36
- ),
37
- ],
38
- };
39
-
40
- export default { component: PaginationListItem } as Meta;
@@ -1,39 +0,0 @@
1
- import type { FC } from 'react';
2
-
3
- import type { LinkLike } from '#ui/types';
4
-
5
- import styles from './index.module.css';
6
-
7
- export type PaginationListItemProps = {
8
- url: string;
9
- pageNumber: number;
10
- // One-based number of the current page
11
- currentPage: number;
12
- totalPages: number;
13
- as?: LinkLike;
14
- label: string;
15
- };
16
-
17
- const PaginationListItem: FC<PaginationListItemProps> = ({
18
- url,
19
- pageNumber,
20
- currentPage,
21
- totalPages,
22
- as: Component = 'a',
23
- label,
24
- }) => {
25
- return (
26
- <li key={pageNumber} aria-setsize={totalPages} aria-posinset={pageNumber}>
27
- <Component
28
- href={url}
29
- aria-label={label}
30
- className={styles.listItem}
31
- {...(pageNumber === currentPage && { 'aria-current': 'page' })}
32
- >
33
- <span>{pageNumber}</span>
34
- </Component>
35
- </li>
36
- );
37
- };
38
-
39
- export default PaginationListItem;
@@ -1,15 +0,0 @@
1
- import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/solid';
2
- import type { FC, SVGAttributes } from 'react';
3
-
4
- type PrevNextArrowProps = {
5
- type: 'previous' | 'next';
6
- } & SVGAttributes<SVGSVGElement>;
7
-
8
- const PrevNextArrow: FC<PrevNextArrowProps> = ({ type, ...extra }) => {
9
- const ChevronComponent =
10
- type === 'previous' ? ChevronLeftIcon : ChevronRightIcon;
11
-
12
- return <ChevronComponent {...extra} />;
13
- };
14
-
15
- export default PrevNextArrow;
@@ -1,180 +0,0 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'node:assert/strict';
3
-
4
- import { render, screen } from '@testing-library/react';
5
-
6
- import { isVisible } from '../../../../../tests/utilities.mjs';
7
-
8
- import BasePagination from '#ui/Common/BasePagination';
9
-
10
- const getPageLabel = number => number.toString();
11
- const labels = {
12
- aria: 'Aria',
13
- prevAria: 'Previous Aria',
14
- prev: 'Previous',
15
- nextAria: 'Next Aria',
16
- next: 'Next',
17
- };
18
-
19
- function renderPagination({
20
- currentPage = 1,
21
- pages,
22
- currentPageSiblingsCount,
23
- }) {
24
- const parsedPages = new Array(pages)
25
- .fill({ url: 'page' })
26
- .map(item => ({ url: `${item.url}-${Math.random()}` }));
27
-
28
- render(
29
- <BasePagination
30
- currentPage={currentPage}
31
- pages={parsedPages}
32
- currentPageSiblingsCount={currentPageSiblingsCount}
33
- getPageLabel={getPageLabel}
34
- labels={labels}
35
- />
36
- );
37
-
38
- return {
39
- currentPage,
40
- parsedPages,
41
- };
42
- }
43
-
44
- describe('Pagination', () => {
45
- describe('Rendering', () => {
46
- it('Renders the navigation buttons even if no pages are passed to it', () => {
47
- renderPagination({ currentPage: 0, pages: 0 });
48
-
49
- assert.ok(isVisible(screen.getByRole('navigation')));
50
- assert.ok(
51
- isVisible(
52
- screen.getByRole('button', {
53
- name: labels.prevAria,
54
- })
55
- )
56
- );
57
- assert.ok(
58
- isVisible(
59
- screen.getByRole('button', {
60
- name: labels.nextAria,
61
- })
62
- )
63
- );
64
- });
65
-
66
- it('Renders the passed pages and current page', () => {
67
- const { currentPage, parsedPages } = renderPagination({
68
- pages: 4,
69
- });
70
-
71
- const pageElements = screen.getAllByRole('link');
72
-
73
- assert.equal(pageElements.length, parsedPages.length);
74
-
75
- pageElements.forEach((page, index) => {
76
- if (index + 1 === currentPage) {
77
- assert.strictEqual(page.getAttribute('aria-current'), 'page');
78
- }
79
-
80
- assert.ok(isVisible(page));
81
- });
82
- });
83
- });
84
-
85
- describe('Ellipsis behavior', () => {
86
- it('When the pages size is equal or smaller than currentPageSiblingsCount + 5, all pages are shown', () => {
87
- renderPagination({
88
- pages: 6,
89
- });
90
-
91
- assert.ok(!screen.queryByText('...')?.ownerDocument);
92
-
93
- const pageElements = screen.getAllByRole('link');
94
-
95
- assert.deepEqual(
96
- pageElements.map(element => element.textContent),
97
- ['1', '2', '3', '4', '5', '6']
98
- );
99
- });
100
-
101
- it('Shows left ellipsis when the left sibling of the current page is at least two pages away from the first page', () => {
102
- renderPagination({
103
- currentPage: 5,
104
- pages: 8,
105
- });
106
-
107
- assert.ok(isVisible(screen.getByText('...')));
108
-
109
- const pageElements = screen.getAllByRole('link');
110
-
111
- assert.deepEqual(
112
- pageElements.map(element => element.textContent),
113
- ['1', '4', '5', '6', '7', '8']
114
- );
115
- });
116
-
117
- it('Shows right ellipsis when the right sibling of the current page is at least two pages away from the last page', () => {
118
- renderPagination({
119
- currentPage: 3,
120
- pages: 8,
121
- });
122
-
123
- assert.ok(isVisible(screen.getByText('...')));
124
-
125
- const pageElements = screen.getAllByRole('link');
126
-
127
- assert.deepEqual(
128
- pageElements.map(element => element.textContent),
129
- ['1', '2', '3', '4', '5', '8']
130
- );
131
- });
132
-
133
- it('Shows right and left ellipses when the current page siblings are both at least two pages away from the first and last pages', () => {
134
- renderPagination({
135
- currentPage: 5,
136
- pages: 10,
137
- });
138
-
139
- assert.equal(screen.getAllByText('...').length, 2);
140
-
141
- const pageElements = screen.getAllByRole('link');
142
-
143
- assert.deepEqual(
144
- pageElements.map(element => element.textContent),
145
- ['1', '4', '5', '6', '10']
146
- );
147
- });
148
- });
149
-
150
- describe('Navigation buttons', () => {
151
- it('Disables "Previous" button when the currentPage is equal to the first page', () => {
152
- renderPagination({
153
- pages: 2,
154
- });
155
-
156
- assert.ok(
157
- screen
158
- .getByRole('button', {
159
- name: labels.prevAria,
160
- })
161
- .getAttribute('aria-disabled')
162
- );
163
- });
164
-
165
- it('Disables "Next" button when the currentPage is equal to the last page', () => {
166
- renderPagination({
167
- currentPage: 2,
168
- pages: 2,
169
- });
170
-
171
- assert.ok(
172
- screen
173
- .getByRole('button', {
174
- name: labels.nextAria,
175
- })
176
- .getAttribute('aria-disabled')
177
- );
178
- });
179
- });
180
- });