Skip to content
wmzyPublic

Latest commit

 

History

220 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Haze UI

The React UI component library with controllable states.

English | 简体中文

npm downloads CI Scorecard

haze-ui is a React 19 component library styled with Linaria (zero-runtime CSS-in-JS) against --haze-* design tokens: 148 components in 9 groups, ESM-only with a tree-shakeable preserveModules dist, RTL by construction, and an RSC-aware split ('use client' is pre-injected only on interactive modules, so the static subset renders as React Server Components). Every stateful component speaks the same ControlOrValue<T> protocol — one prop, checked?: Control<T> | T, covers controlled and uncontrolled usage. Only react and react-dom (v19) are peers; every engine (react-f0rm, TanStack Table, recharts, dnd-kit, qrcode) is a regular dependency that tree-shakes away when your imports never reach it.

Quickstart

npm i haze-ui
# or
pnpm add haze-ui

Load the CSS — pick one of two modes:

// A) one full stylesheet (simplest)
import 'haze-ui/styles.css';
// B) the official Vite plugin injects per-component CSS automatically
//    vite.config.ts
import hazeCss from 'vite-plugin-haze-ui';

export default { plugins: [react(), hazeCss()] };

Install the plugin with npm i -D vite-plugin-haze-ui.

Then render your first component:

import { lightTheme, Button } from 'haze-ui';

export function App() {
  return (
    <main className={lightTheme}>
      <Button onClick={() => console.log('haze!')}>Start</Button>
    </main>
  );
}

The theme class activates the token set — that is the whole setup. For a template start, painless is a RealWorld SPA template built on haze-ui — clone it and delete what you don't need.

Colors are generated in OKLCH with interaction states derived at runtime via CSS relative colors, so the browser floor is Chrome/Edge 119+, Safari 16.4+ or Firefox 128+ (no HSL/hex fallbacks).

Browser support semantics

The browserslist field in package.json governs the JS API surface only: eslint-plugin-compat lints every src/**/*.{ts,tsx} file against those targets (chrome >= 119, edge >= 119, safari >= 16.4, firefox >= 128), so a modern JS API below that floor fails CI rather than shipping. CSS is intentionally not transpiled: OKLCH colors, CSS relative colors, the popover attribute and CSS anchor positioning are emitted as-is with no polyfills or fallbacks — the same four engines are the hard CSS floor.

Highlights

  • React 19 only, by design — ref-as-prop, native popover/anchor-positioning overlays and the RSC-aware 'use client' split build on React 19's shapes; there is no React 18 compatibility layer (peer range react: ^19.0.0). → Getting started
  • Accessibility as a release gate — an axe case in every component test suite, Playwright e2e across Chromium/Firefox/WebKit plus a phone-viewport project, pixel-locked visual baselines, and a real VoiceOver smoke suite on macOS CI. → Accessibility guide · A11y contracts
  • Per-component CSS — the JS entry imports no stylesheet. Load the full haze-ui/styles.css, cherry-pick haze-ui/css/*.css subpaths, or let vite-plugin-haze-ui inject the right files per import through haze-ui/css-manifest.json. → Getting started
  • Control<T> | T controllable state — one state prop per component, powered by react-use-control; no defaultXxx/xxx dual API to keep in sync. → Getting started
  • Curated icons, zero cost — haze-ui/icons re-exports the ~100 most common lucide-react glyphs to pair with the Icon component, plus the matching hazeIconSize scale; lucide-react is a regular dependency with sideEffects: false, so unused icons — or the whole set — tree-shake away.
  • AI / chat component family — ChatContainer, ChatMessage, StreamingText, ToolCallCard, ThinkingIndicator and ChatInput cover the agent chat surface; Plan, Queue, InlineCitation and the collapsible StepTimeline trace rows cover the agentic-UI patterns, with a unit-tested adapter recipe for the Vercel AI SDK's useChat. → AI showcase · Recipes
  • React Compiler verified — the whole suite runs green with babel-plugin-react-compiler enabled (pnpm test:compiler): auto-memoization is part of the release gate, not a hope.
  • Runtime benchmarks — pnpm bench (vitest bench, jsdom) measures pure JS-side costs of the heaviest components — 1000-row DataTable render and sort flips, a 5000-item VirtualList scroll window, and Select panel open/close cycles. Informational numbers for trend spotting; CI runs the job non-blocking.
  • Codemod upgrade toolchain — pnpm codemod <transform> <path> runs the jscodeshift-powered migrations in scripts/codemods; every future major ships a codemod for its breaking changes.
  • Native-form ready — value-holding components (Select, Switch, Rating, Slider, TagInput, OTPInput, Segmented, ColorPicker, RichTextEditor) accept a name and submit into FormData, so <form action={serverAction}> works without a form library; react-f0rm integration stays first-class.
  • Multi-calendar date layer — Gregorian plus six built-in adapters (Hijri Umm al-Qura, Persian, Hebrew, Japanese era, Buddhist, Ethiopic): integer-arithmetic implementations cross-verified against full-ICU Intl oracles, exported from the barrel via getAdapter(). → Components
  • OKLCH tokens with W3C DTF export — hover/active/focus-ring colors re-derive at runtime from CSS relative-color formulas, and the whole token registry exports to the W3C Design Tokens format for Figma / Tokens Studio. → Tokens · Theme editor

Ecosystem

Resource Link
Documentation https://wmzy.github.io/haze-ui/
Getting started https://wmzy.github.io/haze-ui/getting-started
Migration guide (AntD / shadcn) https://wmzy.github.io/haze-ui/guides/migration
llms.txt / full API for AI readers https://wmzy.github.io/haze-ui/llms.txt
MCP server — ships as a bin of this package (npx haze-ui-mcp) https://wmzy.github.io/haze-ui/help
shadcn registry registry/README.md — pnpm dlx shadcn@latest add wmzy/haze-ui/button
painless (RealWorld SPA template) https://github.com/wmzy/painless — GitHub
vite-plugin-haze-ui (CSS auto-injection) https://www.npmjs.com/package/vite-plugin-haze-ui — npm

Every styled export is also installable through the shadcn CLI as a thin wrapper over the npm package — see registry/README.md.

Release channels

Channel Install Version shape Who it's for
stable (latest) npm i haze-ui 1.34.1 Production. Cut from main by semantic-release whenever a relevant commit (feat/fix/perf…) lands.
beta npm i haze-ui@beta 1.35.0-beta.1 Trying upcoming changes early. Cut from the beta branch through semantic-release's prerelease flow — same commit analysis, changelog and GitHub Release as stable, published to the beta dist-tag so latest never moves.
canary npm i haze-ui@canary 0.0.0-canary.a1b2c3d4.123 Verifying a fix against one exact commit. Manually dispatched from any ref, stamped with the commit SHA + run number, and fully bypasses semantic-release — no commit analysis, no changelog, no git tag.

Beta vs canary in one line: beta is an ordered prerelease line (x.y.z-beta.n) that graduates to stable when its commits merge into main; canary is a disposable per-commit snapshot (0.0.0-canary.<sha>.<run>) that the next dispatch supersedes and nothing ever promotes.

Community

Building with haze-ui? We would love to feature you. Open an issue titled used by: <your project> with the project name, a link and (optionally) a logo, and it will be added to this README.

License

MIT

Releases

Packages

Used by

Contributors

Languages