@umituz/web-design-system 3.1.22 → 4.0.2

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 (84) hide show
  1. package/README.md +137 -469
  2. package/dist/styles.css +2 -0
  3. package/package.json +31 -31
  4. package/src/__tests__/cn.test.ts +24 -0
  5. package/src/__tests__/components.smoke.test.tsx +78 -0
  6. package/src/__tests__/styles.contract.test.ts +60 -0
  7. package/src/domain/tokens/index.ts +8 -49
  8. package/src/index.ts +8 -10
  9. package/src/infrastructure/constants/component.constants.ts +3 -17
  10. package/src/infrastructure/constants/index.ts +4 -2
  11. package/src/infrastructure/constants/timing.constants.ts +46 -0
  12. package/src/infrastructure/utils/calculation.utils.ts +74 -0
  13. package/src/infrastructure/utils/cn.util.ts +1 -1
  14. package/src/infrastructure/utils/index.ts +12 -0
  15. package/src/presentation/atoms/IconButton.tsx +55 -0
  16. package/src/presentation/atoms/Progress.tsx +2 -1
  17. package/src/presentation/atoms/Spinner.tsx +1 -1
  18. package/src/presentation/atoms/Switch.tsx +2 -2
  19. package/src/presentation/atoms/Text.tsx +15 -13
  20. package/src/presentation/atoms/Tooltip.tsx +2 -1
  21. package/src/presentation/atoms/index.ts +3 -0
  22. package/src/presentation/hooks/index.ts +0 -3
  23. package/src/presentation/hooks/useClickOutside.ts +16 -10
  24. package/src/presentation/hooks/useClipboard.ts +30 -12
  25. package/src/presentation/hooks/useDebounce.ts +9 -11
  26. package/src/presentation/hooks/useLocalStorage.ts +32 -20
  27. package/src/presentation/hooks/useMediaQuery.ts +20 -15
  28. package/src/presentation/hooks/useScrollLock.ts +40 -12
  29. package/src/presentation/hooks/useToggle.ts +8 -6
  30. package/src/presentation/molecules/ActiveFilterTags.tsx +19 -18
  31. package/src/presentation/molecules/Avatar.tsx +1 -1
  32. package/src/presentation/molecules/CodeBlock.tsx +50 -48
  33. package/src/presentation/molecules/InputGroup.tsx +1 -1
  34. package/src/presentation/molecules/ListItem.tsx +40 -29
  35. package/src/presentation/molecules/Select.tsx +1 -1
  36. package/src/presentation/molecules/Toggle.tsx +4 -4
  37. package/src/presentation/molecules/index.ts +0 -3
  38. package/src/presentation/organisms/Alert.tsx +1 -1
  39. package/src/presentation/organisms/DataTable.tsx +26 -15
  40. package/src/presentation/organisms/Dialog.tsx +1 -1
  41. package/src/presentation/organisms/DropdownMenu.tsx +2 -2
  42. package/src/presentation/organisms/HoverCard.tsx +1 -1
  43. package/src/presentation/organisms/LoadingState.tsx +1 -5
  44. package/src/presentation/organisms/Popover.tsx +1 -1
  45. package/src/presentation/organisms/StatCard.tsx +2 -2
  46. package/src/presentation/organisms/Table.tsx +2 -2
  47. package/src/presentation/organisms/index.ts +0 -60
  48. package/src/styles/compile.css +18 -0
  49. package/src/styles/theme.css +131 -0
  50. package/src/domain/tokens/animation.tokens.ts +0 -87
  51. package/src/domain/tokens/color.tokens.ts +0 -95
  52. package/src/domain/tokens/radius.tokens.ts +0 -27
  53. package/src/domain/tokens/shadow.tokens.ts +0 -25
  54. package/src/domain/tokens/spacing.tokens.ts +0 -65
  55. package/src/domain/tokens/typography.tokens.ts +0 -74
  56. package/src/infrastructure/error/ErrorBoundary.tsx +0 -258
  57. package/src/infrastructure/error/ErrorDisplay.tsx +0 -346
  58. package/src/infrastructure/error/SuspenseWrapper.tsx +0 -133
  59. package/src/infrastructure/error/index.ts +0 -5
  60. package/src/infrastructure/performance/index.ts +0 -92
  61. package/src/infrastructure/performance/useLazyLoading.ts +0 -342
  62. package/src/infrastructure/performance/useMemoryOptimization.ts +0 -293
  63. package/src/infrastructure/performance/usePerformanceMonitor.ts +0 -158
  64. package/src/infrastructure/security/index.ts +0 -10
  65. package/src/infrastructure/security/security-config.ts +0 -171
  66. package/src/infrastructure/security/useFormValidation.ts +0 -216
  67. package/src/infrastructure/security/validation.ts +0 -246
  68. package/src/presentation/hooks/useLanguage.ts +0 -109
  69. package/src/presentation/molecules/Breadcrumb.tsx +0 -54
  70. package/src/presentation/organisms/AlertDialog.tsx +0 -181
  71. package/src/presentation/organisms/Calendar.tsx +0 -79
  72. package/src/presentation/organisms/Comments.tsx +0 -103
  73. package/src/presentation/organisms/ConfirmDialog.tsx +0 -97
  74. package/src/presentation/organisms/FilterBar.tsx +0 -244
  75. package/src/presentation/organisms/FilterSidebar.tsx +0 -172
  76. package/src/presentation/organisms/Footer.tsx +0 -86
  77. package/src/presentation/organisms/FormModal.tsx +0 -126
  78. package/src/presentation/organisms/Grid.tsx +0 -128
  79. package/src/presentation/organisms/ImageLightbox.tsx +0 -252
  80. package/src/presentation/organisms/MainNavbar.tsx +0 -320
  81. package/src/presentation/organisms/Modal.tsx +0 -173
  82. package/src/presentation/organisms/Navbar.tsx +0 -75
  83. package/src/presentation/organisms/NewsletterSignup.tsx +0 -165
  84. package/src/presentation/organisms/QuickActionCard.tsx +0 -93
