Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions template/components/color-mode-switch/ColorModeSwitch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { DBSwitch, DBTooltip } from "@db-ux/react-core-components";
import { useColorMode } from "@template/context/color-mode-context.tsx";

const ColorModeSwitch = () => {
const { colorMode, toggleColorMode } = useColorMode();
const isDark = colorMode === "dark";

return (
<DBSwitch
checked={isDark}
visualAid
icon="sun"
iconTrailing="moon"
showLabel={false}
onChange={toggleColorMode}>
<DBTooltip>
Switch color scheme (light/dark)
</DBTooltip>
Switch color scheme (light/dark)
</DBSwitch>
);
};

export default ColorModeSwitch;
66 changes: 66 additions & 0 deletions template/context/color-mode-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {
createContext,
useContext,
useState,
useEffect,
type ReactNode,
} from "react";

type ColorMode = "light" | "dark";

interface ColorModeContextValue {
colorMode: ColorMode;
setColorMode: (colorMode: ColorMode) => void;
toggleColorMode: () => void;
}

const STORAGE_KEY = "db-ux-mode";
const SHELL_SELECTOR = ".db-shell";

const ColorModeContext = createContext<ColorModeContextValue | undefined>(undefined);

function getInitialColorMode(): ColorMode {
if (typeof window === "undefined") {
return "light";
}

const stored = window.localStorage.getItem(STORAGE_KEY);
if (stored === "light" || stored === "dark") {
return stored;
}

return "light";
}

export const ColorModeProvider = ({ children }: { children: ReactNode }) => {
const [colorMode, setColorMode] = useState<ColorMode>(getInitialColorMode);

useEffect(() => {
window.localStorage.setItem("db-ux-mode", colorMode);

const shell = document.querySelector(SHELL_SELECTOR);
if (shell instanceof HTMLElement) {
shell.setAttribute("data-mode", colorMode);
}
}, [colorMode]);

const setMode = (next: ColorMode) => {
setColorMode(next);
};

const toggleColorMode = () => {
setColorMode((prev) => (prev === "light" ? "dark" : "light"));
};

const value: ColorModeContextValue = { colorMode, setColorMode: setMode, toggleColorMode };

return <ColorModeContext.Provider value={value}>{children}</ColorModeContext.Provider>;
};

export const useColorMode = (): ColorModeContextValue => {
const ctx = useContext(ColorModeContext);
if (!ctx) {
throw new Error("useColorMode must be used inside a ColorModeProvider");
}
return ctx;
};
74 changes: 36 additions & 38 deletions template/layouts/default/shell/Shell.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
import { type PropsWithChildren, type ReactElement } from "react";

import {
DBControlPanelDesktop,
DBControlPanelMobile,
DBShell,
} from "@db-ux/react-core-components";
import { ColorModeProvider } from "@template/context/color-mode-context.tsx";
import { DBControlPanelDesktop, DBControlPanelMobile, DBShell } from "@db-ux/react-core-components";
import PrimaryActions from "@template/layouts/default/shell/control-panel/primary-actions.tsx";
import MainNavigation from "@template/layouts/default/shell/control-panel/main-navigation.tsx";
import SubNavigation from "@template/layouts/default/shell/control-panel/sub-navigation.tsx";
import Brand from "@template/layouts/default/shell/control-panel/brand.tsx";
import { findSubNavigation } from "@template/utils/navigation.utils.ts";

export function Shell({ children }: PropsWithChildren): ReactElement {
const subNavigation = findSubNavigation(window.location.pathname);
const subNavigation = findSubNavigation(window.location.pathname);

/*
* TODO: We need to get the subNavigation if we are inside a subNavigation Item as well
* */
/*
* TODO: We need to get the subNavigation if we are inside a subNavigation Item as well
* */

return (
<DBShell
fadeIn
subNavigationDesktopPosition="left"
subNavigation={
subNavigation ? <SubNavigation navigationItems={subNavigation} /> : null
}
subNavigationMobilePosition="none"
controlPanelDesktop={
<DBControlPanelDesktop
brand={<Brand />}
primaryActions={<PrimaryActions />}
>
<MainNavigation />
</DBControlPanelDesktop>
}
controlPanelMobile={
<DBControlPanelMobile
brand={<Brand />}
primaryActions={<PrimaryActions />}
>
<MainNavigation mobile />
</DBControlPanelMobile>
}
>
{children}
</DBShell>
);
return (
<ColorModeProvider>
<DBShell
fadeIn
subNavigationDesktopPosition="left"
subNavigation={
subNavigation ? <SubNavigation navigationItems={subNavigation} /> : null
}
subNavigationMobilePosition="none"
controlPanelDesktop={
<DBControlPanelDesktop
brand={<Brand />}
primaryActions={<PrimaryActions />}
>
<MainNavigation />
</DBControlPanelDesktop>
}
controlPanelMobile={
<DBControlPanelMobile
brand={<Brand />}
primaryActions={<PrimaryActions />}
>
<MainNavigation mobile />
</DBControlPanelMobile>
}
>
{children}
</DBShell>
</ColorModeProvider>
);
}
14 changes: 8 additions & 6 deletions template/layouts/default/shell/control-panel/primary-actions.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { DBControlPanelPrimaryActions } from "@db-ux/react-core-components";
import { appConfig } from "@root/app.config.ts";
import { Search } from "@template/layouts/default/shell/search";
import ColorModeSwitch from "@template/components/color-mode-switch/ColorModeSwitch.tsx";

const PrimaryActions = () => (
<DBControlPanelPrimaryActions>
{ <Search /> }
<a className="db-button" href={`${appConfig.basePath}resources/documentation/getting-started`} data-variant="brand">
Start now
</a>
</DBControlPanelPrimaryActions>
<DBControlPanelPrimaryActions>
<ColorModeSwitch />
<Search />
<a className="db-button" href={`${appConfig.basePath}resources/documentation/getting-started`} data-variant="brand">
Start now
</a>
</DBControlPanelPrimaryActions>
);

export default PrimaryActions;
2 changes: 1 addition & 1 deletion template/layouts/default/shell/search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export function Search(): ReactElement {
onClick={() => setSearchOpen(true)}
>
Open Search
<DBTooltip placement="left">Open Search</DBTooltip>
<DBTooltip>Open Search</DBTooltip>
</DBButton>
<DBDrawer open={searchOpen} onClose={() => setSearchOpen(false)}>
<div className="dba-search-result-container">
Expand Down