PXLKIT UI KIT FOR REACT
A React component kit built on three promises. Surface system — flip every component between an 8-bit pixel aesthetic and a flat linear one with a single prop, same API either way. Accessibility-first — WAI-ARIA roles, keyboard navigation, focus rings, and reduced-motion fallbacks ship on every interactive, not bolted on later. Batteries-included — DataTable, Stepper, Sidebar, Timeline, Calendar, Charts, OTPInput and 103+ more are already in the box. Use the sidebar to browse all 111 components and the PixelToast guide.
New in 2.2: the same 111 components for Vue 3 and Angular — same markup, theme and keyboard behaviour, checked against React by parity tests. See Vue and Angular below.
Components
111
Icon Packs
7
Design Tokens
7 tones
New in 2.2
Vue + Angular
GETTING STARTED
Three steps and you're rendering. Install the React kit, @pxlkit/ui-kit — or, new in 2.2, @pxlkit/ui-kit-vue or @pxlkit/ui-kit-angular — with your framework's icon components and the icon packs you use; import its stylesheet — a Tailwind CSS v4 entry point, so Tailwind's Vite or PostCSS plugin must run on it; and use the components. The three kits render the same markup and classes and behave the same way. Every primitive accepts the shared , size, and surface contract — so what you learn on applies to , , and the other 108. The code on this page follows the framework you pick.
npm install @pxlkit/ui-kit @pxlkit/core @pxlkit/gamification @pxlkit/ui# Next.js — create-next-app --tailwind sets this up. Otherwise:npm install -D tailwindcss @tailwindcss/postcss postcss// postcss.config.mjsexport default { plugins: { '@tailwindcss/postcss': {} } };# Vitenpm install -D tailwindcss @tailwindcss/vite// vite.config.tsimport tailwindcss from '@tailwindcss/vite';// …plugins: [react(), tailwindcss()],The kit's stylesheet is a Tailwind CSS v4 entry point, so Tailwind has to process it. Without that step the build still succeeds, but the CSS keeps @theme, @source and @apply as written and the components render unstyled.
// 1. In your Tailwind CSS file (e.g., index.css), in place of @import "tailwindcss":// @import "@pxlkit/ui-kit/styles.css";// 2. Use the componentsimport { PixelButton, PixelInput } from '@pxlkit/ui-kit';import { PxlKitIcon } from '@pxlkit/core';import { Trophy } from '@pxlkit/gamification';import { Search } from '@pxlkit/ui';export function QuickStart() { return ( <> <PixelButton tone="green" iconLeft={<PxlKitIcon icon={Trophy} size={16} decorative />}> Create Quest </PixelButton> <PixelInput label="Search" prefix={<PxlKitIcon icon={Search} size={16} decorative />} placeholder="Find icons..." /> </> );}Next.js (App Router). Keep app/layout.tsx a Server Component and put the providers in a 'use client' file of your own; start files that use the components' hooks or event handlers with 'use client', and import server-side helpers such as buildGoogleFontsUrl from @pxlkit/ui-kit-core. The setup guide has the files.
Server rendering. The three kits render on the server and hydrate — Next.js, Nuxt, @angular/ssr. A calendar shows the current month and marks today, which depends on the reader's clock: give PixelCalendarGrid a month (or a value) for a stable server render, or render a current-month calendar in the browser only — next/dynamic with ssr: false in Next.js, <ClientOnly> in Nuxt, @defer in Angular.
From React props to Vue and Angular
The props tables on this page use the React names. The Vue and Angular kits keep those names and defaults, and follow their framework where React has its own idiom:
| React | Vue | Angular |
|---|---|---|
| <PixelButton>, <PixelTextLink> (render a <button> or an <a>) | <PixelButton> | an attribute on your element: <button pxlButton>, <a pxlTextLink> |
| any other component: <PixelBadge> | <PixelBadge> | an element: <pxl-badge> |
| children | the default slot | projected content |
| element props: icon, iconLeft, footer, action | named slots, kebab-case: #icon-left | inputs taking text or an <ng-template> |
| value + onChange | v-model | [(value)]; form controls also take ngModel and formControlName |
| open + onOpenChange, checked + onChange | v-model:open, v-model:checked | [(open)], [(checked)] |
| other callbacks: onClose | events: @close | outputs: (closed) — past tense where the present would shadow a DOM event |
| const form = useForm(); <PixelForm form={form}> on React Hook Form | const form = useForm() in <script setup>; <PixelForm :form="form"> on VeeValidate | <form [pxlForm]="group"> on reactive forms |
| className | class | class |
| <PxlKitSurfaceProvider surface> | <PxlKitSurfaceProvider surface> | providePxlKitSurface() for the app, pxlKitSurface="…" on an element |
Common API Surface
These props are accepted by every UI-kit component where applicable. Each component's individual props table below also lists them inline — so each table is a complete, self-contained reference. This shared block remains as a quick overview.
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "green" | "cyan" | "gold" | "red" | "purple" | "pink" | "neutral" | varies | Color scheme — shared across all components |
| size | "sm" | "md" | "lg" | "md" | Controls height, padding, and font size |
| surface | "pixel" | "linear" | inherits from PxlKitSurfaceProvider, falls back to "pixel" | Visual aesthetic. Per-component override of the global surface — see Surface System. |
| disabled | boolean | false | Standard HTML disabled state — applies to every interactive component (buttons, inputs, switches, sliders, segmented, etc.). |
| iconLeft / iconRight | ReactNode | — | Icon slots flanking the label. Accepted by PixelButton; PxlKitButton/PixelSplitButton use the single `icon` slot. Inputs take `prefix` and `suffix` instead (`icon` is the older name of `prefix`). |
| label | string | — | Accessible label for inputs/controls (PixelInput, PixelSelect, PixelCheckbox, PixelSwitch, PixelSlider, PixelRadioGroup, …). Buttons use `children` for their visible text, not `label`. |
| children | ReactNode | — | Required for container components (PixelCard, PixelModal, PixelTooltip, animations, etc.). Listed here once; not repeated in each table. |
| className | string | — | Extra CSS class names merged onto the outer element. |
PXLKIT FOR VUE 3 · NEW IN 2.2
@pxlkit/ui-kit-vue is the Vue 3 edition of this kit: the same 111 components, markup, Tailwind CSS v4 theme and keyboard behaviour as the React kit, checked against it example by example. They are single-file components — React's element props become slots, value and open become v-model, callbacks become events. It needs Vue 3.5 or later, renders on the server with Nuxt or vue/server-renderer and hydrates without mismatches. The icon components come from @pxlkit/vue; React is never installed.
npm install @pxlkit/ui-kit-vue @pxlkit/vuenpm install -D tailwindcss @tailwindcss/viteimport { defineConfig } from 'vite';import vue from '@vitejs/plugin-vue';import tailwindcss from '@tailwindcss/vite';export default defineConfig({ plugins: [vue(), tailwindcss()],});@import "@pxlkit/ui-kit-vue/styles.css";<script setup lang="ts">import { ref } from 'vue';import { PixelButton, PixelInput, PxlKitSurfaceProvider } from '@pxlkit/ui-kit-vue';const email = ref('');function save() { // send email.value}</script><template> <PxlKitSurfaceProvider surface="pixel"> <PixelInput v-model="email" label="Email" placeholder="you@studio.dev" /> <PixelButton tone="green" @click="save">Save</PixelButton> </PxlKitSurfaceProvider></template>Nuxt. No Nuxt module or build.transpile entry is needed: add @tailwindcss/vite to vite.plugins and the stylesheet to css in nuxt.config.ts (see the Tailwind step above). Nuxt auto-imports your own components, not a package's, so import the kit's components where you use them. Every example on this page has a Vue tab; the package README maps the whole API.
PXLKIT FOR ANGULAR · NEW IN 2.2
@pxlkit/ui-kit-angular brings the same 111 components to Angular 20, 21 and 22 as standalone, signal-based components — <button pxlButton>, <pxl-modal> — with the React kit's markup, theme and keyboard behaviour. Form controls implement ControlValueAccessor, so ngModel, formControlName and [formControl] work; overlays take [(open)]. They run in zoneless and zone.js applications and hydrate with @angular/ssr. The icon components come from @pxlkit/angular.
npm install @pxlkit/ui-kit-angular @pxlkit/angular# Tailwind CSS v4: ng new my-app --style=tailwind (Angular CLI 21 and later),# or on Angular 20: npm install -D tailwindcss @tailwindcss/postcss postcss# and a .postcssrc.json with { "plugins": { "@tailwindcss/postcss": {} } }@import "@pxlkit/ui-kit-angular/styles.css";import type { ApplicationConfig } from '@angular/core';import { providePxlKitSurface } from '@pxlkit/ui-kit-angular';export const appConfig: ApplicationConfig = { providers: [ // …keep the providers ng new generated (change detection, router, // provideClientHydration() in SSR apps), and add: providePxlKitSurface('pixel'), ],};import { Component } from '@angular/core';import { FormsModule } from '@angular/forms';import { PixelButton, PixelInput } from '@pxlkit/ui-kit-angular';@Component({ selector: 'app-signup', imports: [FormsModule, PixelButton, PixelInput], template: ` <pxl-input label="Email" placeholder="you@studio.dev" [(ngModel)]="email" /> <button pxlButton tone="green" (click)="save()">Save</button> `,})export class Signup { protected email = ''; protected save() { // send this.email }}Keep the providers ng new generated — provideClientHydration() in particular: without it the browser throws the server markup away and renders again. Every example on this page has an Angular tab; the package README maps the whole API, overlays and form controls included.
DESIGN TOKENS
All components use CSS custom properties for theming. Override these variables to customize the entire kit. Dark and light themes are built in via the .dark class. Colors are applied through the tone prop on components like , , and .
Colors
Green
--retro-green
Cyan
--retro-cyan
Gold
--retro-gold
Red
--retro-red
Purple
--retro-purple
Typography
Press Start 2P
Titles & accents — font-pixel
JetBrains Mono
Code & UI labels — font-mono
Inter
Body text — font-sans
Surfaces
Background
--retro-bg
Surface
--retro-surface
Card
--retro-card
Border
--retro-border
SURFACE SYSTEM
v1.4.0Every UI-kit component has two visual surfaces: the retro 8-bit "pixel" aesthetic (default — sharp pixel borders, pressed shadows, mono fonts) and a flatter, more modern "linear" aesthetic (subtle 1px borders, rounded corners, sans fonts). You toggle it globally with <PxlKitSurfaceProvider>, or per-component with the surface prop. Useful for embedding Pxlkit into a non-retro product without rewriting the components.
Side-by-side
surface="pixel" (default)
surface="linear"
Every component also accepts `surface` directly
Every UI-kit component (PixelButton, PixelInput, PixelCard, …) exposes a surface?: "pixel" | "linear" prop that overrides the nearest provider. Use it when you need a single button in linear mode inside an otherwise pixel-mode page.
// === GLOBAL toggle: wrap your whole app once ===// app/providers.tsx — in Next.js (App Router) the providers live in a Client Component'use client';import { PxlKitSurfaceProvider, PixelButton, PixelCard } from '@pxlkit/ui-kit';export function Providers({ children }: { children: React.ReactNode }) { return <PxlKitSurfaceProvider surface="linear">{children}</PxlKitSurfaceProvider>;}// app/layout.tsx stays a Server Component and renders <Providers>{children}</Providers> in <body>.// In a Vite app, wrap <App /> in main.tsx instead.// === LOCAL override: one component in a different mode ===<PxlKitSurfaceProvider surface="pixel"> <PixelCard title="Retro card"> {/* This one button breaks the pixel surface */} <PixelButton tone="green" surface="linear">Modern button</PixelButton> </PixelCard></PxlKitSurfaceProvider>LOCALE / TURKISH SUPPORT
v1.3.0PxlKit includes built-in locale support for Turkish (tr) and English (en). Turkish requires special handling because of the dotted/dotless i distinction, and the latin-ext Google Fonts subset for characters like ğ, ş, ı, İ, ç, ö, ü.
Why Turkish Needs Special Handling
| Input | English Uppercase | Turkish Uppercase | Note |
|---|---|---|---|
| i | I | İ (U+0130) | Dotted uppercase İ in Turkish |
| ı (U+0131) | I | I | Dotless ı is unique to Turkish |
| istanbul | ISTANBUL | İSTANBUL | Complete word difference |
Live Demo — Turkish vs English
ISTANBUL IŞLEMLERI
İSTANBUL İŞLEMLERİ
Notice how the section title "istanbul işlemleri" renders differently: English shows ISTANBUL ISLEMLERI while Turkish correctly shows İSTANBUL İŞLEMLERİ. The avatar initials also change — "İG" (Turkish) vs "IG" (English) for "işıl gündüz".
Turkish Characters — Font Preview
Press Start 2P (font-pixel)
Ç Ğ İ Ö Ş Ü
ç ğ ı ö ş ü
JetBrains Mono (font-mono)
Ç Ğ İ Ö Ş Ü
ç ğ ı ö ş ü
Inter (font-sans)
Ç Ğ İ Ö Ş Ü
ç ğ ı ö ş ü
Turkish Pangram (font-pixel)
Pijamalı hasta yağız şoföre çabucak güvendi
// === STEP 1: Wrap your app — in src/main.tsx (Vite), or in a 'use client' providers file (Next.js App Router) ===import { PxlKitLocaleProvider } from '@pxlkit/ui-kit';export function Providers({ children }: { children: React.ReactNode }) { return <PxlKitLocaleProvider locale="tr">{children}</PxlKitLocaleProvider>;}// Server-rendered apps: also set lang="tr" on <html> (app/layout.tsx in Next.js).// === STEP 2: Google Fonts — ensure the latin-ext subset ===// In your CSS file or HTML <head>:// @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&subset=latin,latin-ext&display=swap');// Or build the URL — from @pxlkit/ui-kit-core, which a Server Component (app/layout.tsx) can import:import { buildGoogleFontsUrl } from '@pxlkit/ui-kit-core';const fontsUrl = buildGoogleFontsUrl('tr');// → includes &subset=latin,latin-ext// === STEP 3: Use locale-aware text in your components (a Client Component in Next.js) ===import { usePxlKitLocale, toLocaleUpper } from '@pxlkit/ui-kit';function MyTitle({ text }: { text: string }) { const { upper } = usePxlKitLocale(); return <h1 className="font-pixel">{upper(text)}</h1>; // "istanbul" → "İSTANBUL" when locale is "tr"}// Or use the standalone function:toLocaleUpper('istanbul', 'tr'); // → "İSTANBUL"toLocaleUpper('istanbul', 'en'); // → "ISTANBUL"Important: CSS text-transform
CSS text-transform: uppercase is automatically locale-aware when the lang attribute is set. PxlKitLocaleProvider sets lang on a wrapper div. For full page coverage, also set lang="tr" on your <html> tag.
All three fonts support Turkish
Press Start 2P, Inter, and JetBrains Mono all include Latin Extended characters (ğ, Ğ, ı, İ, ş, Ş, ç, Ç, ö, Ö, ü, Ü). The latin-ext subset in the Google Fonts URL ensures these glyphs are downloaded.
PIXELINPUT
inputimport { PixelInput } from '@pxlkit/ui-kit';export function Default() { return ( <PixelInput label="Username" placeholder="hero@pxlkit.xyz" hint="Your retro alias" /> );}PIXELPASSWORDINPUT
passwordinputimport { PixelPasswordInput } from '@pxlkit/ui-kit';export function Default() { return <PixelPasswordInput label="Password" placeholder="Enter password" />;}PIXELTEXTAREA
textareaFieldShell wrapper as .import { PixelTextarea } from '@pxlkit/ui-kit';export function Default() { return ( <PixelTextarea label="Notes" placeholder="Write something..." hint="Up to 280 characters." /> );}PIXELSELECT
selectimport { PixelSelect } from '@pxlkit/ui-kit';const FRUITS = [ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date' },];export function Default() { return ( <PixelSelect label="Fruit" options={FRUITS} placeholder="Pick a fruit" hint="Choose your favorite" /> );}PIXELCHECKBOX
checkboximport { useState } from 'react';import { PixelCheckbox } from '@pxlkit/ui-kit';export function Default() { const [checked, setChecked] = useState(false); return ( <PixelCheckbox label="Accept terms" checked={checked} onChange={setChecked} /> );}PIXELRADIOGROUP
radiogroupimport { useState } from 'react';import { PixelRadioGroup } from '@pxlkit/ui-kit';const PLANS = [ { value: 'free', label: 'Free' }, { value: 'pro', label: 'Pro' }, { value: 'team', label: 'Team' },];export function Default() { const [value, setValue] = useState('free'); return ( <PixelRadioGroup label="Plan" value={value} options={PLANS} onChange={setValue} /> );}PIXELSWITCH
switchimport { useState } from 'react';import { PixelSwitch } from '@pxlkit/ui-kit';export function Default() { const [on, setOn] = useState(false); return <PixelSwitch label="Enable notifications" checked={on} onChange={setOn} />;}PIXELSLIDER
sliderimport { useState } from 'react';import { PixelSlider } from '@pxlkit/ui-kit';export function Default() { const [value, setValue] = useState(40); return ( <PixelSlider label="Volume" value={value} onChange={setValue} /> );}PIXELSEGMENTED
segmentedLayout density
import { useState } from 'react';import { PixelSegmented } from '@pxlkit/ui-kit';const VIEWS = [ { value: 'grid', label: 'Grid' }, { value: 'list', label: 'List' }, { value: 'kanban', label: 'Kanban' },];export function Default() { const [value, setValue] = useState('grid'); return ( <PixelSegmented label="View" value={value} options={VIEWS} onChange={setValue} /> );}PIXELCARD
cardSocial Pack
import { PixelCard } from '@pxlkit/ui-kit';export function WithFooter() { return ( <PixelCard title="Invoice #1042" footer={<span className="text-xs text-retro-muted">Due in 7 days</span>} > <p>Total: $1,250.00</p> </PixelCard> );}PIXELSTATCARD
statcardTotal Icons
204
+12 new
Components
111
100% typed
Downloads
8.2k
+24%
Stars
1.4k
trending
import { PixelStatCard } from '@pxlkit/ui-kit';export function Default() { return <PixelStatCard label="Revenue" value="$12,480" trend="+8.2% vs last week" />}PIXELTABLE
table| Component | Category | Status |
|---|---|---|
| PixelButton | Actions | Stable |
| PixelSelect | Inputs | Stable |
| PixelTable | Data Display | New |
| PixelAvatar | Data Display | New |
| PixelSkeleton | Feedback | New |
import { PixelTable } from '@pxlkit/ui-kit';type Row = { id: string; name: string; role: string; status: string;};const rows: Row[] = [ { id: '1', name: 'Alice', role: 'Engineer', status: 'active' }, { id: '2', name: 'Bob', role: 'Designer', status: 'idle' }, { id: '3', name: 'Carol', role: 'PM', status: 'active' },];const baseColumns = [ { key: 'name', header: 'Name' }, { key: 'role', header: 'Role' }, { key: 'status', header: 'Status' },];export function Default() { return <PixelTable<Row> columns={baseColumns} data={rows} />;}PIXELAVATAR
avatarimport { PixelAvatar } from '@pxlkit/ui-kit';export function Default() { return <PixelAvatar name="Joangel De La Rosa" />;}PIXELBADGE
badgeimport { PixelBadge } from '@pxlkit/ui-kit';export function Default() { return <PixelBadge>NEW</PixelBadge>;}PIXELCHIP
chipimport { useState } from 'react';import { PixelChip } from '@pxlkit/ui-kit';export function Deletable() { const [visible, setVisible] = useState(true); if (!visible) return null; return ( <PixelChip label="Remove me" tone="red" onDelete={() => setVisible(false)} /> );}PIXELTEXTLINK
textlink<a> when href is provided, otherwise as <button>. Supports all anchor and button attributes via spread props.import { PixelTextLink } from '@pxlkit/ui-kit';export function Default() { return <PixelTextLink href="https://pxlkit.xyz">Read the docs</PixelTextLink>;}PIXELCODEINLINE
codeinlineUse useState for local state, PxlKitIcon for icons, green gold red neutral
import { PixelCodeInline } from '@pxlkit/ui-kit';export function Default() { return <PixelCodeInline>npm install</PixelCodeInline>;}PIXELKBD
kbdimport { PixelKbd } from '@pxlkit/ui-kit';export function Default() { return <PixelKbd>Enter</PixelKbd>;}PIXELCOLORSWATCH
colorswatchGreen
--retro-green
Cyan
--retro-cyan
Gold
--retro-gold
Red
--retro-red
Purple
--retro-purple
import { PixelColorSwatch } from '@pxlkit/ui-kit';export function Default() { return <PixelColorSwatch name="cyan" cssVar="--color-retro-cyan" />;}PIXELALERT
alertBuild Success
Package compiled and DTS types generated.
Warning
Some components still need visual fine-tuning review.
Breaking Change
PixelSelect API changed from native to custom dropdown in v2.0.
Tip
Use the tone prop to match your alert to the appropriate severity level.
import { PixelAlert, PixelButton } from '@pxlkit/ui-kit';const InfoIcon = () => ( <span aria-hidden style={{ width: 14, height: 14, borderRadius: 9999, background: 'currentColor', display: 'inline-block', }} />);export function WithAction() { return ( <PixelAlert tone="red" title="Connection lost" message="We couldn't reach the server. Check your network and retry." icon={<InfoIcon />} action={ <PixelButton size="sm" tone="red" variant="outline"> Retry </PixelButton> } /> );}PIXELPROGRESS
progressimport { PixelProgress } from '@pxlkit/ui-kit';export function Default() { return <PixelProgress value={60} label="HP" />;}PIXELSKELETON
skeletonimport { PixelSkeleton } from '@pxlkit/ui-kit';export function Default() { return <PixelSkeleton width="12rem" height="1rem" />;}PIXELEMPTYSTATE
emptystateNo results found
Adjust your filters or create a new custom component for this kit.
import { PixelEmptyState, PixelButton } from '@pxlkit/ui-kit';const FolderIcon = () => ( <span aria-hidden style={{ width: 32, height: 32, borderRadius: 4, border: '2px solid currentColor', display: 'inline-block', }} />);export function WithIconAndAction() { return ( <PixelEmptyState icon={<FolderIcon />} title="No documents" description="Upload a file or create a new document to begin." action={ <PixelButton size="sm" tone="green" variant="solid"> Create document </PixelButton> } /> );}PIXELTOAST
toast<PxlKitToastProvider> draws one for every toast you push with (injectToast() in Angular) — you rarely render it yourself. Push some live in the playground below. The icon packages' standalone PixelToast, one toast whose visibility you control, is documented in /docs#toast-notifications.Saved
Your changes were saved.
Not saved
The server did not answer. Try again.
Syncing…
Fetching the latest updates.
File deleted
report.pdf went to the bin.
import { PixelToast } from '@pxlkit/ui-kit';import type { ToastItem } from '@pxlkit/ui-kit';const noop = () => {};const baseToast = (overrides: Partial<ToastItem> = {}): ToastItem => ({ id: 'demo', title: 'Saved', message: 'Your changes have been persisted.', tone: 'cyan', duration: 0, ...overrides,});export function Default() { return <PixelToast toast={baseToast()} onDismiss={noop} />;}USETOAST()
usetoast()<PxlKitToastProvider> once around your app; under it, useToast() (React, Vue) or injectToast() (Angular) returns the toast API. The provider keeps the queue, draws the in its viewport — stacked by default, a landmark F8 moves focus to — announces each toast to screen readers, and holds the countdowns while the page is hidden. Try it:import React from 'react';import { PxlKitToastProvider, useToast, PixelButton } from '@pxlkit/ui-kit';function TriggerRow({ children }: { children: React.ReactNode }) { return <div className="flex flex-wrap gap-2">{children}</div>;}function DefaultTriggers() { const { toast } = useToast(); return ( <TriggerRow> <PixelButton size="sm" onClick={() => toast({ title: 'Saved', message: 'Your changes were persisted.' })}> Push toast </PixelButton> </TriggerRow> );}export function Default() { return ( <PxlKitToastProvider> <DefaultTriggers /> </PxlKitToastProvider> );}PIXELTABS
tabsimport { PixelTabs } from '@pxlkit/ui-kit';import type { TabItem } from '@pxlkit/ui-kit';const ITEMS: TabItem[] = [ { id: 'overview', label: 'Overview', content: <p>High-level summary of the project.</p> }, { id: 'activity', label: 'Activity', content: <p>Recent events and commits.</p> }, { id: 'settings', label: 'Settings', content: <p>Configuration for this workspace.</p> },];export function Default() { return <PixelTabs items={ITEMS} defaultValue="overview" />;}PIXELACCORDION
accordionimport { PixelAccordion } from '@pxlkit/ui-kit';const SAMPLE_ITEMS = [ { id: 'overview', title: 'Overview', content: 'Introductory section that opens by default.', }, { id: 'details', title: 'Details', content: 'Secondary section with extended copy.', }, { id: 'faq', title: 'FAQ', content: 'Common questions and short answers.', },];export function Default() { return <PixelAccordion items={SAMPLE_ITEMS} />;}PIXELCOLLAPSIBLE
collapsibleThis panel starts expanded. Click the label to collapse it.
import { PixelCollapsible } from '@pxlkit/ui-kit';export function Default() { return ( <PixelCollapsible label="Show details"> <p className="text-xs text-retro-muted"> Hidden content revealed when the header is toggled. </p> </PixelCollapsible> );}PIXELPAGINATION
paginationimport { useState } from 'react';import { PixelPagination } from '@pxlkit/ui-kit';export function Default() { const [page, setPage] = useState(1); return <PixelPagination page={page} total={10} onChange={setPage} />;}PIXELMODAL
modalimport { useState } from 'react';import { PixelModal, PixelButton } from '@pxlkit/ui-kit';export function Default() { const [open, setOpen] = useState(false); return ( <> <PixelButton onClick={() => setOpen(true)}>Open modal</PixelButton> <PixelModal open={open} onClose={() => setOpen(false)} title="Default modal"> <p>This is a minimal modal with title and body content.</p> </PixelModal> </> );}PIXELTOOLTIP
tooltipimport { PixelTooltip, PixelButton } from '@pxlkit/ui-kit';export function Default() { return ( <PixelTooltip label="Save your changes"> <PixelButton>Save</PixelButton> </PixelTooltip> );}PIXELDROPDOWN
dropdownimport { PixelDropdown } from '@pxlkit/ui-kit';export function Default() { return ( <PixelDropdown label="Actions" items={[ { value: 'edit', label: 'Edit' }, { value: 'duplicate', label: 'Duplicate' }, { value: 'archive', label: 'Archive' }, ]} onSelect={() => {}} /> );}PIXELSECTION
sectionEXAMPLE SECTION
This is a wrapped content area with border and padding.
import { PixelSection } from '@pxlkit/ui-kit';export function Default() { return ( <PixelSection title="Overview" subtitle="Key metrics for this period."> <p className="text-sm text-retro-muted"> Section content goes here. Wrap any layout block. </p> </PixelSection> );}PIXELDIVIDER
dividerimport { PixelDivider } from '@pxlkit/ui-kit';export function Default() { return <PixelDivider />;}PIXELBAREINPUT
bareinput<input> wrapper with forwardRef support. Use as the base for custom text fields or form controls.Renders an unstyled <input> element. For styled text fields with labels, hints, and errors, use .
import { PixelBareInput } from '@pxlkit/ui-kit';export function Default() { return <PixelBareInput placeholder="Type something" />;}PIXELBARETEXTAREA
baretextarea<textarea> wrapper with forwardRef support. Use for custom multi-line inputs.Renders an unstyled <textarea> element. For styled multi-line input with labels and errors, use .
import { PixelBareTextarea } from '@pxlkit/ui-kit';export function Default() { return <PixelBareTextarea placeholder="Write something..." rows={4} />;}TRIGGER MODES
all animationsEvery animation component accepts a trigger prop that controls when it plays. The default "mount" mode preserves backward compatibility — the animation fires on render.
Plays immediately on render (default).
Plays while the pointer is over the element.
Plays once per click. Re-click to replay.
Plays while the element has focus-within.
Plays when scrolled into the viewport (IntersectionObserver).
Controlled mode — true = playing, false = idle.
// Plays on hover<PixelBounce trigger="hover"> <PxlKitIcon icon={Star} size={20} /></PixelBounce>// Plays once per click<PixelShake trigger="click" repeat={2}> <PixelBadge tone="red">Error</PixelBadge></PixelShake>// Controlled by parent stateconst [active, setActive] = useState(false);<PixelPulse trigger={active}> <PixelBadge tone="green">Live</PixelBadge></PixelPulse>// Fade in when scrolled into view<PixelFadeIn trigger="inView" duration={600}> <PixelCard title="Hello">Visible!</PixelCard></PixelFadeIn>// Callback when animation completes<PixelFadeIn trigger="click" onComplete={() => console.log('done!')}> <p>Click me</p></PixelFadeIn>HOVER
CLICK
HOVER
PIXELFADEIN
fadeintrigger to control when it fires — e.g. "inView" for scroll-triggered reveals. Combines well with for staggered entrances.Faded In
import { PixelFadeIn } from '@pxlkit/ui-kit';export function Default() { return ( <PixelFadeIn> <div style={{ padding: 16, background: '#111', color: '#fff' }}> Fades in on mount </div> </PixelFadeIn> );}PIXELSLIDEIN
slideindistance and pacing using easing. Complements .import { PixelSlideIn } from '@pxlkit/ui-kit';export function Default() { return ( <PixelSlideIn> <div style={{ padding: 16, background: '#111', color: '#fff' }}> Slides in from below on mount </div> </PixelSlideIn> );}PIXELPULSE
pulseCPU
87%
import { PixelPulse } from '@pxlkit/ui-kit';export function Default() { return ( <PixelPulse> <span>Pulse</span> </PixelPulse> );}PIXELBOUNCE
bounceduration and stop it with repeat=1.import { PixelBounce } from '@pxlkit/ui-kit';export function Default() { return ( <PixelBounce> <span>Bounce</span> </PixelBounce> );}PIXELFLOAT
floatimport { PixelFloat } from '@pxlkit/ui-kit';export function Default() { return ( <PixelFloat> <span>Float</span> </PixelFloat> );}PIXELSHAKE
shakerepeat low to avoid visual fatigue. Often paired with .import { PixelShake } from '@pxlkit/ui-kit';export function Default() { return ( <PixelShake> <span>Shake on mount</span> </PixelShake> );}PIXELROTATE
rotatedirection to reverse or alternate spin behavior for loading indicators and decorative accents.import { PixelRotate } from '@pxlkit/ui-kit';export function Default() { return ( <PixelRotate> <span>Rotate</span> </PixelRotate> );}PIXELZOOMIN
zoominPack Ready
import { PixelZoomIn } from '@pxlkit/ui-kit';export function Default() { return ( <PixelZoomIn> <div style={{ padding: 16, background: '#0EA5E9', color: '#fff', borderRadius: 8 }}> Zoom in content </div> </PixelZoomIn> );}PIXELFLICKER
flickerSIGNAL LOCKED
import { PixelFlicker } from '@pxlkit/ui-kit';export function Default() { return ( <PixelFlicker> <span>OPEN 24/7</span> </PixelFlicker> );}PIXELTYPEWRITER
typewriterimport { PixelTypewriter } from '@pxlkit/ui-kit';export function Default() { return <PixelTypewriter text="Hello, pxlkit." />;}PIXELGLITCH
glitchtrigger, tune speed and intensity.ERROR
2500ms / 4px
CORRUPT
1800ms / 5px
badge / 3px
PXLKIT
2200ms / 6px
import { PixelGlitch } from '@pxlkit/ui-kit';export function Default() { return ( <PixelGlitch> <span className="text-2xl font-bold">SYSTEM ONLINE</span> </PixelGlitch> );}Real live demos for every component that ships in @pxlkit/ui-kit. Each preview is the Default example function authored alongside the component in <Component>.examples.tsx (single source of truth).
PIXELCOMBOBOX
combobox@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelCombobox } from '@pxlkit/ui-kit';const FRUITS = [ { value: 'apple', label: 'Apple' }, { value: 'banana', label: 'Banana' }, { value: 'cherry', label: 'Cherry' }, { value: 'date', label: 'Date' }, { value: 'elderberry', label: 'Elderberry' }, { value: 'fig', label: 'Fig' }, { value: 'grape', label: 'Grape' },];export function Default() { return ( <PixelCombobox label="Fruit" options={FRUITS} placeholder="Pick a fruit" hint="Type to filter" /> );}PIXELMULTISELECT
multiselect@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import React from 'react';import { PixelMultiSelect } from '@pxlkit/ui-kit';const OPTIONS = [ { value: 'react', label: 'React' }, { value: 'vue', label: 'Vue' }, { value: 'svelte', label: 'Svelte' }, { value: 'solid', label: 'Solid' }, { value: 'angular', label: 'Angular', disabled: true },];export function Default() { const [value, setValue] = React.useState<string[]>(['react']); return ( <PixelMultiSelect label="Frameworks" options={OPTIONS} value={value} onChange={setValue} placeholder="Pick frameworks…" /> );}PIXELDATEPICKER
datepicker@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelDatePicker } from '@pxlkit/ui-kit';export function Default() { const [date, setDate] = useState<Date | null>(null); return ( <PixelDatePicker label="Pick a date" value={date} onChange={setDate} placeholder="Select date" /> );}PIXELNUMBERINPUT
numberinput@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelNumberInput } from '@pxlkit/ui-kit';export function Default() { const [value, setValue] = useState<number>(5); return ( <PixelNumberInput label="Quantity" value={value} onChange={setValue} min={0} max={100} /> );}PIXELOTPINPUT
otpinput@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import React from 'react';import { PixelOTPInput } from '@pxlkit/ui-kit';export function Default() { const [value, setValue] = React.useState('') return <PixelOTPInput length={6} value={value} onChange={setValue} />}PIXELFILEUPLOAD
fileupload@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelFileUpload } from '@pxlkit/ui-kit';export function Default() { const [files, setFiles] = useState<File[]>([]); return ( <PixelFileUpload label="Upload files" hint="PNG or JPG, up to 5 MB each" value={files} onChange={setFiles} accept="image/*" multiple maxSize={5 * 1024 * 1024} maxFiles={5} /> );}PIXELFORM
form@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useForm } from 'react-hook-form';import { PixelForm, PixelInput } from '@pxlkit/ui-kit';type DefaultValues = { username: string; email: string;};export function Default() { const form = useForm<DefaultValues>({ defaultValues: { username: '', email: '' }, }); return ( <PixelForm form={form} onSubmit={(data) => { // eslint-disable-next-line no-console console.log('submit', data); }} > <PixelForm.Field name="username" rules={{ required: 'Username is required' }} render={({ field }) => ( <PixelForm.Item> <PixelForm.Label>Username</PixelForm.Label> <PixelForm.Control> <PixelInput placeholder="pxlhero" {...field} /> </PixelForm.Control> <PixelForm.Description>Your retro alias.</PixelForm.Description> <PixelForm.Message /> </PixelForm.Item> )} /> <PixelForm.Field name="email" rules={{ required: 'Email is required', pattern: { value: /.+@.+\..+/, message: 'Enter a valid email' }, }} render={({ field }) => ( <PixelForm.Item> <PixelForm.Label>Email</PixelForm.Label> <PixelForm.Control> <PixelInput type="email" placeholder="hero@pxlkit.xyz" {...field} /> </PixelForm.Control> <PixelForm.Message /> </PixelForm.Item> )} /> </PixelForm> );}PIXELINPUTGROUP
inputgroup@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelInputGroup } from '@pxlkit/ui-kit';export function Default() { return ( <PixelInputGroup aria-label="Website URL"> <input aria-label="Protocol" defaultValue="https://" className="bg-transparent px-2 outline-none" /> <input aria-label="Domain name" defaultValue="pxlkit" className="bg-transparent px-2 outline-none" /> <input aria-label="Top-level domain" defaultValue=".xyz" className="bg-transparent px-2 outline-none" /> </PixelInputGroup> );}PIXELTOGGLEGROUP
togglegroup@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelToggle, PixelToggleGroup } from '@pxlkit/ui-kit';export function Default() { const [value, setValue] = useState<string>('left'); return ( <PixelToggleGroup type="single" value={value} onChange={setValue} aria-label="Text alignment" > <PixelToggle value="left">Left</PixelToggle> <PixelToggle value="center">Center</PixelToggle> <PixelToggle value="right">Right</PixelToggle> </PixelToggleGroup> );}PIXELTOGGLE
toggle@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelToggle } from '@pxlkit/ui-kit';export function Default() { const [pressed, setPressed] = useState(false); return ( <PixelToggle value="bold" pressed={pressed} onPressedChange={setPressed}> Bold </PixelToggle> );}PIXELDATERANGEPICKER
daterangepicker@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelDateRangePicker, type DateRangeValue } from '@pxlkit/ui-kit';export function Default() { const [range, setRange] = useState<DateRangeValue>({}); return ( <PixelDateRangePicker label="Date range" value={range} onChange={setRange} placeholder="Select date range" /> );}PIXELCALENDARGRID
calendargrid@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelCalendarGrid } from '@pxlkit/ui-kit';export function Default() { const [value, setValue] = useState<Date | null>(null) return <PixelCalendarGrid value={value} onChange={setValue} />}PIXELCOLORINPUT
colorinput@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelColorInput } from '@pxlkit/ui-kit';export function Default() { const [value, setValue] = useState<string>('#06b6d4'); return ( <PixelColorInput label="Brand color" value={value} onChange={setValue} /> );}PIXELRIBBON
ribbon@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import React from 'react';import { PixelRibbon } from '@pxlkit/ui-kit';function Container({ children }: { children: React.ReactNode }) { return ( <div className="relative inline-block border-2 border-retro-border bg-retro-bg/60 p-8 text-retro-text"> <div>Card content</div> {children} </div> );}export function Default() { return ( <Container> <PixelRibbon>New</PixelRibbon> </Container> );}PIXELSTARRATING
starrating@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelStarRating } from '@pxlkit/ui-kit';export function Default() { return <PixelStarRating value={4} />;}PIXELICONFRAME
iconframe@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelIconFrame } from '@pxlkit/ui-kit';const Glyph = () => ( <span style={{ fontFamily: 'monospace', fontWeight: 700 }}>{'>_'}</span>);export function Default() { return <PixelIconFrame icon={<Glyph />} />;}PIXELDATATABLE
datatable@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.| Alice | Engineer | active |
| Bob | Designer | idle |
| Carol | PM | active |
| Dan | Engineer | active |
| Eve | Designer | idle |
import { PixelDataTable, createColumnHelper, type ColumnDef } from '@pxlkit/ui-kit';type Row = { id: string; name: string; role: string; status: string;};const rows: Row[] = [ { id: '1', name: 'Alice', role: 'Engineer', status: 'active' }, { id: '2', name: 'Bob', role: 'Designer', status: 'idle' }, { id: '3', name: 'Carol', role: 'PM', status: 'active' }, { id: '4', name: 'Dan', role: 'Engineer', status: 'active' }, { id: '5', name: 'Eve', role: 'Designer', status: 'idle' },];const ch = createColumnHelper<Row>();const columns: ColumnDef<Row, unknown>[] = [ ch.accessor('name', { header: 'Name' }) as ColumnDef<Row, unknown>, ch.accessor('role', { header: 'Role' }) as ColumnDef<Row, unknown>, ch.accessor('status', { header: 'Status' }) as ColumnDef<Row, unknown>,];export function Default() { return <PixelDataTable<Row> data={rows} columns={columns} />;}PIXELCAROUSEL
carousel@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelCarousel } from '@pxlkit/ui-kit';function Slide({ label, tone }: { label: string; tone: string }) { return ( <div className="flex h-32 items-center justify-center border border-retro-border bg-retro-surface text-retro-text" style={{ background: tone }} > <span className="text-xs">{label}</span> </div> );}export function Default() { return ( <PixelCarousel aria-label="Featured items"> <PixelCarousel.Item> <Slide label="Slide 1" tone="rgba(14,165,233,0.15)" /> </PixelCarousel.Item> <PixelCarousel.Item> <Slide label="Slide 2" tone="rgba(168,85,247,0.15)" /> </PixelCarousel.Item> <PixelCarousel.Item> <Slide label="Slide 3" tone="rgba(34,197,94,0.15)" /> </PixelCarousel.Item> </PixelCarousel> );}PIXELTIMELINE
timeline@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.- Order placed09:00Confirmation email sent.
- Packed11:20At the warehouse.
- Shipped—Awaiting carrier pickup.
import { PixelTimeline, PixelTimelineItem } from '@pxlkit/ui-kit';export function Default() { return ( <PixelTimeline active={1}> <PixelTimelineItem title="Order placed" time="09:00"> Confirmation email sent. </PixelTimelineItem> <PixelTimelineItem title="Packed" time="11:20"> At the warehouse. </PixelTimelineItem> <PixelTimelineItem title="Shipped" time="—"> Awaiting carrier pickup. </PixelTimelineItem> </PixelTimeline> );}PIXELSTATGROUP
statgroup@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Users
1,284
Revenue
$12.4k
Active
312
import { PixelStatGroup, PixelStatCard } from '@pxlkit/ui-kit';export function Default() { return ( <PixelStatGroup aria-label="Key metrics"> <PixelStatCard label="Users" value="1,284" /> <PixelStatCard label="Revenue" value="$12.4k" /> <PixelStatCard label="Active" value="312" /> </PixelStatGroup> );}PIXELAVATARGROUP
avatargroup@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelAvatarGroup, PixelAvatar } from '@pxlkit/ui-kit';export function Default() { return ( <PixelAvatarGroup aria-label="3 team members"> <PixelAvatar name="Joangel De La Rosa" /> <PixelAvatar name="Ana Lopez" /> <PixelAvatar name="Carlos Diaz" /> </PixelAvatarGroup> );}PIXELBADGEGROUP
badgegroup@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelBadgeGroup, PixelBadge } from '@pxlkit/ui-kit';export function Default() { return ( <PixelBadgeGroup aria-label="Tags"> <PixelBadge tone="cyan">react</PixelBadge> <PixelBadge tone="green">typescript</PixelBadge> <PixelBadge tone="gold">design</PixelBadge> </PixelBadgeGroup> );}PIXELCHIPGROUP
chipgroup@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import React, { useState } from 'react';import { PixelChipGroup, PixelChip } from '@pxlkit/ui-kit';const Chip = PixelChip as unknown as React.ComponentType< React.ComponentProps<typeof PixelChip> & { value: string }>;export function Default() { const [value, setValue] = useState<string[]>(['react']); return ( <PixelChipGroup value={value} onChange={setValue} aria-label="Frameworks"> <Chip value="react" label="React" tone="cyan" /> <Chip value="vue" label="Vue" tone="green" /> <Chip value="svelte" label="Svelte" tone="gold" /> </PixelChipGroup> );}PIXELSPARKLINE
sparkline@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelSparkline } from '@pxlkit/ui-kit';const sample = [ { x: 'Mon', y: 12 }, { x: 'Tue', y: 18 }, { x: 'Wed', y: 9 }, { x: 'Thu', y: 24 }, { x: 'Fri', y: 16 }, { x: 'Sat', y: 21 }, { x: 'Sun', y: 14 },];export function Default() { return <PixelSparkline data={sample} />;}PIXELBARCHART
barchart@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelBarChart } from '@pxlkit/ui-kit';const sample = [ { x: 'Mon', y: 12 }, { x: 'Tue', y: 18 }, { x: 'Wed', y: 9 }, { x: 'Thu', y: 24 }, { x: 'Fri', y: 16 }, { x: 'Sat', y: 21 }, { x: 'Sun', y: 14 },];export function Default() { return <PixelBarChart data={sample} />;}PIXELAREACHART
areachart@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelAreaChart } from '@pxlkit/ui-kit';const sample = [ { x: 'Mon', y: 12 }, { x: 'Tue', y: 18 }, { x: 'Wed', y: 9 }, { x: 'Thu', y: 24 }, { x: 'Fri', y: 16 }, { x: 'Sat', y: 21 }, { x: 'Sun', y: 14 },];export function Default() { return <PixelAreaChart data={sample} />;}PIXELFEATURECARD
featurecard@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Realtime sync
Push every keystroke to peers via WebSockets — under 50ms p95.
import { PixelFeatureCard } from '@pxlkit/ui-kit';export function Default() { return ( <PixelFeatureCard title="Realtime sync" description="Push every keystroke to peers via WebSockets — under 50ms p95." /> );}PIXELPRICINGCARD
pricingcard@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Starter
Everything you need to ship your first project.
- Included: 10 projects
- Included: Basic analytics
- Included: Email support
- Not included: Priority support
import { PixelPricingCard } from '@pxlkit/ui-kit';export function Default() { return ( <PixelPricingCard tone="cyan" name="Starter" description="Everything you need to ship your first project." price={{ amount: '$19', period: '/mo' }} features={[ { label: '10 projects' }, { label: 'Basic analytics' }, { label: 'Email support' }, { label: 'Priority support', included: false }, ]} /> );}PIXELTESTIMONIALCARD
testimonialcard@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.“pxlkit dropped the polish ceiling. Our marketing site felt like a product launch in a week.”
import { PixelTestimonialCard } from '@pxlkit/ui-kit';export function Default() { return ( <PixelTestimonialCard quote="pxlkit dropped the polish ceiling. Our marketing site felt like a product launch in a week." name="Marisol Quintero" role="Head of Design" company="Northbeam" stars={5} verified /> );}PIXELHEROSECTION
herosection@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.A hero inside a page
Its headline is an h2, under the page's own h1.
import { PixelHeroSection } from '@pxlkit/ui-kit';export function Default() { return ( <PixelHeroSection eyebrow="Introducing" headline="Pixel-perfect retro UI for modern web" subline="A component kit that brings cinematic, terminal-grade interfaces to React apps." primaryCta={<button type="button">Get started</button>} secondaryCta={<button type="button">View docs</button>} /> )}PIXELHEROMEDIA
heromedia@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelHeroMedia } from '@pxlkit/ui-kit';const Placeholder = ({ label }: { label: string }) => ( <div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-cyan-500/20 to-purple-500/20 text-xs font-mono text-retro-muted"> {label} </div>);export function Default() { return ( <PixelHeroMedia ratio="16/10"> <Placeholder label="16:10 media" /> </PixelHeroMedia> );}PIXELSPINNER
spinner@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelSpinner } from '@pxlkit/ui-kit';export function Default() { return <PixelSpinner />}PIXELSTEPPER
stepper@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelStepper } from '@pxlkit/ui-kit';export function Default() { return ( <PixelStepper active={1}> <PixelStepper.Step label="Account" description="Create your account" /> <PixelStepper.Step label="Profile" description="Add some details" /> <PixelStepper.Step label="Confirm" description="Review and submit" /> </PixelStepper> );}PIXELPORTAL
portal@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelPortal } from '@pxlkit/ui-kit';export function Default() { return ( <PixelPortal> <div>Portaled content (renders into document.body after mount)</div> </PixelPortal> )}PIXELPOPOVER
popover@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelPopover } from '@pxlkit/ui-kit';export function Default() { const [open, setOpen] = useState(false); return ( <PixelPopover open={open} onOpenChange={setOpen}> <PixelPopover.Trigger> <button type="button">Open popover</button> </PixelPopover.Trigger> <PixelPopover.Content aria-labelledby="popover-title"> <h3 id="popover-title" className="font-bold mb-1"> Popover </h3> <p className="text-sm">Floating content anchored to the trigger.</p> </PixelPopover.Content> </PixelPopover> );}PIXELDRAWER
drawer@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelDrawer } from '@pxlkit/ui-kit';export function Default() { const [open, setOpen] = useState(false); return ( <> <button type="button" onClick={() => setOpen(true)}> Open drawer </button> <PixelDrawer open={open} onOpenChange={setOpen} title="Settings"> <PixelDrawer.Header> <span>Settings</span> <button type="button" onClick={() => setOpen(false)}> Close </button> </PixelDrawer.Header> <PixelDrawer.Body> <p>Drawer content goes here.</p> </PixelDrawer.Body> <PixelDrawer.Footer> <button type="button" onClick={() => setOpen(false)}> Done </button> </PixelDrawer.Footer> </PixelDrawer> </> );}PIXELCOMMAND
command@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelCommand } from '@pxlkit/ui-kit';export function Default() { const [open, setOpen] = useState(false); return ( <> <button type="button" onClick={() => setOpen(true)}> Open command palette </button> <PixelCommand open={open} onOpenChange={setOpen} groups={[ { heading: 'Actions', items: [ { id: 'new-file', label: 'New file', shortcut: 'Ctrl+N', onSelect: () => setOpen(false), }, { id: 'open-file', label: 'Open file…', shortcut: 'Ctrl+O', onSelect: () => setOpen(false), }, { id: 'save', label: 'Save', shortcut: 'Ctrl+S', onSelect: () => setOpen(false), }, ], }, { heading: 'Navigation', items: [ { id: 'go-home', label: 'Go to home', keywords: ['dashboard', 'start'], onSelect: () => setOpen(false), }, { id: 'go-settings', label: 'Go to settings', keywords: ['preferences', 'config'], onSelect: () => setOpen(false), }, ], }, ]} /> </> );}PIXELALERTDIALOG
alertdialog@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelAlertDialog } from '@pxlkit/ui-kit';export function Default() { const [open, setOpen] = useState(false); return ( <div> <button type="button" onClick={() => setOpen(true)}> Open alert dialog </button> <PixelAlertDialog open={open} onOpenChange={setOpen} title="Save changes?" description="Your edits will be applied to the live document." actionLabel="Save" onAction={() => setOpen(false)} /> </div> );}PIXELSHEET
sheet@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { useState } from 'react';import { PixelSheet } from '@pxlkit/ui-kit';export function Default() { const [open, setOpen] = useState(false); return ( <> <button type="button" onClick={() => setOpen(true)}> Open sheet </button> <PixelSheet open={open} onOpenChange={setOpen} title="Quick actions" description="Pick an action below" > <p>Sheet content goes here.</p> <button type="button" onClick={() => setOpen(false)}> Close </button> </PixelSheet> </> );}PIXELBOX
box@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Surface-aware container box.
import { PixelBox } from '@pxlkit/ui-kit';export function Default() { return ( <PixelBox tone="neutral" variant="solid" padding="md"> <p className="text-sm text-retro-muted">Surface-aware container box.</p> </PixelBox> );}PIXELSTACK
stack@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelStack } from '@pxlkit/ui-kit';export function Default() { return ( <PixelStack gap={4}> <div className="text-sm text-retro-muted">First item</div> <div className="text-sm text-retro-muted">Second item</div> <div className="text-sm text-retro-muted">Third item</div> </PixelStack> );}PIXELCLUSTER
cluster@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import React from 'react';import { PixelCluster } from '@pxlkit/ui-kit';function Chip({ children }: { children: React.ReactNode }) { return ( <span className="rounded border border-retro-border px-2 py-1 text-xs text-retro-text"> {children} </span> );}export function Default() { return ( <PixelCluster> <Chip>react</Chip> <Chip>typescript</Chip> <Chip>tailwind</Chip> <Chip>next</Chip> <Chip>vite</Chip> </PixelCluster> );}PIXELGRID
grid@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import React from 'react';import { PixelGrid } from '@pxlkit/ui-kit';function Cell({ children }: { children: React.ReactNode }) { return ( <div className="border border-retro-border bg-retro-surface p-3 text-sm text-retro-text"> {children} </div> );}export function Default() { return ( <PixelGrid cols={3} gap={4}> <Cell>One</Cell> <Cell>Two</Cell> <Cell>Three</Cell> <Cell>Four</Cell> <Cell>Five</Cell> <Cell>Six</Cell> </PixelGrid> );}PIXELEQUALHEIGHTGRID
equalheightgrid@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.One
Short copy.
Two
A longer body that forces the row to grow taller than the first card.
Three
Medium length copy here.
import { cn, PixelEqualHeightGrid } from '@pxlkit/ui-kit';function Card({ title, body, className }: { title: string; body: string; className?: string }) { return ( <div className={cn('border border-retro-border p-4', className)}> <h3 className="text-sm font-semibold text-retro-text">{title}</h3> <p className="text-sm text-retro-muted">{body}</p> <div className="mt-2 text-xs text-retro-muted">Footer</div> </div> );}export function Default() { return ( <PixelEqualHeightGrid cols={{ base: 1, sm: 3 }} gap={4}> <Card title="One" body="Short copy." /> <Card title="Two" body="A longer body that forces the row to grow taller than the first card." /> <Card title="Three" body="Medium length copy here." /> </PixelEqualHeightGrid> );}PIXELCENTER
center@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Centered content with the default max-width and page gutter.
import { PixelCenter } from '@pxlkit/ui-kit';export function Default() { return ( <PixelCenter> <p className="text-sm text-retro-muted"> Centered content with the default max-width and page gutter. </p> </PixelCenter> );}PIXELCONTAINER
container@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Default container — section landmark, xl max-width, lg rhythm.
import { PixelContainer } from '@pxlkit/ui-kit';export function Default() { return ( <PixelContainer> <p className="text-sm text-retro-muted">Default container — section landmark, xl max-width, lg rhythm.</p> </PixelContainer> );}PIXELTWOCOLUMN
twocolumn@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelTwoColumn } from '@pxlkit/ui-kit';export function Default() { return ( <PixelTwoColumn left={<div className="text-sm text-retro-muted">Left column</div>} right={<div className="text-sm text-retro-muted">Right column</div>} /> );}PIXELSECTIONHEADER
sectionheader@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Section: Build pixel-perfect interfaces
A retro-cinematic component kit with surface awareness and rhythm tokens.
import { PixelSectionHeader } from '@pxlkit/ui-kit';export function Default() { return ( <PixelSectionHeader eyebrow="Section" title="Build pixel-perfect interfaces" description="A retro-cinematic component kit with surface awareness and rhythm tokens." /> );}PIXELBENTO
bento@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.import { PixelBento, PixelBentoCell } from '@pxlkit/ui-kit';export function Default() { return ( <PixelBento columns={3} gap={4}> <PixelBentoCell span="2x2" kind="feature" tone="cyan"> <strong>Feature</strong> <span>Spans 2x2 with a feature layout.</span> </PixelBentoCell> <PixelBentoCell span="1x1" kind="stat" tone="green"> <strong>42</strong> <span>Stats</span> </PixelBentoCell> <PixelBentoCell span="1x1" kind="compact" tone="gold"> <span>Compact</span> </PixelBentoCell> <PixelBentoCell span="2x1" kind="feature" tone="purple"> <strong>Wide</strong> <span>Spans 2x1.</span> </PixelBentoCell> <PixelBentoCell span="1x1" kind="media" tone="neutral"> <div className="h-full w-full bg-retro-surface" /> </PixelBentoCell> </PixelBento> );}PIXELBENTOCELL
bentocell@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Feature cell
Span 2x1 with feature layout.
import { PixelBento, PixelBentoCell } from '@pxlkit/ui-kit';export function Default() { return ( <PixelBento columns={3} gap={4}> <PixelBentoCell kind="feature" tone="neutral" span="2x1"> <h3 className="text-sm font-semibold">Feature cell</h3> <p className="text-sm text-retro-muted">Span 2x1 with feature layout.</p> </PixelBentoCell> <PixelBentoCell kind="stat" tone="cyan" span="1x1"> <span className="text-xs text-retro-muted">Active</span> <strong className="text-2xl">128</strong> </PixelBentoCell> <PixelBentoCell kind="compact" tone="green" span="1x1"> <span className="text-sm">Compact</span> </PixelBentoCell> </PixelBento> );}PIXELSCROLLAREA
scrollarea@pxlkit/ui-kit, @pxlkit/ui-kit-vue and @pxlkit/ui-kit-angular. See the v2.2.0 changelog for release notes, or the full reference for props, accessibility, keyboard and the examples in React, Vue and Angular.Scroll item 1
Scroll item 2
Scroll item 3
Scroll item 4
Scroll item 5
Scroll item 6
Scroll item 7
Scroll item 8
Scroll item 9
Scroll item 10
Scroll item 11
Scroll item 12
import { PixelScrollArea } from '@pxlkit/ui-kit';export function Default() { return ( <PixelScrollArea aria-label="Sample scrollable region" maxHeight={160}> <div className="space-y-2 p-3"> {Array.from({ length: 12 }).map((_, i) => ( <p key={i} className="text-sm text-retro-muted"> Scroll item {i + 1} </p> ))} </div> </PixelScrollArea> );}