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

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 (70) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.esm.js +11 -2
  4. package/dist/index.js +11 -2
  5. package/dist/styles.css +1 -1
  6. package/package.json +1 -1
  7. package/src/index.css +1046 -0
  8. package/src/index.ts +9 -1
  9. package/src/plugins/theme-css-generator.ts +354 -0
  10. package/src/styles/base/fonts.css +30 -0
  11. package/src/styles/base/generated-theme-variables.css +573 -0
  12. package/src/styles/base/index.css +7 -0
  13. package/src/styles/base/reset.css +48 -0
  14. package/src/styles/base/theme.css +1068 -0
  15. package/src/styles/base/typography.css +68 -0
  16. package/src/styles/base/variables.css +5 -0
  17. package/src/styles/components/CLAUDE.md +62 -0
  18. package/src/styles/components/base/badge.css +428 -0
  19. package/src/styles/components/base/button.css +774 -0
  20. package/src/styles/components/base/card.css +601 -0
  21. package/src/styles/components/base/checkbox.css +442 -0
  22. package/src/styles/components/base/index.css +9 -0
  23. package/src/styles/components/base/input.css +887 -0
  24. package/src/styles/components/base/label.css +296 -0
  25. package/src/styles/components/data-display/chart.css +353 -0
  26. package/src/styles/components/data-display/data-grid.css +619 -0
  27. package/src/styles/components/data-display/index.css +9 -0
  28. package/src/styles/components/data-display/list.css +560 -0
  29. package/src/styles/components/data-display/table.css +498 -0
  30. package/src/styles/components/data-display/timeline.css +764 -0
  31. package/src/styles/components/data-display/tree.css +881 -0
  32. package/src/styles/components/feedback/alert.css +358 -0
  33. package/src/styles/components/feedback/index.css +7 -0
  34. package/src/styles/components/feedback/progress.css +435 -0
  35. package/src/styles/components/feedback/skeleton.css +337 -0
  36. package/src/styles/components/feedback/toast.css +564 -0
  37. package/src/styles/components/index.css +17 -0
  38. package/src/styles/components/navigation/breadcrumb.css +465 -0
  39. package/src/styles/components/navigation/index.css +9 -0
  40. package/src/styles/components/navigation/menu.css +572 -0
  41. package/src/styles/components/navigation/pagination.css +635 -0
  42. package/src/styles/components/navigation/sidebar.css +807 -0
  43. package/src/styles/components/navigation/stepper.css +519 -0
  44. package/src/styles/components/navigation/tabs.css +404 -0
  45. package/src/styles/components/overlay/backdrop.css +243 -0
  46. package/src/styles/components/overlay/index.css +8 -0
  47. package/src/styles/components/overlay/modal.css +482 -0
  48. package/src/styles/components/overlay/popover.css +607 -0
  49. package/src/styles/components/overlay/portal.css +213 -0
  50. package/src/styles/components/overlay/tooltip.css +488 -0
  51. package/src/styles/generated-theme-variables.css +573 -0
  52. package/src/styles/index.css +5 -0
  53. package/src/styles/layers/index.css +54 -0
  54. package/src/styles/layers/overrides.css +108 -0
  55. package/src/styles/layers/validation.css +159 -0
  56. package/src/styles/layers/validation.js +310 -0
  57. package/src/styles/themes/default.css +450 -0
  58. package/src/styles/themes/enterprise.css +370 -0
  59. package/src/styles/themes/harvey.css +436 -0
  60. package/src/styles/themes/index.css +4 -0
  61. package/src/styles/themes/stan-design.css +572 -0
  62. package/src/styles/utilities/advanced-transition-system.css +467 -0
  63. package/src/styles/utilities/battery-conscious-animations.css +289 -0
  64. package/src/styles/utilities/enterprise-mobile-experience.css +817 -0
  65. package/src/styles/utilities/hardware-acceleration.css +121 -0
  66. package/src/styles/utilities/index.css +20 -0
  67. package/src/styles/utilities/mobile-skeleton-loading.css +596 -0
  68. package/src/styles/utilities/semantic-input-system.css +451 -0
  69. package/src/styles/utilities/touch-friendly-interface.css +247 -0
  70. package/src/styles/utilities/touch-optimization.css +165 -0
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @rakeyshgidwani/roger-ui-bank-theme-stan-design
3
- * Complete design system package with stan-design theme
3
+ * Production-ready design system package with stan-design theme
4
4
  *
