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