From e02cdef593d95fc9c8ce1cb9d3a28f0dea5ee521 Mon Sep 17 00:00:00 2001 From: Malav Shah Date: Fri, 2 Jan 2026 17:45:43 -0700 Subject: [PATCH 1/5] feat(ui): Added Skip To Content --- apps/site/components/withNavBar.module.css | 18 ++++++++++++++++++ apps/site/components/withNavBar.tsx | 12 +++++++++--- apps/site/layouts/About.tsx | 4 +++- apps/site/layouts/ArticlePage.tsx | 4 +++- apps/site/layouts/Blog.tsx | 2 +- apps/site/layouts/Default.tsx | 4 +++- apps/site/layouts/Download.tsx | 2 +- apps/site/layouts/DownloadArchive.tsx | 4 +++- apps/site/layouts/GlowingBackdrop.tsx | 2 ++ apps/site/layouts/Learn.tsx | 2 +- apps/site/layouts/Post.tsx | 2 +- packages/i18n/src/locales/en.json | 3 ++- 12 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 apps/site/components/withNavBar.module.css diff --git a/apps/site/components/withNavBar.module.css b/apps/site/components/withNavBar.module.css new file mode 100644 index 0000000000000..b0f26f801566b --- /dev/null +++ b/apps/site/components/withNavBar.module.css @@ -0,0 +1,18 @@ +@reference "../styles/index.css"; + +.skipToContent { + @apply sr-only + focus:not-sr-only + focus:absolute + focus:top-4 + focus:left-4 + focus:z-50 + focus:rounded + focus:bg-green-600 + focus:px-4 + focus:py-2 + focus:text-white + focus:ring-2 + focus:ring-green-400 + focus:outline-none; +} diff --git a/apps/site/components/withNavBar.tsx b/apps/site/components/withNavBar.tsx index f62aaca997899..285ac13480651 100644 --- a/apps/site/components/withNavBar.tsx +++ b/apps/site/components/withNavBar.tsx @@ -4,7 +4,7 @@ import LanguageDropdown from '@node-core/ui-components/Common/LanguageDropDown'; import Skeleton from '@node-core/ui-components/Common/Skeleton'; import NavBar from '@node-core/ui-components/Containers/NavBar'; // TODO(@AvivKeller): I don't like that we are importing styles from another module -import styles from '@node-core/ui-components/Containers/NavBar/index.module.css'; +import navBarStyles from '@node-core/ui-components/Containers/NavBar/index.module.css'; import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub'; import { availableLocales } from '@node-core/website-i18n'; import dynamic from 'next/dynamic'; @@ -21,12 +21,14 @@ import { useRouter, usePathname } from '#site/navigation.mjs'; import type { SimpleLocaleConfig } from '@node-core/ui-components/types'; import type { FC } from 'react'; +import styles from './withNavBar.module.css'; + const ThemeToggle = dynamic( () => import('@node-core/ui-components/Common/ThemeToggle'), { ssr: false, loading: () => ( - + ), } ); @@ -55,6 +57,10 @@ const WithNavBar: FC = () => {
+ + {t('components.common.skipToContent')} + + ({ link, @@ -85,7 +91,7 @@ const WithNavBar: FC = () => { diff --git a/apps/site/layouts/About.tsx b/apps/site/layouts/About.tsx index 90ea86349a9d3..ea6260b27f1f5 100644 --- a/apps/site/layouts/About.tsx +++ b/apps/site/layouts/About.tsx @@ -16,7 +16,9 @@ const AboutLayout: FC = ({ children }) => (
-
{children}
+
+ {children} +
diff --git a/apps/site/layouts/ArticlePage.tsx b/apps/site/layouts/ArticlePage.tsx index b8369a7344ab2..37216ae07be11 100644 --- a/apps/site/layouts/ArticlePage.tsx +++ b/apps/site/layouts/ArticlePage.tsx @@ -15,7 +15,9 @@ const ArticlePageLayout: FC = ({ children }) => (
-
{children}
+
+ {children} +
diff --git a/apps/site/layouts/Blog.tsx b/apps/site/layouts/Blog.tsx index 216e793bebb12..17fb23029e896 100644 --- a/apps/site/layouts/Blog.tsx +++ b/apps/site/layouts/Blog.tsx @@ -54,7 +54,7 @@ const BlogLayout: FC = () => {
-
+
= ({ children }) => (
-
{children}
+
+ {children} +
diff --git a/apps/site/layouts/Download.tsx b/apps/site/layouts/Download.tsx index cfd6501b10678..dee2e309dc0fa 100644 --- a/apps/site/layouts/Download.tsx +++ b/apps/site/layouts/Download.tsx @@ -18,7 +18,7 @@ const DownloadLayout: FC = async ({ children }) => {
-
+

{frontmatter.title}

diff --git a/apps/site/layouts/DownloadArchive.tsx b/apps/site/layouts/DownloadArchive.tsx index 8096582ea79ef..e9e43288e5fc6 100644 --- a/apps/site/layouts/DownloadArchive.tsx +++ b/apps/site/layouts/DownloadArchive.tsx @@ -10,7 +10,9 @@ const DownloadArchiveLayout: FC = ({ children }) => (
-
{children}
+
+ {children} +
diff --git a/apps/site/layouts/GlowingBackdrop.tsx b/apps/site/layouts/GlowingBackdrop.tsx index efe869ead99d6..bbfb16430d05d 100644 --- a/apps/site/layouts/GlowingBackdrop.tsx +++ b/apps/site/layouts/GlowingBackdrop.tsx @@ -22,6 +22,8 @@ const GlowingBackdropLayout: FC<
= ({ children }) => (
-
+
{children} diff --git a/apps/site/layouts/Post.tsx b/apps/site/layouts/Post.tsx index b638b1ef8c5d5..407fed6230241 100644 --- a/apps/site/layouts/Post.tsx +++ b/apps/site/layouts/Post.tsx @@ -27,7 +27,7 @@ const PostLayout: FC = ({ children }) => {
-
+
{type === 'vulnerability' && }

{frontmatter.title}

diff --git a/packages/i18n/src/locales/en.json b/packages/i18n/src/locales/en.json index 50a030f600447..b4e0f6728a43a 100644 --- a/packages/i18n/src/locales/en.json +++ b/packages/i18n/src/locales/en.json @@ -268,7 +268,8 @@ "themeToggle": { "light": "Switch to Light Mode", "dark": "Switch to Dark Mode" - } + }, + "skipToContent": "Skip to content" }, "metabar": { "lastUpdated": "Last Updated", From d6c8016e0f6d8f7e7caf7596b6799c68b22dc345 Mon Sep 17 00:00:00 2001 From: Malav Shah Date: Fri, 2 Jan 2026 19:08:46 -0700 Subject: [PATCH 2/5] feat(ui): moved Skip to Content as a component, added test and storybook file --- apps/site/components/withNavBar.tsx | 13 +++++------- .../__tests__/index.test.jsx | 14 +++++++++++++ .../SkipToContentButton/index.module.css | 7 ++++--- .../SkipToContentButton/index.stories.tsx | 14 +++++++++++++ .../src/Common/SkipToContentButton/index.tsx | 21 +++++++++++++++++++ 5 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx rename apps/site/components/withNavBar.module.css => packages/ui-components/src/Common/SkipToContentButton/index.module.css (66%) create mode 100644 packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx create mode 100644 packages/ui-components/src/Common/SkipToContentButton/index.tsx diff --git a/apps/site/components/withNavBar.tsx b/apps/site/components/withNavBar.tsx index 285ac13480651..e2d49c6c359a7 100644 --- a/apps/site/components/withNavBar.tsx +++ b/apps/site/components/withNavBar.tsx @@ -2,9 +2,10 @@ import LanguageDropdown from '@node-core/ui-components/Common/LanguageDropDown'; import Skeleton from '@node-core/ui-components/Common/Skeleton'; +import SkipToContentButton from '@node-core/ui-components/Common/SkipToContentButton'; import NavBar from '@node-core/ui-components/Containers/NavBar'; // TODO(@AvivKeller): I don't like that we are importing styles from another module -import navBarStyles from '@node-core/ui-components/Containers/NavBar/index.module.css'; +import styles from '@node-core/ui-components/Containers/NavBar/index.module.css'; import GitHubIcon from '@node-core/ui-components/Icons/Social/GitHub'; import { availableLocales } from '@node-core/website-i18n'; import dynamic from 'next/dynamic'; @@ -21,14 +22,12 @@ import { useRouter, usePathname } from '#site/navigation.mjs'; import type { SimpleLocaleConfig } from '@node-core/ui-components/types'; import type { FC } from 'react'; -import styles from './withNavBar.module.css'; - const ThemeToggle = dynamic( () => import('@node-core/ui-components/Common/ThemeToggle'), { ssr: false, loading: () => ( - + ), } ); @@ -57,9 +56,7 @@ const WithNavBar: FC = () => {
- - {t('components.common.skipToContent')} - + ({ @@ -91,7 +88,7 @@ const WithNavBar: FC = () => { diff --git a/packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx b/packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx new file mode 100644 index 0000000000000..450347dd3a619 --- /dev/null +++ b/packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx @@ -0,0 +1,14 @@ +import { describe, it } from 'node:test'; +import assert from 'node:assert/strict'; + +import { render, screen } from '@testing-library/react'; + +import SkipToContentButton from '../'; + +describe('SkipToContentButton', () => { + it('renders with correct label', () => { + render(); + const link = screen.getByRole('link', { name: 'Skip to content' }); + assert.ok(link); + }); +}); diff --git a/apps/site/components/withNavBar.module.css b/packages/ui-components/src/Common/SkipToContentButton/index.module.css similarity index 66% rename from apps/site/components/withNavBar.module.css rename to packages/ui-components/src/Common/SkipToContentButton/index.module.css index b0f26f801566b..cd8457908d2d3 100644 --- a/apps/site/components/withNavBar.module.css +++ b/packages/ui-components/src/Common/SkipToContentButton/index.module.css @@ -1,4 +1,4 @@ -@reference "../styles/index.css"; +@reference "../../styles/index.css"; .skipToContent { @apply sr-only @@ -13,6 +13,7 @@ focus:py-2 focus:text-white focus:ring-2 - focus:ring-green-400 - focus:outline-none; + focus:ring-green-500 + focus:outline-none + dark:focus:ring-green-400; } diff --git a/packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx b/packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx new file mode 100644 index 0000000000000..7a555d3efcae7 --- /dev/null +++ b/packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx @@ -0,0 +1,14 @@ +import SkipToContentButton from '#ui/Common/SkipToContentButton'; + +import type { Meta as MetaObj, StoryObj } from '@storybook/react-webpack5'; + +type Story = StoryObj; +type Meta = MetaObj; + +export const Default: Story = { + args: { + label: 'Skip to content', + }, +}; + +export default { component: SkipToContentButton } as Meta; diff --git a/packages/ui-components/src/Common/SkipToContentButton/index.tsx b/packages/ui-components/src/Common/SkipToContentButton/index.tsx new file mode 100644 index 0000000000000..b0ccbe1a21c60 --- /dev/null +++ b/packages/ui-components/src/Common/SkipToContentButton/index.tsx @@ -0,0 +1,21 @@ +import type { FC, AnchorHTMLAttributes } from 'react'; + +import styles from './index.module.css'; + +type SkipToContentButtonProps = AnchorHTMLAttributes & { + label: string; +}; + +const SkipToContentButton: FC = ({ + label, + href = '#main', + ...props +}) => { + return ( + + {label} + + ); +}; + +export default SkipToContentButton; From 8e83b4e0192512470661ea685e56ed0a5dd31433 Mon Sep 17 00:00:00 2001 From: Malav Shah Date: Sat, 3 Jan 2026 16:14:29 -0700 Subject: [PATCH 3/5] feat(tests): remove SkipToContentButton test file --- .../SkipToContentButton/__tests__/index.test.jsx | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx diff --git a/packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx b/packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx deleted file mode 100644 index 450347dd3a619..0000000000000 --- a/packages/ui-components/src/Common/SkipToContentButton/__tests__/index.test.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import { describe, it } from 'node:test'; -import assert from 'node:assert/strict'; - -import { render, screen } from '@testing-library/react'; - -import SkipToContentButton from '../'; - -describe('SkipToContentButton', () => { - it('renders with correct label', () => { - render(); - const link = screen.getByRole('link', { name: 'Skip to content' }); - assert.ok(link); - }); -}); From 37aa948460abc1d14b6e294fc7546ef3d2191498 Mon Sep 17 00:00:00 2001 From: Malav Shah Date: Sat, 3 Jan 2026 16:21:24 -0700 Subject: [PATCH 4/5] feat(ui): refactor SkipToContentButton to use children prop instead of label --- apps/site/components/withNavBar.tsx | 4 +++- .../src/Common/SkipToContentButton/index.stories.tsx | 2 +- .../src/Common/SkipToContentButton/index.tsx | 12 ++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/site/components/withNavBar.tsx b/apps/site/components/withNavBar.tsx index e2d49c6c359a7..59c07eebbccea 100644 --- a/apps/site/components/withNavBar.tsx +++ b/apps/site/components/withNavBar.tsx @@ -56,7 +56,9 @@ const WithNavBar: FC = () => {
- + + {t('components.common.skipToContent')} + ({ diff --git a/packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx b/packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx index 7a555d3efcae7..97c9775478c0a 100644 --- a/packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx +++ b/packages/ui-components/src/Common/SkipToContentButton/index.stories.tsx @@ -7,7 +7,7 @@ type Meta = MetaObj; export const Default: Story = { args: { - label: 'Skip to content', + children: 'Skip to content', }, }; diff --git a/packages/ui-components/src/Common/SkipToContentButton/index.tsx b/packages/ui-components/src/Common/SkipToContentButton/index.tsx index b0ccbe1a21c60..6f4024eb63130 100644 --- a/packages/ui-components/src/Common/SkipToContentButton/index.tsx +++ b/packages/ui-components/src/Common/SkipToContentButton/index.tsx @@ -1,19 +1,19 @@ -import type { FC, AnchorHTMLAttributes } from 'react'; +import type { FC, AnchorHTMLAttributes, PropsWithChildren } from 'react'; import styles from './index.module.css'; -type SkipToContentButtonProps = AnchorHTMLAttributes & { - label: string; -}; +type SkipToContentButtonProps = PropsWithChildren< + AnchorHTMLAttributes +>; const SkipToContentButton: FC = ({ - label, + children, href = '#main', ...props }) => { return ( - {label} + {children} ); }; From 1e671bab55989e07a7e0a142c4896c322b36f172 Mon Sep 17 00:00:00 2001 From: Malav Shah Date: Sun, 4 Jan 2026 11:16:49 -0700 Subject: [PATCH 5/5] feat(ui): update WithNavBar component structure for improved accessibility --- apps/site/components/withNavBar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/site/components/withNavBar.tsx b/apps/site/components/withNavBar.tsx index 59c07eebbccea..9a9ace98e1eb0 100644 --- a/apps/site/components/withNavBar.tsx +++ b/apps/site/components/withNavBar.tsx @@ -54,12 +54,12 @@ const WithNavBar: FC = () => { return (
- - {t('components.common.skipToContent')} + + ({ link,