Skip to main content
Guide

Getting Started

kouji-ui is a headless Angular 22 UI library. The core is behaviour — bring your own styles, or add the themed components.

Installation

Two paths — pick one, mix as you grow.

Styled

Drop-in ready. Behaviour, styled wrappers, and the 13 themes. Pick a theme with [data-theme="kouji"] on <html> and ship.

Loading editor

Headless

Just the behaviour layer. Directives expose ARIA semantics and data-* hooks; you bring the CSS (Tailwind, design tokens, plain stylesheets — anything).

Loading editor
◈

Angular 22+ only. Standalone components, signals throughout. No Angular CDK and no third-party UI runtime — the only required peers are @angular/* and rxjs.

Global stylesheets

Register these once in angular.json. @kouji-ui/core/styles.css is the core's one global stylesheet — overlay chrome, the [kjIcon] mask, .kj-prose typography and the kjMotion presets. Together with the components overlay.css it is the only thing that paints every floating panel — popover, tooltip, dropdown menu, dialog, drawer, toast, confirm popup, sheet. The wrapper components carry no styleUrl of their own, so omitting overlay.css leaves every panel unstyled.

Loading editor

On Vite or Analog there is no angular.json: import the same three files by package specifier from your global stylesheet. Every path is declared in the packages' exports maps, so bundlers that enforce them resolve it.

Loading editor

Prefer à la carte? The core aggregate is exactly these four files, each published on its own:

Loading editor
◈

Overlay panels need these. Every panel is rendered by a headless directive (<kj-popover-content>, <kj-dropdown-menu-content>, …), and directives carry no styles. Skip the overlay stylesheets and a panel composed straight from the directives comes up with no background, no border and no shadow — even though the markup is correct. Wrapper components such as <kj-popover> inline the same CSS, so a page that happens to render one looks fine while the rest do not.

Vite / Analog

There is no angular.json outside the Angular CLI, so the three global stylesheets are imported by package specifier from your own global stylesheet (see Global stylesheets above), and that stylesheet is imported once from the app entry.

Loading editor

Nothing else is needed in vite.config.ts. Both packages ship pure-ESM FESM2022 with "sideEffects": false, no CommonJS interop and no module-scope document / window access, so Vite externalizes them for SSR without ssr.noExternal.

Loading editor

Optional peers

Only the @angular/* packages and rxjs are required. Everything heavy — ECharts, Monaco, Lexical, TanStack Virtual, Lucide — is an optional peer reached through a dynamic import() or an import type, so a bare import '@kouji-ui/core' resolves in plain Node with none of them installed.

Loading editor

Quick start

Import directive directly — no NgModules needed.

Loading editor

Headless usage

The core package ships no component styles. Directives add ARIA attributes and data-* attributes you can target in your stylesheets:

Loading editor

Angular forms

Form controls compose KjFormControl via hostDirectives, so they work with reactive forms out of the box:

Loading editor

Accessibility

Every component targets WCAG 2.1 AAA. Keyboard interactions, ARIA patterns, and focus management are baked into the headless primitives.

Use the a11y utilities to enhance your own components:

Loading editor
♿

All overlay components (Dialog, Menu, Select) compose KjFocusTrap, KjRovingTabindex, and KjLiveRegion from @kouji-ui/core for full keyboard + screen-reader support — verified against NVDA, JAWS, and VoiceOver.