shru-design-system 0.0.6 → 0.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shru-design-system",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "A comprehensive design system with theme toggle, components, and token-based theming",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -35,8 +35,9 @@
35
35
  "apps/*"
36
36
  ],
37
37
  "scripts": {
38
- "build": "tsup src/index.ts --dts --format esm,cjs",
39
- "build:lib": "tsup src/index.ts --dts --format esm,cjs",
38
+ "build": "npm run build:css && tsup src/index.ts --dts --format esm,cjs",
39
+ "build:lib": "npm run build:css && tsup src/index.ts --dts --format esm,cjs",
40
+ "build:css": "node scripts/build-css.js",
40
41
  "postinstall": "npm run build:lib",
41
42
  "copy:tokens": "node scripts/copy-tokens.js",
42
43
  "copy:globals": "node scripts/copy-globals.js",
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Build script to pre-generate all Tailwind utilities needed by components
5
+ * This ensures users don't need to configure Tailwind - they just import the CSS
6
+ */
7
+
8
+ import { readFileSync, writeFileSync, readdirSync, statSync } from 'fs'
9
+ import { join, dirname } from 'path'
10
+ import { fileURLToPath } from 'url'
11
+
12
+ const __filename = fileURLToPath(import.meta.url)
13
+ const __dirname = dirname(__filename)
14
+ const rootDir = join(__dirname, '..')
15
+ const componentsDir = join(rootDir, 'apps/design-system/src/design-system/components')
16
+ const stylesDir = join(rootDir, 'apps/design-system/styles')
17
+ const outputFile = join(stylesDir, 'globals.css')
18
+
19
+ // Extract all Tailwind classes from a string
20
+ function extractTailwindClasses(content) {
21
+ const classRegex = /className=["']([^"']+)["']/g
22
+ const cnRegex = /cn\(["']([^"']+)["']/g
23
+ const classes = new Set()
24
+
25
+ // Match className="..."
26
+ let match
27
+ while ((match = classRegex.exec(content)) !== null) {
28
+ match[1].split(/\s+/).forEach(cls => {
29
+ if (cls && !cls.startsWith('{') && !cls.includes('${')) {
30
+ classes.add(cls)
31
+ }
32
+ })
33
+ }
34
+
35
+ // Match cn("...")
36
+ while ((match = cnRegex.exec(content)) !== null) {
37
+ match[1].split(/\s+/).forEach(cls => {
38
+ if (cls) classes.add(cls)
39
+ })
40
+ }
41
+
42
+ return Array.from(classes)
43
+ }
44
+
45
+ // Recursively find all component files
46
+ function findComponentFiles(dir, fileList = []) {
47
+ const files = readdirSync(dir)
48
+
49
+ files.forEach(file => {
50
+ const filePath = join(dir, file)
51
+ const stat = statSync(filePath)
52
+
53
+ if (stat.isDirectory()) {
54
+ findComponentFiles(filePath, fileList)
55
+ } else if (file.endsWith('.tsx') || file.endsWith('.ts')) {
56
+ fileList.push(filePath)
57
+ }
58
+ })
59
+
60
+ return fileList
61
+ }
62
+
63
+ // Collect all classes from components
64
+ const componentFiles = findComponentFiles(componentsDir)
65
+ const allClasses = new Set()
66
+
67
+ console.log(`Scanning ${componentFiles.length} component files...`)
68
+
69
+ componentFiles.forEach(file => {
70
+ try {
71
+ const content = readFileSync(file, 'utf-8')
72
+ const classes = extractTailwindClasses(content)
73
+ classes.forEach(cls => allClasses.add(cls))
74
+ } catch (err) {
75
+ console.warn(`Warning: Could not read ${file}:`, err.message)
76
+ }
77
+ })
78
+
79
+ // Also add common utilities that are always needed
80
+ const commonUtilities = [
81
+ // Layout
82
+ 'flex', 'inline-flex', 'grid', 'block', 'inline-block', 'hidden',
83
+ 'items-center', 'items-start', 'items-end', 'justify-center', 'justify-between', 'justify-start', 'justify-end',
84
+ 'flex-col', 'flex-row', 'flex-wrap', 'flex-nowrap',
85
+ 'gap-1', 'gap-2', 'gap-3', 'gap-4', 'gap-6', 'gap-8',
86
+
87
+ // Spacing
88
+ 'p-0', 'p-1', 'p-2', 'p-3', 'p-4', 'p-6', 'p-8',
89
+ 'px-1', 'px-2', 'px-3', 'px-4', 'px-6', 'px-8',
90
+ 'py-1', 'py-2', 'py-3', 'py-4', 'py-6', 'py-8',
91
+ 'm-0', 'm-1', 'm-2', 'm-4', 'm-6', 'm-8',
92
+ 'mx-auto', 'my-auto',
93
+ 'mb-1', 'mb-2', 'mb-4', 'mb-6', 'mb-8',
94
+ 'mt-1', 'mt-2', 'mt-4', 'mt-6', 'mt-8',
95
+ 'mr-1', 'mr-2', 'mr-4',
96
+ 'ml-1', 'ml-2', 'ml-4',
97
+
98
+ // Sizing
99
+ 'w-full', 'w-auto', 'w-fit', 'w-1/2', 'w-1/3', 'w-2/3', 'w-1/4', 'w-3/4',
100
+ 'h-full', 'h-auto', 'h-fit', 'h-screen', 'min-h-screen',
101
+ 'h-4', 'h-5', 'h-6', 'h-8', 'h-9', 'h-10', 'h-12', 'h-14', 'h-16',
102
+ 'w-4', 'w-5', 'w-6', 'w-8', 'w-10', 'w-12', 'w-14', 'w-16',
103
+ 'min-w-0', 'max-w-full', 'max-w-screen-xl', 'max-w-screen-2xl',
104
+
105
+ // Border radius
106
+ 'rounded-none', 'rounded-sm', 'rounded', 'rounded-md', 'rounded-lg', 'rounded-xl', 'rounded-2xl', 'rounded-full',
107
+
108
+ // Colors (common variants)
109
+ 'bg-transparent', 'bg-current',
110
+ 'text-transparent', 'text-current',
111
+ 'border-transparent', 'border-current',
112
+
113
+ // Typography
114
+ 'text-xs', 'text-sm', 'text-base', 'text-lg', 'text-xl', 'text-2xl', 'text-3xl', 'text-4xl',
115
+ 'font-thin', 'font-light', 'font-normal', 'font-medium', 'font-semibold', 'font-bold', 'font-extrabold',
116
+ 'leading-none', 'leading-tight', 'leading-normal', 'leading-relaxed', 'leading-loose',
117
+ 'text-left', 'text-center', 'text-right', 'text-justify',
118
+ 'uppercase', 'lowercase', 'capitalize', 'normal-case',
119
+ 'whitespace-normal', 'whitespace-nowrap', 'whitespace-pre',
120
+
121
+ // Effects
122
+ 'shadow-sm', 'shadow', 'shadow-md', 'shadow-lg', 'shadow-xl', 'shadow-2xl', 'shadow-none',
123
+ 'opacity-0', 'opacity-25', 'opacity-50', 'opacity-75', 'opacity-100',
124
+
125
+ // Transitions
126
+ 'transition', 'transition-all', 'transition-colors', 'transition-opacity', 'transition-transform',
127
+ 'duration-75', 'duration-100', 'duration-150', 'duration-200', 'duration-300', 'duration-500',
128
+ 'ease-in', 'ease-out', 'ease-in-out',
129
+
130
+ // Transforms
131
+ 'scale-95', 'scale-100', 'scale-105', 'scale-110',
132
+ 'rotate-0', 'rotate-90', 'rotate-180',
133
+
134
+ // Position
135
+ 'relative', 'absolute', 'fixed', 'sticky', 'static',
136
+ 'inset-0', 'top-0', 'right-0', 'bottom-0', 'left-0',
137
+ 'z-0', 'z-10', 'z-20', 'z-30', 'z-40', 'z-50',
138
+
139
+ // Overflow
140
+ 'overflow-hidden', 'overflow-auto', 'overflow-scroll', 'overflow-visible',
141
+ 'overflow-x-hidden', 'overflow-y-hidden',
142
+
143
+ // Display
144
+ 'sr-only', 'not-sr-only',
145
+
146
+ // Interactive
147
+ 'cursor-pointer', 'cursor-not-allowed', 'cursor-default',
148
+ 'select-none', 'select-text', 'select-all',
149
+ 'pointer-events-none', 'pointer-events-auto',
150
+
151
+ // States
152
+ 'hover:opacity-80', 'hover:opacity-90', 'hover:scale-105', 'hover:scale-110',
153
+ 'active:scale-95', 'active:opacity-80',
154
+ 'focus:outline-none', 'focus:ring-2', 'focus:ring-offset-2',
155
+ 'disabled:opacity-50', 'disabled:cursor-not-allowed', 'disabled:pointer-events-none',
156
+
157
+ // Responsive (common breakpoints)
158
+ 'sm:block', 'sm:hidden', 'md:block', 'md:hidden', 'lg:block', 'lg:hidden',
159
+ 'sm:flex', 'md:flex', 'lg:flex',
160
+ ]
161
+
162
+ commonUtilities.forEach(cls => allClasses.add(cls))
163
+
164
+ console.log(`Found ${allClasses.size} unique Tailwind classes`)
165
+
166
+ // Read the current globals.css
167
+ let globalsContent = readFileSync(outputFile, 'utf-8')
168
+
169
+ // Remove the old @layer utilities section if it exists
170
+ const utilitiesStart = globalsContent.indexOf('@layer utilities {')
171
+ const utilitiesEnd = globalsContent.indexOf('}\n\n@layer components', utilitiesStart)
172
+ if (utilitiesStart !== -1 && utilitiesEnd !== -1) {
173
+ globalsContent = globalsContent.slice(0, utilitiesStart) + globalsContent.slice(utilitiesEnd + 2)
174
+ }
175
+
176
+ // Generate safelist comment
177
+ const safelistComment = `/*
178
+ * Pre-generated utility classes for design system components
179
+ * These utilities are explicitly defined to ensure they work in consuming apps
180
+ * without requiring Tailwind configuration or scanning
181
+ *
182
+ * Generated from ${componentFiles.length} component files
183
+ * Total classes: ${allClasses.size}
184
+ */\n\n`
185
+
186
+ // Generate utility classes
187
+ const utilityClasses = Array.from(allClasses)
188
+ .sort()
189
+ .map(cls => {
190
+ // Skip complex classes with variables for now - handle common ones
191
+ if (cls.includes('${') || cls.includes('{')) return null
192
+
193
+ // Generate CSS for common patterns
194
+ if (cls.startsWith('rounded-')) {
195
+ if (cls === 'rounded-full') return `.${cls} { border-radius: 9999px !important; }`
196
+ if (cls === 'rounded-none') return `.${cls} { border-radius: 0 !important; }`
197
+ if (cls === 'rounded') return `.${cls} { border-radius: var(--radius) !important; }`
198
+ if (cls === 'rounded-sm') return `.${cls} { border-radius: var(--radius-sm) !important; }`
199
+ if (cls === 'rounded-md') return `.${cls} { border-radius: var(--radius-md) !important; }`
200
+ if (cls === 'rounded-lg') return `.${cls} { border-radius: var(--radius-lg) !important; }`
201
+ if (cls === 'rounded-xl') return `.${cls} { border-radius: var(--radius-xl) !important; }`
202
+ if (cls === 'rounded-2xl') return `.${cls} { border-radius: calc(var(--radius) + 8px) !important; }`
203
+ }
204
+
205
+ // For other classes, we'll let Tailwind generate them
206
+ // But we need to ensure they're in the safelist
207
+ return null
208
+ })
209
+ .filter(Boolean)
210
+ .join('\n')
211
+
212
+ // Insert the safelist and utilities before @layer components
213
+ const componentsMarker = globalsContent.indexOf('@layer components')
214
+ if (componentsMarker !== -1) {
215
+ const beforeComponents = globalsContent.slice(0, componentsMarker)
216
+ const afterComponents = globalsContent.slice(componentsMarker)
217
+
218
+ globalsContent = beforeComponents +
219
+ safelistComment +
220
+ `@layer utilities {\n${utilityClasses}\n}\n\n` +
221
+ afterComponents
222
+ } else {
223
+ // Append if no components layer found
224
+ globalsContent += '\n\n' + safelistComment + `@layer utilities {\n${utilityClasses}\n}\n`
225
+ }
226
+
227
+ writeFileSync(outputFile, globalsContent, 'utf-8')
228
+ console.log(`✅ Updated ${outputFile}`)
229
+ console.log(` Added ${utilityClasses.split('\n').filter(l => l.trim()).length} explicit utility overrides`)
230
+ console.log(` Total classes scanned: ${allClasses.size}`)
231
+