5
5
  * Auto-generated exports for:
6
6
  * - 41 UI components
@@ -9,6 +9,11 @@
9
9
  * - 30 theme system components
10
10
  * - 131 TypeScript types
11
11
  * - 4 design tokens
12
+ * - 0 build plugins
13
+ * - Complete CSS system (61+ files)
14
+ *
15
+ * PRODUCTION BUNDLE: Excludes development-only tools
16
+ * (testing utilities, dev tools, storybook examples)
12
17
  */
13
18
 
14
19
  // UI Components
@@ -169,6 +174,9 @@ export { TokenGenerator } from './tokens/tokenGenerator';
169
174
  export { TokenManager } from './tokens/tokenManager';
170
175
  export { TokenValidator } from './tokens/tokenValidator';
171
176
 
177
+ // Build Plugins
178
+
179
+
172
180
  // Types
173
181
  export type { NavigationBaseProps } from './components/ui/navigation/types';
174
182
  export type { NavigationItem } from './components/ui/navigation/types';
@@ -0,0 +1,354 @@
1
+ import { resolve } from 'path'
2
+ import { existsSync, mkdirSync, writeFileSync } from 'fs'
3
+ import type { Plugin } from 'vite'
4
+ import type { MultiThemeConfig } from '../themes/types'
5
+ import { defaultThemes } from '../themes/base-themes'
6
+
7
+ export default function themeCSSGenerator(): Plugin {
8
+ let config: any
9
+
10
+ // Helper function to safely convert values to strings
11
+ const valueToString = (value: any): string => {
12
+ if (Array.isArray(value)) {
13
+ return value.join(', ')
14
+ }
15
+ if (typeof value === 'object' && value !== null) {
16
+ return JSON.stringify(value)
17
+ }
18
+ return String(value)
19
+ }
20
+
21
+ // Helper function to create CSS variable name
22
+ const createCSSVarName = (path: string[]): string => {
23
+ return `--cs-${path.join('-').replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`)}`
24
+ }
25
+
26
+ // Generate @font-face declarations from font configuration
27
+ const generateFontFaces = (themeObj: MultiThemeConfig): string => {
28
+ let css = ''
29
+
30
+ if (!themeObj.fonts) return css
31
+
32
+ Object.entries(themeObj.fonts).forEach(([, fontConfig]) => {
33
+ if (fontConfig.source?.type === 'custom' && fontConfig.source.files?.woff2) {
34
+ const { family, source, weights, display } = fontConfig
35
+
36
+ if (weights && Array.isArray(weights) && weights.length > 0) {
37
+ const minWeight = Math.min(...weights)
38
+ const maxWeight = Math.max(...weights)
39
+
40
+ css += `\n@font-face {\n`
41
+ css += ` font-family: '${family}';\n`
42
+ css += ` src: url('${source.files.woff2}') format('woff2-variations');\n`
43
+ css += ` font-weight: ${minWeight} ${maxWeight};\n`
44
+ css += ` font-display: ${display || 'swap'};\n`
45
+ css += `}\n`
46
+ }
47
+ }
48
+ })
49
+
50
+ return css
51
+ }
52
+
53
+ // NEW: Extract breakpoints from anywhere in the theme object
54
+ const extractBreakpoints = (obj: any): any => {
55
+ let breakpoints: any = {}
56
+
57
+ const searchForBreakpoints = (currentObj: any, currentPath: string[] = []) => {
58
+ if (typeof currentObj !== 'object' || currentObj === null) {
59
+ return
60
+ }
61
+
62
+ Object.entries(currentObj).forEach(([key, value]) => {
63
+ if (key === 'breakpoints' && typeof value === 'object' && value !== null) {
64
+ // Found breakpoints, extract them
65
+ Object.entries(value).forEach(([bpKey, bpValue]) => {
66
+ if (typeof bpValue === 'string' || typeof bpValue === 'number') {
67
+ breakpoints[bpKey] = bpValue
68
+ }
69
+ })
70
+ } else if (typeof value === 'object' && value !== null) {
71
+ // Recursively search deeper
72
+ searchForBreakpoints(value, [...currentPath, key])
73
+ }
74
+ })
75
+ }
76
+
77
+ searchForBreakpoints(obj)
78
+ return breakpoints
79
+ }
80
+
81
+ // NEW: Generate breakpoint CSS variables and @custom-media queries
82
+ const generateBreakpointVariables = (breakpoints: any): string => {
83
+ let css = ''
84
+ if (Object.keys(breakpoints).length === 0) { return css }
85
+
86
+ css += ` /* Breakpoint Variables */\n`
87
+ Object.entries(breakpoints).forEach(([key, value]) => {
88
+ css += ` --cs-breakpoints-${key}: ${value};\n`
89
+ })
90
+ css += '\n'
91
+
92
+ // NEW: Generate @custom-media queries for use in media queries
93
+ css += ` /* Custom Media Queries for Breakpoints */\n`
94
+ Object.entries(breakpoints).forEach(([key, value]) => {
95
+ css += ` @custom-media --bp-${key} (min-width: ${value});\n`
96
+ })
97
+ css += '\n'
98
+
99
+ return css
100
+ }
101
+
102
+ // Recursively generate CSS variables from theme object
103
+ const generateCSSVariables = (obj: any, path: string[] = []): string => {
104
+ let css = ''
105
+
106
+ if (typeof obj !== 'object' || obj === null) {
107
+ return css
108
+ }
109
+
110
+ Object.entries(obj).forEach(([key, value]) => {
111
+ const currentPath = [...path, key]
112
+
113
+ if (typeof value === 'string' || typeof value === 'number') {
114
+ // Generate CSS variable for primitive values
115
+ const cssVarName = createCSSVarName(currentPath)
116
+ css += ` ${cssVarName}: ${value};\n`
117
+ } else if (Array.isArray(value)) {
118
+ // Handle arrays (like font weights, tags)
119
+ const cssVarName = createCSSVarName(currentPath)
120
+ css += ` ${cssVarName}: ${valueToString(value)};\n`
121
+ } else if (typeof value === 'object' && value !== null) {
122
+ // Recursively process nested objects
123
+ css += generateCSSVariables(value, currentPath)
124
+ }
125
+ })
126
+
127
+ return css
128
+ }
129
+
130
+ // Generate CSS from theme object using structured traversal
131
+ const generateSingleThemeCSS = (themeName: string, themeObj: MultiThemeConfig): string => {
132
+ // Always generate light + dark mode CSS
133
+ return generateLightDarkCSS(themeName, themeObj)
134
+ }
135
+
136
+ // Generate light and dark mode CSS
137
+ const generateLightDarkCSS = (themeName: string, themeObj: MultiThemeConfig): string => {
138
+ let css = `/* ${themeName} Theme - Light & Dark Modes */\n`
139
+
140
+ // Generate @font-face declarations
141
+ css += generateFontFaces(themeObj)
142
+
143
+ // NEW: Extract breakpoints from anywhere in the theme
144
+ const breakpoints = extractBreakpoints(themeObj)
145
+
146
+ // Generate light mode variables (default)
147
+ css += `:root {\n`
148
+ css += ` /* Light Mode Variables */\n`
149
+
150
+ // NEW: Generate breakpoint variables first
151
+ css += generateBreakpointVariables(breakpoints)
152
+
153
+ // Generate all other CSS variables
154
+ css += generateCSSVariables(themeObj)
155
+ css += '}\n\n'
156
+
157
+ // Generate dark mode variables
158
+ css += `.dark {\n`
159
+ css += ` /* Dark Mode Variables */\n`
160
+
161
+ if (themeObj.modes?.dark?.colors && Object.keys(themeObj.modes.dark.colors).length > 0) {
162
+ // Use custom dark mode colors if defined
163
+ css += generateDarkModeColors(themeObj.modes.dark.colors)
164
+ } else {
165
+ // Generate automatic dark mode by adapting colors
166
+ css += generateDarkModeVariables(themeObj)
167
+ }
168
+
169
+ css += '}\n'
170
+ return css
171
+ }
172
+
173
+ // Generate dark mode colors from explicit color definitions
174
+ const generateDarkModeColors = (darkColors: any): string => {
175
+ let css = ''
176
+
177
+ Object.entries(darkColors).forEach(([colorKey, colorValue]) => {
178
+ if (typeof colorValue === 'object' && colorValue !== null) {
179
+ // Handle nested color objects (like surface, text, etc.)
180
+ Object.entries(colorValue).forEach(([subKey, subValue]) => {
181
+ if (typeof subValue === 'string' || typeof subValue === 'number') {
182
+ css += ` --cs-colors-${colorKey}-${subKey}: ${subValue};\n`
183
+ }
184
+ })
185
+ } else if (typeof colorValue === 'string' || typeof colorValue === 'number') {
186
+ // Handle direct color values
187
+ css += ` --cs-colors-${colorKey}: ${colorValue};\n`
188
+ }
189
+ })
190
+
191
+ return css
192
+ }
193
+
194
+ // Generate dark mode variables by adapting light mode colors
195
+ const generateDarkModeVariables = (themeObj: MultiThemeConfig): string => {
196
+ // Create a dark variant of the theme by adapting colors
197
+ const darkTheme = adaptThemeForDarkMode(themeObj)
198
+
199
+ // Generate CSS variables only for the properties that exist in the dark theme
200
+ let css = ''
201
+
202
+ if (darkTheme.colors) {
203
+ // Generate CSS variables for colors
204
+ Object.entries(darkTheme.colors).forEach(([colorKey, colorValue]) => {
205
+ if (typeof colorValue === 'object' && colorValue !== null) {
206
+ // Handle nested color objects (like surface, text, etc.)
207
+ Object.entries(colorValue).forEach(([subKey, subValue]) => {
208
+ if (typeof subValue === 'string' || typeof subValue === 'number') {
209
+ css += ` --cs-colors-${colorKey}-${subKey}: ${subValue};\n`
210
+ }
211
+ })
212
+ } else if (typeof colorValue === 'string' || typeof colorValue === 'number') {
213
+ // Handle direct color values
214
+ css += ` --cs-colors-${colorKey}: ${colorValue};\n`
215
+ }
216
+ })
217
+ }
218
+
219
+ // Add some basic dark mode variables for testing
220
+ css += ` --cs-colors-surface-background: #0f172a;\n`
221
+ css += ` --cs-colors-surface-surface: #1e293b;\n`
222
+ css += ` --cs-colors-surface-border: #334155;\n`
223
+ css += ` --cs-colors-surface-divider: #475569;\n`
224
+ css += ` --cs-colors-text-primary: #f8fafc;\n`
225
+ css += ` --cs-colors-text-secondary: #cbd5e1;\n`
226
+ css += ` --cs-colors-text-muted: #94a3b8;\n`
227
+
228
+ return css
229
+ }
230
+
231
+ // Adapt theme for dark mode
232
+ const adaptThemeForDarkMode = (_themeObj: MultiThemeConfig): Partial<MultiThemeConfig> => {
233
+ // This would implement your dark mode color adaptation logic
234
+ // You can use the existing ColorManager or implement custom logic
235
+ return {
236
+ colors: {
237
+ surface: {
238
+ background: '#0f172a', // Dark background
239
+ surface: '#1e293b', // Dark surface
240
+ border: '#334155', // Dark border
241
+ divider: '#475569' // Dark divider
242
+ },
243
+ text: {
244
+ primary: '#f8fafc', // Light text
245
+ secondary: '#cbd5e1', // Muted text
246
+ muted: '#94a3b8', // Muted text
247
+ inverse: '#0f172a', // Dark text for light backgrounds
248
+ onPrimary: '#0f172a', // Text on primary color
249
+ onSecondary: '#0f172a', // Text on secondary color
250
+ onSurface: '#f8fafc' // Text on surface
251
+ }
252
+ // ... other color adaptations
253
+ } as any // Type assertion to bypass strict typing for now
254
+ }
255
+ }
256
+
257
+ // Generate CSS for all themes using structured approach
258
+ const generateAllThemesCSS = () => {
259
+ try {
260
+ // Create themes directory if it doesn't exist
261
+ const themesDir = resolve(config.root, 'src/styles/themes')
262
+ if (!existsSync(themesDir)) {
263
+ mkdirSync(themesDir, { recursive: true })
264
+ }
265
+
266
+ let indexCSS = '/* Theme Index - Import all themes */\n'
267
+ let defaultThemeCSS = '/* Default Theme Variables (Coach-Stan) */\n'
268
+
269
+ // Use defaultThemes instead of hardcoded themeFiles
270
+ for (const [themeKey, themeObj] of Object.entries(defaultThemes)) {
271
+ try {
272
+ // Generate CSS for this specific theme
273
+ const themeCSS = generateSingleThemeCSS(themeObj.meta.name, themeObj)
274
+
275
+ // Write individual theme file
276
+ const themeFileName = `${themeKey}.css`
277
+ const themeOutputPath = resolve(themesDir, themeFileName)
278
+ writeFileSync(themeOutputPath, themeCSS, 'utf-8')
279
+
280
+ console.log(`✅ Generated dual-mode CSS for theme: ${themeObj.meta.name} -> ${themeFileName}`)
281
+
282
+ // Add import to index file
283
+ indexCSS += `@import './${themeFileName}';\n`
284
+
285
+ // Set stan-design theme as default
286
+ if (themeKey === 'stan-design') {
287
+ defaultThemeCSS += themeCSS
288
+ }
289
+
290
+ } catch (error) {
291
+ console.error(`❌ Error processing ${themeKey}:`, error)
292
+ }
293
+ }
294
+
295
+ // Write theme index file
296
+ const indexPath = resolve(config.root, 'src/styles/themes/index.css')
297
+ writeFileSync(indexPath, indexCSS, 'utf-8')
298
+
299
+ // Write default theme file (for backward compatibility)
300
+ const defaultPath = resolve(config.root, 'src/styles/generated-theme-variables.css')
301
+ writeFileSync(defaultPath, defaultThemeCSS, 'utf-8')
302
+
303
+ console.log('✅ Theme CSS Generator: Generated all dual-mode theme files successfully')
304
+
305
+ } catch (error) {
306
+ console.error('❌ Theme CSS Generator Error:', error)
307
+ }
308
+ }
309
+
310
+ // Main function to generate theme CSS
311
+ const generateThemeCSS = () => {
312
+ try {
313
+ // Check if themes directory exists
314
+ const themesSourceDir = resolve(config.root, 'src/themes/themes')
315
+
316
+ if (!existsSync(themesSourceDir)) {
317
+ console.warn('⚠️ Theme CSS Generator: themes/themes/ directory not found')
318
+ return
319
+ }
320
+
321
+ // Generate CSS for all themes
322
+ generateAllThemesCSS()
323
+
324
+ } catch (error) {
325
+ console.error('❌ Theme CSS Generator Error:', error)
326
+ }
327
+ }
328
+
329
+ return {
330
+ name: 'theme-css-generator',
331
+
332
+ configResolved(resolvedConfig) {
333
+ config = resolvedConfig
334
+ },
335
+
336
+ buildStart() {
337
+ generateThemeCSS()
338
+ },
339
+
340
+ handleHotUpdate({ file }) {
341
+ // Use defaultThemes keys instead of hardcoded file paths
342
+ const themeKeys = Object.keys(defaultThemes)
343
+ const shouldRegenerate = themeKeys.some(themeKey =>
344
+ file.includes(`themes/${themeKey}.ts`) ||
345
+ file.includes('inheritance.ts') ||
346
+ file.includes('types.ts')
347
+ )
348
+
349
+ if (shouldRegenerate) {
350
+ generateThemeCSS()
351
+ }
352
+ }
353
+ }
354
+ }
@@ -0,0 +1,30 @@
1
+ /* Clash Display Variable Font Declarations */
2
+
3
+ @font-face {
4
+ font-family: 'Clash Display';
5
+ src: url('/fonts/clash-display/ClashDisplay-Variable.woff2') format('woff2-variations');
6
+ font-weight: 200 700;
7
+ font-style: normal;
8
+ font-display: swap;
9
+ }
10
+
11
+ /* Fallback for browsers that don't support variable fonts */
12
+ @supports not (font-variation-settings: normal) {
13
+ @font-face {
14
+ font-family: 'Clash Display';
15
+ src: url('/fonts/clash-display/ClashDisplay-Variable.woff2') format('woff2');
16
+ font-weight: 400;
17
+ font-style: normal;
18
+ font-display: swap;
19
+ }
20
+ }
21
+
22
+ /* Fallback for older browsers that don't support WOFF2 */
23
+ @supports not (font-display: swap) {
24
+ @font-face {
25
+ font-family: 'Clash Display';
26
+ src: url('/fonts/clash-display/ClashDisplay-Variable.woff') format('woff');
27
+ font-weight: 200 700;
28
+ font-style: normal;
29
+ }
30
+ }