@buschschwick/uac-ui
v1.1.0
Published
Black-and-white brutalist monospace component library for React, built on Material UI.
Maintainers
Readme
@buschschwick/uac-ui
A black-and-white brutalist monospace component library for React, built on
Material UI. It packages the design language used by cord
and wave-viewer — pure black surfaces, white text, monospace type, sharp
corners, no shadows, structure defined by 1px borders at varying opacity — as a
reusable MUI theme plus a small set of themed components.
Install
npm install @buschschwick/uac-ui @mui/material @mui/system @emotion/react @emotion/styled
# (react and react-dom are expected to already be in your app)@mui/material, @mui/system, @emotion/react, @emotion/styled, react, and
react-dom are peer dependencies — your app provides them, so there's only
one copy of React/emotion at runtime.
Usage
Wrap your app once in UacThemeProvider, then import themed components from the
package:
import {
UacThemeProvider,
Panel,
SectionLabel,
Button,
Input,
} from "@buschschwick/uac-ui";
export default function App() {
return (
<UacThemeProvider>
<Panel padding={6}>
<SectionLabel>chords</SectionLabel>
<Input placeholder="search chords…" fullWidth />
<Button variant="outlined">add</Button>
<Button variant="contained">save</Button> {/* inverted white/black */}
</Panel>
</UacThemeProvider>
);
}No Tailwind is required in the consuming app — all styling ships via emotion in the theme.
Components
UacThemeProvider, Panel, SectionLabel, Input, Modal, ColorField,
plus themed MUI re-exports: Button, IconButton, TextField, Chip, Tabs,
Tab, Select, MenuItem, Dialog, Card, Paper, ToggleButton,
ToggleButtonGroup, Typography, Box, Stack, Container, Grid,
Divider, Collapse, Slider, Switch, FormControl, FormControlLabel,
InputLabel, Menu, Tooltip, CircularProgress, Link.
Because the look lives entirely in the theme, you can also use any other MUI
component imported directly from @mui/material and it will match.
Color switching
The default look is black/white, but the whole UI can be recolored at runtime —
this is what powers wave-viewer's background/primary color picker. Give
UacThemeProvider a background and a primary color; the foreground (text,
borders, the muted alpha ramp) is derived automatically for readable contrast,
flipping to dark text on light backgrounds.
import { UacThemeProvider, ColorField, useUacColors } from "@buschschwick/uac-ui";
function ColorControls() {
// Read and update the live theme colors from anywhere in the tree.
const { backgroundColor, primaryColor, setBackgroundColor, setPrimaryColor } =
useUacColors();
return (
<>
<ColorField label="background" value={backgroundColor} onChange={setBackgroundColor} />
<ColorField label="primary" value={primaryColor} onChange={setPrimaryColor} />
</>
);
}
export default function App() {
return (
// Uncontrolled: the provider owns the colors. (Or drive them with the
// controlled `backgroundColor` / `primaryColor` + `onColorsChange` props.)
<UacThemeProvider defaultBackgroundColor="#000000" defaultPrimaryColor="#4ade80">
<ColorControls />
{/* ...the rest of the app recolors live... */}
</UacThemeProvider>
);
}createUacTheme accepts the same colors directly, alongside the color-math
helpers (readableForeground, withAlpha, alphaRamp, …) re-exported from the
package for use in non-MUI surfaces such as a <canvas>:
import { createUacTheme, readableForeground } from "@buschschwick/uac-ui";
const theme = createUacTheme({ backgroundColor: "#101418", primaryColor: "#ff4d4d" });
const textColor = readableForeground("#101418"); // "#ffffff"Theme & tokens
Use the theme without the provider, or merge customizations on top:
import { createUacTheme, uacTheme } from "@buschschwick/uac-ui";
const theme = createUacTheme({
palette: { primary: { main: "#00e5ff" } }, // deep-merged onto the base
});Raw design tokens are exported from the /theme subpath for non-MUI use (for
example, styling a <canvas>):
import { tokens } from "@buschschwick/uac-ui/theme";
ctx.strokeStyle = tokens.color.whiteAlpha[40];
ctx.font = `14px ${tokens.font.mono}`;Development
npm install
npm run storybook # visual playground / living docs at :6006
npm run build # bundle to dist/ (ESM + CJS + .d.ts) via tsup
npm run typecheck
npm run lintLicense
Unlicense — public domain.