@@ -1,25 +0,0 @@
1
- /**
2
- * Shadow Tokens
3
- * @description Box shadow scale
4
- */
5
-
6
- export type ShadowToken =
7
- | 'sm'
8
- | 'default'
9
- | 'md'
10
- | 'lg'
11
- | 'xl'
12
- | '2xl'
13
- | 'inner'
14
- | 'none';
15
-
16
- export const shadows: Record<ShadowToken, string> = {
17
- 'sm': '0 1px 2px 0 rgb(0 0 0 / 0.05)',
18
- 'default': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
19
- 'md': '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
20
- 'lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
21
- 'xl': '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
22
- '2xl': '0 25px 50px -12px rgb(0 0 0 / 0.25)',
23
- 'inner': 'inset 0 2px 4px 0 rgb(0 0 0 / 0.05)',
24
- 'none': '0 0 #0000',
25
- };
@@ -1,65 +0,0 @@
1
- /**
2
- * Spacing Tokens
3
- * @description Consistent spacing scale
4
- */
5
-
6
- export type SpacingToken =
7
- | '0'
8
- | 'px'
9
- | '0.5'
10
- | '1'
11
- | '1.5'
12
- | '2'
13
- | '2.5'
14
- | '3'
15
- | '3.5'
16
- | '4'
17
- | '5'
18
- | '6'
19
- | '7'
20
- | '8'
21
- | '9'
22
- | '10'
23
- | '12'
24
- | '16'
25
- | '20'
26
- | '24'
27
- | '32'
28
- | '40'
29
- | '48'
30
- | '56'
31
- | '64'
32
- | '72'
33
- | '80'
34
- | '96';
35
-
36
- export const spacing: Record<SpacingToken, string> = {
37
- '0': '0',
38
- 'px': '1px',
39
- '0.5': '0.125rem',
40
- '1': '0.25rem',
41
- '1.5': '0.375rem',
42
- '2': '0.5rem',
43
- '2.5': '0.625rem',
44
- '3': '0.75rem',
45
- '3.5': '0.875rem',
46
- '4': '1rem',
47
- '5': '1.25rem',
48
- '6': '1.5rem',
49
- '7': '1.75rem',
50
- '8': '2rem',
51
- '9': '2.25rem',
52
- '10': '2.5rem',
53
- '12': '3rem',
54
- '16': '4rem',
55
- '20': '5rem',
56
- '24': '6rem',
57
- '32': '8rem',
58
- '40': '10rem',
59
- '48': '12rem',
60
- '56': '14rem',
61
- '64': '16rem',
62
- '72': '18rem',
63
- '80': '20rem',
64
- '96': '24rem',
65
- };
@@ -1,74 +0,0 @@
1
- /**
2
- * Typography Tokens
3
- * @description Font sizes, weights, and line heights
4
- */
5
-
6
- export type FontSizeToken =
7
- | 'xs'
8
- | 'sm'
9
- | 'base'
10
- | 'lg'
11
- | 'xl'
12
- | '2xl'
13
- | '3xl'
14
- | '4xl'
15
- | '5xl'
16
- | '6xl'
17
- | '7xl'
18
- | '8xl'
19
- | '9xl';
20
-
21
- export type FontWeightToken =
22
- | 'thin'
23
- | 'extralight'
24
- | 'light'
25
- | 'normal'
26
- | 'medium'
27
- | 'semibold'
28
- | 'bold'
29
- | 'extrabold'
30
- | 'black';
31
-
32
- export const fontSizes: Record<FontSizeToken, string> = {
33
- 'xs': '0.75rem',
34
- 'sm': '0.875rem',
35
- 'base': '1rem',
36
- 'lg': '1.125rem',
37
- 'xl': '1.25rem',
38
- '2xl': '1.5rem',
39
- '3xl': '1.875rem',
40
- '4xl': '2.25rem',
41
- '5xl': '3rem',
42
- '6xl': '3.75rem',
43
- '7xl': '4.5rem',
44
- '8xl': '6rem',
45
- '9xl': '8rem',
46
- };
47
-
48
- export const fontWeights: Record<FontWeightToken, string> = {
49
- 'thin': '100',
50
- 'extralight': '200',
51
- 'light': '300',
52
- 'normal': '400',
53
- 'medium': '500',
54
- 'semibold': '600',
55
- 'bold': '700',
56
- 'extrabold': '800',
57
- 'black': '900',
58
- };
59
-
60
- export const lineHeights: Record<FontSizeToken, string> = {
61
- 'xs': '1rem',
62
- 'sm': '1.25rem',
63
- 'base': '1.5rem',
64
- 'lg': '1.75rem',
65
- 'xl': '1.75rem',
66
- '2xl': '2rem',
67
- '3xl': '2.25rem',
68
- '4xl': '2.5rem',
69
- '5xl': '1',
70
- '6xl': '1',
71
- '7xl': '1',
72
- '8xl': '1',
73
- '9xl': '1',
74
- };
@@ -1,258 +0,0 @@
1
- import React, { Component, ErrorInfo, ReactNode, memo } from "react";
2
-
3
- interface Props {
4
- children: ReactNode;
5
- fallback?: ReactNode;
6
- onError?: (error: Error, errorInfo: ErrorInfo) => void;
7
- showDetails?: boolean;
8
- level?: 'page' | 'component' | 'feature';
9
- }
10
-
11
- interface State {
12
- hasError: boolean;
13
- error?: Error;
14
- errorInfo?: ErrorInfo;
15
- errorId?: string;
16
- }
17
-
18
- const ErrorDetails = memo(({ error, errorInfo, showDetails }: {
19
- error: Error;
20
- errorInfo?: ErrorInfo;
21
- showDetails: boolean;
22
- }) => {
23
- if (!showDetails || !import.meta.env.DEV) return null;
24
-
25
- return (
26
- <div style={{ padding: '16px', background: '#f5f5f5', borderRadius: '8px', marginTop: '16px' }}>
27
- <h4 style={{ fontWeight: 600, fontSize: '14px', marginBottom: '8px' }}>
28
- 🐛 Error Details (Development)
29
- </h4>
30
- <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
31
- <div>
32
- <p style={{ fontSize: '12px', fontWeight: 500, color: '#666' }}>Message:</p>
33
- <pre style={{ fontSize: '12px', color: '#dc2626', overflow: 'auto' }}>{error.message}</pre>
34
- </div>
35
- {error.stack && (
36
- <div>
37
- <p style={{ fontSize: '12px', fontWeight: 500, color: '#666' }}>Stack:</p>
38
- <pre style={{ fontSize: '12px', color: '#666', overflow: 'auto', maxHeight: '128px' }}>
39
- {error.stack}
40
- </pre>
41
- </div>
42
- )}
43
- {errorInfo?.componentStack && (
44
- <div>
45
- <p style={{ fontSize: '12px', fontWeight: 500, color: '#666' }}>Component Stack:</p>
46
- <pre style={{ fontSize: '12px', color: '#666', overflow: 'auto', maxHeight: '128px' }}>
47
- {errorInfo.componentStack}
48
- </pre>
49
- </div>
50
- )}
51
- </div>
52
- </div>
53
- );
54
- });
55
-
56
- ErrorDetails.displayName = 'ErrorDetails';
57
-
58
- export class ErrorBoundary extends Component<Props, State> {
59
- constructor(props: Props) {
60
- super(props);
61
- this.state = { hasError: false };
62
- }
63
-
64
- static getDerivedStateFromError(error: Error): Partial<State> {
65
- return {
66
- hasError: true,
67
- error,
68
- errorId: `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
69
- };
70
- }
71
-
72
- componentDidCatch(error: Error, errorInfo: ErrorInfo) {
73
- this.setState({ error, errorInfo });
74
-
75
- this.props.onError?.(error, errorInfo);
76
-
77
- if (import.meta.env.DEV) {
78
- console.group('🚨 ErrorBoundary caught an error');
79
- console.error('Error:', error);
80
- console.error('Error Info:', errorInfo);
81
- console.groupEnd();
82
- }
83
- }
84
-
85
- private handleReset = () => {
86
- this.setState({ hasError: false, error: undefined, errorInfo: undefined, errorId: undefined });
87
- };
88
-
89
- private handleGoHome = () => {
90
- window.location.href = '/';
91
- };
92
-
93
- private getLevelConfig = () => {
94
- const { level = 'component' } = this.props;
95
-
96
- switch (level) {
97
- case 'page':
98
- return {
99
- title: 'Page Error',
100
- description: 'This page encountered an unexpected error.',
101
- showHomeButton: true,
102
- };
103
- case 'feature':
104
- return {
105
- title: 'Feature Error',
106
- description: 'This feature is temporarily unavailable due to an error.',
107
- showHomeButton: false,
108
- };
109
- default:
110
- return {
111
- title: 'Component Error',
112
- description: 'A component on this page encountered an error.',
113
- showHomeButton: false,
114
- };
115
- }
116
- };
117
-
118
- render() {
119
- if (this.state.hasError) {
120
- if (this.props.fallback) {
121
- return this.props.fallback;
122
- }
123
-
124
- const config = this.getLevelConfig();
125
- const { showDetails = false } = this.props;
126
-
127
- return (
128
- <div style={{
129
- minHeight: '100vh',
130
- display: 'flex',
131
- alignItems: 'center',
132
- justifyContent: 'center',
133
- padding: '16px',
134
- background: 'linear-gradient(to bottom right, #fef2f2, #fff7ed)'
135
- }}>
136
- <div style={{
137
- width: '100%',
138
- maxWidth: '672px',
139
- background: 'white',
140
- borderRadius: '8px',
141
- boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
142
- overflow: 'hidden'
143
- }}>
144
- <div style={{ padding: '24px' }}>
145
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
146
- <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
147
- <div style={{
148
- width: '48px',
149
- height: '48px',
150
- background: '#fecaca',
151
- borderRadius: '50%',
152
- display: 'flex',
153
- alignItems: 'center',
154
- justifyContent: 'center'
155
- }}>
156
- <span style={{ fontSize: '24px' }}>⚠️</span>
157
- </div>
158
- <div>
159
- <h2 style={{ color: '#dc2626', margin: 0, fontSize: '20px', fontWeight: 600 }}>
160
- {config.title}
161
- </h2>
162
- <p style={{ color: '#666', margin: 0, fontSize: '14px' }}>
163
- {config.description}
164
- </p>
165
- </div>
166
- </div>
167
- {this.state.errorId && (
168
- <span style={{
169
- background: '#dc2626',
170
- color: 'white',
171
- padding: '4px 8px',
172
- borderRadius: '4px',
173
- fontSize: '12px',
174
- fontWeight: 500
175
- }}>
176
- ID: {this.state.errorId.slice(-8)}
177
- </span>
178
- )}
179
- </div>
180
- </div>
181
-
182
- <div style={{ padding: '0 24px 24px', display: 'flex', flexDirection: 'column', gap: '16px' }}>
183
- {this.state.error && (
184
- <ErrorDetails
185
- error={this.state.error}
186
- errorInfo={this.state.errorInfo}
187
- showDetails={showDetails}
188
- />
189
- )}
190
-
191
- <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
192
- <button
193
- onClick={this.handleReset}
194
- style={{
195
- padding: '8px 16px',
196
- background: 'white',
197
- border: '1px solid #d1d5db',
198
- borderRadius: '6px',
199
- fontSize: '14px',
200
- fontWeight: 500,
201
- cursor: 'pointer',
202
- display: 'flex',
203
- alignItems: 'center',
204
- gap: '8px'
205
- }}
206
- >
207
- 🔄 Try Again
208
- </button>
209
- <button
210
- onClick={() => window.location.reload()}
211
- style={{
212
- padding: '8px 16px',
213
- background: '#3b82f6',
214
- color: 'white',
215
- border: 'none',
216
- borderRadius: '6px',
217
- fontSize: '14px',
218
- fontWeight: 500,
219
- cursor: 'pointer',
220
- display: 'flex',
221
- alignItems: 'center',
222
- gap: '8px'
223
- }}
224
- >
225
- 🔄 Refresh Page
226
- </button>
227
- {config.showHomeButton && (
228
- <button
229
- onClick={this.handleGoHome}
230
- style={{
231
- padding: '8px 16px',
232
- background: '#6b7280',
233
- color: 'white',
234
- border: 'none',
235
- borderRadius: '6px',
236
- fontSize: '14px',
237
- fontWeight: 500,
238
- cursor: 'pointer',
239
- display: 'flex',
240
- alignItems: 'center',
241
- gap: '8px'
242
- }}
243
- >
244
- 🏠 Go Home
245
- </button>
246
- )}
247
- </div>
248
- </div>
249
- </div>
250
- </div>
251
- );
252
- }
253
-
254
- return this.props.children;
255
- }
256
- }
257
-
258
- export default ErrorBoundary;