@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.
- package/CHANGELOG.md +1 -1
- package/dist/index.d.ts +131 -131
- package/dist/index.esm.js +148 -148
- package/dist/index.js +148 -148
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/ui/accessibility-demo.tsx +271 -0
- package/src/components/ui/advanced-component-architecture-demo.tsx +916 -0
- package/src/components/ui/advanced-transition-system-demo.tsx +670 -0
- package/src/components/ui/advanced-transition-system.tsx +395 -0
- package/src/components/ui/animation/animated-container.tsx +166 -0
- package/src/components/ui/animation/index.ts +19 -0
- package/src/components/ui/animation/staggered-container.tsx +68 -0
- package/src/components/ui/animation-demo.tsx +250 -0
- package/src/components/ui/badge.tsx +33 -0
- package/src/components/ui/battery-conscious-animation-demo.tsx +568 -0
- package/src/components/ui/border-radius-shadow-demo.tsx +187 -0
- package/src/components/ui/button.tsx +36 -0
- package/src/components/ui/card.tsx +207 -0
- package/src/components/ui/checkbox.tsx +30 -0
- package/src/components/ui/color-preview.tsx +411 -0
- package/src/components/ui/data-display/chart.tsx +653 -0
- package/src/components/ui/data-display/data-grid-simple.tsx +76 -0
- package/src/components/ui/data-display/data-grid.tsx +680 -0
- package/src/components/ui/data-display/list.tsx +456 -0
- package/src/components/ui/data-display/table.tsx +482 -0
- package/src/components/ui/data-display/timeline.tsx +441 -0
- package/src/components/ui/data-display/tree.tsx +602 -0
- package/src/components/ui/data-display/types.ts +536 -0
- package/src/components/ui/enterprise-mobile-experience-demo.tsx +749 -0
- package/src/components/ui/enterprise-mobile-experience.tsx +464 -0
- package/src/components/ui/feedback/alert.tsx +157 -0
- package/src/components/ui/feedback/progress.tsx +292 -0
- package/src/components/ui/feedback/skeleton.tsx +185 -0
- package/src/components/ui/feedback/toast.tsx +280 -0
- package/src/components/ui/feedback/types.ts +125 -0
- package/src/components/ui/font-preview.tsx +288 -0
- package/src/components/ui/form-demo.tsx +553 -0
- package/src/components/ui/hardware-acceleration-demo.tsx +547 -0
- package/src/components/ui/input.tsx +35 -0
- package/src/components/ui/label.tsx +16 -0
- package/src/components/ui/layout-demo.tsx +367 -0
- package/src/components/ui/layouts/adaptive-layout.tsx +139 -0
- package/src/components/ui/layouts/desktop-layout.tsx +224 -0
- package/src/components/ui/layouts/index.ts +10 -0
- package/src/components/ui/layouts/mobile-layout.tsx +162 -0
- package/src/components/ui/layouts/tablet-layout.tsx +197 -0
- package/src/components/ui/mobile-form-validation.tsx +451 -0
- package/src/components/ui/mobile-input-demo.tsx +201 -0
- package/src/components/ui/mobile-input.tsx +281 -0
- package/src/components/ui/mobile-skeleton-loading-demo.tsx +638 -0
- package/src/components/ui/navigation/breadcrumb.tsx +158 -0
- package/src/components/ui/navigation/index.ts +36 -0
- package/src/components/ui/navigation/menu.tsx +374 -0
- package/src/components/ui/navigation/navigation-demo.tsx +324 -0
- package/src/components/ui/navigation/pagination.tsx +272 -0
- package/src/components/ui/navigation/sidebar.tsx +383 -0
- package/src/components/ui/navigation/stepper.tsx +303 -0
- package/src/components/ui/navigation/tabs.tsx +205 -0
- package/src/components/ui/navigation/types.ts +299 -0
- package/src/components/ui/overlay/backdrop.tsx +81 -0
- package/src/components/ui/overlay/focus-manager.tsx +143 -0
- package/src/components/ui/overlay/index.ts +36 -0
- package/src/components/ui/overlay/modal.tsx +270 -0
- package/src/components/ui/overlay/overlay-manager.tsx +110 -0
- package/src/components/ui/overlay/popover.tsx +462 -0
- package/src/components/ui/overlay/portal.tsx +79 -0
- package/src/components/ui/overlay/tooltip.tsx +303 -0
- package/src/components/ui/overlay/types.ts +196 -0
- package/src/components/ui/performance-demo.tsx +596 -0
- package/src/components/ui/semantic-input-system-demo.tsx +502 -0
- package/src/components/ui/semantic-input-system-demo.tsx.disabled +873 -0
- package/src/components/ui/tablet-layout.tsx +192 -0
- package/src/components/ui/theme-customizer.tsx +386 -0
- package/src/components/ui/theme-preview.tsx +310 -0
- package/src/components/ui/theme-switcher.tsx +264 -0
- package/src/components/ui/theme-toggle.tsx +38 -0
- package/src/components/ui/token-demo.tsx +195 -0
- package/src/components/ui/touch-demo.tsx +462 -0
- package/src/components/ui/touch-friendly-interface-demo.tsx +519 -0
- package/src/components/ui/touch-friendly-interface.tsx +296 -0
- package/src/hooks/index.ts +190 -0
- package/src/hooks/use-accessibility-support.ts +518 -0
- package/src/hooks/use-adaptive-layout.ts +289 -0
- package/src/hooks/use-advanced-patterns.ts +294 -0
- package/src/hooks/use-advanced-transition-system.ts +393 -0
- package/src/hooks/use-animation-profile.ts +288 -0
- package/src/hooks/use-battery-animations.ts +384 -0
- package/src/hooks/use-battery-conscious-loading.ts +475 -0
- package/src/hooks/use-battery-optimization.ts +330 -0
- package/src/hooks/use-battery-status.ts +299 -0
- package/src/hooks/use-component-performance.ts +344 -0
- package/src/hooks/use-device-loading-states.ts +459 -0
- package/src/hooks/use-device.tsx +110 -0
- package/src/hooks/use-enterprise-mobile-experience.ts +488 -0
- package/src/hooks/use-form-feedback.ts +403 -0
- package/src/hooks/use-form-performance.ts +513 -0
- package/src/hooks/use-frame-rate.ts +251 -0
- package/src/hooks/use-gestures.ts +338 -0
- package/src/hooks/use-hardware-acceleration.ts +341 -0
- package/src/hooks/use-input-accessibility.ts +455 -0
- package/src/hooks/use-input-performance.ts +506 -0
- package/src/hooks/use-layout-performance.ts +319 -0
- package/src/hooks/use-loading-accessibility.ts +535 -0
- package/src/hooks/use-loading-performance.ts +473 -0
- package/src/hooks/use-memory-usage.ts +287 -0
- package/src/hooks/use-mobile-form-layout.ts +464 -0
- package/src/hooks/use-mobile-form-validation.ts +518 -0
- package/src/hooks/use-mobile-keyboard-optimization.ts +472 -0
- package/src/hooks/use-mobile-layout.ts +302 -0
- package/src/hooks/use-mobile-optimization.ts +406 -0
- package/src/hooks/use-mobile-skeleton.ts +402 -0
- package/src/hooks/use-mobile-touch.ts +414 -0
- package/src/hooks/use-performance-throttling.ts +348 -0
- package/src/hooks/use-performance.ts +316 -0
- package/src/hooks/use-reusable-architecture.ts +414 -0
- package/src/hooks/use-semantic-input-types.ts +357 -0
- package/src/hooks/use-semantic-input.ts +565 -0
- package/src/hooks/use-tablet-layout.ts +384 -0
- package/src/hooks/use-touch-friendly-input.ts +524 -0
- package/src/hooks/use-touch-friendly-interface.ts +331 -0
- package/src/hooks/use-touch-optimization.ts +375 -0
- package/src/index.ts +279 -279
- package/src/lib/utils.ts +6 -0
- package/src/themes/README.md +272 -0
- package/src/themes/ThemeContext.tsx +31 -0
- package/src/themes/ThemeProvider.tsx +232 -0
- package/src/themes/accessibility/index.ts +27 -0
- package/src/themes/accessibility.ts +259 -0
- package/src/themes/aria-patterns.ts +420 -0
- package/src/themes/base-themes.ts +55 -0
- package/src/themes/colorManager.ts +380 -0
- package/src/themes/examples/dark-theme.ts +154 -0
- package/src/themes/examples/minimal-theme.ts +108 -0
- package/src/themes/focus-management.ts +701 -0
- package/src/themes/fontLoader.ts +201 -0
- package/src/themes/high-contrast.ts +621 -0
- package/src/themes/index.ts +19 -0
- package/src/themes/inheritance.ts +227 -0
- package/src/themes/keyboard-navigation.ts +550 -0
- package/src/themes/motion-reduction.ts +662 -0
- package/src/themes/navigation.ts +238 -0
- package/src/themes/screen-reader.ts +645 -0
- package/src/themes/systemThemeDetector.ts +182 -0
- package/src/themes/themeCSSUpdater.ts +262 -0
- package/src/themes/themePersistence.ts +238 -0
- package/src/themes/themes/default.ts +586 -0
- package/src/themes/themes/harvey.ts +554 -0
- package/src/themes/themes/stan-design.ts +683 -0
- package/src/themes/types.ts +460 -0
- package/src/themes/useSystemTheme.ts +48 -0
- package/src/themes/useTheme.ts +87 -0
- package/src/themes/validation.ts +462 -0
- package/src/tokens/index.ts +34 -0
- package/src/tokens/tokenExporter.ts +397 -0
- package/src/tokens/tokenGenerator.ts +276 -0
- package/src/tokens/tokenManager.ts +248 -0
- package/src/tokens/tokenValidator.ts +543 -0
- package/src/tokens/types.ts +78 -0
- package/src/utils/bundle-analyzer.ts +260 -0
- package/src/utils/bundle-splitting.ts +483 -0
- package/src/utils/lazy-loading.ts +441 -0
- package/src/utils/performance-monitor.ts +513 -0
- package/src/utils/tree-shaking.ts +274 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import React, { forwardRef, useState, useEffect } from 'react'
|
|
2
|
+
import { cn } from '../../lib/utils'
|
|
3
|
+
|
|
4
|
+
// Enterprise Button Component
|
|
5
|
+
export interface EnterpriseButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
6
|
+
variant?: 'default' | 'secondary' | 'outline' | 'ghost' | 'premium'
|
|
7
|
+
size?: 'sm' | 'default' | 'lg' | 'xl'
|
|
8
|
+
loading?: boolean
|
|
9
|
+
children: React.ReactNode
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const EnterpriseButton = forwardRef<HTMLButtonElement, EnterpriseButtonProps>(
|
|
13
|
+
({ className, variant = 'default', size = 'default', loading = false, children, ...props }, ref) => {
|
|
14
|
+
const [isPressed, setIsPressed] = useState(false)
|
|
15
|
+
|
|
16
|
+
const baseClasses = 'enterprise-button enterprise-mobile-optimized enterprise-interaction-refined'
|
|
17
|
+
|
|
18
|
+
const variantClasses = {
|
|
19
|
+
default: 'enterprise-button',
|
|
20
|
+
secondary: 'enterprise-button-secondary',
|
|
21
|
+
outline: 'enterprise-button-outline',
|
|
22
|
+
ghost: 'enterprise-button-ghost',
|
|
23
|
+
premium: 'enterprise-button enterprise-interaction-premium'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const sizeClasses = {
|
|
27
|
+
sm: 'px-4 py-2 text-sm min-h-[40px] min-w-[40px]',
|
|
28
|
+
default: 'px-6 py-3 text-base min-h-[48px] min-w-[48px]',
|
|
29
|
+
lg: 'px-8 py-4 text-lg min-h-[56px] min-w-[56px]',
|
|
30
|
+
xl: 'px-10 py-5 text-xl min-h-[64px] min-w-[64px]'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const handleMouseDown = () => setIsPressed(true)
|
|
34
|
+
const handleMouseUp = () => setIsPressed(false)
|
|
35
|
+
const handleMouseLeave = () => setIsPressed(false)
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<button
|
|
39
|
+
ref={ref}
|
|
40
|
+
className={cn(
|
|
41
|
+
baseClasses,
|
|
42
|
+
variantClasses[variant],
|
|
43
|
+
sizeClasses[size],
|
|
44
|
+
loading && 'enterprise-loading',
|
|
45
|
+
isPressed && 'scale-95',
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
onMouseDown={handleMouseDown}
|
|
49
|
+
onMouseUp={handleMouseUp}
|
|
50
|
+
onMouseLeave={handleMouseLeave}
|
|
51
|
+
disabled={loading}
|
|
52
|
+
{...props}
|
|
53
|
+
>
|
|
54
|
+
{loading && (
|
|
55
|
+
<span className="enterprise-loading-spinner mr-2" />
|
|
56
|
+
)}
|
|
57
|
+
{children}
|
|
58
|
+
</button>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
EnterpriseButton.displayName = 'EnterpriseButton'
|
|
64
|
+
|
|
65
|
+
// Enterprise Card Component
|
|
66
|
+
export interface EnterpriseCardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
67
|
+
variant?: 'default' | 'interactive' | 'premium' | 'featured'
|
|
68
|
+
children: React.ReactNode
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const EnterpriseCard = forwardRef<HTMLDivElement, EnterpriseCardProps>(
|
|
72
|
+
({ className, variant = 'default', children, ...props }, ref) => {
|
|
73
|
+
const baseClasses = 'enterprise-card enterprise-visual-refined'
|
|
74
|
+
|
|
75
|
+
const variantClasses = {
|
|
76
|
+
default: '',
|
|
77
|
+
interactive: 'enterprise-card-interactive enterprise-interaction-refined',
|
|
78
|
+
premium: 'enterprise-card-premium enterprise-interaction-premium',
|
|
79
|
+
featured: 'enterprise-card-premium enterprise-interaction-premium border-2 border-cs-accent'
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<div
|
|
84
|
+
ref={ref}
|
|
85
|
+
className={cn(
|
|
86
|
+
baseClasses,
|
|
87
|
+
variantClasses[variant],
|
|
88
|
+
className
|
|
89
|
+
)}
|
|
90
|
+
{...props}
|
|
91
|
+
>
|
|
92
|
+
{children}
|
|
93
|
+
</div>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
EnterpriseCard.displayName = 'EnterpriseCard'
|
|
99
|
+
|
|
100
|
+
// Enterprise Input Component
|
|
101
|
+
export interface EnterpriseInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
102
|
+
variant?: 'default' | 'success' | 'error' | 'warning'
|
|
103
|
+
label?: string
|
|
104
|
+
required?: boolean
|
|
105
|
+
children?: React.ReactNode
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const EnterpriseInput = forwardRef<HTMLInputElement, EnterpriseInputProps>(
|
|
109
|
+
({ className, variant = 'default', label, required = false, children, ...props }, ref) => {
|
|
110
|
+
const [isFocused, setIsFocused] = useState(false)
|
|
111
|
+
|
|
112
|
+
const baseClasses = 'enterprise-input enterprise-mobile-optimized enterprise-accessibility'
|
|
113
|
+
|
|
114
|
+
const variantClasses = {
|
|
115
|
+
default: '',
|
|
116
|
+
success: 'enterprise-input-success',
|
|
117
|
+
error: 'enterprise-input-error',
|
|
118
|
+
warning: 'enterprise-input-warning'
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const handleFocus = () => setIsFocused(true)
|
|
122
|
+
const handleBlur = () => setIsFocused(false)
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<div className="space-y-2">
|
|
126
|
+
{label && (
|
|
127
|
+
<label className={cn(
|
|
128
|
+
'enterprise-label',
|
|
129
|
+
required && 'enterprise-label-required'
|
|
130
|
+
)}>
|
|
131
|
+
{label}
|
|
132
|
+
</label>
|
|
133
|
+
)}
|
|
134
|
+
<div className="relative">
|
|
135
|
+
<input
|
|
136
|
+
ref={ref}
|
|
137
|
+
className={cn(
|
|
138
|
+
baseClasses,
|
|
139
|
+
variantClasses[variant],
|
|
140
|
+
isFocused && 'enterprise-input-focused',
|
|
141
|
+
className
|
|
142
|
+
)}
|
|
143
|
+
onFocus={handleFocus}
|
|
144
|
+
onBlur={handleBlur}
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
{children}
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
EnterpriseInput.displayName = 'EnterpriseInput'
|
|
155
|
+
|
|
156
|
+
// Enterprise Progress Component
|
|
157
|
+
export interface EnterpriseProgressProps {
|
|
158
|
+
value: number
|
|
159
|
+
max?: number
|
|
160
|
+
variant?: 'default' | 'success' | 'warning' | 'error'
|
|
161
|
+
size?: 'sm' | 'default' | 'lg'
|
|
162
|
+
showLabel?: boolean
|
|
163
|
+
className?: string
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export const EnterpriseProgress: React.FC<EnterpriseProgressProps> = ({
|
|
167
|
+
value,
|
|
168
|
+
max = 100,
|
|
169
|
+
variant = 'default',
|
|
170
|
+
size = 'default',
|
|
171
|
+
showLabel = true,
|
|
172
|
+
className
|
|
173
|
+
}) => {
|
|
174
|
+
const percentage = Math.min(100, Math.max(0, (value / max) * 100))
|
|
175
|
+
|
|
176
|
+
const baseClasses = 'enterprise-progress enterprise-performance'
|
|
177
|
+
|
|
178
|
+
const sizeClasses = {
|
|
179
|
+
sm: 'h-1',
|
|
180
|
+
default: 'h-2',
|
|
181
|
+
lg: 'h-3'
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const variantClasses = {
|
|
185
|
+
default: 'enterprise-progress-bar',
|
|
186
|
+
success: 'enterprise-progress-bar bg-gradient-to-r from-cs-success to-cs-success/80',
|
|
187
|
+
warning: 'enterprise-progress-bar bg-gradient-to-r from-cs-warning to-cs-warning/80',
|
|
188
|
+
error: 'enterprise-progress-bar bg-gradient-to-r from-cs-error to-cs-error/80'
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return (
|
|
192
|
+
<div className={cn('space-y-2', className)}>
|
|
193
|
+
{showLabel && (
|
|
194
|
+
<div className="flex justify-between items-center text-sm">
|
|
195
|
+
<span className="text-cs-text-primary font-medium">Progress</span>
|
|
196
|
+
<span className="text-cs-text-secondary">{Math.round(percentage)}%</span>
|
|
197
|
+
</div>
|
|
198
|
+
)}
|
|
199
|
+
<div className={cn(baseClasses, sizeClasses[size])}>
|
|
200
|
+
<div
|
|
201
|
+
className={cn(variantClasses[variant])}
|
|
202
|
+
style={{ width: `${percentage}%` }}
|
|
203
|
+
/>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Enterprise Quality Metric Component
|
|
210
|
+
export interface EnterpriseQualityMetricProps {
|
|
211
|
+
score: number
|
|
212
|
+
label: string
|
|
213
|
+
description?: string
|
|
214
|
+
variant?: 'default' | 'excellent' | 'good' | 'needs-improvement'
|
|
215
|
+
className?: string
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export const EnterpriseQualityMetric: React.FC<EnterpriseQualityMetricProps> = ({
|
|
219
|
+
score,
|
|
220
|
+
label,
|
|
221
|
+
description,
|
|
222
|
+
className
|
|
223
|
+
}) => {
|
|
224
|
+
const getVariantClass = () => {
|
|
225
|
+
if (score >= 90) return 'enterprise-quality-excellent'
|
|
226
|
+
if (score >= 80) return 'enterprise-quality-good'
|
|
227
|
+
if (score < 80) return 'enterprise-quality-needs-improvement'
|
|
228
|
+
return 'enterprise-quality-metric'
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const getScoreColor = () => {
|
|
232
|
+
if (score >= 90) return 'text-cs-success'
|
|
233
|
+
if (score >= 80) return 'text-cs-warning'
|
|
234
|
+
if (score < 80) return 'text-cs-error'
|
|
235
|
+
return 'text-cs-primary'
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<div className={cn('enterprise-quality-metric', getVariantClass(), className)}>
|
|
240
|
+
<div className={cn('enterprise-quality-score', getScoreColor())}>
|
|
241
|
+
{score}
|
|
242
|
+
</div>
|
|
243
|
+
<div className="enterprise-quality-label">
|
|
244
|
+
{label}
|
|
245
|
+
</div>
|
|
246
|
+
{description && (
|
|
247
|
+
<div className="enterprise-quality-description">
|
|
248
|
+
{description}
|
|
249
|
+
</div>
|
|
250
|
+
)}
|
|
251
|
+
</div>
|
|
252
|
+
)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Enterprise Status Component
|
|
256
|
+
export interface EnterpriseStatusProps {
|
|
257
|
+
phase: 'initializing' | 'optimizing' | 'polishing' | 'verifying' | 'complete' | 'enterprise-ready'
|
|
258
|
+
children: React.ReactNode
|
|
259
|
+
className?: string
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export const EnterpriseStatus: React.FC<EnterpriseStatusProps> = ({
|
|
263
|
+
phase,
|
|
264
|
+
children,
|
|
265
|
+
className
|
|
266
|
+
}) => {
|
|
267
|
+
const phaseClasses = {
|
|
268
|
+
initializing: 'enterprise-status-initializing',
|
|
269
|
+
optimizing: 'enterprise-status-optimizing',
|
|
270
|
+
polishing: 'enterprise-status-polishing',
|
|
271
|
+
verifying: 'enterprise-status-verifying',
|
|
272
|
+
complete: 'enterprise-status-complete',
|
|
273
|
+
'enterprise-ready': 'enterprise-status-enterprise-ready'
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const phaseIcons = {
|
|
277
|
+
initializing: '🔄',
|
|
278
|
+
optimizing: '⚡',
|
|
279
|
+
polishing: '✨',
|
|
280
|
+
verifying: '🔍',
|
|
281
|
+
complete: '✅',
|
|
282
|
+
'enterprise-ready': '🏆'
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return (
|
|
286
|
+
<span className={cn('enterprise-status', phaseClasses[phase], className)}>
|
|
287
|
+
<span className="text-lg">{phaseIcons[phase]}</span>
|
|
288
|
+
{children}
|
|
289
|
+
</span>
|
|
290
|
+
)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Enterprise Container Component
|
|
294
|
+
export interface EnterpriseContainerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
295
|
+
children: React.ReactNode
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export const EnterpriseContainer: React.FC<EnterpriseContainerProps> = ({
|
|
299
|
+
className,
|
|
300
|
+
children,
|
|
301
|
+
...props
|
|
302
|
+
}) => {
|
|
303
|
+
return (
|
|
304
|
+
<div
|
|
305
|
+
className={cn('enterprise-container', className)}
|
|
306
|
+
{...props}
|
|
307
|
+
>
|
|
308
|
+
{children}
|
|
309
|
+
</div>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Enterprise Section Component
|
|
314
|
+
export interface EnterpriseSectionProps extends React.HTMLAttributes<HTMLElement> {
|
|
315
|
+
children: React.ReactNode
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export const EnterpriseSection: React.FC<EnterpriseSectionProps> = ({
|
|
319
|
+
className,
|
|
320
|
+
children,
|
|
321
|
+
...props
|
|
322
|
+
}) => {
|
|
323
|
+
return (
|
|
324
|
+
<section
|
|
325
|
+
className={cn('enterprise-section', className)}
|
|
326
|
+
{...props}
|
|
327
|
+
>
|
|
328
|
+
{children}
|
|
329
|
+
</section>
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Enterprise Grid Component
|
|
334
|
+
export interface EnterpriseGridProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
335
|
+
cols?: 1 | 2 | 3 | 4
|
|
336
|
+
children: React.ReactNode
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export const EnterpriseGrid: React.FC<EnterpriseGridProps> = ({
|
|
340
|
+
cols = 1,
|
|
341
|
+
className,
|
|
342
|
+
children,
|
|
343
|
+
...props
|
|
344
|
+
}) => {
|
|
345
|
+
const colsClasses = {
|
|
346
|
+
1: 'enterprise-grid-cols-1',
|
|
347
|
+
2: 'enterprise-grid-cols-2',
|
|
348
|
+
3: 'enterprise-grid-cols-3',
|
|
349
|
+
4: 'enterprise-grid-cols-4'
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return (
|
|
353
|
+
<div
|
|
354
|
+
className={cn('enterprise-grid', colsClasses[cols], className)}
|
|
355
|
+
{...props}
|
|
356
|
+
>
|
|
357
|
+
{children}
|
|
358
|
+
</div>
|
|
359
|
+
)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Enterprise Loading Component
|
|
363
|
+
export interface EnterpriseLoadingProps {
|
|
364
|
+
size?: 'sm' | 'default' | 'lg'
|
|
365
|
+
text?: string
|
|
366
|
+
className?: string
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export const EnterpriseLoading: React.FC<EnterpriseLoadingProps> = ({
|
|
370
|
+
size = 'default',
|
|
371
|
+
text = 'Loading...',
|
|
372
|
+
className
|
|
373
|
+
}) => {
|
|
374
|
+
const sizeClasses = {
|
|
375
|
+
sm: 'w-4 h-4',
|
|
376
|
+
default: 'w-6 h-6',
|
|
377
|
+
lg: 'w-8 h-8'
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return (
|
|
381
|
+
<div className={cn('flex items-center justify-center space-x-2', className)}>
|
|
382
|
+
<div className={cn('enterprise-loading-spinner', sizeClasses[size])} />
|
|
383
|
+
{text && (
|
|
384
|
+
<span className="text-cs-text-secondary text-sm font-medium">
|
|
385
|
+
{text}
|
|
386
|
+
</span>
|
|
387
|
+
)}
|
|
388
|
+
</div>
|
|
389
|
+
)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Enterprise Notification Component
|
|
393
|
+
export interface EnterpriseNotificationProps {
|
|
394
|
+
type: 'success' | 'warning' | 'error' | 'info'
|
|
395
|
+
title: string
|
|
396
|
+
message?: string
|
|
397
|
+
onClose?: () => void
|
|
398
|
+
duration?: number
|
|
399
|
+
className?: string
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export const EnterpriseNotification: React.FC<EnterpriseNotificationProps> = ({
|
|
403
|
+
type,
|
|
404
|
+
title,
|
|
405
|
+
message,
|
|
406
|
+
onClose,
|
|
407
|
+
duration = 5000,
|
|
408
|
+
className
|
|
409
|
+
}) => {
|
|
410
|
+
const [isVisible, setIsVisible] = useState(true)
|
|
411
|
+
|
|
412
|
+
useEffect(() => {
|
|
413
|
+
if (duration > 0) {
|
|
414
|
+
const timer = setTimeout(() => {
|
|
415
|
+
setIsVisible(false)
|
|
416
|
+
onClose?.()
|
|
417
|
+
}, duration)
|
|
418
|
+
|
|
419
|
+
return () => clearTimeout(timer)
|
|
420
|
+
}
|
|
421
|
+
}, [duration, onClose])
|
|
422
|
+
|
|
423
|
+
const typeClasses = {
|
|
424
|
+
success: 'enterprise-notification-success',
|
|
425
|
+
warning: 'enterprise-notification-warning',
|
|
426
|
+
error: 'enterprise-notification-error',
|
|
427
|
+
info: 'enterprise-notification-info'
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const typeIcons = {
|
|
431
|
+
success: '✅',
|
|
432
|
+
warning: '⚠️',
|
|
433
|
+
error: '❌',
|
|
434
|
+
info: 'ℹ️'
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (!isVisible) return null
|
|
438
|
+
|
|
439
|
+
return (
|
|
440
|
+
<div className={cn('enterprise-notification', typeClasses[type], className)}>
|
|
441
|
+
<div className="flex items-start space-x-3">
|
|
442
|
+
<span className="text-lg">{typeIcons[type]}</span>
|
|
443
|
+
<div className="flex-1">
|
|
444
|
+
<h4 className="text-sm font-semibold text-cs-text-primary">
|
|
445
|
+
{title}
|
|
446
|
+
</h4>
|
|
447
|
+
{message && (
|
|
448
|
+
<p className="text-sm text-cs-text-secondary mt-1">
|
|
449
|
+
{message}
|
|
450
|
+
</p>
|
|
451
|
+
)}
|
|
452
|
+
</div>
|
|
453
|
+
{onClose && (
|
|
454
|
+
<button
|
|
455
|
+
onClick={onClose}
|
|
456
|
+
className="text-cs-text-secondary hover:text-cs-text-primary transition-colors"
|
|
457
|
+
>
|
|
458
|
+
✕
|
|
459
|
+
</button>
|
|
460
|
+
)}
|
|
461
|
+
</div>
|
|
462
|
+
</div>
|
|
463
|
+
)
|
|
464
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React, { useState, useCallback } from 'react';
|
|
2
|
+
import { AlertProps, AlertAction } 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 alert type
|
|
36
|
+
const getAlertIcon = (type: AlertProps['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
|
+
// Alert Action Button Component
|
|
52
|
+
const AlertActionButton: React.FC<AlertAction & { theme: string }> = ({
|
|
53
|
+
label,
|
|
54
|
+
onClick,
|
|
55
|
+
variant = 'primary'
|
|
56
|
+
}) => {
|
|
57
|
+
return (
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
className={`alert__action-button alert__action-button--${variant}`}
|
|
61
|
+
onClick={onClick}
|
|
62
|
+
>
|
|
63
|
+
{label}
|
|
64
|
+
</button>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Main Alert Component
|
|
69
|
+
export const Alert: React.FC<AlertProps> = ({
|
|
70
|
+
title,
|
|
71
|
+
message,
|
|
72
|
+
type = 'info',
|
|
73
|
+
dismissible = false,
|
|
74
|
+
onDismiss,
|
|
75
|
+
icon,
|
|
76
|
+
actions = [],
|
|
77
|
+
showIcon = true,
|
|
78
|
+
closable = false,
|
|
79
|
+
persistent = false,
|
|
80
|
+
className = '',
|
|
81
|
+
theme = 'stan-design',
|
|
82
|
+
size = 'md',
|
|
83
|
+
variant = 'default'
|
|
84
|
+
}) => {
|
|
85
|
+
// const { getTheme } = useTheme();
|
|
86
|
+
// const themeConfig = getTheme(theme);
|
|
87
|
+
// Note: colors not needed as we're using semantic CSS classes
|
|
88
|
+
|
|
89
|
+
const [isVisible, setIsVisible] = useState(true);
|
|
90
|
+
|
|
91
|
+
const handleDismiss = useCallback(() => {
|
|
92
|
+
if (onDismiss) {
|
|
93
|
+
onDismiss();
|
|
94
|
+
}
|
|
95
|
+
if (!persistent) {
|
|
96
|
+
setIsVisible(false);
|
|
97
|
+
}
|
|
98
|
+
}, [onDismiss, persistent]);
|
|
99
|
+
|
|
100
|
+
const shouldShowIcon = showIcon && (icon || type);
|
|
101
|
+
const shouldShowClose = (closable || dismissible) && !persistent;
|
|
102
|
+
|
|
103
|
+
if (!isVisible) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<div
|
|
109
|
+
className={`alert__container alert__container--${size} alert__container--${type} alert__container--${variant} ${className}`}
|
|
110
|
+
role="alert"
|
|
111
|
+
aria-live="polite"
|
|
112
|
+
>
|
|
113
|
+
{shouldShowIcon && (
|
|
114
|
+
<div className={`alert__icon alert__icon--${type}`}>
|
|
115
|
+
{icon || getAlertIcon(type, 'alert__icon')}
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
|
|
119
|
+
<div className="alert__content">
|
|
120
|
+
{title && (
|
|
121
|
+
<h3 className="alert__title">
|
|
122
|
+
{title}
|
|
123
|
+
</h3>
|
|
124
|
+
)}
|
|
125
|
+
|
|
126
|
+
<div className={`alert__message ${!title ? 'alert__message--only' : ''}`}>
|
|
127
|
+
{message}
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
{actions.length > 0 && (
|
|
131
|
+
<div className="alert__actions">
|
|
132
|
+
{actions.map((action, index) => (
|
|
133
|
+
<AlertActionButton
|
|
134
|
+
key={index}
|
|
135
|
+
{...action}
|
|
136
|
+
theme={theme}
|
|
137
|
+
/>
|
|
138
|
+
))}
|
|
139
|
+
</div>
|
|
140
|
+
)}
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
{shouldShowClose && (
|
|
144
|
+
<button
|
|
145
|
+
type="button"
|
|
146
|
+
className="alert__close-button"
|
|
147
|
+
onClick={handleDismiss}
|
|
148
|
+
aria-label="Close alert"
|
|
149
|
+
>
|
|
150
|
+
<XMarkIcon className="alert__close-icon" />
|
|
151
|
+
</button>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export default Alert;
|