@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.6 → 0.1.7

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 (82) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/index.d.ts +7 -0
  3. package/dist/index.esm.js +18 -1
  4. package/dist/index.js +18 -1
  5. package/dist/setupTests.d.ts +124 -0
  6. package/dist/setupTests.esm.js +122 -0
  7. package/dist/setupTests.js +122 -0
  8. package/dist/styles.css +1 -1
  9. package/package.json +1 -1
  10. package/src/index.css +1046 -0
  11. package/src/index.ts +18 -0
  12. package/src/plugins/theme-css-generator.ts +354 -0
  13. package/src/setupTests.ts +124 -0
  14. package/src/stories/README.md +39 -0
  15. package/src/stories/components/ThemeDebugger.tsx +143 -0
  16. package/src/stories/index.ts +29 -0
  17. package/src/stories/storybook-theme-imports.css +51 -0
  18. package/src/styles/base/fonts.css +30 -0
  19. package/src/styles/base/generated-theme-variables.css +573 -0
  20. package/src/styles/base/index.css +7 -0
  21. package/src/styles/base/reset.css +48 -0
  22. package/src/styles/base/theme.css +1068 -0
  23. package/src/styles/base/typography.css +68 -0
  24. package/src/styles/base/variables.css +5 -0
  25. package/src/styles/components/CLAUDE.md +62 -0
  26. package/src/styles/components/base/badge.css +428 -0
  27. package/src/styles/components/base/button.css +774 -0
  28. package/src/styles/components/base/card.css +601 -0
  29. package/src/styles/components/base/checkbox.css +442 -0
  30. package/src/styles/components/base/index.css +9 -0
  31. package/src/styles/components/base/input.css +887 -0
  32. package/src/styles/components/base/label.css +296 -0
  33. package/src/styles/components/data-display/chart.css +353 -0
  34. package/src/styles/components/data-display/data-grid.css +619 -0
  35. package/src/styles/components/data-display/index.css +9 -0
  36. package/src/styles/components/data-display/list.css +560 -0
  37. package/src/styles/components/data-display/table.css +498 -0
  38. package/src/styles/components/data-display/timeline.css +764 -0
  39. package/src/styles/components/data-display/tree.css +881 -0
  40. package/src/styles/components/feedback/alert.css +358 -0
  41. package/src/styles/components/feedback/index.css +7 -0
  42. package/src/styles/components/feedback/progress.css +435 -0
  43. package/src/styles/components/feedback/skeleton.css +337 -0
  44. package/src/styles/components/feedback/toast.css +564 -0
  45. package/src/styles/components/index.css +17 -0
  46. package/src/styles/components/navigation/breadcrumb.css +465 -0
  47. package/src/styles/components/navigation/index.css +9 -0
  48. package/src/styles/components/navigation/menu.css +572 -0
  49. package/src/styles/components/navigation/pagination.css +635 -0
  50. package/src/styles/components/navigation/sidebar.css +807 -0
  51. package/src/styles/components/navigation/stepper.css +519 -0
  52. package/src/styles/components/navigation/tabs.css +404 -0
  53. package/src/styles/components/overlay/backdrop.css +243 -0
  54. package/src/styles/components/overlay/index.css +8 -0
  55. package/src/styles/components/overlay/modal.css +482 -0
  56. package/src/styles/components/overlay/popover.css +607 -0
  57. package/src/styles/components/overlay/portal.css +213 -0
  58. package/src/styles/components/overlay/tooltip.css +488 -0
  59. package/src/styles/generated-theme-variables.css +573 -0
  60. package/src/styles/index.css +5 -0
  61. package/src/styles/layers/index.css +54 -0
  62. package/src/styles/layers/overrides.css +108 -0
  63. package/src/styles/layers/validation.css +159 -0
  64. package/src/styles/layers/validation.js +310 -0
  65. package/src/styles/themes/default.css +450 -0
  66. package/src/styles/themes/enterprise.css +370 -0
  67. package/src/styles/themes/harvey.css +436 -0
  68. package/src/styles/themes/index.css +4 -0
  69. package/src/styles/themes/stan-design.css +572 -0
  70. package/src/styles/utilities/advanced-transition-system.css +467 -0
  71. package/src/styles/utilities/battery-conscious-animations.css +289 -0
  72. package/src/styles/utilities/enterprise-mobile-experience.css +817 -0
  73. package/src/styles/utilities/hardware-acceleration.css +121 -0
  74. package/src/styles/utilities/index.css +20 -0
  75. package/src/styles/utilities/mobile-skeleton-loading.css +596 -0
  76. package/src/styles/utilities/semantic-input-system.css +451 -0
  77. package/src/styles/utilities/touch-friendly-interface.css +247 -0
  78. package/src/styles/utilities/touch-optimization.css +165 -0
  79. package/src/test-utils/index.ts +7 -0
  80. package/src/test-utils/theme-testing.tsx +219 -0
  81. package/src/testing/test-automation.ts +627 -0
  82. package/src/testing/test-utils.tsx +367 -0
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Testing Utilities for Component Testing Framework
3
+ * Provides comprehensive testing helpers for visual regression, theme switching,
4
+ * state testing, responsive testing, and accessibility testing
5
+ */
6
+
7
+ import React from 'react';
8
+ import { render, RenderOptions, RenderResult } from '@testing-library/react';
9
+ import { ThemeProvider } from '../themes/ThemeProvider';
10
+ // Note: Components are imported in tests where needed
11
+
12
+ // Theme names available for testing
13
+ export type ThemeName = 'default' | 'stan-design' | 'harvey';
14
+
15
+ // Extended render options for comprehensive testing
16
+ interface ExtendedRenderOptions extends Omit<RenderOptions, 'wrapper'> {
17
+ theme?: ThemeName;
18
+ wrapper?: React.ComponentType<{ children: React.ReactNode }>;
19
+ }
20
+
21
+ /**
22
+ * Custom render function with theme provider wrapper
23
+ */
24
+ export function renderWithTheme(
25
+ ui: React.ReactElement,
26
+ options: ExtendedRenderOptions = {}
27
+ ): RenderResult {
28
+ const { theme, wrapper: Wrapper, ...renderOptions } = options;
29
+
30
+ function ThemeWrapper({ children }: { children: React.ReactNode }) {
31
+ const content = theme ? (
32
+ <ThemeProvider defaultTheme={theme}>{children}</ThemeProvider>
33
+ ) : (
34
+ children
35
+ );
36
+
37
+ return Wrapper ? <Wrapper>{content}</Wrapper> : <>{content}</>;
38
+ }
39
+
40
+ return render(ui, { wrapper: ThemeWrapper, ...renderOptions });
41
+ }
42
+
43
+ /**
44
+ * Test all theme variants of a component
45
+ */
46
+ export function testAllThemes(
47
+ component: React.ReactElement,
48
+ testFn: (theme: ThemeName, result: RenderResult) => void
49
+ ) {
50
+ const themes: ThemeName[] = ['default', 'stan-design', 'harvey'];
51
+
52
+ themes.forEach((theme) => {
53
+ describe(`with ${theme} theme`, () => {
54
+ const result = renderWithTheme(component, { theme });
55
+ testFn(theme, result);
56
+ });
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Viewport sizes for responsive testing
62
+ */
63
+ export const viewports = {
64
+ mobile: { width: 375, height: 667 },
65
+ tablet: { width: 768, height: 1024 },
66
+ desktop: { width: 1024, height: 768 },
67
+ wide: { width: 1440, height: 900 },
68
+ ultrawide: { width: 1920, height: 1080 },
69
+ } as const;
70
+
71
+ /**
72
+ * Set viewport size for responsive testing
73
+ */
74
+ export function setViewport(size: keyof typeof viewports) {
75
+ const { width, height } = viewports[size];
76
+
77
+ // Mock window dimensions
78
+ Object.defineProperty(window, 'innerWidth', {
79
+ writable: true,
80
+ configurable: true,
81
+ value: width,
82
+ });
83
+
84
+ Object.defineProperty(window, 'innerHeight', {
85
+ writable: true,
86
+ configurable: true,
87
+ value: height,
88
+ });
89
+
90
+ // Trigger resize event
91
+ window.dispatchEvent(new Event('resize'));
92
+ }
93
+
94
+ /**
95
+ * Test component across all viewport sizes
96
+ */
97
+ export function testAllViewports(
98
+ component: React.ReactElement,
99
+ testFn: (viewport: keyof typeof viewports, result: RenderResult) => void
100
+ ) {
101
+ Object.keys(viewports).forEach((viewport) => {
102
+ const viewportKey = viewport as keyof typeof viewports;
103
+
104
+ describe(`at ${viewport} viewport`, () => {
105
+ beforeEach(() => {
106
+ setViewport(viewportKey);
107
+ });
108
+
109
+ const result = render(component);
110
+ testFn(viewportKey, result);
111
+ });
112
+ });
113
+ }
114
+
115
+ /**
116
+ * Component states for state testing
117
+ */
118
+ export const componentStates = [
119
+ 'default',
120
+ 'hover',
121
+ 'focus',
122
+ 'active',
123
+ 'disabled',
124
+ 'loading',
125
+ 'error',
126
+ ] as const;
127
+
128
+ export type ComponentState = typeof componentStates[number];
129
+
130
+ /**
131
+ * Apply state to an element for testing
132
+ */
133
+ export function applyState(element: HTMLElement, state: ComponentState) {
134
+ switch (state) {
135
+ case 'hover':
136
+ element.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));
137
+ break;
138
+ case 'focus':
139
+ element.focus();
140
+ break;
141
+ case 'active':
142
+ element.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
143
+ break;
144
+ case 'disabled':
145
+ if ('disabled' in element) {
146
+ (element as any).disabled = true;
147
+ } else {
148
+ element.setAttribute('aria-disabled', 'true');
149
+ }
150
+ break;
151
+ case 'loading':
152
+ element.setAttribute('aria-busy', 'true');
153
+ break;
154
+ case 'error':
155
+ element.setAttribute('aria-invalid', 'true');
156
+ break;
157
+ default:
158
+ // Default state - no modifications needed
159
+ break;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Test all component states
165
+ */
166
+ export function testAllStates(
167
+ getElement: () => HTMLElement,
168
+ testFn: (state: ComponentState, element: HTMLElement) => void
169
+ ) {
170
+ componentStates.forEach((state) => {
171
+ describe(`in ${state} state`, () => {
172
+ const element = getElement();
173
+ applyState(element, state);
174
+ testFn(state, element);
175
+ });
176
+ });
177
+ }
178
+
179
+ /**
180
+ * Mock CSS media queries for responsive testing
181
+ */
182
+ export function mockMediaQuery(query: string, matches: boolean = true) {
183
+ const mockMediaQuery = {
184
+ matches,
185
+ media: query,
186
+ onchange: null,
187
+ addListener: jest.fn(),
188
+ removeListener: jest.fn(),
189
+ addEventListener: jest.fn(),
190
+ removeEventListener: jest.fn(),
191
+ dispatchEvent: jest.fn(),
192
+ };
193
+
194
+ Object.defineProperty(window, 'matchMedia', {
195
+ writable: true,
196
+ value: jest.fn().mockImplementation(() => mockMediaQuery),
197
+ });
198
+
199
+ return mockMediaQuery;
200
+ }
201
+
202
+ /**
203
+ * Performance testing utilities
204
+ */
205
+ export const performanceUtils = {
206
+ /**
207
+ * Measure component render time
208
+ */
209
+ measureRenderTime: (renderFn: () => RenderResult): number => {
210
+ const start = performance.now();
211
+ renderFn();
212
+ const end = performance.now();
213
+ return end - start;
214
+ },
215
+
216
+ /**
217
+ * Test render performance across multiple runs
218
+ */
219
+ testRenderPerformance: (
220
+ renderFn: () => RenderResult,
221
+ iterations: number = 10,
222
+ maxTime: number = 50 // ms
223
+ ): { average: number; max: number; passed: boolean } => {
224
+ const times: number[] = [];
225
+
226
+ for (let i = 0; i < iterations; i++) {
227
+ const time = performanceUtils.measureRenderTime(renderFn);
228
+ times.push(time);
229
+ }
230
+
231
+ const average = times.reduce((sum, time) => sum + time, 0) / times.length;
232
+ const max = Math.max(...times);
233
+ const passed = max <= maxTime;
234
+
235
+ return { average, max, passed };
236
+ },
237
+ };
238
+
239
+ /**
240
+ * Accessibility testing utilities
241
+ */
242
+ export const a11yUtils = {
243
+ /**
244
+ * Check if element has proper ARIA labels
245
+ */
246
+ hasAriaLabel: (element: HTMLElement): boolean => {
247
+ return Boolean(
248
+ element.getAttribute('aria-label') ||
249
+ element.getAttribute('aria-labelledby') ||
250
+ element.getAttribute('aria-describedby')
251
+ );
252
+ },
253
+
254
+ /**
255
+ * Check if element is keyboard accessible
256
+ */
257
+ isKeyboardAccessible: (element: HTMLElement): boolean => {
258
+ const tabIndex = element.getAttribute('tabindex');
259
+ const isInteractive = ['button', 'input', 'select', 'textarea', 'a'].includes(
260
+ element.tagName.toLowerCase()
261
+ );
262
+
263
+ return (
264
+ isInteractive ||
265
+ (tabIndex !== null && parseInt(tabIndex) >= 0) ||
266
+ element.hasAttribute('role')
267
+ );
268
+ },
269
+
270
+ /**
271
+ * Check if element has sufficient color contrast
272
+ * Note: This is a simplified check - full contrast checking requires advanced algorithms
273
+ */
274
+ hasSufficientContrast: (element: HTMLElement): boolean => {
275
+ const styles = window.getComputedStyle(element);
276
+ const color = styles.color;
277
+ const backgroundColor = styles.backgroundColor;
278
+
279
+ // This is a simplified check - in a real implementation,
280
+ // you would use a proper contrast ratio calculation
281
+ return color !== backgroundColor;
282
+ },
283
+ };
284
+
285
+ /**
286
+ * Visual regression testing utilities
287
+ */
288
+ export const visualRegressionUtils = {
289
+ /**
290
+ * Create a snapshot test for visual regression
291
+ */
292
+ expectComponentSnapshot: (component: React.ReactElement, name?: string) => {
293
+ const { container } = renderWithTheme(component, { theme: 'default' });
294
+ expect(container.firstChild).toMatchSnapshot(name);
295
+ },
296
+
297
+ /**
298
+ * Test component visual consistency across themes
299
+ */
300
+ expectThemeConsistency: (component: React.ReactElement) => {
301
+ const themes: ThemeName[] = ['default', 'stan-design', 'harvey'];
302
+
303
+ themes.forEach((theme) => {
304
+ const { container } = renderWithTheme(component, { theme });
305
+ expect(container.firstChild).toMatchSnapshot(`theme-${theme}`);
306
+ });
307
+ },
308
+
309
+ /**
310
+ * Test component visual consistency across states
311
+ */
312
+ expectStateConsistency: (
313
+ getComponent: (state: ComponentState) => React.ReactElement
314
+ ) => {
315
+ componentStates.forEach((state) => {
316
+ const component = getComponent(state);
317
+ const { container } = render(component);
318
+ expect(container.firstChild).toMatchSnapshot(`state-${state}`);
319
+ });
320
+ },
321
+ };
322
+
323
+ /**
324
+ * Cross-browser testing utilities
325
+ */
326
+ export const crossBrowserUtils = {
327
+ /**
328
+ * Mock different user agents for browser testing
329
+ */
330
+ mockUserAgent: (userAgent: string) => {
331
+ Object.defineProperty(navigator, 'userAgent', {
332
+ writable: true,
333
+ value: userAgent,
334
+ });
335
+ },
336
+
337
+ /**
338
+ * Test component across different browsers
339
+ */
340
+ testAcrossBrowsers: (
341
+ component: React.ReactElement,
342
+ testFn: (browser: string, result: RenderResult) => void
343
+ ) => {
344
+ const browsers = {
345
+ chrome: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
346
+ firefox: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
347
+ safari: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15',
348
+ edge: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.59',
349
+ };
350
+
351
+ Object.entries(browsers).forEach(([browser, userAgent]) => {
352
+ describe(`in ${browser}`, () => {
353
+ beforeEach(() => {
354
+ crossBrowserUtils.mockUserAgent(userAgent);
355
+ });
356
+
357
+ const result = render(component);
358
+ testFn(browser, result);
359
+ });
360
+ });
361
+ },
362
+ };
363
+
364
+ // Re-export testing library utilities
365
+ export * from '@testing-library/react';
366
+ export * from '@testing-library/user-event';
367
+ export { default as userEvent } from '@testing-library/user-event';