PXLKIT UI KIT
A full-featured, fully custom React component library built with TypeScript, Tailwind CSS, and Pxlkit pixel-art icons. Every element is hand-crafted without native browser UI components — designed for retro-futuristic interfaces that work flawlessly across all devices. Use the sidebar to navigate all 53 components and PixelToast docs.
Components
53
Icon Packs
6
Design Tokens
6 tones
Fully Custom
100%
Documentation
GETTING STARTED
Import components from the UI Kit module and pair them with any icon from the Pxlkit icon packs. All components share a common API surface with , size, and icon props for consistent theming. See , , and for examples.
import { PixelButton, PixelCard, PixelInput } from '@/components/ui-kit';import { PxlKitIcon } from '@pxlkit/core';import { Trophy } from '@pxlkit/gamification';import { Search } from '@pxlkit/ui';// Button with icon<PixelButton tone="green" iconLeft={<PxlKitIcon icon={Trophy} size={16} />}> Create Quest</PixelButton>// Input with icon<PixelInput label="Search" icon={<PxlKitIcon icon={Search} size={16} />} placeholder="Find icons..."/>Common API Surface
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "green" | "cyan" | "gold" | "red" | "purple" | "neutral" | varies | Color scheme — shared across all components |
| size | "sm" | "md" | "lg" | "md" | Controls height, padding, and font size |
| iconLeft / iconRight | ReactNode | — | Slot for icons before/after label (see buttons) |
| label | string | — | Accessible label for inputs and controls |
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-body
Surfaces
Background
--retro-bg
Surface
--retro-surface
Card
--retro-card
Border
--retro-border
Actions
Inputs
PIXELINPUT
input<PixelInput label="Search" icon={<PxlKitIcon icon={Search} size={16} />} placeholder="Find components..." tone="cyan"/><PixelInput label="Email" error="Invalid email address" />PIXELPASSWORDINPUT
passwordinput<PixelPasswordInput label="Password" placeholder="Enter your password" />PIXELTEXTAREA
textareaFieldShell wrapper as .<PixelTextarea label="Bio" placeholder="Tell us about yourself..." />PIXELSELECT
select<PixelSelect label="Icon Pack" value={pack} onChange={setPack} options={[ { value: 'ui', label: 'UI' }, { value: 'gamification', label: 'Gamification' }, { value: 'social', label: 'Social' }, ]}/>PIXELCHECKBOX
checkbox<PixelCheckbox label="Enable animations" checked={enabled} onChange={setEnabled} tone="green"/>PIXELRADIOGROUP
radiogroup<PixelRadioGroup label="Framework" value={framework} onChange={setFramework} options={[ { value: 'react', label: 'React' }, { value: 'vue', label: 'Vue' }, { value: 'svelte', label: 'Svelte' }, ]}/>PIXELSWITCH
switch<PixelSwitch label="Auto refresh" checked={on} onChange={setOn} />PIXELSLIDER
slider<PixelSlider label="Volume" value={vol} onChange={setVol} min={0} max={100} /><PixelSlider label="Opacity" value={opacity} onChange={setOpacity} tone="gold" />PIXELSEGMENTED
segmentedLayout density
<PixelSegmented label="Density" value={density} onChange={setDensity} options={[ { value: 'compact', label: 'Compact' }, { value: 'comfortable', label: 'Comfortable' }, ]}/>Data Display
PIXELCARD
cardSocial Pack
<PixelCard title="Gamification" icon={<PxlKitIcon icon={Trophy} size={16} />} footer={<PixelButton tone="gold" size="sm">Use Pack</PixelButton>}> RPG icons, rewards, and game UI elements.</PixelCard>PIXELSTATCARD
statcardTotal Icons
204
+12 new
Components
53
100% typed
Downloads
8.2k
+24%
Stars
1.4k
trending
<PixelStatCard label="Downloads" value="12.4k" tone="green" trend="+15% this week" />PIXELTABLE
table| Component | Category | Status |
|---|---|---|
| PixelButton | Actions | Stable |
| PixelSelect | Inputs | Stable |
| PixelTable | Data Display | New |
| PixelAvatar | Data Display | New |
| PixelSkeleton | Feedback | New |
<PixelTable columns={[ { key: 'name', header: 'Component' }, { key: 'category', header: 'Category' }, { key: 'status', header: 'Status' }, ]} data={[ { name: 'PixelButton', category: 'Actions', status: <PixelBadge tone="green">Stable</PixelBadge> }, { name: 'PixelTable', category: 'Data', status: <PixelBadge tone="gold">New</PixelBadge> }, ]}/>PIXELAVATAR
avatar<PixelAvatar name="Joangel De La Rosa" tone="green" /><PixelAvatar name="AI Bot" tone="purple" size="lg" />PIXELBADGE
badge<PixelBadge tone="green">Stable</PixelBadge><PixelBadge tone="gold">Beta</PixelBadge><PixelBadge tone="red">Deprecated</PixelBadge>PIXELCHIP
chip<PixelChip label="react" tone="cyan" /><PixelChip label="removable" tone="gold" onRemove={() => {}} />PIXELTEXTLINK
textlink<a> when href is provided, otherwise as <button>. Supports all anchor and button attributes via spread props.<PixelTextLink href="/docs" tone="cyan">Documentation</PixelTextLink><PixelTextLink tone="gold" onClick={() => alert('clicked')}>Action Link</PixelTextLink>PIXELCODEINLINE
codeinlineUse useState for local state, PxlKitIcon for icons, green gold red neutral
<PixelCodeInline tone="cyan">useState</PixelCodeInline><PixelCodeInline tone="purple">PxlKitIcon</PixelCodeInline>PIXELKBD
kbd<PixelKbd>Ctrl</PixelKbd> + <PixelKbd>K</PixelKbd><PixelKbd>⌘</PixelKbd> + <PixelKbd>Shift</PixelKbd> + <PixelKbd>P</PixelKbd>PIXELCOLORSWATCH
colorswatchGreen
--retro-green
Cyan
--retro-cyan
Gold
--retro-gold
Red
--retro-red
Purple
--retro-purple
<PixelColorSwatch name="Green" cssVar="--retro-green" /><PixelColorSwatch name="Cyan" cssVar="--retro-cyan" />Feedback
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.
<PixelAlert tone="green" icon={<PxlKitIcon icon={CheckCircle} size={16} />} title="Build Success" message="Package compiled successfully." action={<PixelButton tone="green" size="sm">View Logs</PixelButton>}/>PIXELPROGRESS
progress<PixelProgress value={72} tone="green" label="Upload Progress" />PIXELSKELETON
skeleton<PixelSkeleton width="200px" height="1rem" /><PixelSkeleton width="40px" height="40px" rounded />PIXELEMPTYSTATE
emptystateNo results found
Adjust your filters or create a new custom component for this kit.
<PixelEmptyState title="No results" description="Try adjusting your search or filters." icon={<PxlKitIcon icon={Search} size={20} />} action={<PixelButton tone="green">Reset Filters</PixelButton>}/>PIXELTOAST
toastToastProvider + useToast(). Supports tones, positions, custom icons (static or animated), duration, and dismiss controls. The old /toast route now redirects here.Detailed integration docs are also available in /docs#toast-notifications.
import { useToast } from '@/components/ToastProvider';import { CheckCircle, WarningTriangle } from '@pxlkit/feedback';import { FireSword } from '@pxlkit/gamification';function SaveButton() { const { toast, success, warning } = useToast(); return ( <> <PixelButton onClick={() => success('SAVED', 'Changes synced to server', CheckCircle)} > Save </PixelButton> <PixelButton onClick={() => toast({ tone: 'warning', title: 'LOW HEALTH', message: 'Use a potion now', position: 'bottom-right', duration: 3500, animatedIcon: FireSword, }) } > Show Warning Toast </PixelButton> </> );}Navigation
PIXELTABS
tabs<PixelTabs items={[ { id: 'overview', label: 'Overview', content: '...' }, { id: 'api', label: 'API', content: '...' }, { id: 'tokens', label: 'Tokens', content: '...' },]} />PIXELACCORDION
accordion<PixelAccordion items={[ { id: '1', title: 'How to use icons', content: '...' }, { id: '2', title: 'Custom themes', content: '...' },]} />PIXELCOLLAPSIBLE
collapsibleThis panel starts expanded. Click the label to collapse it.
<PixelCollapsible label="Show details"> <p>Hidden content revealed on toggle.</p></PixelCollapsible><PixelCollapsible label="Open by default" defaultOpen tone="green"> <p>Visible from the start.</p></PixelCollapsible>PIXELPAGINATION
pagination<PixelPagination page={page} total={5} onChange={setPage} />Overlay
PIXELMODAL
modalconst [open, setOpen] = useState(false);<PixelButton onClick={() => setOpen(true)}>Open Modal</PixelButton><PixelModal open={open} title="Confirm Action" onClose={() => setOpen(false)}> <p>Are you sure you want to proceed?</p> <PixelButton tone="green" onClick={() => setOpen(false)}>Confirm</PixelButton></PixelModal>PIXELTOOLTIP
tooltip<PixelTooltip content="Edit this item" position="top"> <PxlKitButton label="Edit" icon={<PxlKitIcon icon={Edit} size={16} />} /></PixelTooltip>PIXELDROPDOWN
dropdown<PixelDropdown label="Actions" items={[ { value: 'copy', label: 'Copy snippet' }, { value: 'preview', label: 'Open preview' }, { value: 'delete', label: 'Delete item' }, ]} onSelect={(v) => console.log(v)}/>Layout
PIXELSECTION
sectionEXAMPLE SECTION
This is a wrapped content area with border and padding.
<PixelSection title="Actions" subtitle="Interactive button components."> {children}</PixelSection>PIXELDIVIDER
dividerSection Break
Actions
Inputs
<PixelDivider /><PixelDivider label="Section" tone="green" />Primitives
PIXELBAREINPUT
bareinput<input> wrapper with forwardRef support. Use as the base for custom text fields or form controls. Accepts all native input attributes.Renders an unstyled <input> element. For styled text fields with labels, hints, and errors, use .
<PixelBareInput type="text" placeholder="Unstyled input..." className="border px-2 py-1" />PIXELBARETEXTAREA
baretextarea<textarea> wrapper with forwardRef support. Use for custom multi-line inputs. Accepts all native textarea attributes.Renders an unstyled <textarea> element. For styled multi-line input with labels and errors, use .
<PixelBareTextarea rows={3} placeholder="Unstyled textarea..." className="border px-2 py-1 w-full" />Animations
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} colorful /></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
<PixelFadeIn duration={400} delay={0} easing="ease-out"> <PixelCard title="Hello World">Faded in!</PixelCard></PixelFadeIn>// Scroll-triggered fade<PixelFadeIn trigger="inView" duration={600}> <p>I appear when scrolled into view</p></PixelFadeIn>PIXELSLIDEIN
slideindistance and pacing using easing. Complements .<PixelSlideIn from="down" duration={350} distance={14} easing="ease-out"> <PixelButton tone="green">Slid In</PixelButton></PixelSlideIn>// Staggered list{items.map((item, i) => ( <PixelSlideIn key={item} from="right" delay={i * 80}> <PixelCard title={item} /> </PixelSlideIn>))}PIXELPULSE
pulseCPU
87%
<PixelPulse duration={2000}> <PixelBadge tone="red">Live</PixelBadge></PixelPulse>PIXELBOUNCE
bounceduration and stop it with repeat=1.<PixelBounce duration={800}> <PxlKitIcon icon={Trophy} size={24} colorful /></PixelBounce>// Finite bounce<PixelBounce duration={600} repeat={3}> <PixelBadge tone="gold">+100 XP</PixelBadge></PixelBounce>PIXELFLOAT
float<PixelFloat distance={8} duration={2400}> <PxlKitIcon icon={Star} size={20} colorful /></PixelFloat>PIXELSHAKE
shakerepeat low to avoid visual fatigue. Often paired with .<PixelShake duration={450} repeat={2} distance={3}> <PixelBadge tone="red">Invalid Input</PixelBadge></PixelShake>PIXELROTATE
rotatedirection to reverse or alternate spin behavior for loading indicators and decorative accents.<PixelRotate duration={1800} direction="normal" repeat="infinite"> <PxlKitIcon icon={Gear} size={22} colorful /></PixelRotate>PIXELZOOMIN
zoominPack Ready
<PixelZoomIn duration={320} startScale={0.9}> <PixelCard title="Quick Reveal">Zoomed entrance</PixelCard></PixelZoomIn>PIXELFLICKER
flickerSIGNAL LOCKED
<PixelFlicker duration={2200}> <p className="font-pixel text-retro-cyan">SIGNAL LOCKED</p></PixelFlicker>PIXELTYPEWRITER
typewriter<PixelTypewriter text="Hello, World!" speed={60} tone="green" /><PixelTypewriter text="// loading system..." speed={40} delay={800} tone="cyan" cursor />PIXELGLITCH
glitchtrigger, tune speed and intensity.ERROR
2500ms / 4px
CORRUPT
1800ms / 5px
badge / 3px
PXLKIT
2200ms / 6px
<PixelGlitch trigger="hover" duration={3000} intensity={4}> <h1 className="font-pixel text-retro-green">SYSTEM ERROR</h1></PixelGlitch>Parallax
PIXELPARALLAXLAYER
parallaxlayerspeed to control the multiplier — 0 = static, 0.5 = half speed (far background), negative = reverse direction. GPU-composited via translate3d. Wrap inside for clipped layouts.Scroll the page to see the parallax effect on these layers:
<PixelParallaxGroup className="h-[400px]"> {/* Slow background layer */} <PixelParallaxLayer speed={0.3} className="absolute inset-0"> <img src="/bg-stars.png" className="w-full h-full object-cover" /> </PixelParallaxLayer> {/* Foreground content */} <PixelParallaxLayer speed={-0.1}> <PixelCard title="Floating Card">I move slightly opposite to scroll</PixelCard> </PixelParallaxLayer></PixelParallaxGroup>PIXELPARALLAXGROUP
parallaxgroupoverflow: hidden and position: relative automatically. Wrap and elements inside.<PixelParallaxGroup as="section" className="h-[600px] bg-retro-bg"> <PixelParallaxLayer speed={0.2}> {/* Background */} </PixelParallaxLayer> <PixelMouseParallax strength={15}> {/* Foreground that follows cursor */} </PixelMouseParallax></PixelParallaxGroup>PIXELMOUSEPARALLAX
mouseparallaxstrength to control max travel distance in px. Set invert to move away from cursor. Perfect for floating elements, hero backgrounds, and interactive depth effects.Move your mouse over this area:
follows (12px)
inverted (25px)
subtle (8px)
{/* Follows cursor */}<PixelMouseParallax strength={15}> <PxlKitIcon icon={Star} size={32} colorful /></PixelMouseParallax>{/* Moves away from cursor (depth feel) */}<PixelMouseParallax strength={25} invert> <PixelBadge tone="cyan">Background layer</PixelBadge></PixelMouseParallax>Full Inventory