An atomic, CSS-first, user interface toolkit and library for building custom elements and user interfaces. Built on the web platform, Material Design 3 specifications, and the Lit library.
pnpm add @atomic/ui
# or
npm install @atomic/ui
# or
yarn add @atomic/ui@atomic/ui provides a comprehensive Material Design 3 component library with two approaches:
- CSS-First Components — Pure CSS/SCSS modules that can be used with any framework or vanilla HTML
- Custom Elements — Web components built with Lit for enhanced functionality and encapsulation
The following custom elements are complete and ready to use:
| Component | Description | Status |
|---|---|---|
ez-appbar |
Top application bar with Material Design 3 styling | ✅ MVP Complete |
ez-base |
Base class for building custom elements | ✅ MVP Complete |
ez-button-surface |
Interactive button surface with ripple effects | ✅ MVP Complete |
ez-field |
Form field wrapper component | ✅ MVP Complete |
ez-ripple |
Material Design 3 state layer / ripple effect | ✅ MVP Complete |
ez-shape |
Shape morphing and styling utilities | ✅ MVP Complete |
import '@atomic/ui/ez-appbar';
// Use in HTML
<ez-appbar>
<h1>My Application</h1>
</ez-appbar>
// With size and style variants
<ez-appbar size="medium" class="ez-outlined">
<hgroup>
<h1>My Application</h1>
<p>Subtitle text</p>
</hgroup>
</ez-appbar>Each component can be imported individually:
import { EzAppbarElement } from '@atomic/ui/ez-appbar';
import { EzBaseElement } from '@atomic/ui/ez-base';
import { EzButtonSurfaceElement } from '@atomic/ui/ez-button-surface';
import { EzFieldElement } from '@atomic/ui/ez-field';
import { EzRippleElement } from '@atomic/ui/ez-ripple';
import { EzShapeElement } from '@atomic/ui/ez-shape';Or import everything:
import * from '@atomic/ui';The library includes a comprehensive Material Design 3 design system built with SCSS. These components work without JavaScript and can be used with any framework.
| Component | Description | Features |
|---|---|---|
| Button | Material Design 3 buttons | Filled, Outlined, Tonal, Text, Elevated, FAB, Icon Button, Square |
| Button Group | Grouped button layouts | Horizontal and vertical grouping |
| Badge | Notification badges | Small/large, positioned, standalone |
| Card | Container cards | Filled, Outlined, Elevated variants |
| Chip | Compact elements for filters, selections, and actions | Assist, Filter, Input, Suggestion; checkbox/radio label pattern |
| Dialog | Modal dialogs | Full-screen and standard dialogs |
| Divider | Visual separators | Horizontal and vertical dividers |
| Field | Form field containers | Material Design 3 field styling |
| Fieldset | Grouped form controls | Accessible fieldset styling |
| Input | Form inputs | Text, Checkbox, Radio, Switch, Range, Color |
| List | Lists and list items | Material Design 3 list patterns |
| Shape | Shape utilities | Shape morphing and styling |
| Menu | Menu components | Dropdown and context menus |
| Form | Form containers | Form layout utilities |
| Table | Data tables | Basic table styling |
| Section | Section containers | Content sections |
| Focus Ring | Focus indicators | Accessible focus styling |
| Spacing | Spacing utilities | Consistent spacing system |
Import the compiled CSS in your HTML:
<link rel="stylesheet" href="node_modules/@atomic/ui/dist/css/index.min.css">Or import SCSS modules in your build:
@import '@atomic/ui/scss/modules/button/index.scss';
@import '@atomic/ui/scss/modules/card.scss';Or import the entire design system:
@import '@atomic/ui/scss/modules/index.scss';<button class="ez-button ez-filled ez-primary">
Filled Button
</button>
<button class="ez-button ez-outlined ez-secondary">
Outlined Button
</button>
<button class="ez-button ez-fab">
<span class="material-icons">add</span>
</button>The SCSS system includes:
- Base Styles — Reset, typography, spacing, elevation, motion, shape, state layers
- Theming — Light, dark, and high-contrast themes
- Design Tokens — Material Design 3 color, typography, and spacing tokens
- Typography — Material Design 3 typescale system
- Placeholders — Reusable SCSS placeholders for common patterns
- Node.js v24+
- pnpm (recommended package manager)
- Playwright (for testing)
# Install dependencies
pnpm install
# Install Playwright browsers (required for tests)
pnpm exec playwright install --with-deps| Script | Description |
|---|---|
pnpm build |
Build CSS, JavaScript, and type definitions |
pnpm build:css |
Build CSS from SCSS modules |
pnpm build:js |
Build JavaScript with Vite |
pnpm watch |
Watch mode for development |
pnpm test |
Run all tests with Vitest |
pnpm storybook |
Start Storybook dev server |
pnpm build-storybook |
Build static Storybook |
pnpm eslint |
Run ESLint |
pnpm eslintfix |
Run ESLint with auto-fix |
pnpm stylelint |
Run Stylelint |
pnpm stylelintfix |
Run Stylelint with auto-fix |
pnpm typings |
Generate TypeScript declarations |
pnpm docs |
Generate TypeDoc documentation |
packages/ui/
├── ez-appbar/ # Appbar custom element
├── ez-base/ # Base element class
├── ez-button-surface/ # Button surface element
├── ez-field/ # Field element
├── ez-ripple/ # Ripple/state layer element
├── ez-shape/ # Shape element
├── scss/ # SCSS design system
│ ├── base/ # Foundation styles
│ ├── material/ # Material Design 3 tokens
│ ├── modules/ # Component styles
│ └── placeholders/ # Reusable placeholders
├── utils/ # Utility functions
└── mixins/ # TypeScript mixins
This package uses Vitest with Playwright for browser testing, and Storybook interaction tests.
# Run all tests
pnpm test
# Start Storybook (includes interactive tests)
pnpm storybookTests are written using:
If you're using WSL, you may need to install Chrome:
https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps#install-google-chrome-for-linux
From the repository root:
pnpm run new:elementThis will scaffold a new component with the ez-{name} naming convention. See ez-ripple and ez-field for reference implementations.
Post-scaffolding steps:
- Update imports to use
.jsextensions (not.ts) - Fix
@lit-labs/reactimports to@lit/react(if using React wrappers) - Manually add exports to
packages/ui/package.json - Add exports to
packages/ui-react/package.jsonandpackages/ui-next/package.jsonif needed
- Use optional chaining and proper null checks instead of
! - Prefer
Promise.allwith array mapping overawaitin loops - Follow ESLint rules; use
pnpm lintfixto auto-fix
- Import
../scss/component-prelude.scssin component SCSS files - Use
@extend %md-typescale-{role}-{size}placeholders for typography - Use control classes for size, theme, and style variants
- Only create CSS custom properties for dynamic values (theme/variant switching)
- Favor direct styling over unnecessary custom properties
- Use
<ez-ripple>component for Material Design 3 state layers - Apply border styles via control classes; use
<hr>for content-only dividers
Use @atomic/ui-react for React-specific wrappers:
pnpm add @atomic/ui-reactimport { EzAppbar } from '@atomic/ui-react';
function App() {
return (
<EzAppbar size="medium">
<h1>My Application</h1>
</EzAppbar>
);
}Use @atomic/ui-next for Next.js-optimized wrappers:
pnpm add @atomic/ui-nextSee packages/ui-react and packages/ui-next for more details.
Contributions are welcome! Please see the main repository README for contribution guidelines.
- Material Design 3 - Design specifications
- Lit - Web components library
- Storybook - Component development and testing