@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.3 → 0.1.5

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.
Files changed (164) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/index.d.ts +131 -131
  3. package/dist/index.esm.js +148 -148
  4. package/dist/index.js +148 -148
  5. package/dist/styles.css +1 -1
  6. package/package.json +1 -1
  7. package/src/components/ui/accessibility-demo.tsx +271 -0
  8. package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
  9. package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
  10. package/src/components/ui/advanced-transition-system.tsx +395 -0
  11. package/src/components/ui/animation/animated-container.tsx +166 -0
  12. package/src/components/ui/animation/index.ts +19 -0
  13. package/src/components/ui/animation/staggered-container.tsx +68 -0
  14. package/src/components/ui/animation-demo.tsx +250 -0
  15. package/src/components/ui/badge.tsx +33 -0
  16. package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
  17. package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
  18. package/src/components/ui/button.tsx +36 -0
  19. package/src/components/ui/card.tsx +207 -0
  20. package/src/components/ui/checkbox.tsx +30 -0
  21. package/src/components/ui/color-preview.tsx +411 -0
  22. package/src/components/ui/data-display/chart.tsx +653 -0
  23. package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
  24. package/src/components/ui/data-display/data-grid.tsx +680 -0
  25. package/src/components/ui/data-display/list.tsx +456 -0
  26. package/src/components/ui/data-display/table.tsx +482 -0
  27. package/src/components/ui/data-display/timeline.tsx +441 -0
  28. package/src/components/ui/data-display/tree.tsx +602 -0
  29. package/src/components/ui/data-display/types.ts +536 -0
  30. package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
  31. package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
  32. package/src/components/ui/feedback/alert.tsx +157 -0
  33. package/src/components/ui/feedback/progress.tsx +292 -0
  34. package/src/components/ui/feedback/skeleton.tsx +185 -0
  35. package/src/components/ui/feedback/toast.tsx +280 -0
  36. package/src/components/ui/feedback/types.ts +125 -0
  37. package/src/components/ui/font-preview.tsx +288 -0
  38. package/src/components/ui/form-demo.tsx +553 -0
  39. package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
  40. package/src/components/ui/input.tsx +35 -0
  41. package/src/components/ui/label.tsx +16 -0
  42. package/src/components/ui/layout-demo.tsx +367 -0
  43. package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
  44. package/src/components/ui/layouts/desktop-layout.tsx +224 -0
  45. package/src/components/ui/layouts/index.ts +10 -0
  46. package/src/components/ui/layouts/mobile-layout.tsx +162 -0
  47. package/src/components/ui/layouts/tablet-layout.tsx +197 -0
  48. package/src/components/ui/mobile-form-validation.tsx +451 -0
  49. package/src/components/ui/mobile-input-demo.tsx +201 -0
  50. package/src/components/ui/mobile-input.tsx +281 -0
  51. package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
  52. package/src/components/ui/navigation/breadcrumb.tsx +158 -0
  53. package/src/components/ui/navigation/index.ts +36 -0
  54. package/src/components/ui/navigation/menu.tsx +374 -0
  55. package/src/components/ui/navigation/navigation-demo.tsx +324 -0
  56. package/src/components/ui/navigation/pagination.tsx +272 -0
  57. package/src/components/ui/navigation/sidebar.tsx +383 -0
  58. package/src/components/ui/navigation/stepper.tsx +303 -0
  59. package/src/components/ui/navigation/tabs.tsx +205 -0
  60. package/src/components/ui/navigation/types.ts +299 -0
  61. package/src/components/ui/overlay/backdrop.tsx +81 -0
  62. package/src/components/ui/overlay/focus-manager.tsx +143 -0
  63. package/src/components/ui/overlay/index.ts +36 -0
  64. package/src/components/ui/overlay/modal.tsx +270 -0
  65. package/src/components/ui/overlay/overlay-manager.tsx +110 -0
  66. package/src/components/ui/overlay/popover.tsx +462 -0
  67. package/src/components/ui/overlay/portal.tsx +79 -0
  68. package/src/components/ui/overlay/tooltip.tsx +303 -0
  69. package/src/components/ui/overlay/types.ts +196 -0
  70. package/src/components/ui/performance-demo.tsx +596 -0
  71. package/src/components/ui/semantic-input-system-demo.tsx +502 -0
  72. package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
  73. package/src/components/ui/tablet-layout.tsx +192 -0
  74. package/src/components/ui/theme-customizer.tsx +386 -0
  75. package/src/components/ui/theme-preview.tsx +310 -0
  76. package/src/components/ui/theme-switcher.tsx +264 -0
  77. package/src/components/ui/theme-toggle.tsx +38 -0
  78. package/src/components/ui/token-demo.tsx +195 -0
  79. package/src/components/ui/touch-demo.tsx +462 -0
  80. package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
  81. package/src/components/ui/touch-friendly-interface.tsx +296 -0
  82. package/src/hooks/index.ts +190 -0
  83. package/src/hooks/use-accessibility-support.ts +518 -0
  84. package/src/hooks/use-adaptive-layout.ts +289 -0
  85. package/src/hooks/use-advanced-patterns.ts +294 -0
  86. package/src/hooks/use-advanced-transition-system.ts +393 -0
  87. package/src/hooks/use-animation-profile.ts +288 -0
  88. package/src/hooks/use-battery-animations.ts +384 -0
  89. package/src/hooks/use-battery-conscious-loading.ts +475 -0
  90. package/src/hooks/use-battery-optimization.ts +330 -0
  91. package/src/hooks/use-battery-status.ts +299 -0
  92. package/src/hooks/use-component-performance.ts +344 -0
  93. package/src/hooks/use-device-loading-states.ts +459 -0
  94. package/src/hooks/use-device.tsx +110 -0
  95. package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
  96. package/src/hooks/use-form-feedback.ts +403 -0
  97. package/src/hooks/use-form-performance.ts +513 -0
  98. package/src/hooks/use-frame-rate.ts +251 -0
  99. package/src/hooks/use-gestures.ts +338 -0
  100. package/src/hooks/use-hardware-acceleration.ts +341 -0
  101. package/src/hooks/use-input-accessibility.ts +455 -0
  102. package/src/hooks/use-input-performance.ts +506 -0
  103. package/src/hooks/use-layout-performance.ts +319 -0
  104. package/src/hooks/use-loading-accessibility.ts +535 -0
  105. package/src/hooks/use-loading-performance.ts +473 -0
  106. package/src/hooks/use-memory-usage.ts +287 -0
  107. package/src/hooks/use-mobile-form-layout.ts +464 -0
  108. package/src/hooks/use-mobile-form-validation.ts +518 -0
  109. package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
  110. package/src/hooks/use-mobile-layout.ts +302 -0
  111. package/src/hooks/use-mobile-optimization.ts +406 -0
  112. package/src/hooks/use-mobile-skeleton.ts +402 -0
  113. package/src/hooks/use-mobile-touch.ts +414 -0
  114. package/src/hooks/use-performance-throttling.ts +348 -0
  115. package/src/hooks/use-performance.ts +316 -0
  116. package/src/hooks/use-reusable-architecture.ts +414 -0
  117. package/src/hooks/use-semantic-input-types.ts +357 -0
  118. package/src/hooks/use-semantic-input.ts +565 -0
  119. package/src/hooks/use-tablet-layout.ts +384 -0
  120. package/src/hooks/use-touch-friendly-input.ts +524 -0
  121. package/src/hooks/use-touch-friendly-interface.ts +331 -0
  122. package/src/hooks/use-touch-optimization.ts +375 -0
  123. package/src/index.ts +279 -279
  124. package/src/lib/utils.ts +6 -0
  125. package/src/themes/README.md +272 -0
  126. package/src/themes/ThemeContext.tsx +31 -0
  127. package/src/themes/ThemeProvider.tsx +232 -0
  128. package/src/themes/accessibility/index.ts +27 -0
  129. package/src/themes/accessibility.ts +259 -0
  130. package/src/themes/aria-patterns.ts +420 -0
  131. package/src/themes/base-themes.ts +55 -0
  132. package/src/themes/colorManager.ts +380 -0
  133. package/src/themes/examples/dark-theme.ts +154 -0
  134. package/src/themes/examples/minimal-theme.ts +108 -0
  135. package/src/themes/focus-management.ts +701 -0
  136. package/src/themes/fontLoader.ts +201 -0
  137. package/src/themes/high-contrast.ts +621 -0
  138. package/src/themes/index.ts +19 -0
  139. package/src/themes/inheritance.ts +227 -0
  140. package/src/themes/keyboard-navigation.ts +550 -0
  141. package/src/themes/motion-reduction.ts +662 -0
  142. package/src/themes/navigation.ts +238 -0
  143. package/src/themes/screen-reader.ts +645 -0
  144. package/src/themes/systemThemeDetector.ts +182 -0
  145. package/src/themes/themeCSSUpdater.ts +262 -0
  146. package/src/themes/themePersistence.ts +238 -0
  147. package/src/themes/themes/default.ts +586 -0
  148. package/src/themes/themes/harvey.ts +554 -0
  149. package/src/themes/themes/stan-design.ts +683 -0
  150. package/src/themes/types.ts +460 -0
  151. package/src/themes/useSystemTheme.ts +48 -0
  152. package/src/themes/useTheme.ts +87 -0
  153. package/src/themes/validation.ts +462 -0
  154. package/src/tokens/index.ts +34 -0
  155. package/src/tokens/tokenExporter.ts +397 -0
  156. package/src/tokens/tokenGenerator.ts +276 -0
  157. package/src/tokens/tokenManager.ts +248 -0
  158. package/src/tokens/tokenValidator.ts +543 -0
  159. package/src/tokens/types.ts +78 -0
  160. package/src/utils/bundle-analyzer.ts +260 -0
  161. package/src/utils/bundle-splitting.ts +483 -0
  162. package/src/utils/lazy-loading.ts +441 -0
  163. package/src/utils/performance-monitor.ts +513 -0
  164. package/src/utils/tree-shaking.ts +274 -0
