diff --git a/apps/site/components/withNavBar.tsx b/apps/site/components/withNavBar.tsx
index 8cab6b824c919..24ca3d9d794f2 100644
--- a/apps/site/components/withNavBar.tsx
+++ b/apps/site/components/withNavBar.tsx
@@ -2,7 +2,6 @@
import LanguageDropdown from '@node-core/ui-components/Common/LanguageDropDown';
import Skeleton from '@node-core/ui-components/Common/Skeleton';
-import ThemeToggle from '@node-core/ui-components/Common/ThemeToggle';
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';
@@ -27,6 +26,16 @@ const SearchButton = dynamic(() => import('#site/components/Common/Search'), {
),
});
+const ThemeToggle = dynamic(
+ () => import('@node-core/ui-components/Common/ThemeToggle'),
+ {
+ ssr: false,
+ loading: () => (
+
+ ),
+ }
+);
+
const WithNavBar: FC = () => {
const { navigationItems } = useSiteNavigation();
const { resolvedTheme, setTheme } = useTheme();
@@ -39,6 +48,11 @@ const WithNavBar: FC = () => {
const toggleCurrentTheme = () =>
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark');
+ const themeToggleAriaLabel =
+ resolvedTheme === 'dark'
+ ? t('components.common.themeToggle.light')
+ : t('components.common.themeToggle.dark');
+
const changeLanguage = (locale: SimpleLocaleConfig) =>
replace(pathname!, { locale: locale.code });
@@ -63,7 +77,7 @@ const WithNavBar: FC = () => {
- page.evaluate(() => document.documentElement.dataset.theme);
+ page.evaluate(
+ () => document.documentElement.dataset.theme as 'light' | 'dark'
+ );
+
+const getCurrentAriaLabel = (theme: string) =>
+ theme === 'dark'
+ ? locators.themeToggleAriaLabels.light
+ : locators.themeToggleAriaLabels.dark;
const openLanguageMenu = async (page: Page) => {
const button = page.getByRole('button', {
@@ -65,21 +74,27 @@ test.describe('Node.js Website', () => {
test.describe('Theme', () => {
test('should toggle between light/dark themes', async ({ page }) => {
const themeToggle = page.getByRole('button', {
- name: locators.themeToggleName,
+ name: /Switch to (Light|Dark) Mode/i,
});
- await expect(themeToggle).toBeVisible();
const initialTheme = await getTheme(page);
+ const initialAriaLabel = getCurrentAriaLabel(initialTheme);
+ let currentAriaLabel = await themeToggle.getAttribute('aria-label');
+ expect(currentAriaLabel).toBe(initialAriaLabel);
+
await themeToggle.click();
const newTheme = await getTheme(page);
- expect(newTheme).not.toEqual(initialTheme);
- expect(['light', 'dark']).toContain(newTheme);
+ const newAriaLabel = getCurrentAriaLabel(newTheme);
+ currentAriaLabel = await themeToggle.getAttribute('aria-label');
+
+ expect(newTheme).not.toBe(initialTheme);
+ expect(currentAriaLabel).toBe(newAriaLabel);
});
test('should persist theme across page navigation', async ({ page }) => {
const themeToggle = page.getByRole('button', {
- name: locators.themeToggleName,
+ name: /Switch to (Light|Dark) Mode/i,
});
await themeToggle.click();
const selectedTheme = await getTheme(page);
diff --git a/packages/i18n/src/locales/en.json b/packages/i18n/src/locales/en.json
index cadcca42859f3..5465c88e9882e 100644
--- a/packages/i18n/src/locales/en.json
+++ b/packages/i18n/src/locales/en.json
@@ -229,7 +229,8 @@
"label": "Choose Language"
},
"themeToggle": {
- "label": "Toggle Dark Mode"
+ "light": "Switch to Light Mode",
+ "dark": "Switch to Dark Mode"
}
},
"metabar": {
diff --git a/packages/ui-components/src/Containers/NavBar/index.module.css b/packages/ui-components/src/Containers/NavBar/index.module.css
index 331f63f46d83c..764c0edd5ec7a 100644
--- a/packages/ui-components/src/Containers/NavBar/index.module.css
+++ b/packages/ui-components/src/Containers/NavBar/index.module.css
@@ -108,6 +108,12 @@ span.searchButtonSkeleton {
}
}
+span.themeToggleSkeleton {
+ @apply size-9
+ rounded-md
+ py-4;
+}
+
.ghIconWrapper {
@apply size-9
rounded-md