@brutalcomponent/react
Version:
Brutalist React components
329 lines (323 loc) • 8.54 kB
JavaScript
;
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