UNPKG

@brutalcomponent/react

Version:
329 lines (323 loc) 8.54 kB
'use strict'; var React = require('react'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var React__default = /*#__PURE__*/_interopDefault(React); /** * @brutalcomponent/react * (c) David Heffler (https://dvh.sh) * Licensed under MIT */ var brutalThemes = { // Default monochrome + pastels default: { name: "default", label: "Default", colors: { white: "#FFFFFF", black: "#000000", gray: { 50: "#FAFAFA", 100: "#F5F5F5", 200: "#E5E5E5", 300: "#D4D4D4", 400: "#A3A3A3", 500: "#737373", 600: "#525252", 700: "#404040", 800: "#262626", 900: "#171717" }, accent: { primary: "#FFD6E8", // pink secondary: "#D6EDFF", // sky tertiary: "#D6FFE5", // mint quaternary: "#FFE5D6" // peach }, success: "#D6FFE5", warning: "#FFF3D6", danger: "#FFD6D6", info: "#D6EDFF" }, shadows: { sm: "2px 2px 0px 0px rgba(0,0,0,1)", base: "4px 4px 0px 0px rgba(0,0,0,1)", md: "6px 6px 0px 0px rgba(0,0,0,1)", lg: "8px 8px 0px 0px rgba(0,0,0,1)", xl: "12px 12px 0px 0px rgba(0,0,0,1)" } }, // Dark mode dark: { name: "dark", label: "Dark", colors: { white: "#000000", black: "#FFFFFF", gray: { 50: "#171717", 100: "#262626", 200: "#404040", 300: "#525252", 400: "#737373", 500: "#A3A3A3", 600: "#D4D4D4", 700: "#E5E5E5", 800: "#F5F5F5", 900: "#FAFAFA" }, accent: { primary: "#FF69B4", // hot pink secondary: "#00CED1", // dark turquoise tertiary: "#32CD32", // lime green quaternary: "#FF6347" // tomato }, success: "#32CD32", warning: "#FFD700", danger: "#DC143C", info: "#1E90FF" }, shadows: { sm: "2px 2px 0px 0px rgba(255,255,255,1)", base: "4px 4px 0px 0px rgba(255,255,255,1)", md: "6px 6px 0px 0px rgba(255,255,255,1)", lg: "8px 8px 0px 0px rgba(255,255,255,1)", xl: "12px 12px 0px 0px rgba(255,255,255,1)" } }, // High contrast contrast: { name: "contrast", label: "High Contrast", colors: { white: "#FFFFFF", black: "#000000", gray: { 50: "#FFFFFF", 100: "#F0F0F0", 200: "#CCCCCC", 300: "#999999", 400: "#666666", 500: "#333333", 600: "#1A1A1A", 700: "#0D0D0D", 800: "#050505", 900: "#000000" }, accent: { primary: "#FF0000", // pure red secondary: "#0000FF", // pure blue tertiary: "#00FF00", // pure green quaternary: "#FFFF00" // pure yellow }, success: "#00FF00", warning: "#FFFF00", danger: "#FF0000", info: "#0000FF" }, shadows: { sm: "3px 3px 0px 0px rgba(0,0,0,1)", base: "5px 5px 0px 0px rgba(0,0,0,1)", md: "7px 7px 0px 0px rgba(0,0,0,1)", lg: "10px 10px 0px 0px rgba(0,0,0,1)", xl: "15px 15px 0px 0px rgba(0,0,0,1)" } }, // Neon neon: { name: "neon", label: "Neon", colors: { white: "#0A0A0A", black: "#FFFFFF", gray: { 50: "#1A1A1A", 100: "#2A2A2A", 200: "#3A3A3A", 300: "#4A4A4A", 400: "#5A5A5A", 500: "#7A7A7A", 600: "#9A9A9A", 700: "#BABABA", 800: "#DADADA", 900: "#FAFAFA" }, accent: { primary: "#FF00FF", // magenta secondary: "#00FFFF", // cyan tertiary: "#FFFF00", // yellow quaternary: "#FF00AA" // pink }, success: "#00FF88", warning: "#FFAA00", danger: "#FF0055", info: "#00AAFF" }, shadows: { sm: "2px 2px 0px 0px rgba(255,0,255,0.8)", base: "4px 4px 0px 0px rgba(255,0,255,0.8)", md: "6px 6px 0px 0px rgba(255,0,255,0.8)", lg: "8px 8px 0px 0px rgba(255,0,255,0.8)", xl: "12px 12px 0px 0px rgba(255,0,255,0.8)" } }, // Newspaper paper: { name: "paper", label: "Newspaper", colors: { white: "#FFF9E6", black: "#1A1611", gray: { 50: "#FFF9E6", 100: "#F7F1DC", 200: "#E8DFC8", 300: "#D4C8AA", 400: "#B8A887", 500: "#8B7B61", 600: "#5F5343", 700: "#3D352B", 800: "#2B251D", 900: "#1A1611" }, accent: { primary: "#B8A887", // sepia secondary: "#8B4513", // saddle brown tertiary: "#2F4F4F", // dark slate gray quaternary: "#800020" // burgundy }, success: "#556B2F", warning: "#DAA520", danger: "#8B0000", info: "#483D8B" }, shadows: { sm: "2px 2px 0px 0px rgba(26,22,17,0.8)", base: "4px 4px 0px 0px rgba(26,22,17,0.8)", md: "6px 6px 0px 0px rgba(26,22,17,0.8)", lg: "8px 8px 0px 0px rgba(26,22,17,0.8)", xl: "12px 12px 0px 0px rgba(26,22,17,0.8)" } } }; var ThemeContext = React.createContext(void 0); var ThemeProvider = ({ children, defaultTheme = "default", storageKey = "brutal-theme" }) => { const [themeName, setThemeName] = React.useState(defaultTheme); const [accentColor, setAccentColor] = React.useState("primary"); const [mounted, setMounted] = React.useState(false); const theme = brutalThemes[themeName] || brutalThemes.default; React.useEffect(() => { const savedTheme = localStorage.getItem(storageKey); const savedAccent = localStorage.getItem( `${storageKey}-accent` ); if (savedTheme && brutalThemes[savedTheme]) { setThemeName(savedTheme); } if (savedAccent && ["primary", "secondary", "tertiary", "quaternary"].includes(savedAccent)) { setAccentColor(savedAccent); } setMounted(true); }, [storageKey]); React.useEffect(() => { if (!mounted) return; const root = document.documentElement; root.style.setProperty("--brutal-white", theme.colors.white); root.style.setProperty("--brutal-black", theme.colors.black); Object.entries(theme.colors.gray).forEach(([key, value]) => { root.style.setProperty(`--brutal-gray-${key}`, value); }); Object.entries(theme.colors.accent).forEach(([key, value]) => { root.style.setProperty(`--brutal-accent-${key}`, value); }); root.style.setProperty("--brutal-accent", theme.colors.accent[accentColor]); root.style.setProperty("--brutal-success", theme.colors.success); root.style.setProperty("--brutal-warning", theme.colors.warning); root.style.setProperty("--brutal-danger", theme.colors.danger); root.style.setProperty("--brutal-info", theme.colors.info); Object.entries(theme.shadows).forEach(([key, value]) => { root.style.setProperty(`--brutal-shadow-${key}`, value); }); localStorage.setItem(storageKey, themeName); localStorage.setItem(`${storageKey}-accent`, accentColor); }, [theme, themeName, accentColor, mounted, storageKey]); const handleSetTheme = (newThemeName) => { if (brutalThemes[newThemeName]) { setThemeName(newThemeName); } }; if (!mounted) { return null; } return /* @__PURE__ */ React__default.default.createElement( ThemeContext.Provider, { value: { theme, themeName, setTheme: handleSetTheme, accentColor, setAccentColor } }, children ); }; var useTheme = () => { const context = React.useContext(ThemeContext); if (!context) { throw new Error("useTheme must be used within a ThemeProvider"); } return context; }; /** * @file src/providers/ThemeProvider.tsx * @author David (https://dvh.sh) * @license MIT * * @created Fri Sep 12 2025 * @updated Fri Sep 12 2025 * * @description * Theme provider for brutal component library with multiple theme support * @client This component requires client-side JavaScript */ /** * @file src/providers/index.ts * @author David (https://dvh.sh) * @license MIT * * @created Fri Sep 12 2025 * @updated Fri Sep 12 2025 * * @description * Barrel export for context providers. */ exports.ThemeProvider = ThemeProvider; exports.brutalThemes = brutalThemes; exports.useTheme = useTheme; //# sourceMappingURL=chunk-C2WN7L23.js.map //# sourceMappingURL=chunk-C2WN7L23.js.map