@projectdiscoveryio/design-system 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/dist/index.js ADDED
@@ -0,0 +1,1439 @@
1
+ import React, { forwardRef, useMemo, memo, createContext, Component, useState, useEffect, useContext } from 'react';
2
+ import { cva } from 'class-variance-authority';
3
+ import * as LucideIcons from 'lucide-react';
4
+ import { Loader2 } from 'lucide-react';
5
+ export { LucideIcons as Icons };
6
+ import { clsx } from 'clsx';
7
+ import { twMerge } from 'tailwind-merge';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+
10
+ // src/theme/types.ts
11
+ var THEME_MODES = ["light", "dark", "system"];
12
+ var THEME_NAMES = ["base", "brand"];
13
+ var ADAPTER_TYPES = ["shadcn", "material"];
14
+ var DEFAULT_ADAPTER = "shadcn";
15
+ var DEFAULT_THEME = "base";
16
+ var DEFAULT_MODE = "system";
17
+
18
+ // src/theme/config.ts
19
+ var globalConfig = {
20
+ adapter: DEFAULT_ADAPTER,
21
+ theme: DEFAULT_THEME,
22
+ mode: DEFAULT_MODE
23
+ };
24
+ function setDesignSystemConfig(config) {
25
+ globalConfig = { ...globalConfig, ...config };
26
+ }
27
+ function getDesignSystemConfig() {
28
+ return { ...globalConfig };
29
+ }
30
+ function getAdapter() {
31
+ return globalConfig.adapter;
32
+ }
33
+ function getThemeName() {
34
+ return globalConfig.theme;
35
+ }
36
+ function getThemeMode() {
37
+ return globalConfig.mode;
38
+ }
39
+ function cn(...inputs) {
40
+ return twMerge(clsx(inputs));
41
+ }
42
+ var ButtonPrimitive = forwardRef(
43
+ ({ asChild = false, type = "button", children, ...props }, ref) => {
44
+ if (asChild && React.isValidElement(children)) {
45
+ return React.cloneElement(children, {
46
+ ...props,
47
+ ref,
48
+ type
49
+ });
50
+ }
51
+ return /* @__PURE__ */ jsx(
52
+ "button",
53
+ {
54
+ ref,
55
+ type,
56
+ ...props,
57
+ children
58
+ }
59
+ );
60
+ }
61
+ );
62
+ ButtonPrimitive.displayName = "ButtonPrimitive";
63
+ var iconCache = /* @__PURE__ */ new Map();
64
+ var loggedIcons = /* @__PURE__ */ new Set();
65
+ function getIcon(iconName) {
66
+ if (!iconName || typeof iconName !== "string") {
67
+ return null;
68
+ }
69
+ if (iconCache.has(iconName)) {
70
+ return iconCache.get(iconName) || null;
71
+ }
72
+ let IconComponent = null;
73
+ if (iconName in LucideIcons) {
74
+ IconComponent = LucideIcons[iconName];
75
+ } else {
76
+ const pascalCaseName = iconName.charAt(0).toUpperCase() + iconName.slice(1);
77
+ if (pascalCaseName in LucideIcons) {
78
+ IconComponent = LucideIcons[pascalCaseName];
79
+ }
80
+ }
81
+ if (IconComponent) {
82
+ const isValidComponent = typeof IconComponent === "function" || typeof IconComponent === "object" && IconComponent !== null;
83
+ if (isValidComponent) {
84
+ iconCache.set(iconName, IconComponent);
85
+ if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
86
+ if (!loggedIcons.has(iconName)) {
87
+ console.debug(`[pd-design] Icon "${iconName}" found and cached`);
88
+ loggedIcons.add(iconName);
89
+ }
90
+ }
91
+ return IconComponent;
92
+ }
93
+ }
94
+ if (process.env.NODE_ENV !== "production") {
95
+ const availableIcons = Object.keys(LucideIcons).filter((k) => {
96
+ const icon = LucideIcons[k];
97
+ return !k.includes("Icon") && icon && (typeof icon === "function" || typeof icon === "object");
98
+ }).slice(0, 10);
99
+ console.warn(`[pd-design] Icon "${iconName}" not found in lucide-react. Available icons: ${availableIcons.join(", ")}...`);
100
+ }
101
+ return null;
102
+ }
103
+ function renderIcon(iconName, size = "h-4 w-4", className) {
104
+ const IconComponent = getIcon(iconName);
105
+ if (!IconComponent) {
106
+ return null;
107
+ }
108
+ return React.createElement(IconComponent, {
109
+ className: `${size} ${className || ""}`.trim()
110
+ });
111
+ }
112
+ function iconExists(iconName) {
113
+ return getIcon(iconName) !== null;
114
+ }
115
+ function getAvailableIconNames() {
116
+ return Object.keys(LucideIcons).filter(
117
+ (name) => {
118
+ const icon = LucideIcons[name];
119
+ return icon && (typeof icon === "function" || typeof icon === "object") && !name.includes("Icon");
120
+ }
121
+ );
122
+ }
123
+ var buttonVariants = cva(
124
+ "pd-inline-flex pd-items-center pd-justify-center pd-font-medium pd-transition-colors pd-focus-visible:outline-none pd-focus-visible:ring-2 pd-focus-visible:ring-[var(--pd-border-blue)] pd-focus-visible:ring-offset-2 pd-disabled:pointer-events-none pd-disabled:cursor-not-allowed pd-disabled:hover:pd-bg-[inherit] pd-disabled:hover:pd-text-[inherit] pd-disabled:hover:pd-border-[inherit] pd-disabled:active:pd-bg-[inherit] pd-disabled:active:pd-text-[inherit] pd-disabled:active:pd-border-[inherit] [font-family:var(--pd-font-sans,Geist,sans-serif)] [gap:var(--pd-button-gap)] [border-radius:var(--pd-radius-button)] pd-shadow-none",
125
+ {
126
+ variants: {
127
+ variant: {
128
+ primary: "pd-border-0",
129
+ secondary: "pd-border",
130
+ ghost: "pd-border-0",
131
+ destructive: "pd-border-0"
132
+ },
133
+ intent: {
134
+ primary: "",
135
+ success: "",
136
+ warning: "",
137
+ danger: "",
138
+ neutral: ""
139
+ },
140
+ size: {
141
+ sm: "[padding-top:var(--pd-button-padding-sm-vertical)] [padding-bottom:var(--pd-button-padding-sm-vertical)] [padding-left:var(--pd-button-padding-sm-horizontal)] [padding-right:var(--pd-button-padding-sm-horizontal)] pd-text-xs [line-height:var(--pd-button-line-height-sm)] [letter-spacing:var(--pd-button-letter-spacing)]",
142
+ md: "[padding-top:var(--pd-button-padding-md-vertical)] [padding-bottom:var(--pd-button-padding-md-vertical)] [padding-left:var(--pd-button-padding-md-horizontal)] [padding-right:var(--pd-button-padding-md-horizontal)] pd-text-xs [line-height:var(--pd-button-line-height-md)] [letter-spacing:var(--pd-button-letter-spacing)]",
143
+ lg: "[padding-top:var(--pd-button-padding-lg-vertical)] [padding-bottom:var(--pd-button-padding-lg-vertical)] [padding-left:var(--pd-button-padding-lg-horizontal)] [padding-right:var(--pd-button-padding-lg-horizontal)] pd-text-base [line-height:var(--pd-button-line-height-lg)] [letter-spacing:var(--pd-button-letter-spacing)]"
144
+ }
145
+ },
146
+ compoundVariants: [
147
+ // Primary variant - using new semantic tokens
148
+ {
149
+ variant: "primary",
150
+ intent: "primary",
151
+ class: "pd-bg-[var(--pd-background-invert)] pd-text-[var(--pd-content-on-color)] hover:pd-bg-[var(--pd-background-invert-light)] active:pd-bg-[var(--pd-background-invert)]"
152
+ },
153
+ {
154
+ variant: "primary",
155
+ intent: "success",
156
+ class: "pd-bg-[var(--pd-intent-success-bg)] pd-text-[var(--pd-intent-success-text)] hover:pd-bg-[var(--pd-intent-success-bg-hover)] active:pd-bg-[var(--pd-intent-success-bg-active)]"
157
+ },
158
+ {
159
+ variant: "primary",
160
+ intent: "warning",
161
+ class: "pd-bg-[var(--pd-intent-warning-bg)] pd-text-[var(--pd-intent-warning-text)] hover:pd-bg-[var(--pd-intent-warning-bg-hover)] active:pd-bg-[var(--pd-intent-warning-bg-active)]"
162
+ },
163
+ {
164
+ variant: "primary",
165
+ intent: "danger",
166
+ class: "pd-bg-[var(--pd-intent-danger-bg)] pd-text-[var(--pd-destructive-foreground)] hover:pd-bg-[var(--pd-intent-danger-bg-hover)] active:pd-bg-[var(--pd-intent-danger-bg-active)] pd-disabled:pd-bg-[var(--pd-intent-danger-bg)] pd-disabled:pd-text-[var(--pd-content-subtle)]"
167
+ },
168
+ {
169
+ variant: "primary",
170
+ intent: "neutral",
171
+ class: "pd-bg-[var(--pd-intent-neutral-bg)] pd-text-[var(--pd-intent-neutral-text)] hover:pd-bg-[var(--pd-intent-neutral-bg-hover)] active:pd-bg-[var(--pd-intent-neutral-bg-active)]"
172
+ },
173
+ // Secondary variant - White bg default, always has light grey border
174
+ {
175
+ variant: "secondary",
176
+ intent: "primary",
177
+ class: "pd-bg-[var(--pd-background-primary)] pd-text-[var(--pd-content-secondary)] hover:pd-bg-[var(--pd-background-low)] hover:pd-text-[var(--pd-content-primary)] active:pd-bg-[var(--pd-background-low-on-hover)] active:pd-text-[var(--pd-content-primary)] pd-border pd-border-[var(--pd-border-secondary)]"
178
+ },
179
+ {
180
+ variant: "secondary",
181
+ intent: "success",
182
+ class: "pd-bg-[var(--pd-intent-success-bg)] pd-text-[var(--pd-intent-success-text)] hover:pd-bg-[var(--pd-intent-success-bg-hover)] active:pd-bg-[var(--pd-intent-success-bg-active)] pd-border-[var(--pd-intent-success-border)]"
183
+ },
184
+ {
185
+ variant: "secondary",
186
+ intent: "warning",
187
+ class: "pd-bg-[var(--pd-intent-warning-bg)] pd-text-[var(--pd-intent-warning-text)] hover:pd-bg-[var(--pd-intent-warning-bg-hover)] active:pd-bg-[var(--pd-intent-warning-bg-active)] pd-border-[var(--pd-intent-warning-border)]"
188
+ },
189
+ {
190
+ variant: "secondary",
191
+ intent: "danger",
192
+ class: "pd-bg-[var(--pd-intent-danger-bg)] pd-text-[var(--pd-intent-danger-text)] hover:pd-bg-[var(--pd-intent-danger-bg-hover)] hover:pd-text-[var(--pd-intent-danger-hover)] active:pd-bg-[var(--pd-intent-danger-bg-active)] pd-border pd-border-[var(--pd-intent-danger-border)]"
193
+ },
194
+ {
195
+ variant: "secondary",
196
+ intent: "neutral",
197
+ class: "pd-bg-[var(--pd-intent-neutral-bg)] pd-text-[var(--pd-intent-neutral-text)] hover:pd-bg-[var(--pd-intent-neutral-bg-hover)] active:pd-bg-[var(--pd-intent-neutral-bg-active)] pd-border-[var(--pd-intent-neutral-border)]"
198
+ },
199
+ // Ghost variant - Transparent default, light grey fill on hover/pressed/loading
200
+ {
201
+ variant: "ghost",
202
+ intent: "primary",
203
+ class: "pd-border-0 pd-bg-transparent pd-text-[var(--pd-content-secondary)] hover:pd-bg-[var(--pd-background-low)] hover:pd-text-[var(--pd-content-primary)] active:pd-bg-[var(--pd-background-low-on-hover)] active:pd-text-[var(--pd-content-primary)] pd-disabled:pd-text-[var(--pd-content-subtle)]"
204
+ },
205
+ {
206
+ variant: "ghost",
207
+ intent: "success",
208
+ class: "pd-border-0 pd-bg-transparent hover:pd-bg-[var(--pd-intent-success-bg)] pd-text-[var(--pd-intent-success-text)] hover:pd-text-[var(--pd-intent-success-hover)]"
209
+ },
210
+ {
211
+ variant: "ghost",
212
+ intent: "warning",
213
+ class: "pd-border-0 pd-bg-transparent hover:pd-bg-[var(--pd-intent-warning-bg)] pd-text-[var(--pd-intent-warning-text)] hover:pd-text-[var(--pd-intent-warning-hover)]"
214
+ },
215
+ {
216
+ variant: "ghost",
217
+ intent: "danger",
218
+ class: "pd-border-0 pd-bg-transparent pd-text-[var(--pd-intent-danger-text)] hover:pd-bg-[var(--pd-intent-danger-bg)] hover:pd-text-[var(--pd-intent-danger-hover)]"
219
+ },
220
+ {
221
+ variant: "ghost",
222
+ intent: "neutral",
223
+ class: "pd-border-0 pd-bg-transparent pd-text-[var(--pd-intent-neutral-text)] hover:pd-text-[var(--pd-intent-neutral-hover)]"
224
+ },
225
+ // Destructive variant - Red text, light red/pink background, different on hover/active/disabled
226
+ {
227
+ variant: "destructive",
228
+ intent: "primary",
229
+ class: "pd-border-0 pd-bg-[var(--pd-background-red)] pd-text-[var(--pd-content-red)] hover:pd-bg-[var(--pd-background-red-on-hover)] hover:pd-text-[var(--pd-content-red-on-hover)] active:pd-bg-[var(--pd-intent-danger-bg-active)] pd-disabled:pd-bg-transparent pd-disabled:pd-text-[var(--pd-content-subtle)]"
230
+ },
231
+ {
232
+ variant: "destructive",
233
+ intent: "success",
234
+ class: "pd-border-0 pd-bg-[var(--pd-intent-success-bg)] pd-text-[var(--pd-intent-success-text)] hover:pd-bg-[var(--pd-intent-success-bg-hover)] hover:pd-text-[var(--pd-intent-success-hover)] active:pd-bg-[var(--pd-intent-success-bg-active)] pd-disabled:pd-bg-transparent pd-disabled:pd-text-[var(--pd-content-subtle)]"
235
+ },
236
+ {
237
+ variant: "destructive",
238
+ intent: "warning",
239
+ class: "pd-border-0 pd-bg-[var(--pd-intent-warning-bg)] pd-text-[var(--pd-intent-warning-text)] hover:pd-bg-[var(--pd-intent-warning-bg-hover)] hover:pd-text-[var(--pd-intent-warning-hover)] active:pd-bg-[var(--pd-intent-warning-bg-active)] pd-disabled:pd-bg-transparent pd-disabled:pd-text-[var(--pd-content-subtle)]"
240
+ },
241
+ {
242
+ variant: "destructive",
243
+ intent: "danger",
244
+ class: "pd-border-0 pd-bg-[var(--pd-intent-danger-bg)] pd-text-[var(--pd-intent-danger-text)] hover:pd-bg-[var(--pd-intent-danger-bg-hover)] hover:pd-text-[var(--pd-intent-danger-hover)] active:pd-bg-[var(--pd-intent-danger-bg-active)] pd-disabled:pd-bg-transparent pd-disabled:pd-text-[var(--pd-content-subtle)]"
245
+ },
246
+ {
247
+ variant: "destructive",
248
+ intent: "neutral",
249
+ class: "pd-border-0 pd-bg-[var(--pd-intent-neutral-bg)] pd-text-[var(--pd-intent-neutral-text)] hover:pd-bg-[var(--pd-intent-neutral-bg-hover)] hover:pd-text-[var(--pd-intent-neutral-hover)] active:pd-bg-[var(--pd-intent-neutral-bg-active)] pd-disabled:pd-bg-transparent pd-disabled:pd-text-[var(--pd-content-subtle)]"
250
+ }
251
+ ],
252
+ defaultVariants: {
253
+ variant: "primary",
254
+ intent: "primary",
255
+ size: "md"
256
+ }
257
+ }
258
+ );
259
+ var ShadcnButton = forwardRef(
260
+ ({
261
+ variant = "primary",
262
+ intent = "primary",
263
+ size = "md",
264
+ disabled,
265
+ loading,
266
+ fullWidth,
267
+ startIcon,
268
+ endIcon,
269
+ loadingText,
270
+ asChild,
271
+ href,
272
+ target,
273
+ children,
274
+ ...props
275
+ }, ref) => {
276
+ const buttonClasses = cn(
277
+ buttonVariants({ variant, intent, size }),
278
+ fullWidth && "pd-w-full",
279
+ // Loading states - light mode (apply to all intents for secondary and ghost)
280
+ loading && variant === "primary" && intent === "primary" && "pd-bg-[var(--pd-background-tertiary)] pd-text-[var(--pd-content-secondary)]",
281
+ loading && variant === "secondary" && "pd-bg-[var(--pd-background-tertiary)] pd-text-[var(--pd-content-secondary)] pd-border-[var(--pd-border-secondary)]",
282
+ loading && variant === "ghost" && "!pd-bg-[var(--pd-background-tertiary)] pd-text-[var(--pd-content-secondary)]",
283
+ // Destructive variant loading states - use intent-specific backgrounds
284
+ loading && variant === "destructive" && intent === "primary" && "pd-bg-[var(--pd-background-red)] pd-text-[var(--pd-content-red)]",
285
+ loading && variant === "destructive" && intent === "success" && "pd-bg-[var(--pd-intent-success-bg)] pd-text-[var(--pd-intent-success-text)]",
286
+ loading && variant === "destructive" && intent === "warning" && "pd-bg-[var(--pd-intent-warning-bg)] pd-text-[var(--pd-intent-warning-text)]",
287
+ loading && variant === "destructive" && intent === "danger" && "pd-bg-[var(--pd-intent-danger-bg)] pd-text-[var(--pd-intent-danger-text)]",
288
+ loading && variant === "destructive" && intent === "neutral" && "pd-bg-[var(--pd-intent-neutral-bg)] pd-text-[var(--pd-intent-neutral-text)]",
289
+ // Disabled states - consistent across all variants (no hover/active changes)
290
+ disabled && variant === "primary" && "pd-bg-[var(--pd-background-tertiary)] pd-text-[var(--pd-content-subtle)]",
291
+ disabled && variant === "secondary" && "pd-bg-[var(--pd-background-tertiary)] pd-text-[var(--pd-content-subtle)] pd-border-[var(--pd-border-secondary)]",
292
+ disabled && variant === "ghost" && "pd-bg-transparent pd-text-[var(--pd-content-subtle)]",
293
+ disabled && variant === "destructive" && "pd-bg-transparent pd-text-[var(--pd-content-subtle)]"
294
+ );
295
+ if (href) {
296
+ return /* @__PURE__ */ jsx(
297
+ ButtonPrimitive,
298
+ {
299
+ asChild: true,
300
+ ...props,
301
+ children: /* @__PURE__ */ jsx(
302
+ "a",
303
+ {
304
+ href,
305
+ target,
306
+ rel: target === "_blank" ? "noopener noreferrer" : void 0,
307
+ className: buttonClasses,
308
+ "aria-disabled": disabled || loading,
309
+ style: { pointerEvents: disabled || loading ? "none" : void 0 },
310
+ children: renderButtonContent({ loading, loadingText, startIcon, endIcon, children, size, variant, intent })
311
+ }
312
+ )
313
+ }
314
+ );
315
+ }
316
+ return /* @__PURE__ */ jsx(
317
+ ButtonPrimitive,
318
+ {
319
+ ref,
320
+ disabled: disabled || loading,
321
+ className: buttonClasses,
322
+ asChild,
323
+ ...props,
324
+ children: renderButtonContent({ loading, loadingText, startIcon, endIcon, children, size, variant, intent })
325
+ }
326
+ );
327
+ }
328
+ );
329
+ function renderButtonContent({
330
+ loading,
331
+ loadingText,
332
+ startIcon,
333
+ endIcon,
334
+ children,
335
+ size,
336
+ variant,
337
+ intent
338
+ }) {
339
+ const iconSizeClass = size === "sm" ? "pd-h-3 pd-w-3" : size === "lg" ? "pd-h-5 pd-w-5" : "pd-h-4 pd-w-4";
340
+ const spinnerSizeClass = size === "sm" ? "pd-h-3 pd-w-3" : size === "lg" ? "pd-h-5 pd-w-5" : "pd-h-4 pd-w-4";
341
+ const getLoadingTextColor = () => {
342
+ if (variant === "primary" && intent === "primary") {
343
+ return "pd-text-[var(--pd-content-secondary)]";
344
+ }
345
+ if (variant === "primary" && intent === "danger") {
346
+ return "pd-text-[var(--pd-destructive-foreground)]";
347
+ }
348
+ if (variant === "secondary" && intent === "primary") {
349
+ return "pd-text-[var(--pd-content-secondary)]";
350
+ }
351
+ if (variant === "ghost" && intent === "primary") {
352
+ return "pd-text-[var(--pd-content-secondary)]";
353
+ }
354
+ if (variant === "destructive" && intent === "primary") {
355
+ return "pd-text-[var(--pd-content-red)]";
356
+ }
357
+ if (variant === "destructive" && intent === "success") {
358
+ return "pd-text-[var(--pd-intent-success-text)]";
359
+ }
360
+ if (variant === "destructive" && intent === "warning") {
361
+ return "pd-text-[var(--pd-intent-warning-text)]";
362
+ }
363
+ if (variant === "destructive" && intent === "danger") {
364
+ return "pd-text-[var(--pd-intent-danger-text)]";
365
+ }
366
+ if (variant === "destructive" && intent === "neutral") {
367
+ return "pd-text-[var(--pd-intent-neutral-text)]";
368
+ }
369
+ return "pd-text-[var(--pd-content-secondary)]";
370
+ };
371
+ const loadingTextColor = getLoadingTextColor();
372
+ if (loading) {
373
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
374
+ /* @__PURE__ */ jsx(
375
+ Loader2,
376
+ {
377
+ "aria-hidden": "true",
378
+ className: `${spinnerSizeClass} pd-animate-spin ${loadingTextColor}`
379
+ }
380
+ ),
381
+ /* @__PURE__ */ jsx("span", { className: loadingTextColor, children: loadingText || children }),
382
+ /* @__PURE__ */ jsx("span", { className: "pd-sr-only", children: loadingText ? `Loading: ${loadingText}` : "Loading" })
383
+ ] });
384
+ }
385
+ const StartIconComponent = startIcon ? getIcon(startIcon) : null;
386
+ const EndIconComponent = endIcon ? getIcon(endIcon) : null;
387
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
388
+ StartIconComponent && /* @__PURE__ */ jsx("span", { className: "pd-inline-flex pd-items-center pd-justify-center", children: React.createElement(StartIconComponent, { className: iconSizeClass }) }),
389
+ children,
390
+ EndIconComponent && /* @__PURE__ */ jsx("span", { className: "pd-inline-flex pd-items-center pd-justify-center", children: React.createElement(EndIconComponent, { className: iconSizeClass }) })
391
+ ] });
392
+ }
393
+ ShadcnButton.displayName = "ShadcnButton";
394
+
395
+ // src/adapters/index.ts
396
+ var [SHADCN_ADAPTER, MATERIAL_ADAPTER] = ADAPTER_TYPES;
397
+ function getButtonAdapter() {
398
+ const adapter = getAdapter();
399
+ switch (adapter) {
400
+ case SHADCN_ADAPTER:
401
+ return ShadcnButton;
402
+ case MATERIAL_ADAPTER:
403
+ if (process.env.NODE_ENV !== "production") {
404
+ console.warn("Material adapter not yet enabled. Install @mui/material to use it.");
405
+ }
406
+ return ShadcnButton;
407
+ default:
408
+ return ShadcnButton;
409
+ }
410
+ }
411
+ var ButtonComponent = forwardRef(
412
+ ({
413
+ variant = "primary",
414
+ size = "md",
415
+ loading,
416
+ disabled,
417
+ fullWidth,
418
+ startIcon,
419
+ endIcon,
420
+ loadingText,
421
+ href,
422
+ target,
423
+ type = "button",
424
+ asChild,
425
+ children,
426
+ ...props
427
+ }, ref) => {
428
+ const AdapterButton = getButtonAdapter();
429
+ const { className, ...restProps } = props;
430
+ if (className && process.env.NODE_ENV !== "production") {
431
+ console.warn("Button component does not accept className prop. Use variant, size, and other props for styling.");
432
+ }
433
+ const intent = "primary";
434
+ const accessibilityProps = useMemo(() => {
435
+ const defaults = {};
436
+ if (disabled || loading) {
437
+ defaults["aria-disabled"] = true;
438
+ }
439
+ if (loading) {
440
+ defaults["aria-busy"] = true;
441
+ }
442
+ return defaults;
443
+ }, [disabled, loading]);
444
+ const mergedProps = {
445
+ ...restProps,
446
+ ...accessibilityProps
447
+ };
448
+ return /* @__PURE__ */ jsx(
449
+ AdapterButton,
450
+ {
451
+ ref,
452
+ variant,
453
+ intent,
454
+ size,
455
+ disabled,
456
+ loading,
457
+ fullWidth,
458
+ startIcon,
459
+ endIcon,
460
+ loadingText,
461
+ href,
462
+ target,
463
+ type,
464
+ asChild,
465
+ ...mergedProps,
466
+ children
467
+ }
468
+ );
469
+ }
470
+ );
471
+ ButtonComponent.displayName = "Button";
472
+ var Button = memo(ButtonComponent);
473
+
474
+ // src/tokens/tokens.ts
475
+ var neutral = {
476
+ 100: "#FFFFFF",
477
+ 200: "#EDEDED",
478
+ 300: "#DFDFE2",
479
+ 400: "#BEBEC1",
480
+ 500: "#7E7E8B",
481
+ 600: "#60606C",
482
+ 700: "#4E4E5A",
483
+ 800: "#2F2F37",
484
+ 900: "#17171C",
485
+ 950: "#09090B",
486
+ 1e3: "#FAFAFA"
487
+ };
488
+ var blue = {
489
+ 100: "#EBF1FF",
490
+ 200: "#C2D4FF",
491
+ 300: "#99B7FF",
492
+ 400: "#709AFF",
493
+ 500: "#3772FF",
494
+ 600: "#004BFF",
495
+ 700: "#003FD6",
496
+ 800: "#002680",
497
+ 900: "#001E66",
498
+ 950: "#00123D"
499
+ };
500
+ var orange = {
501
+ 100: "#FFF3EB",
502
+ 200: "#FFE1CC",
503
+ 300: "#FFC9A3",
504
+ 400: "#EC9C64",
505
+ 500: "#FF6800",
506
+ 600: "#D65700",
507
+ 700: "#AD4700",
508
+ 800: "#7A3200",
509
+ 900: "#5C2500",
510
+ 950: "#331500"
511
+ };
512
+ var red = {
513
+ 100: "#FDF2F4",
514
+ 200: "#FADBE1",
515
+ 300: "#F6C1CA",
516
+ 400: "#E15C5C",
517
+ 500: "#E12D4E",
518
+ 600: "#C41C3B",
519
+ 700: "#A11730",
520
+ 800: "#7D1225",
521
+ 900: "#4C0B17",
522
+ 950: "#2D060D"
523
+ };
524
+ var green = {
525
+ 100: "#E0FFEC",
526
+ 200: "#BDFFD5",
527
+ 300: "#8AFFB5",
528
+ 400: "#5CFF98",
529
+ 500: "#09FF63",
530
+ 600: "#00E052",
531
+ 700: "#00B241",
532
+ 800: "#008A32",
533
+ 900: "#006625",
534
+ 950: "#00471A"
535
+ };
536
+ var yellow = {
537
+ 100: "#FFF4E0",
538
+ 200: "#FFE8C2",
539
+ 300: "#FFD999",
540
+ 400: "#FFCA70",
541
+ 500: "#FFAD22",
542
+ 600: "#F09700",
543
+ 700: "#D68700",
544
+ 800: "#7A4D00",
545
+ 900: "#5C3A00",
546
+ 950: "#3D2600"
547
+ };
548
+ var colorPrimitives = {
549
+ neutral,
550
+ blue,
551
+ orange,
552
+ red,
553
+ green,
554
+ yellow
555
+ };
556
+ var typography = {
557
+ fontFamily: {
558
+ sans: ["Geist", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "sans-serif"],
559
+ mono: ["Geist Mono", "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", "monospace"]
560
+ },
561
+ fontSize: {
562
+ xs: "0.75em",
563
+ // 12px
564
+ sm: "0.875em",
565
+ // 14px
566
+ base: "1em",
567
+ // 16px
568
+ lg: "1.125em",
569
+ // 18px
570
+ xl: "1.25em",
571
+ // 20px
572
+ "2xl": "1.5em",
573
+ // 24px
574
+ "3xl": "1.875em",
575
+ // 30px
576
+ "4xl": "2.25em",
577
+ // 36px
578
+ "5xl": "3em",
579
+ // 48px
580
+ "6xl": "3.75em",
581
+ // 60px
582
+ "7xl": "4.5em",
583
+ // 72px
584
+ "8xl": "6em",
585
+ // 96px
586
+ "9xl": "8em"
587
+ // 128px
588
+ },
589
+ fontWeight: {
590
+ normal: "400",
591
+ medium: "500",
592
+ semibold: "600",
593
+ bold: "700"
594
+ },
595
+ lineHeight: {
596
+ tight: "1.25",
597
+ normal: "1.5",
598
+ relaxed: "1.75"
599
+ },
600
+ // Tailwind fontSize lineHeight mappings (for use in tailwind.config.js)
601
+ fontSizeLineHeight: {
602
+ xs: "1em",
603
+ // 16px for 12px font
604
+ sm: "1.25em",
605
+ // 20px for 14px font
606
+ base: "1.5em",
607
+ // 24px for 16px font
608
+ lg: "1.75em",
609
+ // 28px for 18px font
610
+ xl: "1.75em",
611
+ // 28px for 20px font
612
+ "2xl": "2em",
613
+ "3xl": "2.25em",
614
+ "4xl": "2.5em",
615
+ "5xl": "1",
616
+ "6xl": "1",
617
+ "7xl": "1",
618
+ "8xl": "1",
619
+ "9xl": "1"
620
+ },
621
+ letterSpacing: {
622
+ tight: "-0.025em",
623
+ normal: "0",
624
+ wide: "0.025em",
625
+ wider: "0.05em",
626
+ widest: "0.1em",
627
+ button: "0.00833em"
628
+ // 0.1px for 12px font
629
+ }
630
+ };
631
+ var spacing = {
632
+ 0: "0em",
633
+ // 0px
634
+ 1: "0.25em",
635
+ // 4px
636
+ 2: "0.5em",
637
+ // 8px
638
+ 3: "0.75em",
639
+ // 12px
640
+ 4: "1em",
641
+ // 16px
642
+ 5: "1.25em",
643
+ // 20px
644
+ 6: "1.5em",
645
+ // 24px
646
+ 7: "1.75em",
647
+ // 28px
648
+ 8: "2em",
649
+ // 32px
650
+ 9: "2.25em",
651
+ // 36px
652
+ 10: "2.5em"
653
+ // 40px
654
+ };
655
+ var radius = {
656
+ none: "0",
657
+ sm: "0.125em",
658
+ // 2px
659
+ base: "0.25em",
660
+ // 4px
661
+ md: "0.375em",
662
+ // 6px
663
+ lg: "0.5em",
664
+ // 8px
665
+ xl: "0.75em",
666
+ // 12px
667
+ "2xl": "1em",
668
+ // 16px
669
+ "3xl": "1.5em",
670
+ // 24px
671
+ full: "9999px",
672
+ button: "0.5em"
673
+ // 8px - button border radius
674
+ };
675
+ var shadows = {
676
+ sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
677
+ base: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
678
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
679
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
680
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
681
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
682
+ inner: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
683
+ none: "none"
684
+ };
685
+ var zIndex = {
686
+ base: 0,
687
+ dropdown: 1e3,
688
+ sticky: 1020,
689
+ fixed: 1030,
690
+ modalBackdrop: 1040,
691
+ modal: 1050,
692
+ popover: 1060,
693
+ tooltip: 1070
694
+ };
695
+ var button = {
696
+ padding: {
697
+ sm: {
698
+ vertical: "0.5em",
699
+ // 8px
700
+ horizontal: "0.75em"
701
+ // 12px
702
+ },
703
+ md: {
704
+ vertical: "0.625em",
705
+ // 10px
706
+ horizontal: "1em"
707
+ // 16px
708
+ },
709
+ lg: {
710
+ vertical: "0.75em",
711
+ // 12px
712
+ horizontal: "1.25em"
713
+ // 20px
714
+ }
715
+ },
716
+ gap: "0.5em",
717
+ // 8px - gap between icon and text
718
+ lineHeight: {
719
+ sm: "1.333em",
720
+ md: "1.333em",
721
+ // 16px for 12px font-size (1.333 × 12px = 16px)
722
+ lg: "1.333em"
723
+ },
724
+ letterSpacing: "0.00833em"
725
+ // 0.1px for 12px font
726
+ };
727
+ var semanticTokens = {
728
+ light: {
729
+ border: {
730
+ primary: neutral[400],
731
+ secondary: neutral[300],
732
+ subtle: neutral[300],
733
+ invert: neutral[950],
734
+ onColor: neutral[100],
735
+ blue: blue[500],
736
+ blueSubtle: blue[300],
737
+ blueOnHover: blue[700],
738
+ red: red[600],
739
+ redSubtle: red[300],
740
+ redOnHover: red[700],
741
+ orange: orange[600],
742
+ orangeSubtle: orange[300],
743
+ orangeOnHover: orange[700],
744
+ yellow: yellow[600],
745
+ yellowSubtle: yellow[300],
746
+ yellowOnHover: yellow[700],
747
+ green: green[600],
748
+ greenSubtle: green[300],
749
+ greenOnHover: green[700]
750
+ },
751
+ content: {
752
+ primary: neutral[900],
753
+ secondary: neutral[600],
754
+ subtle: neutral[400],
755
+ onColor: neutral[100],
756
+ alwaysWhite: neutral[100],
757
+ alwaysBlack: neutral[950],
758
+ onColorInverse: neutral[950],
759
+ blue: blue[500],
760
+ blueDisabled: blue[400],
761
+ blueOnHover: blue[600],
762
+ green: green[700],
763
+ greenDisabled: green[400],
764
+ greenOnHover: green[600],
765
+ red: red[600],
766
+ redDisabled: red[400],
767
+ redOnHover: red[700],
768
+ orange: orange[600],
769
+ orangeDisabled: orange[400],
770
+ orangeOnHover: orange[700],
771
+ yellow: yellow[600],
772
+ yellowDisabled: yellow[400],
773
+ yellowOnHover: yellow[700]
774
+ },
775
+ background: {
776
+ primary: neutral[100],
777
+ system: neutral[1e3],
778
+ secondary: neutral[200],
779
+ tertiary: neutral[300],
780
+ invert: neutral[950],
781
+ invertLight: neutral[900],
782
+ green: green[100],
783
+ greenOnHover: green[200],
784
+ red: red[100],
785
+ redOnHover: red[200],
786
+ orange: orange[100],
787
+ orangeOnHover: orange[200],
788
+ yellow: orange[100],
789
+ yellowOnHover: orange[200],
790
+ low: neutral[200],
791
+ lowOnHover: neutral[300],
792
+ info: blue[100],
793
+ infoOnHover: blue[300],
794
+ base: neutral[100]
795
+ }
796
+ },
797
+ dark: {
798
+ border: {
799
+ primary: neutral[700],
800
+ secondary: neutral[800],
801
+ subtle: neutral[800],
802
+ invert: neutral[100],
803
+ onColor: neutral[950],
804
+ blue: blue[400],
805
+ blueSubtle: blue[800],
806
+ blueOnHover: blue[500],
807
+ red: red[400],
808
+ redSubtle: red[900],
809
+ redOnHover: red[500],
810
+ orange: orange[400],
811
+ orangeSubtle: orange[900],
812
+ orangeOnHover: orange[500],
813
+ yellow: yellow[400],
814
+ yellowSubtle: yellow[900],
815
+ yellowOnHover: yellow[500],
816
+ green: green[600],
817
+ greenSubtle: green[900],
818
+ greenOnHover: green[700]
819
+ },
820
+ content: {
821
+ primary: neutral[300],
822
+ secondary: neutral[500],
823
+ subtle: neutral[700],
824
+ onColor: neutral[950],
825
+ alwaysWhite: neutral[100],
826
+ alwaysBlack: neutral[950],
827
+ onColorInverse: neutral[100],
828
+ blue: blue[400],
829
+ blueDisabled: blue[800],
830
+ blueOnHover: blue[500],
831
+ green: green[600],
832
+ greenDisabled: green[800],
833
+ greenOnHover: green[500],
834
+ red: red[400],
835
+ redDisabled: red[800],
836
+ redOnHover: red[300],
837
+ orange: orange[400],
838
+ orangeDisabled: orange[800],
839
+ orangeOnHover: orange[300],
840
+ yellow: yellow[400],
841
+ yellowDisabled: yellow[800],
842
+ yellowOnHover: yellow[300]
843
+ },
844
+ background: {
845
+ primary: neutral[950],
846
+ system: neutral[950],
847
+ secondary: neutral[900],
848
+ tertiary: neutral[800],
849
+ invert: neutral[100],
850
+ invertLight: neutral[300],
851
+ green: green[950],
852
+ greenOnHover: green[900],
853
+ red: red[950],
854
+ redOnHover: red[900],
855
+ orange: orange[950],
856
+ orangeOnHover: orange[900],
857
+ yellow: yellow[950],
858
+ yellowOnHover: yellow[900],
859
+ low: neutral[900],
860
+ lowOnHover: neutral[800],
861
+ info: blue[950],
862
+ infoOnHover: blue[900],
863
+ base: neutral[950]
864
+ }
865
+ }
866
+ };
867
+ var COLOR_SCALES = [100, 200, 300, 400, 500, 600, 700, 800, 900, 950, 1e3];
868
+ var VARIANTS = ["primary", "secondary", "ghost", "destructive"];
869
+ var INTENTS = ["primary", "success", "warning", "danger", "neutral"];
870
+ var SIZES = ["sm", "md", "lg"];
871
+ var BUTTON_TYPES = ["button", "submit", "reset"];
872
+ var INPUT_TYPES = ["text", "email", "password", "number", "tel", "url", "search"];
873
+ var ORIENTATIONS = ["horizontal", "vertical"];
874
+ var SURFACE_LEVELS = ["base", "elevated", "overlay"];
875
+ var colors = {
876
+ // Neutral palette
877
+ white: neutral[100],
878
+ black: neutral[950],
879
+ gray50: neutral[200],
880
+ gray100: neutral[300],
881
+ gray200: neutral[400],
882
+ gray300: neutral[500],
883
+ gray400: neutral[500],
884
+ gray500: neutral[500],
885
+ gray600: neutral[600],
886
+ gray700: neutral[700],
887
+ gray800: neutral[800],
888
+ gray900: neutral[900],
889
+ // Primary palette (mapped from blue)
890
+ blue50: blue[100],
891
+ blue100: blue[100],
892
+ blue200: blue[200],
893
+ blue300: blue[300],
894
+ blue400: blue[400],
895
+ blue500: blue[500],
896
+ blue600: blue[600],
897
+ blue700: blue[700],
898
+ blue800: blue[800],
899
+ blue900: blue[900],
900
+ // Success palette (mapped from green)
901
+ green50: green[100],
902
+ green100: green[100],
903
+ green200: green[200],
904
+ green300: green[300],
905
+ green400: green[400],
906
+ green500: green[500],
907
+ green600: green[600],
908
+ green700: green[700],
909
+ green800: green[800],
910
+ green900: green[900],
911
+ // Warning palette (mapped from yellow)
912
+ yellow50: yellow[100],
913
+ yellow100: yellow[100],
914
+ yellow200: yellow[200],
915
+ yellow300: yellow[300],
916
+ yellow400: yellow[400],
917
+ yellow500: yellow[500],
918
+ yellow600: yellow[600],
919
+ yellow700: yellow[700],
920
+ yellow800: yellow[800],
921
+ yellow900: yellow[900],
922
+ // Danger palette (mapped from red)
923
+ red50: red[100],
924
+ red100: red[100],
925
+ red200: red[200],
926
+ red300: red[300],
927
+ red400: red[400],
928
+ red500: red[500],
929
+ red600: red[600],
930
+ red700: red[700],
931
+ red800: red[800],
932
+ red900: red[900]
933
+ };
934
+
935
+ // src/theme/theme.ts
936
+ function resolveThemeMode(mode) {
937
+ if (mode !== "system") {
938
+ return mode;
939
+ }
940
+ if (typeof window !== "undefined" && window.matchMedia) {
941
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
942
+ }
943
+ return "light";
944
+ }
945
+ function createTheme(name, mode) {
946
+ const resolvedMode = resolveThemeMode(mode);
947
+ const semantic = semanticTokens[resolvedMode];
948
+ const cssVariables = {
949
+ // Base colors
950
+ "--color-white": neutral[100],
951
+ "--color-black": neutral[950],
952
+ // shadcn/ui CSS variable mappings for compatibility
953
+ "--background": semantic.background.primary,
954
+ "--foreground": semantic.content.primary,
955
+ "--card": semantic.background.secondary,
956
+ "--card-foreground": semantic.content.primary,
957
+ "--popover": semantic.background.secondary,
958
+ "--popover-foreground": semantic.content.primary,
959
+ "--primary": semantic.content.secondary,
960
+ "--primary-foreground": neutral[100],
961
+ "--secondary": semantic.background.secondary,
962
+ "--secondary-foreground": semantic.content.primary,
963
+ "--muted": semantic.background.secondary,
964
+ "--muted-foreground": semantic.content.subtle,
965
+ "--accent": semantic.background.secondary,
966
+ "--accent-foreground": semantic.content.primary,
967
+ "--destructive": resolvedMode === "light" ? semantic.content.red : semantic.content.red,
968
+ "--destructive-foreground": neutral[100],
969
+ "--border": semantic.border.primary,
970
+ "--input": semantic.border.primary,
971
+ "--ring": semantic.content.secondary,
972
+ "--radius": radius.md
973
+ };
974
+ return {
975
+ name,
976
+ mode: resolvedMode,
977
+ // Store the resolved mode (light/dark) not 'system'
978
+ cssVariables
979
+ };
980
+ }
981
+ function PdThemeProvider({
982
+ children,
983
+ theme: themeName = DEFAULT_THEME,
984
+ mode = DEFAULT_MODE,
985
+ className
986
+ }) {
987
+ const [resolvedMode, setResolvedMode] = useState(
988
+ () => resolveThemeMode(mode)
989
+ );
990
+ useEffect(() => {
991
+ if (mode !== "system" || typeof window === "undefined" || !window.matchMedia) {
992
+ return;
993
+ }
994
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
995
+ const handleChange = (e) => {
996
+ setResolvedMode(e.matches ? "dark" : "light");
997
+ };
998
+ handleChange(mediaQuery);
999
+ if (mediaQuery.addEventListener) {
1000
+ mediaQuery.addEventListener("change", handleChange);
1001
+ return () => mediaQuery.removeEventListener("change", handleChange);
1002
+ } else {
1003
+ mediaQuery.addListener(handleChange);
1004
+ return () => mediaQuery.removeListener(handleChange);
1005
+ }
1006
+ }, [mode]);
1007
+ useEffect(() => {
1008
+ if (mode !== "system") {
1009
+ setResolvedMode(mode === "dark" ? "dark" : "light");
1010
+ }
1011
+ }, [mode]);
1012
+ const effectiveMode = mode === "system" ? resolvedMode : mode;
1013
+ const isDark = effectiveMode === "dark";
1014
+ return /* @__PURE__ */ jsx(
1015
+ "div",
1016
+ {
1017
+ className: clsx(
1018
+ "pd-root",
1019
+ isDark && "pd-dark",
1020
+ `pd-theme-${themeName}`,
1021
+ className
1022
+ ),
1023
+ children
1024
+ }
1025
+ );
1026
+ }
1027
+ PdThemeProvider.displayName = "PdThemeProvider";
1028
+ var ErrorBoundary = class extends Component {
1029
+ constructor(props) {
1030
+ super(props);
1031
+ this.state = {
1032
+ hasError: false,
1033
+ error: null,
1034
+ errorInfo: null
1035
+ };
1036
+ }
1037
+ static getDerivedStateFromError(error) {
1038
+ return {
1039
+ hasError: true,
1040
+ error
1041
+ };
1042
+ }
1043
+ componentDidCatch(error, errorInfo) {
1044
+ this.setState({
1045
+ error,
1046
+ errorInfo
1047
+ });
1048
+ if (this.props.onError) {
1049
+ this.props.onError(error, errorInfo);
1050
+ }
1051
+ if (process.env.NODE_ENV !== "production") {
1052
+ console.error("ErrorBoundary caught an error:", error, errorInfo);
1053
+ }
1054
+ }
1055
+ render() {
1056
+ if (this.state.hasError) {
1057
+ const { fallback } = this.props;
1058
+ const { error, errorInfo } = this.state;
1059
+ if (typeof fallback === "function" && error && errorInfo) {
1060
+ return fallback(error, errorInfo);
1061
+ }
1062
+ if (fallback && typeof fallback !== "function") {
1063
+ return fallback;
1064
+ }
1065
+ return /* @__PURE__ */ jsxs("div", { className: "pd-root pd-p-4 pd-border pd-border-[var(--pd-border-red)] pd-rounded-md pd-bg-[var(--pd-background-red)]", children: [
1066
+ /* @__PURE__ */ jsx("h3", { className: "pd-m-0 pd-mb-2 pd-text-[var(--pd-content-red)]", children: "Something went wrong" }),
1067
+ process.env.NODE_ENV !== "production" && error && /* @__PURE__ */ jsxs("details", { className: "pd-mt-2", children: [
1068
+ /* @__PURE__ */ jsx("summary", { className: "pd-cursor-pointer pd-text-[var(--pd-content-red-on-hover)]", children: "Error details" }),
1069
+ /* @__PURE__ */ jsxs("pre", { className: "pd-mt-2 pd-p-2 pd-bg-[var(--pd-background-red-on-hover)] pd-rounded pd-overflow-auto pd-text-sm", children: [
1070
+ error.toString(),
1071
+ errorInfo?.componentStack
1072
+ ] })
1073
+ ] })
1074
+ ] });
1075
+ }
1076
+ return this.props.children;
1077
+ }
1078
+ };
1079
+ ErrorBoundary.displayName = "ErrorBoundary";
1080
+ var ThemeContext = createContext(null);
1081
+ var parsePreference = (value) => {
1082
+ if (value === "light" || value === "dark" || value === "system") {
1083
+ return value;
1084
+ }
1085
+ return "system";
1086
+ };
1087
+ function ThemeProvider({
1088
+ children,
1089
+ adapter = DEFAULT_ADAPTER,
1090
+ theme: themeName = DEFAULT_THEME,
1091
+ mode: initialMode = DEFAULT_MODE,
1092
+ storageKey
1093
+ }) {
1094
+ const getInitialMode = () => {
1095
+ if (storageKey && typeof window !== "undefined") {
1096
+ const stored = localStorage.getItem(storageKey);
1097
+ if (stored) {
1098
+ return parsePreference(stored);
1099
+ }
1100
+ }
1101
+ return initialMode;
1102
+ };
1103
+ const [mode, setMode] = useState(getInitialMode);
1104
+ const [resolvedMode, setResolvedMode] = useState(
1105
+ () => resolveThemeMode(mode)
1106
+ );
1107
+ useEffect(() => {
1108
+ if (mode !== "system" || typeof window === "undefined" || !window.matchMedia) {
1109
+ return;
1110
+ }
1111
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1112
+ const handleChange = (e) => {
1113
+ setResolvedMode(e.matches ? "dark" : "light");
1114
+ };
1115
+ handleChange(mediaQuery);
1116
+ if (mediaQuery.addEventListener) {
1117
+ mediaQuery.addEventListener("change", handleChange);
1118
+ return () => mediaQuery.removeEventListener("change", handleChange);
1119
+ } else {
1120
+ mediaQuery.addListener(handleChange);
1121
+ return () => mediaQuery.removeListener(handleChange);
1122
+ }
1123
+ }, [mode]);
1124
+ useEffect(() => {
1125
+ if (mode !== "system") {
1126
+ setResolvedMode(mode === "dark" ? "dark" : "light");
1127
+ }
1128
+ }, [mode]);
1129
+ const theme = useMemo(() => {
1130
+ const effectiveMode = mode === "system" ? resolvedMode : mode;
1131
+ return createTheme(themeName, effectiveMode);
1132
+ }, [themeName, mode, resolvedMode]);
1133
+ useEffect(() => {
1134
+ if (storageKey && typeof window !== "undefined") {
1135
+ localStorage.setItem(storageKey, mode);
1136
+ window.dispatchEvent(new Event("theme-preference-changed"));
1137
+ }
1138
+ }, [mode, storageKey]);
1139
+ useEffect(() => {
1140
+ if (!storageKey || typeof window === "undefined") {
1141
+ return;
1142
+ }
1143
+ const handleStorage = (event) => {
1144
+ if (event.key === storageKey && event.newValue) {
1145
+ const newMode = parsePreference(event.newValue);
1146
+ setMode(newMode);
1147
+ }
1148
+ };
1149
+ window.addEventListener("storage", handleStorage);
1150
+ return () => window.removeEventListener("storage", handleStorage);
1151
+ }, [storageKey]);
1152
+ useEffect(() => {
1153
+ if (!storageKey || typeof window === "undefined") {
1154
+ return;
1155
+ }
1156
+ const handlePreferenceChange = () => {
1157
+ const stored = localStorage.getItem(storageKey);
1158
+ if (stored) {
1159
+ const newMode = parsePreference(stored);
1160
+ setMode(newMode);
1161
+ }
1162
+ };
1163
+ window.addEventListener("theme-preference-changed", handlePreferenceChange);
1164
+ return () => window.removeEventListener("theme-preference-changed", handlePreferenceChange);
1165
+ }, [storageKey]);
1166
+ useEffect(() => {
1167
+ setDesignSystemConfig({ adapter, theme: themeName, mode });
1168
+ }, [adapter, themeName, mode]);
1169
+ useEffect(() => {
1170
+ if (typeof window === "undefined" || typeof document === "undefined") {
1171
+ return;
1172
+ }
1173
+ const root = document.documentElement;
1174
+ const effectiveMode = mode === "system" ? resolvedMode : mode;
1175
+ const rafId = requestAnimationFrame(() => {
1176
+ if (effectiveMode === "dark") {
1177
+ root.classList.add("dark");
1178
+ } else {
1179
+ root.classList.remove("dark");
1180
+ }
1181
+ Object.entries(theme.cssVariables).forEach(([key, value]) => {
1182
+ if (!key.startsWith("--background-") && !key.startsWith("--content-") && !key.startsWith("--border-") && !key.startsWith("--intent-") && !key.startsWith("--surface-") && !key.startsWith("--text-") && !key.startsWith("--spacing-") && !key.startsWith("--radius-") && !key.startsWith("--shadow-") && !key.startsWith("--z-") && !key.startsWith("--font-") && !key.startsWith("--line-height-")) {
1183
+ root.style.setProperty(key, value);
1184
+ }
1185
+ });
1186
+ });
1187
+ return () => {
1188
+ cancelAnimationFrame(rafId);
1189
+ if (typeof document !== "undefined") {
1190
+ Object.keys(theme.cssVariables).forEach((key) => {
1191
+ if (!key.startsWith("--background-") && !key.startsWith("--content-") && !key.startsWith("--border-") && !key.startsWith("--intent-") && !key.startsWith("--surface-") && !key.startsWith("--text-") && !key.startsWith("--spacing-") && !key.startsWith("--radius-") && !key.startsWith("--shadow-") && !key.startsWith("--z-") && !key.startsWith("--font-") && !key.startsWith("--line-height-")) {
1192
+ document.documentElement.style.removeProperty(key);
1193
+ }
1194
+ });
1195
+ }
1196
+ };
1197
+ }, [theme, mode, resolvedMode]);
1198
+ useEffect(() => {
1199
+ if (typeof window === "undefined" || typeof document === "undefined") {
1200
+ return;
1201
+ }
1202
+ const body = document.body;
1203
+ const effectiveMode = mode === "system" ? resolvedMode : mode;
1204
+ const isDark = effectiveMode === "dark";
1205
+ body.classList.add("pd-root");
1206
+ if (isDark) {
1207
+ body.classList.add("pd-dark");
1208
+ } else {
1209
+ body.classList.remove("pd-dark");
1210
+ }
1211
+ if (mode === "system") {
1212
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1213
+ const handleSystemChange = (e) => {
1214
+ const systemIsDark = e.matches;
1215
+ if (systemIsDark) {
1216
+ body.classList.add("pd-dark");
1217
+ } else {
1218
+ body.classList.remove("pd-dark");
1219
+ }
1220
+ };
1221
+ handleSystemChange(mediaQuery);
1222
+ if (mediaQuery.addEventListener) {
1223
+ mediaQuery.addEventListener("change", handleSystemChange);
1224
+ return () => {
1225
+ mediaQuery.removeEventListener("change", handleSystemChange);
1226
+ body.classList.remove("pd-root", "pd-dark");
1227
+ };
1228
+ } else {
1229
+ mediaQuery.addListener(handleSystemChange);
1230
+ return () => {
1231
+ mediaQuery.removeListener(handleSystemChange);
1232
+ body.classList.remove("pd-root", "pd-dark");
1233
+ };
1234
+ }
1235
+ }
1236
+ return () => {
1237
+ body.classList.remove("pd-root", "pd-dark");
1238
+ };
1239
+ }, [mode, resolvedMode]);
1240
+ const [configState, setConfigState] = useState(() => getDesignSystemConfig());
1241
+ useEffect(() => {
1242
+ const currentConfig = getDesignSystemConfig();
1243
+ setConfigState(currentConfig);
1244
+ }, [adapter, themeName, mode]);
1245
+ const enhancedSetConfig = React.useCallback((newConfig) => {
1246
+ setDesignSystemConfig(newConfig);
1247
+ const updatedConfig = getDesignSystemConfig();
1248
+ setConfigState(updatedConfig);
1249
+ if (newConfig.mode && newConfig.mode !== mode) {
1250
+ setMode(newConfig.mode);
1251
+ }
1252
+ if (newConfig.mode && storageKey && typeof window !== "undefined") {
1253
+ localStorage.setItem(storageKey, newConfig.mode);
1254
+ window.dispatchEvent(new Event("theme-preference-changed"));
1255
+ }
1256
+ }, [storageKey, mode]);
1257
+ const contextValue = useMemo(() => ({
1258
+ config: configState,
1259
+ setConfig: enhancedSetConfig
1260
+ }), [configState, enhancedSetConfig]);
1261
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: contextValue, children });
1262
+ }
1263
+ function useTheme() {
1264
+ const context = useContext(ThemeContext);
1265
+ if (!context) {
1266
+ throw new Error("useTheme must be used within ThemeProvider");
1267
+ }
1268
+ return context;
1269
+ }
1270
+
1271
+ // src/tokens/semantic.ts
1272
+ var borderTokens = {
1273
+ light: semanticTokens.light.border,
1274
+ dark: semanticTokens.dark.border
1275
+ };
1276
+ var contentTokens = {
1277
+ light: semanticTokens.light.content,
1278
+ dark: semanticTokens.dark.content
1279
+ };
1280
+ var backgroundTokens = {
1281
+ light: semanticTokens.light.background,
1282
+ dark: semanticTokens.dark.background
1283
+ };
1284
+ function createSemanticTokens(mode) {
1285
+ const isLight = mode === "light";
1286
+ const border = isLight ? borderTokens.light : borderTokens.dark;
1287
+ const content = isLight ? contentTokens.light : contentTokens.dark;
1288
+ const background = isLight ? backgroundTokens.light : backgroundTokens.dark;
1289
+ return {
1290
+ intent: {
1291
+ primary: {
1292
+ color: content.secondary,
1293
+ colorHover: isLight ? neutral[700] : neutral[300],
1294
+ colorActive: isLight ? neutral[800] : neutral[200],
1295
+ background: background.secondary,
1296
+ backgroundHover: background.lowOnHover,
1297
+ backgroundActive: background.tertiary,
1298
+ border: border.primary,
1299
+ text: content.primary,
1300
+ textMuted: content.subtle
1301
+ },
1302
+ success: {
1303
+ color: isLight ? green[600] : green[600],
1304
+ colorHover: isLight ? green[700] : green[500],
1305
+ colorActive: isLight ? green[800] : green[700],
1306
+ background: background.green,
1307
+ backgroundHover: background.greenOnHover,
1308
+ backgroundActive: isLight ? green[300] : green[800],
1309
+ border: border.green,
1310
+ text: content.green,
1311
+ textMuted: isLight ? green[700] : green[300]
1312
+ },
1313
+ warning: {
1314
+ color: isLight ? yellow[600] : yellow[400],
1315
+ colorHover: isLight ? yellow[700] : yellow[300],
1316
+ colorActive: isLight ? yellow[800] : yellow[500],
1317
+ background: background.yellow,
1318
+ backgroundHover: background.yellowOnHover,
1319
+ backgroundActive: isLight ? yellow[200] : yellow[900],
1320
+ border: border.yellow,
1321
+ text: content.yellow,
1322
+ textMuted: isLight ? yellow[700] : yellow[300]
1323
+ },
1324
+ danger: {
1325
+ color: isLight ? red[600] : red[400],
1326
+ colorHover: isLight ? red[700] : red[300],
1327
+ colorActive: isLight ? red[800] : red[500],
1328
+ background: background.red,
1329
+ backgroundHover: background.redOnHover,
1330
+ backgroundActive: isLight ? red[200] : red[900],
1331
+ border: border.red,
1332
+ text: content.red,
1333
+ textMuted: isLight ? red[700] : red[300]
1334
+ },
1335
+ neutral: {
1336
+ color: content.secondary,
1337
+ colorHover: isLight ? neutral[700] : neutral[300],
1338
+ colorActive: isLight ? neutral[800] : neutral[200],
1339
+ background: background.secondary,
1340
+ backgroundHover: background.lowOnHover,
1341
+ backgroundActive: background.tertiary,
1342
+ border: border.primary,
1343
+ text: content.primary,
1344
+ textMuted: content.subtle
1345
+ }
1346
+ },
1347
+ surface: {
1348
+ base: {
1349
+ background: background.primary,
1350
+ border: border.primary
1351
+ },
1352
+ elevated: {
1353
+ background: background.secondary,
1354
+ border: border.secondary
1355
+ },
1356
+ overlay: {
1357
+ background: isLight ? "rgba(0, 0, 0, 0.5)" : "rgba(0, 0, 0, 0.7)",
1358
+ border: "transparent"
1359
+ }
1360
+ },
1361
+ text: {
1362
+ heading: content.primary,
1363
+ body: content.primary,
1364
+ muted: content.subtle,
1365
+ disabled: isLight ? content.subtle : neutral[600]
1366
+ }
1367
+ };
1368
+ }
1369
+
1370
+ // src/tokens/index.ts
1371
+ var tokens = {
1372
+ colors: {
1373
+ // Individual color scales
1374
+ neutral,
1375
+ blue,
1376
+ orange,
1377
+ red,
1378
+ green,
1379
+ yellow,
1380
+ // All colors grouped together
1381
+ all: colorPrimitives,
1382
+ // Legacy color names (for backward compatibility)
1383
+ legacy: colors
1384
+ },
1385
+ semantic: semanticTokens,
1386
+ spacing,
1387
+ typography,
1388
+ radius,
1389
+ shadows,
1390
+ zIndex
1391
+ };
1392
+ function extractTextFromChildren(children) {
1393
+ if (typeof children === "string") {
1394
+ return children.trim();
1395
+ }
1396
+ if (typeof children === "number") {
1397
+ return String(children);
1398
+ }
1399
+ if (Array.isArray(children)) {
1400
+ return children.map(extractTextFromChildren).join(" ").trim();
1401
+ }
1402
+ if (React.isValidElement(children) && children.props) {
1403
+ if (children.props.children) {
1404
+ return extractTextFromChildren(children.props.children);
1405
+ }
1406
+ }
1407
+ return "";
1408
+ }
1409
+ function validateAccessibilityProps(props, componentType, options = {}) {
1410
+ if (process.env.NODE_ENV === "production") {
1411
+ return;
1412
+ }
1413
+ const warnings = [];
1414
+ if (componentType === "button" && options.iconOnly && !props["aria-label"] && !props["aria-labelledby"]) {
1415
+ warnings.push(
1416
+ `[pd-design] Icon-only button should have an aria-label or aria-labelledby for accessibility.`
1417
+ );
1418
+ }
1419
+ if ((componentType === "button" || componentType === "link") && !props["aria-label"] && !props["aria-labelledby"] && !extractTextFromChildren(options.children)) {
1420
+ warnings.push(
1421
+ `[pd-design] ${componentType} should have an accessible name (aria-label, aria-labelledby, or text content).`
1422
+ );
1423
+ }
1424
+ if ((componentType === "input" || componentType === "select" || componentType === "textarea") && !props["aria-label"] && !props["aria-labelledby"]) {
1425
+ warnings.push(
1426
+ `[pd-design] ${componentType} should have an accessible label (aria-label or aria-labelledby).`
1427
+ );
1428
+ }
1429
+ if (props.tabIndex !== void 0 && props.tabIndex > 0) {
1430
+ warnings.push(
1431
+ `[pd-design] tabIndex > 0 is not recommended. Use tabIndex={0} for focusable elements or tabIndex={-1} for programmatic focus only.`
1432
+ );
1433
+ }
1434
+ warnings.forEach((warning) => console.warn(warning));
1435
+ }
1436
+
1437
+ export { ADAPTER_TYPES, BUTTON_TYPES, Button, COLOR_SCALES, DEFAULT_ADAPTER, DEFAULT_MODE, DEFAULT_THEME, ErrorBoundary, INPUT_TYPES, INTENTS, ORIENTATIONS, PdThemeProvider, SIZES, SURFACE_LEVELS, THEME_MODES, THEME_NAMES, ThemeProvider, VARIANTS, backgroundTokens, blue, borderTokens, button, colorPrimitives, colors, contentTokens, createSemanticTokens, createTheme, getAdapter, getAvailableIconNames, getDesignSystemConfig, getIcon, getThemeMode, getThemeName, green, iconExists, neutral, orange, radius, red, renderIcon, resolveThemeMode, semanticTokens, setDesignSystemConfig, shadows, spacing, tokens, typography, useTheme, validateAccessibilityProps, yellow, zIndex };
1438
+ //# sourceMappingURL=index.js.map
1439
+ //# sourceMappingURL=index.js.map