@@ -0,0 +1,280 @@
1
+ import React, { useState, useEffect, useCallback, useRef } from 'react';
2
+ import { ToastProps, ToastAction, ToastContainerProps } from './types';
3
+
4
+ // Simple icon components
5
+ const CheckCircleIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
6
+ <svg className={className} fill="currentColor" viewBox="0 0 20 20">
7
+ <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
8
+ </svg>
9
+ );
10
+
11
+ const ExclamationTriangleIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
12
+ <svg className={className} fill="currentColor" viewBox="0 0 20 20">
13
+ <path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
14
+ </svg>
15
+ );
16
+
17
+ const XCircleIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
18
+ <svg className={className} fill="currentColor" viewBox="0 0 20 20">
19
+ <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
20
+ </svg>
21
+ );
22
+
23
+ const InformationCircleIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
24
+ <svg className={className} fill="currentColor" viewBox="0 0 20 20">
25
+ <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
26
+ </svg>
27
+ );
28
+
29
+ const XMarkIcon: React.FC<{ className?: string }> = ({ className = '' }) => (
30
+ <svg className={className} fill="currentColor" viewBox="0 0 20 20">
31
+ <path fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clipRule="evenodd" />
32
+ </svg>
33
+ );
34
+
35
+ // Get icon for toast type
36
+ const getToastIcon = (type: ToastProps['type'], className: string) => {
37
+ switch (type) {
38
+ case 'success':
39
+ return <CheckCircleIcon className={className} />;
40
+ case 'warning':
41
+ return <ExclamationTriangleIcon className={className} />;
42
+ case 'error':
43
+ return <XCircleIcon className={className} />;
44
+ case 'info':
45
+ return <InformationCircleIcon className={className} />;
46
+ default:
47
+ return null;
48
+ }
49
+ };
50
+
51
+ // Note: getToastColors function removed as we're using semantic CSS classes
52
+ /*
53
+ const getToastColors = (type: ToastProps['type'], colors: any) => {
54
+ switch (type) {
55
+ case 'success':
56
+ return {
57
+ background: colors.semantic.success + '10',
58
+ border: colors.semantic.success + '30',
59
+ text: colors.semantic.success,
60
+ icon: colors.semantic.success
61
+ };
62
+ case 'warning':
63
+ return {
64
+ background: colors.semantic.warning + '10',
65
+ border: colors.semantic.warning + '30',
66
+ text: colors.semantic.warning,
67
+ icon: colors.semantic.warning
68
+ };
69
+ case 'error':
70
+ return {
71
+ background: colors.semantic.error + '10',
72
+ border: colors.semantic.error + '30',
73
+ text: colors.semantic.error,
74
+ icon: colors.semantic.error
75
+ };
76
+ case 'info':
77
+ return {
78
+ background: colors.semantic.info + '10',
79
+ border: colors.semantic.info + '30',
80
+ text: colors.semantic.info,
81
+ icon: colors.semantic.info
82
+ };
83
+ default:
84
+ return {
85
+ background: colors.surface.surface,
86
+ border: colors.surface.border,
87
+ text: colors.text.primary,
88
+ icon: colors.text.secondary
89
+ };
90
+ }
91
+ };
92
+ */
93
+
94
+ // Toast Action Button Component
95
+ const ToastActionButton: React.FC<ToastAction> = ({
96
+ label,
97
+ action,
98
+ variant = 'primary'
99
+ }) => {
100
+ return (
101
+ <button
102
+ type="button"
103
+ className={`toast__action-button toast__action-button--${variant}`}
104
+ onClick={() => action}
105
+ >
106
+ {label}
107
+ </button>
108
+ );
109
+ };
110
+
111
+ // Individual Toast Component
112
+ export const Toast: React.FC<ToastProps> = ({
113
+ title,
114
+ message,
115
+ type = 'default',
116
+ duration = 5000,
117
+ onClose,
118
+ actions = [],
119
+ icon,
120
+ showIcon = true,
121
+ closable = true,
122
+ autoClose = true,
123
+ pauseOnHover = true,
124
+ progress = false,
125
+ size = 'md',
126
+ variant = 'default',
127
+ className = '',
128
+ }) => {
129
+ // Note: theme and colors not needed as we're using semantic CSS classes
130
+
131
+ const [isVisible, setIsVisible] = useState(true);
132
+ const [progressValue, setProgressValue] = useState(100);
133
+ const timeoutRef = useRef<NodeJS.Timeout | null>(null);
134
+ const progressRef = useRef<NodeJS.Timeout | null>(null);
135
+
136
+ const handleClose = useCallback(() => {
137
+ setIsVisible(false);
138
+ if (onClose) {
139
+ onClose();
140
+ }
141
+ }, [onClose]);
142
+
143
+ const handleMouseEnter = useCallback(() => {
144
+ if (pauseOnHover && autoClose) {
145
+ if (timeoutRef.current) {
146
+ clearTimeout(timeoutRef.current);
147
+ }
148
+ if (progressRef.current) {
149
+ clearInterval(progressRef.current);
150
+ }
151
+ }
152
+ }, [pauseOnHover, autoClose]);
153
+
154
+ const handleMouseLeave = useCallback(() => {
155
+ if (pauseOnHover && autoClose) {
156
+ startAutoClose();
157
+ }
158
+ }, [pauseOnHover, autoClose]);
159
+
160
+ const startAutoClose = useCallback(() => {
161
+ if (duration > 0 && autoClose) {
162
+ timeoutRef.current = setTimeout(() => {
163
+ handleClose();
164
+ }, duration);
165
+
166
+ if (progress) {
167
+ const startTime = Date.now();
168
+ const endTime = startTime + duration;
169
+
170
+ progressRef.current = setInterval(() => {
171
+ const now = Date.now();
172
+ const remaining = Math.max(0, endTime - now);
173
+ const newProgress = (remaining / duration) * 100;
174
+ setProgressValue(newProgress);
175
+
176
+ if (remaining <= 0) {
177
+ if (progressRef.current) {
178
+ clearInterval(progressRef.current);
179
+ }
180
+ }
181
+ }, 10);
182
+ }
183
+ }
184
+ }, [duration, autoClose, progress, handleClose]);
185
+
186
+ useEffect(() => {
187
+ startAutoClose();
188
+
189
+ return () => {
190
+ if (timeoutRef.current) {
191
+ clearTimeout(timeoutRef.current);
192
+ }
193
+ if (progressRef.current) {
194
+ clearInterval(progressRef.current);
195
+ }
196
+ };
197
+ }, [startAutoClose]);
198
+
199
+ if (!isVisible) {
200
+ return null;
201
+ }
202
+
203
+ const shouldShowIcon = showIcon && (icon || type);
204
+
205
+ return (
206
+ <div
207
+ className={`toast__container toast__container--${size} toast__container--${variant} toast__container--${type} ${className}`}
208
+ role="alert"
209
+ aria-live="polite"
210
+ onMouseEnter={handleMouseEnter}
211
+ onMouseLeave={handleMouseLeave}
212
+ >
213
+ {progress && (
214
+ <div className="toast__progress">
215
+ <div
216
+ className={`toast__progress-bar toast__progress-bar--${type}`}
217
+ style={{ width: `${progressValue}%` }}
218
+ />
219
+ </div>
220
+ )}
221
+
222
+ {shouldShowIcon && (
223
+ <div className={`toast__icon toast__icon--${type}`}>
224
+ {icon || getToastIcon(type, 'toast__icon')}
225
+ </div>
226
+ )}
227
+
228
+ <div className="toast__content">
229
+ {title && (
230
+ <h3 className="toast__title">
231
+ {title}
232
+ </h3>
233
+ )}
234
+
235
+ <div className={`toast__message ${!title ? 'toast__message--only' : ''}`}>
236
+ {message}
237
+ </div>
238
+
239
+ {actions.length > 0 && (
240
+ <div className="toast__actions">
241
+ {actions.map((action, index) => (
242
+ <ToastActionButton
243
+ key={index}
244
+ {...action}
245
+ />
246
+ ))}
247
+ </div>
248
+ )}
249
+ </div>
250
+
251
+ {closable && (
252
+ <button
253
+ type="button"
254
+ className="toast__close-button"
255
+ onClick={handleClose}
256
+ aria-label="Close toast"
257
+ >
258
+ <XMarkIcon className="toast__close-icon" />
259
+ </button>
260
+ )}
261
+ </div>
262
+ );
263
+ };
264
+
265
+ // Toast Container Component
266
+ export const ToastContainer: React.FC<ToastContainerProps & { children: React.ReactNode }> = ({
267
+ position = 'top-right',
268
+ className = '',
269
+ children
270
+ }) => {
271
+ return (
272
+ <div className={`toast-container toast-container--${position} ${className}`}>
273
+ <div className="toast-container__list">
274
+ {children}
275
+ </div>
276
+ </div>
277
+ );
278
+ };
279
+
280
+ export default Toast;
@@ -0,0 +1,125 @@
1
+ import React from 'react';
2
+
3
+ // Base props for all feedback components
4
+ export interface FeedbackBaseProps {
5
+ className?: string;
6
+ theme?: 'stan-design' | 'harvey';
7
+ }
8
+
9
+ // Alert Component Types
10
+ export interface AlertProps extends FeedbackBaseProps {
11
+ title?: string;
12
+ message: string;
13
+ type: 'success' | 'warning' | 'error' | 'info';
14
+ dismissible?: boolean;
15
+ onDismiss?: () => void;
16
+ icon?: React.ReactNode;
17
+ actions?: AlertAction[];
18
+ showIcon?: boolean;
19
+ closable?: boolean;
20
+ persistent?: boolean;
21
+ size?: 'sm' | 'md' | 'lg';
22
+ variant?: 'default' | 'bordered' | 'filled';
23
+ }
24
+
25
+ export interface AlertAction {
26
+ label: string;
27
+ onClick: () => void;
28
+ variant?: 'primary' | 'secondary' | 'ghost';
29
+ size?: 'sm' | 'md' | 'lg';
30
+ }
31
+
32
+ // Toast Component Types
33
+ export interface ToastProps extends FeedbackBaseProps {
34
+ id: string;
35
+ title?: string;
36
+ message: string;
37
+ type: 'success' | 'warning' | 'error' | 'info' | 'default';
38
+ duration?: number; // milliseconds, 0 = persistent
39
+ onClose?: () => void;
40
+ onAction?: (action: string) => void;
41
+ actions?: ToastAction[];
42
+ icon?: React.ReactNode;
43
+ showIcon?: boolean;
44
+ closable?: boolean;
45
+ position?: 'top-left' | 'top-right' | 'top-center' | 'bottom-left' | 'bottom-right' | 'bottom-center';
46
+ autoClose?: boolean;
47
+ pauseOnHover?: boolean;
48
+ draggable?: boolean;
49
+ progress?: boolean;
50
+ size?: 'sm' | 'md' | 'lg';
51
+ variant?: 'default' | 'bordered' | 'filled';
52
+ }
53
+
54
+ export interface ToastAction {
55
+ label: string;
56
+ action: string;
57
+ variant?: 'primary' | 'secondary' | 'ghost';
58
+ }
59
+
60
+ export interface ToastContainerProps {
61
+ position?: ToastProps['position'];
62
+ maxToasts?: number;
63
+ autoClose?: boolean;
64
+ pauseOnHover?: boolean;
65
+ draggable?: boolean;
66
+ progress?: boolean;
67
+ className?: string;
68
+ theme?: 'stan-design' | 'harvey';
69
+ }
70
+
71
+ // Progress Component Types
72
+ export interface ProgressProps extends FeedbackBaseProps {
73
+ value: number; // 0-100
74
+ max?: number;
75
+ min?: number;
76
+ label?: string;
77
+ showLabel?: boolean;
78
+ showValue?: boolean;
79
+ showPercentage?: boolean;
80
+ animated?: boolean;
81
+ striped?: boolean;
82
+ color?: string;
83
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
84
+ variant?: 'linear' | 'circular' | 'steps';
85
+ thickness?: number;
86
+ trackColor?: string;
87
+ progressColor?: string;
88
+ indeterminate?: boolean;
89
+ onComplete?: () => void;
90
+ }
91
+
92
+ export interface ProgressStep {
93
+ label: string;
94
+ value: number;
95
+ status: 'pending' | 'active' | 'completed' | 'error';
96
+ description?: string;
97
+ }
98
+
99
+ // Skeleton Component Types
100
+ export interface SkeletonProps extends FeedbackBaseProps {
101
+ width?: string | number;
102
+ height?: string | number;
103
+ variant?: 'text' | 'circular' | 'rectangular' | 'rounded';
104
+ animation?: 'pulse' | 'wave' | 'none';
105
+ rows?: number;
106
+ spacing?: number;
107
+ show?: boolean;
108
+ className?: string;
109
+ size?: 'sm' | 'md' | 'lg' | 'xl';
110
+ }
111
+
112
+ export interface SkeletonTextProps extends SkeletonProps {
113
+ lines?: number;
114
+ lineHeight?: string | number;
115
+ lastLineWidth?: string | number;
116
+ }
117
+
118
+ export interface SkeletonAvatarProps extends SkeletonProps {
119
+ size?: 'sm' | 'md' | 'lg' | 'xl';
120
+ shape?: 'circular' | 'square' | 'rounded';
121
+ }
122
+
123
+ export interface SkeletonButtonProps extends SkeletonProps {
124
+ fullWidth?: boolean;
125
+ }
@@ -0,0 +1,288 @@
1
+ import React from 'react';
2
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from './card';
3
+ import { Badge } from './badge';
4
+ import { useTheme } from '../../themes';
5
+ import { FontConfig } from '../../themes/types';
6
+
7
+ export interface FontPreviewProps {
8
+ fontConfig?: FontConfig;
9
+ fontType?: 'primary' | 'secondary' | 'display' | 'body' | 'mono';
10
+ showAllVariations?: boolean;
11
+ className?: string;
12
+ }
13
+
14
+ export const FontPreview: React.FC<FontPreviewProps> = ({
15
+ fontConfig,
16
+ fontType = 'primary',
17
+ showAllVariations = false,
18
+ className = ''
19
+ }) => {
20
+ const { currentThemeConfig } = useTheme();
21
+
22
+ // Use provided fontConfig or get from current theme
23
+ const config = fontConfig || currentThemeConfig?.fonts[fontType];
24
+
25
+ if (!config) {
26
+ return (
27
+ <Card className={className}>
28
+ <CardContent className="p-4">
29
+ <p className="text-sm text-muted-foreground">Font configuration not available</p>
30
+ </CardContent>
31
+ </Card>
32
+ );
33
+ }
34
+
35
+ const { family, weights, sizes, lineHeights, letterSpacing, fallbacks, source } = config;
36
+
37
+ // Build full font family string with fallbacks
38
+ const fullFontFamily = fallbacks
39
+ ? `${family}, ${fallbacks.join(', ')}`
40
+ : family;
41
+
42
+ // Sample text for preview
43
+ const sampleText = "The quick brown fox jumps over the lazy dog";
44
+ const sampleNumbers = "1234567890";
45
+ const sampleSpecial = "!@#$%^&*()_+-={}[]|\\:;\"'<>,.?/";
46
+
47
+ return (
48
+ <Card className={className}>
49
+ <CardHeader>
50
+ <CardTitle className="flex items-center justify-between">
51
+ <span className="capitalize">{fontType} Font</span>
52
+ <div className="flex gap-2">
53
+ {source && (
54
+ <Badge variant="outline" className="text-xs">
55
+ {source.type}
56
+ </Badge>
57
+ )}
58
+ <Badge variant="secondary" className="text-xs">
59
+ {weights?.length || 0} weights
60
+ </Badge>
61
+ </div>
62
+ </CardTitle>
63
+ <CardDescription>
64
+ <span className="font-mono text-xs">{family}</span>
65
+ {fallbacks && fallbacks.length > 0 && (
66
+ <div className="mt-1 text-xs text-muted-foreground">
67
+ Fallbacks: {fallbacks.slice(0, 3).join(', ')}
68
+ {fallbacks.length > 3 && ` (+${fallbacks.length - 3} more)`}
69
+ </div>
70
+ )}
71
+ </CardDescription>
72
+ </CardHeader>
73
+
74
+ <CardContent className="space-y-6">
75
+ {/* Font Weights Preview */}
76
+ <div>
77
+ <h4 className="text-sm font-medium mb-3">Font Weights</h4>
78
+ <div className="space-y-2">
79
+ {weights?.map(weight => (
80
+ <div key={weight} className="flex items-center gap-4">
81
+ <Badge variant="outline" className="text-xs w-12 justify-center">
82
+ {weight}
83
+ </Badge>
84
+ <p
85
+ style={{
86
+ fontFamily: fullFontFamily,
87
+ fontWeight: weight,
88
+ fontSize: sizes?.md || '1rem'
89
+ }}
90
+ className="flex-1"
91
+ >
92
+ {sampleText}
93
+ </p>
94
+ </div>
95
+ ))}
96
+ </div>
97
+ </div>
98
+
99
+ {showAllVariations && (
100
+ <>
101
+ {/* Font Sizes Preview */}
102
+ <div>
103
+ <h4 className="text-sm font-medium mb-3">Font Sizes</h4>
104
+ <div className="space-y-2">
105
+ {Object.entries(sizes || {}).map(([size, value]) => (
106
+ <div key={size} className="flex items-center gap-4">
107
+ <Badge variant="outline" className="text-xs w-12 justify-center">
108
+ {size}
109
+ </Badge>
110
+ <span className="text-xs text-muted-foreground w-16">{value}</span>
111
+ <p
112
+ style={{
113
+ fontFamily: fullFontFamily,
114
+ fontSize: value,
115
+ fontWeight: weights?.[0] || 400
116
+ }}
117
+ >
118
+ Sample text
119
+ </p>
120
+ </div>
121
+ ))}
122
+ </div>
123
+ </div>
124
+
125
+ {/* Line Heights Preview */}
126
+ <div>
127
+ <h4 className="text-sm font-medium mb-3">Line Heights</h4>
128
+ <div className="space-y-4">
129
+ {Object.entries(lineHeights || {}).map(([height, value]) => (
130
+ <div key={height} className="space-y-2">
131
+ <div className="flex items-center gap-2">
132
+ <Badge variant="outline" className="text-xs">
133
+ {height}
134
+ </Badge>
135
+ <span className="text-xs text-muted-foreground">{value}</span>
136
+ </div>
137
+ <p
138
+ style={{
139
+ fontFamily: fullFontFamily,
140
+ fontSize: sizes?.md || '1rem',
141
+ lineHeight: value,
142
+ fontWeight: weights?.[0] || 400
143
+ }}
144
+ className="text-sm border-l-2 border-muted pl-4"
145
+ >
146
+ This is a multiline text example to demonstrate how line height affects the spacing between lines of text.
147
+ The line height setting controls the vertical space between each line, which is crucial for readability and
148
+ overall typography appearance.
149
+ </p>
150
+ </div>
151
+ ))}
152
+ </div>
153
+ </div>
154
+
155
+ {/* Letter Spacing Preview */}
156
+ <div>
157
+ <h4 className="text-sm font-medium mb-3">Letter Spacing</h4>
158
+ <div className="space-y-2">
159
+ {Object.entries(letterSpacing || {}).map(([spacing, value]) => (
160
+ <div key={spacing} className="flex items-center gap-4">
161
+ <Badge variant="outline" className="text-xs w-16 justify-center">
162
+ {spacing}
163
+ </Badge>
164
+ <span className="text-xs text-muted-foreground w-16">{value}</span>
165
+ <p
166
+ style={{
167
+ fontFamily: fullFontFamily,
168
+ fontSize: sizes?.md || '1rem',
169
+ letterSpacing: value,
170
+ fontWeight: weights?.[0] || 400
171
+ }}
172
+ className="flex-1"
173
+ >
174
+ Letter spacing example
175
+ </p>
176
+ </div>
177
+ ))}
178
+ </div>
179
+ </div>
180
+ </>
181
+ )}
182
+
183
+ {/* Character Set Preview */}
184
+ <div>
185
+ <h4 className="text-sm font-medium mb-3">Character Support</h4>
186
+ <div className="space-y-3">
187
+ <div>
188
+ <span className="text-xs text-muted-foreground block mb-1">Alphabet</span>
189
+ <p
190
+ style={{
191
+ fontFamily: fullFontFamily,
192
+ fontSize: sizes?.md || '1rem',
193
+ fontWeight: weights?.[0] || 400
194
+ }}
195
+ className="text-sm"
196
+ >
197
+ {sampleText}
198
+ </p>
199
+ </div>
200
+
201
+ <div>
202
+ <span className="text-xs text-muted-foreground block mb-1">Numbers</span>
203
+ <p
204
+ style={{
205
+ fontFamily: fullFontFamily,
206
+ fontSize: sizes?.lg || '1.125rem',
207
+ fontWeight: weights?.[0] || 400,
208
+ letterSpacing: letterSpacing?.wide || '0.025em'
209
+ }}
210
+ className="text-sm"
211
+ >
212
+ {sampleNumbers}
213
+ </p>
214
+ </div>
215
+
216
+ <div>
217
+ <span className="text-xs text-muted-foreground block mb-1">Special Characters</span>
218
+ <p
219
+ style={{
220
+ fontFamily: fullFontFamily,
221
+ fontSize: sizes?.sm || '0.875rem',
222
+ fontWeight: weights?.[0] || 400
223
+ }}
224
+ className="text-sm"
225
+ >
226
+ {sampleSpecial}
227
+ </p>
228
+ </div>
229
+ </div>
230
+ </div>
231
+
232
+ {/* Font Loading Information */}
233
+ {source && (
234
+ <div className="pt-4 border-t">
235
+ <h4 className="text-sm font-medium mb-2">Font Loading</h4>
236
+ <div className="space-y-1 text-xs text-muted-foreground">
237
+ <div>Source: <span className="capitalize">{source.type}</span></div>
238
+ {source.url && <div>URL: {source.url}</div>}
239
+ {source.files && (
240
+ <div>
241
+ Files: {Object.keys(source.files).join(', ')}
242
+ </div>
243
+ )}
244
+ {config.display && (
245
+ <div>Display: {config.display}</div>
246
+ )}
247
+ </div>
248
+ </div>
249
+ )}
250
+ </CardContent>
251
+ </Card>
252
+ );
253
+ };
254
+
255
+ // Multi-font preview component
256
+ export interface FontShowcaseProps {
257
+ showAllVariations?: boolean;
258
+ className?: string;
259
+ }
260
+
261
+ export const FontShowcase: React.FC<FontShowcaseProps> = ({
262
+ showAllVariations = false,
263
+ className = ''
264
+ }) => {
265
+ const { currentThemeConfig } = useTheme();
266
+
267
+ if (!currentThemeConfig?.fonts) {
268
+ return (
269
+ <div className={className}>
270
+ <p className="text-sm text-muted-foreground">No font configuration available</p>
271
+ </div>
272
+ );
273
+ }
274
+
275
+ const fontTypes: Array<keyof typeof currentThemeConfig.fonts> = ['primary', 'secondary', 'display', 'body', 'mono'];
276
+
277
+ return (
278
+ <div className={`space-y-6 ${className}`}>
279
+ {fontTypes.map(fontType => (
280
+ <FontPreview
281
+ key={fontType}
282
+ fontType={fontType}
283
+ showAllVariations={showAllVariations}
284
+ />
285
+ ))}
286
+ </div>
287
+ );
288
+ };