@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.1.5 → 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,165 @@
1
+ /* Touch Optimization & Gesture Support - Story 5 */
2
+
3
+ /* Touch target optimization */
4
+ .touch-target {
5
+ min-height: 44px;
6
+ min-width: 44px;
7
+ touch-action: manipulation;
8
+ -webkit-tap-highlight-color: transparent;
9
+ cursor: pointer;
10
+ user-select: none;
11
+ -webkit-user-select: none;
12
+ -moz-user-select: none;
13
+ -ms-user-select: none;
14
+ }
15
+
16
+ /* Touch feedback animations */
17
+ .touch-feedback {
18
+ transition: transform 0.1s ease-out, opacity 0.1s ease-out;
19
+ will-change: transform;
20
+ }
21
+
22
+ .touch-feedback:active {
23
+ transform: scale(0.95);
24
+ opacity: 0.8;
25
+ }
26
+
27
+ .touch-feedback.touch-pressed {
28
+ transform: scale(0.95);
29
+ opacity: 0.8;
30
+ }
31
+
32
+ /* Touch ripple effect */
33
+ .touch-ripple {
34
+ position: relative;
35
+ overflow: hidden;
36
+ }
37
+
38
+ .touch-ripple::after {
39
+ content: '';
40
+ position: absolute;
41
+ top: 50%;
42
+ left: 50%;
43
+ width: 0;
44
+ height: 0;
45
+ border-radius: 50%;
46
+ background: rgba(255, 255, 255, 0.3);
47
+ transform: translate(-50%, -50%);
48
+ transition: width 0.3s ease-out, height 0.3s ease-out, opacity 0.3s ease-out;
49
+ opacity: 0;
50
+ }
51
+
52
+ .touch-ripple.touch-active::after {
53
+ width: 100px;
54
+ height: 100px;
55
+ opacity: 1;
56
+ }
57
+
58
+ /* Touch-friendly button variants */
59
+ .touch-button {
60
+ @apply touch-target touch-feedback touch-ripple;
61
+ padding: 12px 24px;
62
+ border-radius: 8px;
63
+ font-weight: 500;
64
+ text-align: center;
65
+ display: inline-flex;
66
+ align-items: center;
67
+ justify-content: center;
68
+ gap: 8px;
69
+ }
70
+
71
+ .touch-button:disabled {
72
+ opacity: 0.6;
73
+ cursor: not-allowed;
74
+ transform: none !important;
75
+ }
76
+
77
+ /* Touch-friendly input fields */
78
+ .touch-input {
79
+ @apply touch-target;
80
+ padding: 12px 16px;
81
+ border-radius: 8px;
82
+ border: 2px solid transparent;
83
+ transition: border-color 0.2s ease-out, box-shadow 0.2s ease-out;
84
+ }
85
+
86
+ .touch-input:focus {
87
+ outline: none;
88
+ border-color: var(--cs-primary);
89
+ box-shadow: 0 0 0 3px rgba(var(--cs-primary-rgb), 0.1);
90
+ }
91
+
92
+ /* Touch-friendly card interactions */
93
+ .touch-card {
94
+ @apply touch-feedback;
95
+ transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
96
+ }
97
+
98
+ .touch-card:hover {
99
+ transform: translateY(-2px);
100
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
101
+ }
102
+
103
+ .touch-card:active {
104
+ transform: translateY(0) scale(0.98);
105
+ }
106
+
107
+ /* Touch gesture indicators */
108
+ .touch-gesture-hint {
109
+ position: relative;
110
+ }
111
+
112
+ .touch-gesture-hint::before {
113
+ content: '';
114
+ position: absolute;
115
+ top: -8px;
116
+ right: -8px;
117
+ width: 16px;
118
+ height: 16px;
119
+ background: var(--cs-accent);
120
+ border-radius: 50%;
121
+ opacity: 0.8;
122
+ animation: pulse 2s infinite;
123
+ }
124
+
125
+ @keyframes pulse {
126
+ 0%, 100% {
127
+ transform: scale(1);
128
+ opacity: 0.8;
129
+ }
130
+ 50% {
131
+ transform: scale(1.2);
132
+ opacity: 0.4;
133
+ }
134
+ }
135
+
136
+ /* Touch-friendly spacing utilities */
137
+ .touch-spacing-xs { padding: 8px; }
138
+ .touch-spacing-sm { padding: 12px; }
139
+ .touch-spacing-md { padding: 16px; }
140
+ .touch-spacing-lg { padding: 20px; }
141
+ .touch-spacing-xl { padding: 24px; }
142
+
143
+ /* Touch-friendly margins */
144
+ .touch-margin-xs { margin: 8px; }
145
+ .touch-margin-sm { margin: 12px; }
146
+ .touch-margin-md { margin: 16px; }
147
+ .touch-margin-lg { margin: 20px; }
148
+ .touch-margin-xl { margin: 24px; }
149
+
150
+ /* Touch-friendly grid layouts */
151
+ .touch-grid {
152
+ display: grid;
153
+ gap: 16px;
154
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
155
+ }
156
+
157
+ .touch-grid-compact {
158
+ gap: 12px;
159
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
160
+ }
161
+
162
+ .touch-grid-spacious {
163
+ gap: 24px;
164
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
165
+ }
@@ -0,0 +1,7 @@
1
+ // Test utilities for theme-aware testing
2
+ export * from './theme-testing';
3
+
4
+ // Re-export common testing utilities
5
+ export { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
6
+ export { userEvent } from '@testing-library/user-event';
7
+ export type { RenderResult, RenderOptions } from '@testing-library/react';
@@ -0,0 +1,219 @@
1
+ import React from 'react';
2
+ import { render, RenderOptions, RenderResult } from '@testing-library/react';
3
+ import { ThemeProvider } from '../themes/ThemeProvider';
4
+ import { defaultThemes } from '../themes/base-themes';
5
+ import type { MultiThemeConfig } from '../themes/types';
6
+
7
+ // Mock window.matchMedia for Jest environment
8
+ Object.defineProperty(window, 'matchMedia', {
9
+ writable: true,
10
+ value: jest.fn().mockImplementation(query => ({
11
+ matches: false,
12
+ media: query,
13
+ onchange: null,
14
+ addListener: jest.fn(), // deprecated
15
+ removeListener: jest.fn(), // deprecated
16
+ addEventListener: jest.fn(),
17
+ removeEventListener: jest.fn(),
18
+ dispatchEvent: jest.fn(),
19
+ })),
20
+ });
21
+
22
+ // Test utilities for theme-aware component testing
23
+
24
+ export interface ThemeTestingOptions extends Omit<RenderOptions, 'wrapper'> {
25
+ theme?: string;
26
+ themes?: Record<string, MultiThemeConfig>;
27
+ persistTheme?: boolean;
28
+ }
29
+
30
+ /**
31
+ * Renders a component wrapped with ThemeProvider for testing
32
+ */
33
+ export const renderWithTheme = (
34
+ component: React.ReactElement,
35
+ options: ThemeTestingOptions = {}
36
+ ): RenderResult => {
37
+ const {
38
+ theme = 'stan-design',
39
+ themes = defaultThemes,
40
+ persistTheme = false,
41
+ ...renderOptions
42
+ } = options;
43
+
44
+ const ThemeWrapper = ({ children }: { children: React.ReactNode }) => (
45
+ <ThemeProvider
46
+ defaultTheme={theme}
47
+ themes={themes}
48
+ persistTheme={persistTheme}
49
+ >
50
+ {children}
51
+ </ThemeProvider>
52
+ );
53
+
54
+ return render(component, {
55
+ wrapper: ThemeWrapper,
56
+ ...renderOptions,
57
+ });
58
+ };
59
+
60
+ /**
61
+ * Renders a component in all available themes for comprehensive testing
62
+ */
63
+ export const renderWithAllThemes = (
64
+ component: React.ReactElement,
65
+ options: Omit<ThemeTestingOptions, 'theme'> = {}
66
+ ): Record<string, RenderResult> => {
67
+ const { themes = defaultThemes, ...renderOptions } = options;
68
+ const results: Record<string, RenderResult> = {};
69
+
70
+ Object.keys(themes).forEach(themeName => {
71
+ // Create a unique container for each theme to avoid conflicts
72
+ const container = document.createElement('div');
73
+ container.id = `theme-test-${themeName}`;
74
+ document.body.appendChild(container);
75
+
76
+ results[themeName] = render(component, {
77
+ container,
78
+ wrapper: ({ children }) => (
79
+ <ThemeProvider
80
+ defaultTheme={themeName}
81
+ themes={themes}
82
+ persistTheme={false}
83
+ >
84
+ {children}
85
+ </ThemeProvider>
86
+ ),
87
+ ...renderOptions,
88
+ });
89
+ });
90
+
91
+ return results;
92
+ };
93
+
94
+ /**
95
+ * Cleanup function to remove theme test containers
96
+ */
97
+ export const cleanupThemeTests = (): void => {
98
+ const containers = document.querySelectorAll('[id^="theme-test-"]');
99
+ containers.forEach(container => {
100
+ container.remove();
101
+ });
102
+ };
103
+
104
+ /**
105
+ * Test helper to switch themes during testing
106
+ */
107
+ export const createThemeSwitcher = (initialTheme: string = 'stan-design') => {
108
+ let currentTheme = initialTheme;
109
+
110
+ return {
111
+ getCurrentTheme: () => currentTheme,
112
+ switchTo: (newTheme: string) => {
113
+ currentTheme = newTheme;
114
+ return currentTheme;
115
+ },
116
+ renderWithCurrentTheme: (component: React.ReactElement, options: Omit<ThemeTestingOptions, 'theme'> = {}) => {
117
+ return renderWithTheme(component, { theme: currentTheme, ...options });
118
+ }
119
+ };
120
+ };
121
+
122
+ /**
123
+ * Helper to test theme-specific styles and properties
124
+ */
125
+ export const getThemeStyles = (themeName: string, themes = defaultThemes) => {
126
+ const theme = themes[themeName];
127
+ if (!theme) {
128
+ throw new Error(`Theme '${themeName}' not found in provided themes`);
129
+ }
130
+ return theme;
131
+ };
132
+
133
+ /**
134
+ * Helper to test CSS custom properties applied by themes
135
+ */
136
+ export const getThemeCSSVariables = (element: Element): Record<string, string> => {
137
+ const computedStyle = window.getComputedStyle(element);
138
+ const cssVariables: Record<string, string> = {};
139
+
140
+ // Get all CSS custom properties (variables starting with --)
141
+ for (let i = 0; i < computedStyle.length; i++) {
142
+ const property = computedStyle[i];
143
+ if (property.startsWith('--')) {
144
+ cssVariables[property] = computedStyle.getPropertyValue(property).trim();
145
+ }
146
+ }
147
+
148
+ return cssVariables;
149
+ };
150
+
151
+ /**
152
+ * Helper to wait for theme transitions to complete
153
+ */
154
+ export const waitForThemeTransition = async (duration: number = 300): Promise<void> => {
155
+ return new Promise(resolve => {
156
+ setTimeout(resolve, duration);
157
+ });
158
+ };
159
+
160
+ /**
161
+ * Mock localStorage for theme persistence testing
162
+ */
163
+ export const createThemeStorageMock = () => {
164
+ const storage: Record<string, string> = {};
165
+
166
+ return {
167
+ getItem: jest.fn((key: string) => storage[key] || null),
168
+ setItem: jest.fn((key: string, value: string) => {
169
+ storage[key] = value;
170
+ }),
171
+ removeItem: jest.fn((key: string) => {
172
+ delete storage[key];
173
+ }),
174
+ clear: jest.fn(() => {
175
+ Object.keys(storage).forEach(key => delete storage[key]);
176
+ }),
177
+ get storage() {
178
+ return { ...storage };
179
+ }
180
+ };
181
+ };
182
+
183
+ /**
184
+ * Mock matchMedia for responsive and system theme testing
185
+ */
186
+ export const createMatchMediaMock = (matches: boolean = false) => {
187
+ return jest.fn().mockImplementation((query: string) => ({
188
+ matches,
189
+ media: query,
190
+ onchange: null,
191
+ addListener: jest.fn(),
192
+ removeListener: jest.fn(),
193
+ addEventListener: jest.fn(),
194
+ removeEventListener: jest.fn(),
195
+ dispatchEvent: jest.fn(),
196
+ }));
197
+ };
198
+
199
+ /**
200
+ * Test themes for consistent testing across all theme tests
201
+ */
202
+ export const getTestThemes = () => Object.keys(defaultThemes);
203
+
204
+ /**
205
+ * Helper to test theme contrast and accessibility
206
+ */
207
+ export const getThemeContrastInfo = (themeName: string, themes = defaultThemes) => {
208
+ const theme = themes[themeName];
209
+ if (!theme) {
210
+ throw new Error(`Theme '${themeName}' not found`);
211
+ }
212
+
213
+ return {
214
+ primaryColor: theme.colors.primary[500],
215
+ backgroundColor: theme.colors.text.primary,
216
+ textColor: theme.colors.text.primary,
217
+ borderColor: theme.colors.surface.border,
218
+ };
219
+ };