Files
inbuxa-admin/src/stores/uiStore.ts
T

78 lines
1.8 KiB
TypeScript

/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
type Theme = 'light' | 'dark';
interface UIState {
theme: Theme;
sidebarOpen: boolean;
activeSection: string;
toggleTheme: () => void;
setTheme: (theme: Theme) => void;
toggleSidebar: () => void;
setSidebarOpen: (open: boolean) => void;
setActiveSection: (section: string) => void;
}
function applyThemeClass(theme: Theme) {
if (theme === 'dark') {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}
export const useUIStore = create<UIState>()(
persist(
(set, get) => ({
theme:
typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light',
sidebarOpen: typeof window !== 'undefined' ? (window.matchMedia?.('(min-width: 768px)').matches ?? true) : true,
activeSection: '',
toggleTheme: () => {
const next = get().theme === 'light' ? 'dark' : 'light';
applyThemeClass(next);
set({ theme: next });
},
setTheme: (theme) => {
applyThemeClass(theme);
set({ theme });
},
toggleSidebar: () => {
set({ sidebarOpen: !get().sidebarOpen });
},
setSidebarOpen: (open) => {
set({ sidebarOpen: open });
},
setActiveSection: (section) => {
set({ activeSection: section });
},
}),
{
name: 'stalwart-ui',
partialize: (state) => ({
theme: state.theme,
}),
onRehydrateStorage: () => {
return (state) => {
if (state) {
applyThemeClass(state.theme);
}
};
},
},
),
);