From d616ca0297bb95c04842457444e63258ea953e3a Mon Sep 17 00:00:00 2001 From: Baluduvamsi2006 Date: Sat, 14 Mar 2026 02:22:05 +0530 Subject: [PATCH] feat: add native dark mode toggle to header layout - Introduces DarkModeToggleBtn component with accessible UI controls - Toggles Mantine color scheme between light and dark modes - Updates Header to display toggle button in action group - Enables seamless light/dark theme switching across entire application --- src/components/Header/DarkModeToggleBtn.tsx | 37 +++++++++++++++++++++ src/components/Header/index.tsx | 2 ++ 2 files changed, 39 insertions(+) create mode 100644 src/components/Header/DarkModeToggleBtn.tsx diff --git a/src/components/Header/DarkModeToggleBtn.tsx b/src/components/Header/DarkModeToggleBtn.tsx new file mode 100644 index 0000000000..1b0071bf21 --- /dev/null +++ b/src/components/Header/DarkModeToggleBtn.tsx @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ActionIcon, useComputedColorScheme, useMantineColorScheme } from '@mantine/core'; +import { IconDarkMode, IconLightMode } from '@tabler/icons-react'; + +export const DarkModeToggleBtn = () => { + const { toggleColorScheme } = useMantineColorScheme(); + const computedColorScheme = useComputedColorScheme('light', { getInitialValueInEffect: false }); + const isDark = computedColorScheme === 'dark'; + + return ( + toggleColorScheme()} + variant="light" + size="sm" + aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'} + title={isDark ? 'Switch to light mode' : 'Switch to dark mode'} + > + {isDark ? : } + + ); +}; diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 75e8bc9da8..8852a4d3f3 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -20,6 +20,7 @@ import { useTranslation } from 'react-i18next'; import apisixLogo from '@/assets/apisix-logo.svg'; +import { DarkModeToggleBtn } from './DarkModeToggleBtn'; import { LanguageMenu } from './LanguageMenu'; import { SettingModalBtn } from './SettingModalBtn'; @@ -46,6 +47,7 @@ export const Header: FC = (props) => {
{t('apisix.dashboard')}
+