pixelforge-ui 1.0.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 +233 -0
- package/dist/index.css +1431 -0
- package/dist/index.d.mts +666 -0
- package/dist/index.d.ts +666 -0
- package/dist/index.js +1124 -0
- package/dist/index.mjs +1069 -0
- package/package.json +51 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
Badge: () => Badge,
|
|
34
|
+
Button: () => Button,
|
|
35
|
+
Card: () => Card,
|
|
36
|
+
Dropdown: () => Dropdown,
|
|
37
|
+
Footer: () => Footer,
|
|
38
|
+
Input: () => Input,
|
|
39
|
+
Modal: () => Modal,
|
|
40
|
+
Navbar: () => Navbar,
|
|
41
|
+
Sidebar: () => Sidebar,
|
|
42
|
+
Tooltip: () => Tooltip,
|
|
43
|
+
borderRadius: () => borderRadius,
|
|
44
|
+
breakpoints: () => breakpoints,
|
|
45
|
+
colors: () => colors,
|
|
46
|
+
gamePalettes: () => gamePalettes,
|
|
47
|
+
shadows: () => shadows,
|
|
48
|
+
spacing: () => spacing,
|
|
49
|
+
transitions: () => transitions,
|
|
50
|
+
typography: () => typography,
|
|
51
|
+
zIndex: () => zIndex
|
|
52
|
+
});
|
|
53
|
+
module.exports = __toCommonJS(index_exports);
|
|
54
|
+
|
|
55
|
+
// src/tokens/index.ts
|
|
56
|
+
var colors = {
|
|
57
|
+
primary: {
|
|
58
|
+
lime: "#C4F0C8",
|
|
59
|
+
lavender: "#D4B5E8",
|
|
60
|
+
sky: "#B8E0F0",
|
|
61
|
+
peach: "#F0D9C8",
|
|
62
|
+
mint: "#C8F0E0"
|
|
63
|
+
},
|
|
64
|
+
dark: {
|
|
65
|
+
lime: "#6B9D77",
|
|
66
|
+
lavender: "#8B6BA8",
|
|
67
|
+
sky: "#6BA3C8",
|
|
68
|
+
peach: "#C89968",
|
|
69
|
+
mint: "#6BA89F"
|
|
70
|
+
},
|
|
71
|
+
neutral: {
|
|
72
|
+
black: "#1A1A24",
|
|
73
|
+
dark: "#2D2D3D",
|
|
74
|
+
gray: "#666670",
|
|
75
|
+
light: "#F5F5F0",
|
|
76
|
+
white: "#FFFBF5"
|
|
77
|
+
},
|
|
78
|
+
semantic: {
|
|
79
|
+
success: "#7FD8B8",
|
|
80
|
+
warning: "#FFB347",
|
|
81
|
+
error: "#FF6B6B",
|
|
82
|
+
info: "#B8E0F0"
|
|
83
|
+
},
|
|
84
|
+
accent: "#FF6B9D"
|
|
85
|
+
};
|
|
86
|
+
var typography = {
|
|
87
|
+
font: {
|
|
88
|
+
pixel: '"Press Start 2P", monospace',
|
|
89
|
+
sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
90
|
+
mono: '"Courier New", monospace'
|
|
91
|
+
},
|
|
92
|
+
size: {
|
|
93
|
+
xs: "12px",
|
|
94
|
+
sm: "14px",
|
|
95
|
+
base: "16px",
|
|
96
|
+
lg: "20px",
|
|
97
|
+
xl: "24px",
|
|
98
|
+
"2xl": "32px"
|
|
99
|
+
},
|
|
100
|
+
weight: {
|
|
101
|
+
normal: 400,
|
|
102
|
+
bold: 700
|
|
103
|
+
},
|
|
104
|
+
lineHeight: {
|
|
105
|
+
tight: 1.2,
|
|
106
|
+
normal: 1.5,
|
|
107
|
+
relaxed: 1.75
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var spacing = {
|
|
111
|
+
0: "0",
|
|
112
|
+
1: "4px",
|
|
113
|
+
2: "8px",
|
|
114
|
+
3: "12px",
|
|
115
|
+
4: "16px",
|
|
116
|
+
5: "20px",
|
|
117
|
+
6: "24px",
|
|
118
|
+
8: "32px",
|
|
119
|
+
10: "40px",
|
|
120
|
+
12: "48px",
|
|
121
|
+
16: "64px",
|
|
122
|
+
20: "80px"
|
|
123
|
+
};
|
|
124
|
+
var shadows = {
|
|
125
|
+
sm: "4px 4px 0px rgba(0, 0, 0, 0.2)",
|
|
126
|
+
md: "8px 8px 0px rgba(0, 0, 0, 0.15)",
|
|
127
|
+
lg: "12px 12px 0px rgba(0, 0, 0, 0.1)",
|
|
128
|
+
glow: {
|
|
129
|
+
lime: "0 0 20px rgba(196, 240, 200, 0.4)",
|
|
130
|
+
lavender: "0 0 20px rgba(212, 181, 232, 0.4)",
|
|
131
|
+
sky: "0 0 20px rgba(184, 224, 240, 0.4)",
|
|
132
|
+
peach: "0 0 20px rgba(240, 217, 200, 0.4)"
|
|
133
|
+
},
|
|
134
|
+
press: "2px 2px 0px rgba(0, 0, 0, 0.3), inset 0 2px 0px rgba(0, 0, 0, 0.1)"
|
|
135
|
+
};
|
|
136
|
+
var borderRadius = {
|
|
137
|
+
sm: "4px",
|
|
138
|
+
base: "8px",
|
|
139
|
+
lg: "12px",
|
|
140
|
+
full: "9999px"
|
|
141
|
+
};
|
|
142
|
+
var breakpoints = {
|
|
143
|
+
xs: "320px",
|
|
144
|
+
sm: "640px",
|
|
145
|
+
md: "768px",
|
|
146
|
+
lg: "1024px",
|
|
147
|
+
xl: "1280px",
|
|
148
|
+
"2xl": "1536px"
|
|
149
|
+
};
|
|
150
|
+
var zIndex = {
|
|
151
|
+
hidden: -1,
|
|
152
|
+
base: 0,
|
|
153
|
+
dropdown: 1e3,
|
|
154
|
+
sticky: 1100,
|
|
155
|
+
fixed: 1200,
|
|
156
|
+
modal: 1300,
|
|
157
|
+
popover: 1400,
|
|
158
|
+
tooltip: 1500
|
|
159
|
+
};
|
|
160
|
+
var transitions = {
|
|
161
|
+
fast: "150ms ease-in-out",
|
|
162
|
+
base: "200ms ease-in-out",
|
|
163
|
+
slow: "300ms ease-in-out"
|
|
164
|
+
};
|
|
165
|
+
var gamePalettes = {
|
|
166
|
+
nes: {
|
|
167
|
+
name: "NES Classic",
|
|
168
|
+
colors: ["#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"]
|
|
169
|
+
},
|
|
170
|
+
gameboy: {
|
|
171
|
+
name: "Game Boy",
|
|
172
|
+
colors: ["#9BBC0F", "#8BAC0F", "#306230", "#0F380F"]
|
|
173
|
+
},
|
|
174
|
+
atari: {
|
|
175
|
+
name: "Atari 2600",
|
|
176
|
+
colors: ["#000000", "#FFFFFF", "#FF0000", "#FFFF00"]
|
|
177
|
+
},
|
|
178
|
+
snes: {
|
|
179
|
+
name: "SNES",
|
|
180
|
+
colors: ["#8B008B", "#FF1493", "#1E90FF", "#FFD700"]
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// src/components/Button.tsx
|
|
185
|
+
var import_react = __toESM(require("react"));
|
|
186
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
187
|
+
var Button = import_react.default.forwardRef(
|
|
188
|
+
({
|
|
189
|
+
variant = "primary",
|
|
190
|
+
size = "md",
|
|
191
|
+
disabled = false,
|
|
192
|
+
isLoading = false,
|
|
193
|
+
loadingText,
|
|
194
|
+
children,
|
|
195
|
+
className = "",
|
|
196
|
+
...props
|
|
197
|
+
}, ref) => {
|
|
198
|
+
const baseStyles = `
|
|
199
|
+
inline-flex items-center justify-center
|
|
200
|
+
font-pixel text-sm
|
|
201
|
+
transition-all duration-200
|
|
202
|
+
cursor-pointer
|
|
203
|
+
active:scale-95
|
|
204
|
+
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-pixelforge-accent
|
|
205
|
+
disabled:opacity-50 disabled:cursor-not-allowed
|
|
206
|
+
`;
|
|
207
|
+
const sizeStyles = {
|
|
208
|
+
sm: "px-3 py-2 text-xs gap-2",
|
|
209
|
+
md: "px-4 py-3 text-sm gap-2",
|
|
210
|
+
lg: "px-6 py-4 text-base gap-3"
|
|
211
|
+
};
|
|
212
|
+
const variantStyles = {
|
|
213
|
+
primary: `
|
|
214
|
+
bg-pixelforge-lime text-pixelforge-black
|
|
215
|
+
border-2 border-pixelforge-darkLime
|
|
216
|
+
shadow-px
|
|
217
|
+
hover:shadow-px-lg hover:translate-y-[-2px]
|
|
218
|
+
active:shadow-px-press active:translate-y-[2px]
|
|
219
|
+
dark:bg-pixelforge-darkLime dark:text-pixelforge-white dark:border-pixelforge-lime
|
|
220
|
+
`,
|
|
221
|
+
secondary: `
|
|
222
|
+
bg-pixelforge-lavender text-pixelforge-black
|
|
223
|
+
border-2 border-pixelforge-darkLavender
|
|
224
|
+
shadow-px
|
|
225
|
+
hover:shadow-px-lg hover:translate-y-[-2px]
|
|
226
|
+
active:shadow-px-press active:translate-y-[2px]
|
|
227
|
+
dark:bg-pixelforge-darkLavender dark:text-pixelforge-white dark:border-pixelforge-lavender
|
|
228
|
+
`,
|
|
229
|
+
outline: `
|
|
230
|
+
bg-transparent border-2
|
|
231
|
+
text-pixelforge-black border-pixelforge-darkLime
|
|
232
|
+
hover:bg-pixelforge-lime/10 active:bg-pixelforge-lime/20
|
|
233
|
+
dark:text-pixelforge-white dark:border-pixelforge-lime
|
|
234
|
+
dark:hover:bg-pixelforge-lime/30 dark:active:bg-pixelforge-lime/40
|
|
235
|
+
`,
|
|
236
|
+
ghost: `
|
|
237
|
+
bg-transparent text-pixelforge-black border-2 border-transparent
|
|
238
|
+
hover:bg-pixelforge-lime/20 active:bg-pixelforge-lime/30
|
|
239
|
+
dark:text-pixelforge-white dark:hover:bg-pixelforge-lime/30
|
|
240
|
+
dark:active:bg-pixelforge-lime/40
|
|
241
|
+
`
|
|
242
|
+
};
|
|
243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
244
|
+
"button",
|
|
245
|
+
{
|
|
246
|
+
ref,
|
|
247
|
+
disabled: disabled || isLoading,
|
|
248
|
+
className: `${baseStyles} ${sizeStyles[size]} ${variantStyles[variant]} ${className}`,
|
|
249
|
+
...props,
|
|
250
|
+
children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
251
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "animate-spin", children: "\u27F3" }),
|
|
252
|
+
loadingText || children
|
|
253
|
+
] }) : children
|
|
254
|
+
}
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
);
|
|
258
|
+
Button.displayName = "Button";
|
|
259
|
+
|
|
260
|
+
// src/components/Input.tsx
|
|
261
|
+
var import_react2 = __toESM(require("react"));
|
|
262
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
263
|
+
var Input = import_react2.default.forwardRef(
|
|
264
|
+
({
|
|
265
|
+
label,
|
|
266
|
+
error,
|
|
267
|
+
helperText,
|
|
268
|
+
required,
|
|
269
|
+
leftIcon,
|
|
270
|
+
rightIcon,
|
|
271
|
+
className = "",
|
|
272
|
+
disabled,
|
|
273
|
+
...props
|
|
274
|
+
}, ref) => {
|
|
275
|
+
const hasError = !!error;
|
|
276
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full", children: [
|
|
277
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
278
|
+
"label",
|
|
279
|
+
{
|
|
280
|
+
htmlFor: props.id,
|
|
281
|
+
className: `
|
|
282
|
+
block font-pixel text-xs mb-2
|
|
283
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
284
|
+
${required ? "after:content-['*'] after:text-pixelforge-error after:ml-1" : ""}
|
|
285
|
+
`,
|
|
286
|
+
children: label
|
|
287
|
+
}
|
|
288
|
+
),
|
|
289
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "relative", children: [
|
|
290
|
+
leftIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-pixelforge-black dark:text-pixelforge-white", children: leftIcon }),
|
|
291
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
292
|
+
"input",
|
|
293
|
+
{
|
|
294
|
+
ref,
|
|
295
|
+
disabled,
|
|
296
|
+
className: `
|
|
297
|
+
w-full
|
|
298
|
+
px-4 py-3
|
|
299
|
+
font-mono text-sm
|
|
300
|
+
bg-pixelforge-white dark:bg-pixelforge-dark
|
|
301
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
302
|
+
border-2 border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
303
|
+
rounded-px-sm
|
|
304
|
+
shadow-px
|
|
305
|
+
transition-all duration-200
|
|
306
|
+
placeholder:text-pixelforge-gray/50
|
|
307
|
+
focus:outline-none focus:shadow-px-lg focus:translate-y-[-2px]
|
|
308
|
+
focus:border-pixelforge-accent
|
|
309
|
+
disabled:opacity-50 disabled:cursor-not-allowed
|
|
310
|
+
${hasError ? "border-pixelforge-error focus:border-pixelforge-error shadow-px focus:shadow-px-glow" : ""}
|
|
311
|
+
${leftIcon ? "pl-10" : ""}
|
|
312
|
+
${rightIcon ? "pr-10" : ""}
|
|
313
|
+
${className}
|
|
314
|
+
`,
|
|
315
|
+
...props
|
|
316
|
+
}
|
|
317
|
+
),
|
|
318
|
+
rightIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-pixelforge-black dark:text-pixelforge-white", children: rightIcon })
|
|
319
|
+
] }),
|
|
320
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "mt-2 font-mono text-xs text-pixelforge-error", children: [
|
|
321
|
+
"\u26A0 ",
|
|
322
|
+
error
|
|
323
|
+
] }),
|
|
324
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mt-2 font-mono text-xs text-pixelforge-gray", children: helperText })
|
|
325
|
+
] });
|
|
326
|
+
}
|
|
327
|
+
);
|
|
328
|
+
Input.displayName = "Input";
|
|
329
|
+
|
|
330
|
+
// src/components/Card.tsx
|
|
331
|
+
var import_react3 = __toESM(require("react"));
|
|
332
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
333
|
+
var Card = import_react3.default.forwardRef(
|
|
334
|
+
({
|
|
335
|
+
title,
|
|
336
|
+
subtitle,
|
|
337
|
+
interactive = false,
|
|
338
|
+
variant = "default",
|
|
339
|
+
header,
|
|
340
|
+
footer,
|
|
341
|
+
children,
|
|
342
|
+
className = "",
|
|
343
|
+
...props
|
|
344
|
+
}, ref) => {
|
|
345
|
+
const variantStyles = {
|
|
346
|
+
default: `
|
|
347
|
+
bg-pixelforge-white dark:bg-pixelforge-dark
|
|
348
|
+
border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
349
|
+
`,
|
|
350
|
+
lime: `
|
|
351
|
+
bg-pixelforge-lime/20 dark:bg-pixelforge-darkLime/20
|
|
352
|
+
border-pixelforge-lime dark:border-pixelforge-lime
|
|
353
|
+
`,
|
|
354
|
+
lavender: `
|
|
355
|
+
bg-pixelforge-lavender/20 dark:bg-pixelforge-darkLavender/20
|
|
356
|
+
border-pixelforge-lavender dark:border-pixelforge-lavender
|
|
357
|
+
`,
|
|
358
|
+
sky: `
|
|
359
|
+
bg-pixelforge-sky/20 dark:bg-pixelforge-darkSky/20
|
|
360
|
+
border-pixelforge-sky dark:border-pixelforge-sky
|
|
361
|
+
`,
|
|
362
|
+
peach: `
|
|
363
|
+
bg-pixelforge-peach/20 dark:bg-pixelforge-darkPeach/20
|
|
364
|
+
border-pixelforge-peach dark:border-pixelforge-peach
|
|
365
|
+
`,
|
|
366
|
+
mint: `
|
|
367
|
+
bg-pixelforge-mint/20 dark:bg-pixelforge-darkMint/20
|
|
368
|
+
border-pixelforge-mint dark:border-pixelforge-mint
|
|
369
|
+
`
|
|
370
|
+
};
|
|
371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
372
|
+
"div",
|
|
373
|
+
{
|
|
374
|
+
ref,
|
|
375
|
+
className: `
|
|
376
|
+
border-2 border-solid
|
|
377
|
+
rounded-px
|
|
378
|
+
shadow-px
|
|
379
|
+
transition-all duration-200
|
|
380
|
+
${interactive ? "cursor-pointer hover:shadow-px-lg hover:translate-y-[-2px] active:shadow-px-press active:translate-y-[2px]" : ""}
|
|
381
|
+
${variantStyles[variant]}
|
|
382
|
+
${className}
|
|
383
|
+
`,
|
|
384
|
+
...props,
|
|
385
|
+
children: [
|
|
386
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-b-2 border-pixelforge-darkLime dark:border-pixelforge-lime/30 px-6 py-4", children: header }),
|
|
387
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "p-6", children: [
|
|
388
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "font-pixel text-lg text-pixelforge-black dark:text-pixelforge-white mb-1", children: title }),
|
|
389
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "font-mono text-xs text-pixelforge-gray mb-4", children: subtitle }),
|
|
390
|
+
children
|
|
391
|
+
] }),
|
|
392
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-t-2 border-pixelforge-darkLime dark:border-pixelforge-lime/30 px-6 py-4 bg-pixelforge-light/50 dark:bg-pixelforge-black/20", children: footer })
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
Card.displayName = "Card";
|
|
399
|
+
|
|
400
|
+
// src/components/Badge.tsx
|
|
401
|
+
var import_react4 = __toESM(require("react"));
|
|
402
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
403
|
+
var Badge = import_react4.default.forwardRef(
|
|
404
|
+
({
|
|
405
|
+
variant = "default",
|
|
406
|
+
size = "md",
|
|
407
|
+
dismissible = false,
|
|
408
|
+
onDismiss,
|
|
409
|
+
children,
|
|
410
|
+
className = "",
|
|
411
|
+
...props
|
|
412
|
+
}, ref) => {
|
|
413
|
+
const sizeStyles = {
|
|
414
|
+
sm: "px-2 py-1 text-xs",
|
|
415
|
+
md: "px-3 py-1.5 text-sm",
|
|
416
|
+
lg: "px-4 py-2 text-base"
|
|
417
|
+
};
|
|
418
|
+
const variantStyles = {
|
|
419
|
+
default: `
|
|
420
|
+
bg-pixelforge-light dark:bg-pixelforge-dark
|
|
421
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
422
|
+
border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
423
|
+
`,
|
|
424
|
+
lime: `
|
|
425
|
+
bg-pixelforge-lime text-pixelforge-black
|
|
426
|
+
border-pixelforge-darkLime dark:bg-pixelforge-darkLime dark:text-pixelforge-white dark:border-pixelforge-lime
|
|
427
|
+
`,
|
|
428
|
+
lavender: `
|
|
429
|
+
bg-pixelforge-lavender text-pixelforge-black
|
|
430
|
+
border-pixelforge-darkLavender dark:bg-pixelforge-darkLavender dark:text-pixelforge-white dark:border-pixelforge-lavender
|
|
431
|
+
`,
|
|
432
|
+
sky: `
|
|
433
|
+
bg-pixelforge-sky text-pixelforge-black
|
|
434
|
+
border-pixelforge-darkSky dark:bg-pixelforge-darkSky dark:text-pixelforge-white dark:border-pixelforge-sky
|
|
435
|
+
`,
|
|
436
|
+
peach: `
|
|
437
|
+
bg-pixelforge-peach text-pixelforge-black
|
|
438
|
+
border-pixelforge-darkPeach dark:bg-pixelforge-darkPeach dark:text-pixelforge-white dark:border-pixelforge-peach
|
|
439
|
+
`,
|
|
440
|
+
mint: `
|
|
441
|
+
bg-pixelforge-mint text-pixelforge-black
|
|
442
|
+
border-pixelforge-darkMint dark:bg-pixelforge-darkMint dark:text-pixelforge-white dark:border-pixelforge-mint
|
|
443
|
+
`,
|
|
444
|
+
success: `
|
|
445
|
+
bg-pixelforge-success/20 text-pixelforge-success
|
|
446
|
+
border-pixelforge-success dark:bg-pixelforge-success/10 dark:text-pixelforge-success/80
|
|
447
|
+
`,
|
|
448
|
+
warning: `
|
|
449
|
+
bg-pixelforge-warning/20 text-pixelforge-warning
|
|
450
|
+
border-pixelforge-warning dark:bg-pixelforge-warning/10 dark:text-pixelforge-warning/80
|
|
451
|
+
`,
|
|
452
|
+
error: `
|
|
453
|
+
bg-pixelforge-error/20 text-pixelforge-error
|
|
454
|
+
border-pixelforge-error dark:bg-pixelforge-error/10 dark:text-pixelforge-error/80
|
|
455
|
+
`,
|
|
456
|
+
info: `
|
|
457
|
+
bg-pixelforge-sky/20 text-pixelforge-sky
|
|
458
|
+
border-pixelforge-sky dark:bg-pixelforge-sky/10 dark:text-pixelforge-sky/80
|
|
459
|
+
`
|
|
460
|
+
};
|
|
461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
462
|
+
"span",
|
|
463
|
+
{
|
|
464
|
+
ref,
|
|
465
|
+
className: `
|
|
466
|
+
inline-flex items-center gap-2
|
|
467
|
+
font-pixel text-xs
|
|
468
|
+
border-2
|
|
469
|
+
rounded-px-sm
|
|
470
|
+
whitespace-nowrap
|
|
471
|
+
transition-all duration-200
|
|
472
|
+
${sizeStyles[size]}
|
|
473
|
+
${variantStyles[variant]}
|
|
474
|
+
${className}
|
|
475
|
+
`,
|
|
476
|
+
...props,
|
|
477
|
+
children: [
|
|
478
|
+
children,
|
|
479
|
+
dismissible && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
480
|
+
"button",
|
|
481
|
+
{
|
|
482
|
+
onClick: (e) => {
|
|
483
|
+
e.stopPropagation();
|
|
484
|
+
onDismiss?.();
|
|
485
|
+
},
|
|
486
|
+
className: "ml-1 font-bold hover:opacity-70 transition-opacity",
|
|
487
|
+
"aria-label": "Dismiss",
|
|
488
|
+
children: "\u2715"
|
|
489
|
+
}
|
|
490
|
+
)
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
Badge.displayName = "Badge";
|
|
497
|
+
|
|
498
|
+
// src/components/Modal.tsx
|
|
499
|
+
var import_react5 = require("react");
|
|
500
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
501
|
+
var Modal = ({
|
|
502
|
+
isOpen,
|
|
503
|
+
onClose,
|
|
504
|
+
title,
|
|
505
|
+
closeOnBackdropClick = true,
|
|
506
|
+
showCloseButton = true,
|
|
507
|
+
footer,
|
|
508
|
+
size = "md",
|
|
509
|
+
children
|
|
510
|
+
}) => {
|
|
511
|
+
(0, import_react5.useEffect)(() => {
|
|
512
|
+
if (!isOpen) return;
|
|
513
|
+
const handleKeyDown = (e) => {
|
|
514
|
+
if (e.key === "Escape") {
|
|
515
|
+
onClose();
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
519
|
+
document.body.style.overflow = "hidden";
|
|
520
|
+
return () => {
|
|
521
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
522
|
+
document.body.style.overflow = "unset";
|
|
523
|
+
};
|
|
524
|
+
}, [isOpen, onClose]);
|
|
525
|
+
if (!isOpen) return null;
|
|
526
|
+
const sizeStyles = {
|
|
527
|
+
sm: "max-w-sm",
|
|
528
|
+
md: "max-w-md",
|
|
529
|
+
lg: "max-w-lg"
|
|
530
|
+
};
|
|
531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
532
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
533
|
+
"div",
|
|
534
|
+
{
|
|
535
|
+
className: `
|
|
536
|
+
fixed inset-0 z-modal
|
|
537
|
+
bg-black/40 backdrop-blur-xs
|
|
538
|
+
transition-opacity duration-200
|
|
539
|
+
${isOpen ? "opacity-100" : "opacity-0 pointer-events-none"}
|
|
540
|
+
`,
|
|
541
|
+
onClick: () => closeOnBackdropClick && onClose(),
|
|
542
|
+
"aria-hidden": "true"
|
|
543
|
+
}
|
|
544
|
+
),
|
|
545
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
546
|
+
"div",
|
|
547
|
+
{
|
|
548
|
+
className: `
|
|
549
|
+
fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2
|
|
550
|
+
z-modal w-11/12 ${sizeStyles[size]}
|
|
551
|
+
bg-pixelforge-white dark:bg-pixelforge-dark
|
|
552
|
+
border-2 border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
553
|
+
rounded-px
|
|
554
|
+
shadow-lg
|
|
555
|
+
transition-all duration-200
|
|
556
|
+
${isOpen ? "scale-100 opacity-100" : "scale-95 opacity-0 pointer-events-none"}
|
|
557
|
+
`,
|
|
558
|
+
role: "dialog",
|
|
559
|
+
"aria-modal": "true",
|
|
560
|
+
onClick: (e) => e.stopPropagation(),
|
|
561
|
+
children: [
|
|
562
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between border-b-2 border-pixelforge-darkLime dark:border-pixelforge-lime/30 px-6 py-4", children: [
|
|
563
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: "font-pixel text-lg text-pixelforge-black dark:text-pixelforge-white", children: title }),
|
|
564
|
+
showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
565
|
+
"button",
|
|
566
|
+
{
|
|
567
|
+
onClick: onClose,
|
|
568
|
+
className: `
|
|
569
|
+
text-2xl font-bold
|
|
570
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
571
|
+
hover:opacity-70
|
|
572
|
+
transition-opacity
|
|
573
|
+
p-1 -mr-2
|
|
574
|
+
`,
|
|
575
|
+
"aria-label": "Close modal",
|
|
576
|
+
children: "\u2715"
|
|
577
|
+
}
|
|
578
|
+
)
|
|
579
|
+
] }),
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "px-6 py-6 max-h-[60vh] overflow-y-auto", children }),
|
|
581
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "border-t-2 border-pixelforge-darkLime dark:border-pixelforge-lime/30 px-6 py-4 bg-pixelforge-light/50 dark:bg-pixelforge-black/20", children: footer })
|
|
582
|
+
]
|
|
583
|
+
}
|
|
584
|
+
)
|
|
585
|
+
] });
|
|
586
|
+
};
|
|
587
|
+
Modal.displayName = "Modal";
|
|
588
|
+
|
|
589
|
+
// src/components/Dropdown.tsx
|
|
590
|
+
var import_react6 = require("react");
|
|
591
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
592
|
+
var Dropdown = ({
|
|
593
|
+
trigger,
|
|
594
|
+
items,
|
|
595
|
+
isOpen: controlledIsOpen,
|
|
596
|
+
onOpenChange,
|
|
597
|
+
placement = "bottom"
|
|
598
|
+
}) => {
|
|
599
|
+
const [internalIsOpen, setInternalIsOpen] = (0, import_react6.useState)(false);
|
|
600
|
+
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
601
|
+
const triggerRef = (0, import_react6.useRef)(null);
|
|
602
|
+
const dropdownRef = (0, import_react6.useRef)(null);
|
|
603
|
+
(0, import_react6.useEffect)(() => {
|
|
604
|
+
if (!isOpen) return;
|
|
605
|
+
const handleClickOutside = (e) => {
|
|
606
|
+
if (triggerRef.current?.contains(e.target) || dropdownRef.current?.contains(e.target)) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
handleClose();
|
|
610
|
+
};
|
|
611
|
+
window.addEventListener("mousedown", handleClickOutside);
|
|
612
|
+
return () => window.removeEventListener("mousedown", handleClickOutside);
|
|
613
|
+
}, [isOpen]);
|
|
614
|
+
(0, import_react6.useEffect)(() => {
|
|
615
|
+
if (!isOpen) return;
|
|
616
|
+
const handleKeyDown = (e) => {
|
|
617
|
+
if (e.key === "Escape") {
|
|
618
|
+
handleClose();
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
622
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
623
|
+
}, [isOpen]);
|
|
624
|
+
const handleOpen = () => {
|
|
625
|
+
const newState = !isOpen;
|
|
626
|
+
if (controlledIsOpen === void 0) {
|
|
627
|
+
setInternalIsOpen(newState);
|
|
628
|
+
}
|
|
629
|
+
onOpenChange?.(newState);
|
|
630
|
+
};
|
|
631
|
+
const handleClose = () => {
|
|
632
|
+
if (controlledIsOpen === void 0) {
|
|
633
|
+
setInternalIsOpen(false);
|
|
634
|
+
}
|
|
635
|
+
onOpenChange?.(false);
|
|
636
|
+
};
|
|
637
|
+
const handleItemClick = (item) => {
|
|
638
|
+
if (item.disabled) return;
|
|
639
|
+
item.onClick?.();
|
|
640
|
+
handleClose();
|
|
641
|
+
};
|
|
642
|
+
const placementStyles = {
|
|
643
|
+
bottom: "top-full mt-2",
|
|
644
|
+
top: "bottom-full mb-2",
|
|
645
|
+
left: "right-full mr-2",
|
|
646
|
+
right: "left-full ml-2"
|
|
647
|
+
};
|
|
648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "relative inline-block", children: [
|
|
649
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
650
|
+
"div",
|
|
651
|
+
{
|
|
652
|
+
ref: triggerRef,
|
|
653
|
+
onClick: handleOpen,
|
|
654
|
+
className: "cursor-pointer",
|
|
655
|
+
children: trigger
|
|
656
|
+
}
|
|
657
|
+
),
|
|
658
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
659
|
+
"div",
|
|
660
|
+
{
|
|
661
|
+
ref: dropdownRef,
|
|
662
|
+
className: `
|
|
663
|
+
absolute ${placementStyles[placement]}
|
|
664
|
+
min-w-max
|
|
665
|
+
bg-pixelforge-white dark:bg-pixelforge-dark
|
|
666
|
+
border-2 border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
667
|
+
rounded-px-sm
|
|
668
|
+
shadow-px-lg
|
|
669
|
+
z-dropdown
|
|
670
|
+
py-1
|
|
671
|
+
animation-in fade-in zoom-in-95 duration-200
|
|
672
|
+
`,
|
|
673
|
+
role: "menu",
|
|
674
|
+
children: items.map((item, index) => {
|
|
675
|
+
if (item.divider) {
|
|
676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
677
|
+
"div",
|
|
678
|
+
{
|
|
679
|
+
className: "h-px bg-pixelforge-darkLime/20 dark:bg-pixelforge-lime/20 my-1",
|
|
680
|
+
role: "separator"
|
|
681
|
+
},
|
|
682
|
+
item.id || `divider-${index}`
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
686
|
+
"button",
|
|
687
|
+
{
|
|
688
|
+
onClick: () => handleItemClick(item),
|
|
689
|
+
disabled: item.disabled,
|
|
690
|
+
className: `
|
|
691
|
+
w-full text-left
|
|
692
|
+
px-4 py-2.5
|
|
693
|
+
font-mono text-sm
|
|
694
|
+
transition-colors duration-150
|
|
695
|
+
flex items-center gap-2
|
|
696
|
+
${item.disabled ? "opacity-50 cursor-not-allowed text-pixelforge-gray dark:text-pixelforge-gray/50" : `
|
|
697
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
698
|
+
hover:bg-pixelforge-lime/20 dark:hover:bg-pixelforge-lime/40
|
|
699
|
+
active:bg-pixelforge-lime/30 dark:active:bg-pixelforge-lime/50
|
|
700
|
+
`}
|
|
701
|
+
`,
|
|
702
|
+
role: "menuitem",
|
|
703
|
+
children: item.label
|
|
704
|
+
},
|
|
705
|
+
item.id
|
|
706
|
+
);
|
|
707
|
+
})
|
|
708
|
+
}
|
|
709
|
+
)
|
|
710
|
+
] });
|
|
711
|
+
};
|
|
712
|
+
Dropdown.displayName = "Dropdown";
|
|
713
|
+
|
|
714
|
+
// src/components/Tooltip.tsx
|
|
715
|
+
var import_react7 = require("react");
|
|
716
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
717
|
+
var Tooltip = ({
|
|
718
|
+
content,
|
|
719
|
+
children,
|
|
720
|
+
placement = "top",
|
|
721
|
+
delay = 200,
|
|
722
|
+
disabled = false,
|
|
723
|
+
variant = "default"
|
|
724
|
+
}) => {
|
|
725
|
+
const [isVisible, setIsVisible] = (0, import_react7.useState)(false);
|
|
726
|
+
const [position, setPosition] = (0, import_react7.useState)({ top: 0, left: 0 });
|
|
727
|
+
const triggerRef = (0, import_react7.useRef)(null);
|
|
728
|
+
const tooltipRef = (0, import_react7.useRef)(null);
|
|
729
|
+
const timeoutRef = (0, import_react7.useRef)();
|
|
730
|
+
const handleMouseEnter = () => {
|
|
731
|
+
if (disabled) return;
|
|
732
|
+
timeoutRef.current = setTimeout(() => {
|
|
733
|
+
setIsVisible(true);
|
|
734
|
+
updatePosition();
|
|
735
|
+
}, delay);
|
|
736
|
+
};
|
|
737
|
+
const handleMouseLeave = () => {
|
|
738
|
+
if (timeoutRef.current) {
|
|
739
|
+
clearTimeout(timeoutRef.current);
|
|
740
|
+
}
|
|
741
|
+
setIsVisible(false);
|
|
742
|
+
};
|
|
743
|
+
const updatePosition = () => {
|
|
744
|
+
if (!triggerRef.current || !tooltipRef.current) return;
|
|
745
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
746
|
+
const tooltipRect = tooltipRef.current.getBoundingClientRect();
|
|
747
|
+
const offset = 8;
|
|
748
|
+
let top = 0;
|
|
749
|
+
let left = 0;
|
|
750
|
+
switch (placement) {
|
|
751
|
+
case "top":
|
|
752
|
+
top = triggerRect.top - tooltipRect.height - offset;
|
|
753
|
+
left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
|
|
754
|
+
break;
|
|
755
|
+
case "bottom":
|
|
756
|
+
top = triggerRect.bottom + offset;
|
|
757
|
+
left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
|
|
758
|
+
break;
|
|
759
|
+
case "left":
|
|
760
|
+
top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
|
|
761
|
+
left = triggerRect.left - tooltipRect.width - offset;
|
|
762
|
+
break;
|
|
763
|
+
case "right":
|
|
764
|
+
top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
|
|
765
|
+
left = triggerRect.right + offset;
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
setPosition({ top, left });
|
|
769
|
+
};
|
|
770
|
+
(0, import_react7.useEffect)(() => {
|
|
771
|
+
if (isVisible) {
|
|
772
|
+
updatePosition();
|
|
773
|
+
const handleResize = () => updatePosition();
|
|
774
|
+
window.addEventListener("resize", handleResize);
|
|
775
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
776
|
+
}
|
|
777
|
+
}, [isVisible, placement]);
|
|
778
|
+
(0, import_react7.useEffect)(() => {
|
|
779
|
+
return () => {
|
|
780
|
+
if (timeoutRef.current) {
|
|
781
|
+
clearTimeout(timeoutRef.current);
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
}, []);
|
|
785
|
+
const variantStyles = {
|
|
786
|
+
default: `
|
|
787
|
+
bg-pixelforge-black dark:bg-pixelforge-white
|
|
788
|
+
text-pixelforge-white dark:text-pixelforge-black
|
|
789
|
+
border-2 border-pixelforge-darkLime
|
|
790
|
+
`,
|
|
791
|
+
dark: `
|
|
792
|
+
bg-pixelforge-black/90 dark:bg-pixelforge-white/90
|
|
793
|
+
text-pixelforge-white dark:text-pixelforge-black
|
|
794
|
+
border-2 border-pixelforge-darkLime/50
|
|
795
|
+
backdrop-blur-xs
|
|
796
|
+
`
|
|
797
|
+
};
|
|
798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
799
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
800
|
+
"div",
|
|
801
|
+
{
|
|
802
|
+
ref: triggerRef,
|
|
803
|
+
onMouseEnter: handleMouseEnter,
|
|
804
|
+
onMouseLeave: handleMouseLeave,
|
|
805
|
+
className: "inline-block",
|
|
806
|
+
children
|
|
807
|
+
}
|
|
808
|
+
),
|
|
809
|
+
isVisible && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
810
|
+
"div",
|
|
811
|
+
{
|
|
812
|
+
ref: tooltipRef,
|
|
813
|
+
style: {
|
|
814
|
+
position: "fixed",
|
|
815
|
+
top: `${position.top}px`,
|
|
816
|
+
left: `${position.left}px`
|
|
817
|
+
},
|
|
818
|
+
className: `
|
|
819
|
+
z-tooltip
|
|
820
|
+
px-3 py-2
|
|
821
|
+
font-mono text-xs
|
|
822
|
+
rounded-px-sm
|
|
823
|
+
shadow-px-lg
|
|
824
|
+
whitespace-nowrap
|
|
825
|
+
pointer-events-none
|
|
826
|
+
transition-opacity duration-200
|
|
827
|
+
${variantStyles[variant]}
|
|
828
|
+
`,
|
|
829
|
+
role: "tooltip",
|
|
830
|
+
children: [
|
|
831
|
+
content,
|
|
832
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
833
|
+
"div",
|
|
834
|
+
{
|
|
835
|
+
className: `
|
|
836
|
+
absolute w-2 h-2 bg-pixelforge-black dark:bg-pixelforge-white
|
|
837
|
+
border-r-2 border-b-2 border-pixelforge-darkLime
|
|
838
|
+
${placement === "top" ? "bottom-0 left-1/2 -translate-x-1/2 translate-y-1/2 rotate-45" : placement === "bottom" ? "top-0 left-1/2 -translate-x-1/2 -translate-y-1/2 -rotate-45" : placement === "left" ? "right-0 top-1/2 -translate-y-1/2 translate-x-1/2 rotate-[135deg]" : "left-0 top-1/2 -translate-y-1/2 -translate-x-1/2 -rotate-[135deg]"}
|
|
839
|
+
`
|
|
840
|
+
}
|
|
841
|
+
)
|
|
842
|
+
]
|
|
843
|
+
}
|
|
844
|
+
)
|
|
845
|
+
] });
|
|
846
|
+
};
|
|
847
|
+
Tooltip.displayName = "Tooltip";
|
|
848
|
+
|
|
849
|
+
// src/components/Navbar.tsx
|
|
850
|
+
var import_react8 = __toESM(require("react"));
|
|
851
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
852
|
+
var Navbar = import_react8.default.forwardRef(
|
|
853
|
+
({
|
|
854
|
+
brand,
|
|
855
|
+
links = [],
|
|
856
|
+
rightElement,
|
|
857
|
+
onBrandClick,
|
|
858
|
+
sticky = false,
|
|
859
|
+
className = "",
|
|
860
|
+
...props
|
|
861
|
+
}, ref) => {
|
|
862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
863
|
+
"nav",
|
|
864
|
+
{
|
|
865
|
+
ref,
|
|
866
|
+
className: `
|
|
867
|
+
bg-pixelforge-white dark:bg-pixelforge-dark
|
|
868
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
869
|
+
border-b-2 border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
870
|
+
shadow-px
|
|
871
|
+
transition-all duration-200
|
|
872
|
+
${sticky ? "sticky top-0 z-fixed" : ""}
|
|
873
|
+
${className}
|
|
874
|
+
`,
|
|
875
|
+
...props,
|
|
876
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "max-w-full px-6 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between gap-8", children: [
|
|
877
|
+
brand && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
878
|
+
"button",
|
|
879
|
+
{
|
|
880
|
+
onClick: onBrandClick,
|
|
881
|
+
className: `
|
|
882
|
+
font-pixel text-lg
|
|
883
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
884
|
+
hover:text-pixelforge-accent
|
|
885
|
+
transition-colors
|
|
886
|
+
whitespace-nowrap
|
|
887
|
+
${onBrandClick ? "cursor-pointer" : "cursor-default"}
|
|
888
|
+
`,
|
|
889
|
+
children: brand
|
|
890
|
+
}
|
|
891
|
+
),
|
|
892
|
+
links.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "hidden md:flex items-center gap-1", children: links.map((link, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
893
|
+
"a",
|
|
894
|
+
{
|
|
895
|
+
href: link.href || "#",
|
|
896
|
+
onClick: (e) => {
|
|
897
|
+
if (link.onClick) {
|
|
898
|
+
e.preventDefault();
|
|
899
|
+
link.onClick();
|
|
900
|
+
}
|
|
901
|
+
},
|
|
902
|
+
className: `
|
|
903
|
+
px-4 py-2
|
|
904
|
+
font-mono text-sm
|
|
905
|
+
border-2 border-transparent
|
|
906
|
+
rounded-px-sm
|
|
907
|
+
transition-all duration-200
|
|
908
|
+
${link.disabled ? "opacity-50 cursor-not-allowed text-pixelforge-gray dark:text-pixelforge-gray/50" : `
|
|
909
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
910
|
+
hover:bg-pixelforge-lime/20 dark:hover:bg-pixelforge-lime/40
|
|
911
|
+
${link.active ? "bg-pixelforge-lime/30 dark:bg-pixelforge-lime/50 border-pixelforge-darkLime dark:border-pixelforge-lime" : ""}
|
|
912
|
+
`}
|
|
913
|
+
`,
|
|
914
|
+
children: link.label
|
|
915
|
+
},
|
|
916
|
+
index
|
|
917
|
+
)) }),
|
|
918
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-1" }),
|
|
919
|
+
rightElement && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex items-center gap-4", children: rightElement })
|
|
920
|
+
] }) })
|
|
921
|
+
}
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
);
|
|
925
|
+
Navbar.displayName = "Navbar";
|
|
926
|
+
|
|
927
|
+
// src/components/Sidebar.tsx
|
|
928
|
+
var import_react9 = __toESM(require("react"));
|
|
929
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
930
|
+
var Sidebar = import_react9.default.forwardRef(
|
|
931
|
+
({
|
|
932
|
+
brand,
|
|
933
|
+
items,
|
|
934
|
+
collapsible = true,
|
|
935
|
+
defaultCollapsed = false,
|
|
936
|
+
footer,
|
|
937
|
+
className = "",
|
|
938
|
+
...props
|
|
939
|
+
}, ref) => {
|
|
940
|
+
const [isCollapsed, setIsCollapsed] = (0, import_react9.useState)(defaultCollapsed);
|
|
941
|
+
const [expandedItems, setExpandedItems] = (0, import_react9.useState)([]);
|
|
942
|
+
const toggleExpand = (itemId) => {
|
|
943
|
+
setExpandedItems(
|
|
944
|
+
(prev) => prev.includes(itemId) ? prev.filter((id) => id !== itemId) : [...prev, itemId]
|
|
945
|
+
);
|
|
946
|
+
};
|
|
947
|
+
const renderItem = (item, depth = 0) => {
|
|
948
|
+
const isExpanded = expandedItems.includes(item.id);
|
|
949
|
+
const hasChildren = item.children && item.children.length > 0;
|
|
950
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
951
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
952
|
+
"button",
|
|
953
|
+
{
|
|
954
|
+
onClick: () => {
|
|
955
|
+
if (hasChildren) {
|
|
956
|
+
toggleExpand(item.id);
|
|
957
|
+
}
|
|
958
|
+
item.onClick?.();
|
|
959
|
+
},
|
|
960
|
+
disabled: item.disabled,
|
|
961
|
+
className: `
|
|
962
|
+
w-full text-left
|
|
963
|
+
px-4 py-3
|
|
964
|
+
font-mono text-sm
|
|
965
|
+
border-2 border-transparent
|
|
966
|
+
rounded-px-sm
|
|
967
|
+
transition-all duration-200
|
|
968
|
+
flex items-center gap-3
|
|
969
|
+
${item.disabled ? "opacity-50 cursor-not-allowed text-pixelforge-gray dark:text-pixelforge-gray/50" : `
|
|
970
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
971
|
+
hover:bg-pixelforge-lime/20 dark:hover:bg-pixelforge-lime/40
|
|
972
|
+
${item.active ? "bg-pixelforge-lime/30 dark:bg-pixelforge-lime/50 border-pixelforge-darkLime dark:border-pixelforge-lime" : ""}
|
|
973
|
+
`}
|
|
974
|
+
ml-${depth * 4}
|
|
975
|
+
`,
|
|
976
|
+
style: {
|
|
977
|
+
marginLeft: `${depth * 16}px`
|
|
978
|
+
},
|
|
979
|
+
children: [
|
|
980
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "flex-shrink-0 text-lg", children: item.icon }),
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "flex-1", children: item.label }),
|
|
982
|
+
hasChildren && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
983
|
+
"span",
|
|
984
|
+
{
|
|
985
|
+
className: `
|
|
986
|
+
transition-transform duration-200
|
|
987
|
+
${isExpanded ? "rotate-180" : ""}
|
|
988
|
+
`,
|
|
989
|
+
children: "\u25BC"
|
|
990
|
+
}
|
|
991
|
+
)
|
|
992
|
+
]
|
|
993
|
+
}
|
|
994
|
+
),
|
|
995
|
+
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-1", children: item.children?.map((child) => renderItem(child, depth + 1)) })
|
|
996
|
+
] }, item.id);
|
|
997
|
+
};
|
|
998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
999
|
+
"div",
|
|
1000
|
+
{
|
|
1001
|
+
ref,
|
|
1002
|
+
className: `
|
|
1003
|
+
bg-pixelforge-white dark:bg-pixelforge-dark
|
|
1004
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
1005
|
+
border-r-2 border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
1006
|
+
h-screen
|
|
1007
|
+
overflow-y-auto
|
|
1008
|
+
transition-all duration-300
|
|
1009
|
+
flex flex-col
|
|
1010
|
+
${isCollapsed ? "w-20" : "w-64"}
|
|
1011
|
+
${className}
|
|
1012
|
+
`,
|
|
1013
|
+
...props,
|
|
1014
|
+
children: [
|
|
1015
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "border-b-2 border-pixelforge-darkLime dark:border-pixelforge-lime px-4 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1016
|
+
!isCollapsed && brand && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { className: "font-pixel text-sm text-pixelforge-black dark:text-pixelforge-white truncate", children: brand }),
|
|
1017
|
+
collapsible && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1018
|
+
"button",
|
|
1019
|
+
{
|
|
1020
|
+
onClick: () => setIsCollapsed(!isCollapsed),
|
|
1021
|
+
className: `
|
|
1022
|
+
p-2 -mr-2
|
|
1023
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
1024
|
+
hover:bg-pixelforge-lime/20 dark:hover:bg-pixelforge-lime/30
|
|
1025
|
+
rounded-px-sm
|
|
1026
|
+
transition-all
|
|
1027
|
+
flex-shrink-0
|
|
1028
|
+
`,
|
|
1029
|
+
"aria-label": isCollapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
1030
|
+
children: isCollapsed ? "\u2192" : "\u2190"
|
|
1031
|
+
}
|
|
1032
|
+
)
|
|
1033
|
+
] }) }),
|
|
1034
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex-1 overflow-y-auto py-4 px-2 space-y-1", children: items.map((item) => renderItem(item)) }),
|
|
1035
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "border-t-2 border-pixelforge-darkLime dark:border-pixelforge-lime px-4 py-4", children: footer })
|
|
1036
|
+
]
|
|
1037
|
+
}
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
);
|
|
1041
|
+
Sidebar.displayName = "Sidebar";
|
|
1042
|
+
|
|
1043
|
+
// src/components/Footer.tsx
|
|
1044
|
+
var import_react10 = __toESM(require("react"));
|
|
1045
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1046
|
+
var Footer = import_react10.default.forwardRef(
|
|
1047
|
+
({
|
|
1048
|
+
brand,
|
|
1049
|
+
sections = [],
|
|
1050
|
+
copyright,
|
|
1051
|
+
socialLinks,
|
|
1052
|
+
className = "",
|
|
1053
|
+
...props
|
|
1054
|
+
}, ref) => {
|
|
1055
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1056
|
+
"footer",
|
|
1057
|
+
{
|
|
1058
|
+
ref,
|
|
1059
|
+
className: `
|
|
1060
|
+
bg-pixelforge-white dark:bg-pixelforge-dark
|
|
1061
|
+
text-pixelforge-black dark:text-pixelforge-white
|
|
1062
|
+
border-t-2 border-pixelforge-darkLime dark:border-pixelforge-lime
|
|
1063
|
+
${className}
|
|
1064
|
+
`,
|
|
1065
|
+
...props,
|
|
1066
|
+
children: [
|
|
1067
|
+
(brand || sections.length > 0 || socialLinks) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "max-w-full px-6 py-12", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8", children: [
|
|
1068
|
+
brand && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "col-span-1", children: [
|
|
1069
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "font-pixel text-lg text-pixelforge-black dark:text-pixelforge-white mb-4", children: brand }),
|
|
1070
|
+
socialLinks && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex gap-3", children: socialLinks })
|
|
1071
|
+
] }),
|
|
1072
|
+
sections.map((section, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
|
|
1073
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "font-pixel text-sm text-pixelforge-black dark:text-pixelforge-white mb-4 uppercase tracking-wider", children: section.title }),
|
|
1074
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "space-y-3", children: section.links.map((link, linkIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1075
|
+
"a",
|
|
1076
|
+
{
|
|
1077
|
+
href: link.href || "#",
|
|
1078
|
+
onClick: (e) => {
|
|
1079
|
+
if (link.onClick) {
|
|
1080
|
+
e.preventDefault();
|
|
1081
|
+
link.onClick();
|
|
1082
|
+
}
|
|
1083
|
+
},
|
|
1084
|
+
className: `
|
|
1085
|
+
font-mono text-sm
|
|
1086
|
+
text-pixelforge-gray dark:text-pixelforge-gray/70
|
|
1087
|
+
hover:text-pixelforge-black dark:hover:text-pixelforge-white
|
|
1088
|
+
transition-colors duration-200
|
|
1089
|
+
hover:underline
|
|
1090
|
+
`,
|
|
1091
|
+
children: link.label
|
|
1092
|
+
}
|
|
1093
|
+
) }, linkIndex)) })
|
|
1094
|
+
] }, index))
|
|
1095
|
+
] }) }),
|
|
1096
|
+
copyright && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "border-t-2 border-pixelforge-darkLime dark:border-pixelforge-lime/30 px-6 py-6 bg-pixelforge-light/50 dark:bg-pixelforge-black/20", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "font-mono text-xs text-pixelforge-gray dark:text-pixelforge-gray/70 text-center", children: copyright }) })
|
|
1097
|
+
]
|
|
1098
|
+
}
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
);
|
|
1102
|
+
Footer.displayName = "Footer";
|
|
1103
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1104
|
+
0 && (module.exports = {
|
|
1105
|
+
Badge,
|
|
1106
|
+
Button,
|
|
1107
|
+
Card,
|
|
1108
|
+
Dropdown,
|
|
1109
|
+
Footer,
|
|
1110
|
+
Input,
|
|
1111
|
+
Modal,
|
|
1112
|
+
Navbar,
|
|
1113
|
+
Sidebar,
|
|
1114
|
+
Tooltip,
|
|
1115
|
+
borderRadius,
|
|
1116
|
+
breakpoints,
|
|
1117
|
+
colors,
|
|
1118
|
+
gamePalettes,
|
|
1119
|
+
shadows,
|
|
1120
|
+
spacing,
|
|
1121
|
+
transitions,
|
|
1122
|
+
typography,
|
|
1123
|
+
zIndex
|
|
1124
|
+
});
|