game-locker-ui
v0.1.0
Published
A React component kit for building game locker / loadout UIs. Fully themeable via CSS custom properties, written in TypeScript.
Downloads
106
Readme
game-locker-ui
A React component kit for building game locker / loadout UIs. Fully themeable via CSS custom properties, written in TypeScript.
Installation
npm install game-locker-uiReact 18 is a peer dependency — make sure it is already installed in your project.
Quick Start
import { useState } from 'react';
import {
LockerThemeProvider,
LockerHeader,
LockerItemSlots,
CharacterDisplay,
LockerRightPanel,
} from 'game-locker-ui';
import 'game-locker-ui/styles';
export default function App() {
const [activeTab, setActiveTab] = useState('locker');
return (
<LockerThemeProvider>
<div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
<LockerHeader activeTab={activeTab} onTabChange={setActiveTab} />
<div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
<LockerItemSlots />
<CharacterDisplay />
<LockerRightPanel />
</div>
</div>
</LockerThemeProvider>
);
}Important: Import
'game-locker-ui/styles'once at the top of your app. This injects the--locker-*CSS custom properties that all components depend on.
Components
LockerThemeProvider
Wrap your app (or any subtree) with this provider to apply theme colors. All --locker-* CSS variables are scoped to the wrapper element — they don't pollute :root and are SSR-safe.
<LockerThemeProvider theme={{ bgDark: '#6c3483', selectionColor: '#00ffff' }}>
{/* components pick up the overrides automatically */}
</LockerThemeProvider>| Prop | Type | Default |
|------|------|---------|
| theme | LockerTheme | all defaults (see Theming) |
| children | ReactNode | — |
LockerHeader
The top navigation bar with tab switching, a menu button with notification badge, and a currency counter.
<LockerHeader
activeTab="locker"
onTabChange={(id) => console.log(id)}
vbucks={1200}
/>| Prop | Type | Default |
|------|------|---------|
| activeTab | string | — (required) |
| onTabChange | (id: string) => void | — (required) |
| tabs | LockerTab[] | 7 default tabs (see below) |
| vbucks | number | 800 |
| notificationCount | number | 1 |
Default tabs:
| id | label |
|----|-------|
| play | PLAY |
| battlepass | BATTLE PASS |
| compete | COMPETE |
| locker | LOCKER |
| itemshop | ITEM SHOP (has notification badge) |
| career | CAREER (has notification badge) |
| vbucks | V-BUCKS |
LockerItemSlots
The left panel containing the main loadout row, emote wheel, miscellaneous slots, and a favorites button.
<LockerItemSlots
topRowItems={myOutfits}
onItemSelect={(item) => console.log(item)}
favoriteActive
onFavoriteClick={() => {}}
/>| Prop | Type | Default |
|------|------|---------|
| topRowItems | ItemSlot[] | 5 placeholder slots (outfit, backbling, pickaxe, glider, contrail) |
| emoteSlots | ItemSlot[] | 6 placeholder slots (3 filled, 3 empty) |
| miscSlots | ItemSlot[] | 9 placeholder slots |
| onItemSelect | (item: ItemSlot) => void | — |
| favoriteActive | boolean | false |
| onFavoriteClick | () => void | — |
Supply an image URL on any ItemSlot to render it inside the slot:
const myItems: ItemSlot[] = [
{ id: '1', type: 'outfit', selected: true, image: 'https://example.com/skin.png', label: 'Dark Knight' },
{ id: '2', type: 'backbling' },
];CharacterDisplay
The center panel showing the character preview image, name, rarity, and category label.
<CharacterDisplay
characterName="RAVEN"
rarityLabel="LEGENDARY"
categoryLabel="OUTFIT"
characterImage="https://example.com/raven.png"
/>| Prop | Type | Default |
|------|------|---------|
| characterImage | string | Unsplash placeholder |
| characterName | string | 'SELENA' |
| rarityLabel | string | 'EPIC' |
| categoryLabel | string | 'OUTFIT' |
LockerRightPanel
The right panel with preset action buttons (Load, Save, Random).
<LockerRightPanel
onLoad={() => loadPreset()}
onSave={() => savePreset()}
onRandom={() => randomize()}
/>| Prop | Type | Default |
|------|------|---------|
| title | string | 'PRESETS' |
| loadLabel | string | 'LOAD' |
| saveLabel | string | 'SAVE' |
| randomLabel | string | 'RANDOM' |
| onLoad | () => void | — |
| onSave | () => void | — |
| onRandom | () => void | — |
Theming
All colors are driven by CSS custom properties. Import the stylesheet and override any variable on a parent element — no CSS recompile needed.
CSS variables
| Variable | Default | Used for |
|----------|---------|----------|
| --locker-bg-light | #4a9fdb | Background gradient top, slot borders |
| --locker-bg-mid | #2b7fd4 | Background gradient middle, slot fill |
| --locker-bg-dark | #1e5fb8 | Header, slot fill, button backgrounds |
| --locker-bg-darker | #0d4494 | Currency counter background |
| --locker-selection | #ff00ff | Selected slot border and glow |
| --locker-badge | #ffd700 | Notification badges |
| --locker-glow | #5aaee8 | Character display radial glow |
| --locker-font | 'Luckiest Guy', ... | Heading font stack |
Via LockerThemeProvider (recommended)
<LockerThemeProvider
theme={{
bgDark: '#6c3483',
bgMid: '#8e44ad',
bgLight: '#a569bd',
bgDarker: '#4a235a',
selectionColor: '#00ffff',
badgeColor: '#ff6b00',
}}
>
<YourApp />
</LockerThemeProvider>Via plain CSS (alternative)
.my-custom-locker {
--locker-bg-dark: #1a3a2a;
--locker-selection: #00ff88;
}useLockerTheme() hook
Read the current resolved theme values inside any child component:
import { useLockerTheme } from 'game-locker-ui';
function MyComponent() {
const theme = useLockerTheme();
return <div style={{ color: theme.selectionColor }}>Selected</div>;
}TypeScript Types
import type { ItemSlot, ItemSlotType, LockerTab, LockerTheme } from 'game-locker-ui';
type ItemSlotType =
| 'outfit' | 'backbling' | 'pickaxe' | 'glider' | 'contrail'
| 'emote' | 'spray' | 'emoticon' | 'banner' | 'music';
interface ItemSlot {
id: string;
type: ItemSlotType;
selected?: boolean;
image?: string;
isEmpty?: boolean;
label?: string;
}
interface LockerTab {
id: string;
label: string;
hasNotification?: boolean;
}
interface LockerTheme {
bgLight?: string;
bgMid?: string;
bgDark?: string;
bgDarker?: string;
selectionColor?: string;
badgeColor?: string;
fontFamily?: string;
}Development
npm install # install dependencies
npm run dev # start demo app at localhost:5173
npm run build # build demo app → dist-demo/
npm run build:lib # build npm package → dist/The demo app (src/app/App.tsx) shows a working instance of the full locker layout and serves as a live development environment.
License
MIT
