Skip to main content
Glama

mcp-google-sheets

theme-provider.tsx3.3 kB
import { createContext, useContext, useEffect, useState } from 'react'; import * as RippleHook from 'use-ripple-hook'; import { flagsHooks } from '@/hooks/flags-hooks'; import { colorsUtils } from '@/lib/color-util'; type Theme = 'dark' | 'light' | 'system'; type ThemeProviderProps = { children: React.ReactNode; defaultTheme?: Theme; storageKey?: string; }; type ThemeProviderState = { theme: Theme; setTheme: (theme: Theme) => void; }; const initialState: ThemeProviderState = { theme: 'system', setTheme: () => null, }; const ThemeProviderContext = createContext<ThemeProviderState>(initialState); const setFavicon = (url: string) => { let link: HTMLLinkElement | null = document.querySelector("link[rel*='icon']"); if (!link) { link = document.createElement('link'); link.rel = 'shortcut icon'; document.head.appendChild(link); } link.href = url; }; export function ThemeProvider({ children, defaultTheme = 'system', storageKey = 'ap-ui-theme', ...props }: ThemeProviderProps) { const [theme, setTheme] = useState<Theme>( () => (localStorage.getItem(storageKey) as Theme) || defaultTheme, ); const branding = flagsHooks.useWebsiteBranding(); useEffect(() => { if (!branding) { console.warn('Website brand is not defined'); return; } const root = window.document.documentElement; const resolvedTheme = theme === 'system' ? 'light' : theme; root.classList.remove('light', 'dark'); document.title = branding.websiteName; document.documentElement.style.setProperty( '--primary', colorsUtils.hexToHslString(branding.colors.primary.default), ); setFavicon(branding.logos.favIconUrl); switch (resolvedTheme) { case 'light': { document.documentElement.style.setProperty( '--primary-100', colorsUtils.hexToHslString(branding.colors.primary.light), ); document.documentElement.style.setProperty( '--primary-300', colorsUtils.hexToHslString(branding.colors.primary.dark), ); break; } case 'dark': { document.documentElement.style.setProperty( '--primary-100', colorsUtils.hexToHslString(branding.colors.primary.dark), ); document.documentElement.style.setProperty( '--primary-300', colorsUtils.hexToHslString(branding.colors.primary.light), ); break; } default: break; } root.classList.add(resolvedTheme); }, [theme, branding]); const value = { theme, setTheme: (theme: Theme) => { localStorage.setItem(storageKey, theme); setTheme(theme); }, }; return ( <ThemeProviderContext.Provider {...props} value={value}> {children} </ThemeProviderContext.Provider> ); } export const useTheme = () => { const context = useContext(ThemeProviderContext); if (context === undefined) throw new Error('useTheme must be used within a ThemeProvider'); return context; }; export const useApRipple = () => { const { theme } = useTheme(); return RippleHook.default({ color: theme === 'dark' ? 'rgba(233, 233, 233, 0.2)' : 'rgba(155, 155, 155, 0.2)', cancelAutomatically: true, }); };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server