game-locker-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,296 @@
1
+ # game-locker-ui
2
+
3
+ A React component kit for building game locker / loadout UIs. Fully themeable via CSS custom properties, written in TypeScript.
4
+
5
+ ![React](https://img.shields.io/badge/React-18-61dafb?logo=react) ![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?logo=typescript) ![Tailwind CSS](https://img.shields.io/badge/Tailwind-v4-06b6d4?logo=tailwindcss)
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install game-locker-ui
13
+ ```
14
+
15
+ React 18 is a peer dependency — make sure it is already installed in your project.
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ ```tsx
22
+ import { useState } from 'react';
23
+ import {
24
+ LockerThemeProvider,
25
+ LockerHeader,
26
+ LockerItemSlots,
27
+ CharacterDisplay,
28
+ LockerRightPanel,
29
+ } from 'game-locker-ui';
30
+ import 'game-locker-ui/styles';
31
+
32
+ export default function App() {
33
+ const [activeTab, setActiveTab] = useState('locker');
34
+
35
+ return (
36
+ <LockerThemeProvider>
37
+ <div style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
38
+ <LockerHeader activeTab={activeTab} onTabChange={setActiveTab} />
39
+ <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>
40
+ <LockerItemSlots />
41
+ <CharacterDisplay />
42
+ <LockerRightPanel />
43
+ </div>
44
+ </div>
45
+ </LockerThemeProvider>
46
+ );
47
+ }
48
+ ```
49
+
50
+ > **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.
51
+
52
+ ---
53
+
54
+ ## Components
55
+
56
+ ### `LockerThemeProvider`
57
+
58
+ 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.
59
+
60
+ ```tsx
61
+ <LockerThemeProvider theme={{ bgDark: '#6c3483', selectionColor: '#00ffff' }}>
62
+ {/* components pick up the overrides automatically */}
63
+ </LockerThemeProvider>
64
+ ```
65
+
66
+ | Prop | Type | Default |
67
+ |------|------|---------|
68
+ | `theme` | `LockerTheme` | all defaults (see [Theming](#theming)) |
69
+ | `children` | `ReactNode` | — |
70
+
71
+ ---
72
+
73
+ ### `LockerHeader`
74
+
75
+ The top navigation bar with tab switching, a menu button with notification badge, and a currency counter.
76
+
77
+ ```tsx
78
+ <LockerHeader
79
+ activeTab="locker"
80
+ onTabChange={(id) => console.log(id)}
81
+ vbucks={1200}
82
+ />
83
+ ```
84
+
85
+ | Prop | Type | Default |
86
+ |------|------|---------|
87
+ | `activeTab` | `string` | — (required) |
88
+ | `onTabChange` | `(id: string) => void` | — (required) |
89
+ | `tabs` | `LockerTab[]` | 7 default tabs (see below) |
90
+ | `vbucks` | `number` | `800` |
91
+ | `notificationCount` | `number` | `1` |
92
+
93
+ **Default tabs:**
94
+
95
+ | id | label |
96
+ |----|-------|
97
+ | `play` | PLAY |
98
+ | `battlepass` | BATTLE PASS |
99
+ | `compete` | COMPETE |
100
+ | `locker` | LOCKER |
101
+ | `itemshop` | ITEM SHOP *(has notification badge)* |
102
+ | `career` | CAREER *(has notification badge)* |
103
+ | `vbucks` | V-BUCKS |
104
+
105
+ ---
106
+
107
+ ### `LockerItemSlots`
108
+
109
+ The left panel containing the main loadout row, emote wheel, miscellaneous slots, and a favorites button.
110
+
111
+ ```tsx
112
+ <LockerItemSlots
113
+ topRowItems={myOutfits}
114
+ onItemSelect={(item) => console.log(item)}
115
+ favoriteActive
116
+ onFavoriteClick={() => {}}
117
+ />
118
+ ```
119
+
120
+ | Prop | Type | Default |
121
+ |------|------|---------|
122
+ | `topRowItems` | `ItemSlot[]` | 5 placeholder slots (outfit, backbling, pickaxe, glider, contrail) |
123
+ | `emoteSlots` | `ItemSlot[]` | 6 placeholder slots (3 filled, 3 empty) |
124
+ | `miscSlots` | `ItemSlot[]` | 9 placeholder slots |
125
+ | `onItemSelect` | `(item: ItemSlot) => void` | — |
126
+ | `favoriteActive` | `boolean` | `false` |
127
+ | `onFavoriteClick` | `() => void` | — |
128
+
129
+ Supply an `image` URL on any `ItemSlot` to render it inside the slot:
130
+
131
+ ```ts
132
+ const myItems: ItemSlot[] = [
133
+ { id: '1', type: 'outfit', selected: true, image: 'https://example.com/skin.png', label: 'Dark Knight' },
134
+ { id: '2', type: 'backbling' },
135
+ ];
136
+ ```
137
+
138
+ ---
139
+
140
+ ### `CharacterDisplay`
141
+
142
+ The center panel showing the character preview image, name, rarity, and category label.
143
+
144
+ ```tsx
145
+ <CharacterDisplay
146
+ characterName="RAVEN"
147
+ rarityLabel="LEGENDARY"
148
+ categoryLabel="OUTFIT"
149
+ characterImage="https://example.com/raven.png"
150
+ />
151
+ ```
152
+
153
+ | Prop | Type | Default |
154
+ |------|------|---------|
155
+ | `characterImage` | `string` | Unsplash placeholder |
156
+ | `characterName` | `string` | `'SELENA'` |
157
+ | `rarityLabel` | `string` | `'EPIC'` |
158
+ | `categoryLabel` | `string` | `'OUTFIT'` |
159
+
160
+ ---
161
+
162
+ ### `LockerRightPanel`
163
+
164
+ The right panel with preset action buttons (Load, Save, Random).
165
+
166
+ ```tsx
167
+ <LockerRightPanel
168
+ onLoad={() => loadPreset()}
169
+ onSave={() => savePreset()}
170
+ onRandom={() => randomize()}
171
+ />
172
+ ```
173
+
174
+ | Prop | Type | Default |
175
+ |------|------|---------|
176
+ | `title` | `string` | `'PRESETS'` |
177
+ | `loadLabel` | `string` | `'LOAD'` |
178
+ | `saveLabel` | `string` | `'SAVE'` |
179
+ | `randomLabel` | `string` | `'RANDOM'` |
180
+ | `onLoad` | `() => void` | — |
181
+ | `onSave` | `() => void` | — |
182
+ | `onRandom` | `() => void` | — |
183
+
184
+ ---
185
+
186
+ ## Theming
187
+
188
+ All colors are driven by CSS custom properties. Import the stylesheet and override any variable on a parent element — no CSS recompile needed.
189
+
190
+ ### CSS variables
191
+
192
+ | Variable | Default | Used for |
193
+ |----------|---------|----------|
194
+ | `--locker-bg-light` | `#4a9fdb` | Background gradient top, slot borders |
195
+ | `--locker-bg-mid` | `#2b7fd4` | Background gradient middle, slot fill |
196
+ | `--locker-bg-dark` | `#1e5fb8` | Header, slot fill, button backgrounds |
197
+ | `--locker-bg-darker` | `#0d4494` | Currency counter background |
198
+ | `--locker-selection` | `#ff00ff` | Selected slot border and glow |
199
+ | `--locker-badge` | `#ffd700` | Notification badges |
200
+ | `--locker-glow` | `#5aaee8` | Character display radial glow |
201
+ | `--locker-font` | `'Luckiest Guy', ...` | Heading font stack |
202
+
203
+ ### Via `LockerThemeProvider` (recommended)
204
+
205
+ ```tsx
206
+ <LockerThemeProvider
207
+ theme={{
208
+ bgDark: '#6c3483',
209
+ bgMid: '#8e44ad',
210
+ bgLight: '#a569bd',
211
+ bgDarker: '#4a235a',
212
+ selectionColor: '#00ffff',
213
+ badgeColor: '#ff6b00',
214
+ }}
215
+ >
216
+ <YourApp />
217
+ </LockerThemeProvider>
218
+ ```
219
+
220
+ ### Via plain CSS (alternative)
221
+
222
+ ```css
223
+ .my-custom-locker {
224
+ --locker-bg-dark: #1a3a2a;
225
+ --locker-selection: #00ff88;
226
+ }
227
+ ```
228
+
229
+ ### `useLockerTheme()` hook
230
+
231
+ Read the current resolved theme values inside any child component:
232
+
233
+ ```tsx
234
+ import { useLockerTheme } from 'game-locker-ui';
235
+
236
+ function MyComponent() {
237
+ const theme = useLockerTheme();
238
+ return <div style={{ color: theme.selectionColor }}>Selected</div>;
239
+ }
240
+ ```
241
+
242
+ ---
243
+
244
+ ## TypeScript Types
245
+
246
+ ```ts
247
+ import type { ItemSlot, ItemSlotType, LockerTab, LockerTheme } from 'game-locker-ui';
248
+
249
+ type ItemSlotType =
250
+ | 'outfit' | 'backbling' | 'pickaxe' | 'glider' | 'contrail'
251
+ | 'emote' | 'spray' | 'emoticon' | 'banner' | 'music';
252
+
253
+ interface ItemSlot {
254
+ id: string;
255
+ type: ItemSlotType;
256
+ selected?: boolean;
257
+ image?: string;
258
+ isEmpty?: boolean;
259
+ label?: string;
260
+ }
261
+
262
+ interface LockerTab {
263
+ id: string;
264
+ label: string;
265
+ hasNotification?: boolean;
266
+ }
267
+
268
+ interface LockerTheme {
269
+ bgLight?: string;
270
+ bgMid?: string;
271
+ bgDark?: string;
272
+ bgDarker?: string;
273
+ selectionColor?: string;
274
+ badgeColor?: string;
275
+ fontFamily?: string;
276
+ }
277
+ ```
278
+
279
+ ---
280
+
281
+ ## Development
282
+
283
+ ```bash
284
+ npm install # install dependencies
285
+ npm run dev # start demo app at localhost:5173
286
+ npm run build # build demo app → dist-demo/
287
+ npm run build:lib # build npm package → dist/
288
+ ```
289
+
290
+ The demo app (`src/app/App.tsx`) shows a working instance of the full locker layout and serves as a live development environment.
291
+
292
+ ---
293
+
294
+ ## License
295
+
296
+ MIT