responsive-system 1.0.0

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 (40) hide show
  1. package/ARCHITECTURE.md +195 -0
  2. package/INSTALLATION.md +403 -0
  3. package/README.md +382 -0
  4. package/dist/components/LayoutSwitcher.d.ts +6 -0
  5. package/dist/components/layout/Footer.d.ts +3 -0
  6. package/dist/components/layout/Header.d.ts +3 -0
  7. package/dist/components/layout/Navigation.d.ts +3 -0
  8. package/dist/components/layout/Sidebar.d.ts +3 -0
  9. package/dist/components/layout/index.d.ts +5 -0
  10. package/dist/config/layout.d.ts +15 -0
  11. package/dist/constants/breakpoints.d.ts +19 -0
  12. package/dist/context/NavigationContext.d.ts +13 -0
  13. package/dist/context/ResponsiveLayoutContext.d.ts +22 -0
  14. package/dist/context/SidebarContext.d.ts +11 -0
  15. package/dist/context/index.d.ts +4 -0
  16. package/dist/hooks/index.d.ts +4 -0
  17. package/dist/hooks/useLayout.d.ts +27 -0
  18. package/dist/hooks/useResponsive.d.ts +7 -0
  19. package/dist/hooks/useResponsiveLayout.d.ts +64 -0
  20. package/dist/index.d.ts +11 -0
  21. package/dist/layouts/DashboardLayout.d.ts +7 -0
  22. package/dist/layouts/DefaultLayout.d.ts +7 -0
  23. package/dist/layouts/MainLayout.d.ts +12 -0
  24. package/dist/layouts/MinimalLayout.d.ts +7 -0
  25. package/dist/layouts/SidebarLayout.d.ts +7 -0
  26. package/dist/layouts/index.d.ts +6 -0
  27. package/dist/providers/ResponsiveLayoutProvider.d.ts +15 -0
  28. package/dist/providers/ResponsiveProvider.d.ts +11 -0
  29. package/dist/providers/index.d.ts +3 -0
  30. package/dist/responsive-system.cjs +9 -0
  31. package/dist/responsive-system.cjs.map +1 -0
  32. package/dist/responsive-system.mjs +580 -0
  33. package/dist/responsive-system.mjs.map +1 -0
  34. package/dist/types/responsive.d.ts +43 -0
  35. package/package.json +97 -0
  36. package/scripts/copy-types.js +46 -0
  37. package/scripts/generate-types.js +163 -0
  38. package/scripts/postinstall.js +76 -0
  39. package/src/plugin/responsiveScalePlugin.d.ts +57 -0
  40. package/src/plugin/responsiveScalePlugin.js +296 -0
@@ -0,0 +1,296 @@
1
+ /**
2
+ * Responsive Scale Plugin for Tailwind CSS
3
+ * Auto-scales typography, spacing, line-height, letter-spacing, and shadows across all breakpoints
4
+ */
5
+
6
+ const plugin = require('tailwindcss/plugin')
7
+
8
+ /**
9
+ * Default configuration
10
+ */
11
+ const defaultConfig = {
12
+ // Properties to auto-scale
13
+ scaleProperties: {
14
+ typography: true, // font-size
15
+ spacing: true, // padding, margin, gap, space
16
+ lineHeight: true, // line-height (NEW)
17
+ letterSpacing: true, // letter-spacing (NEW)
18
+ shadows: true, // box-shadow (NEW)
19
+ borderWidth: false, // border-width (experimental)
20
+ sizing: false, // width, height (can break layouts)
21
+ borderRadius: false // rounded-* (usually should stay fixed)
22
+ },
23
+
24
+ // Scale factors per breakpoint
25
+ scales: {
26
+ xs: 1.0, // 0px - mobile
27
+ sm: 1.0, // 640px
28
+ md: 1.0, // 768px
29
+ lg: 1.0, // 1024px
30
+ xl: 1.0, // 1280px
31
+ '2xl': 1.05, // 1536px - +5%
32
+ '3xl': 1.15, // 1920px - +15%
33
+ '4xl': 1.25, // 2560px - +25%
34
+ '5xl': 1.35 // 3840px - +35%
35
+ },
36
+
37
+ // Breakpoint values (must match tailwind.config.js)
38
+ breakpoints: {
39
+ xs: '0px',
40
+ sm: '640px',
41
+ md: '768px',
42
+ lg: '1024px',
43
+ xl: '1280px',
44
+ '2xl': '1536px',
45
+ '3xl': '1920px',
46
+ '4xl': '2560px',
47
+ '5xl': '3840px'
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Creates the responsive scale plugin
53
+ */
54
+ function createResponsiveScalePlugin(userConfig = {}) {
55
+ const config = {
56
+ ...defaultConfig,
57
+ ...userConfig,
58
+ scaleProperties: {
59
+ ...defaultConfig.scaleProperties,
60
+ ...(userConfig.scaleProperties || {})
61
+ },
62
+ scales: {
63
+ ...defaultConfig.scales,
64
+ ...(userConfig.scales || {})
65
+ },
66
+ breakpoints: {
67
+ ...defaultConfig.breakpoints,
68
+ ...(userConfig.breakpoints || {})
69
+ }
70
+ }
71
+
72
+ return plugin(function({ addBase, theme }) {
73
+ const breakpoints = config.breakpoints
74
+ const scales = config.scales
75
+ const { typography, spacing, lineHeight, letterSpacing, shadows, borderWidth } = config.scaleProperties
76
+
77
+ // Generate scaling CSS for each breakpoint
78
+ const scalingStyles = {}
79
+
80
+ Object.entries(breakpoints).forEach(([breakpointName, breakpointValue]) => {
81
+ const scale = scales[breakpointName] || 1.0
82
+
83
+ // Skip if no scaling needed
84
+ if (scale === 1.0) return
85
+
86
+ const mediaQuery = breakpointValue === '0px'
87
+ ? '@media (min-width: 0px)'
88
+ : `@media (min-width: ${breakpointValue})`
89
+
90
+ if (!scalingStyles[mediaQuery]) {
91
+ scalingStyles[mediaQuery] = {}
92
+ }
93
+
94
+ // Initialize :root for this breakpoint
95
+ if (!scalingStyles[mediaQuery][':root']) {
96
+ scalingStyles[mediaQuery][':root'] = {}
97
+ }
98
+
99
+ // Scale typography
100
+ if (typography) {
101
+ scalingStyles[mediaQuery][':root']['--scale-text'] = scale.toString()
102
+ }
103
+
104
+ // Scale spacing
105
+ if (spacing) {
106
+ scalingStyles[mediaQuery][':root']['--scale-spacing'] = scale.toString()
107
+ }
108
+
109
+ // Scale line-height
110
+ if (lineHeight) {
111
+ scalingStyles[mediaQuery][':root']['--scale-line-height'] = scale.toString()
112
+ }
113
+
114
+ // Scale letter-spacing
115
+ if (letterSpacing) {
116
+ scalingStyles[mediaQuery][':root']['--scale-letter-spacing'] = scale.toString()
117
+ }
118
+
119
+ // Scale shadows
120
+ if (shadows) {
121
+ scalingStyles[mediaQuery][':root']['--scale-shadow'] = scale.toString()
122
+ }
123
+
124
+ // Scale border-width
125
+ if (borderWidth) {
126
+ scalingStyles[mediaQuery][':root']['--scale-border'] = scale.toString()
127
+ }
128
+ })
129
+
130
+ // Apply base styles with CSS variables
131
+ addBase({
132
+ ':root': {
133
+ '--scale-text': '1',
134
+ '--scale-spacing': '1',
135
+ '--scale-line-height': '1',
136
+ '--scale-letter-spacing': '1',
137
+ '--scale-shadow': '1',
138
+ '--scale-border': '1'
139
+ },
140
+ ...scalingStyles
141
+ })
142
+ }, {
143
+ theme: {
144
+ extend: {
145
+ // Auto-grid classes for automatic column calculation
146
+ gridTemplateColumns: {
147
+ 'auto-xs': 'repeat(auto-fit, minmax(150px, 1fr))', // Cards muy pequeñas
148
+ 'auto-sm': 'repeat(auto-fit, minmax(200px, 1fr))', // Cards pequeñas
149
+ 'auto-md': 'repeat(auto-fit, minmax(280px, 1fr))', // Cards medianas (default)
150
+ 'auto-lg': 'repeat(auto-fit, minmax(400px, 1fr))', // Cards grandes
151
+ 'auto-xl': 'repeat(auto-fit, minmax(500px, 1fr))', // Cards muy grandes
152
+ },
153
+
154
+ // Extend Tailwind's spacing scale to use CSS variables
155
+ spacing: ({ theme }) => {
156
+ const baseSpacing = theme('spacing')
157
+ const scaledSpacing = {}
158
+
159
+ Object.entries(baseSpacing).forEach(([key, value]) => {
160
+ // Only scale numeric values, skip 'auto', 'px', etc.
161
+ if (typeof value === 'string' && value.match(/^[\d.]+rem$/)) {
162
+ const numValue = parseFloat(value)
163
+ scaledSpacing[key] = `calc(${numValue}rem * var(--scale-spacing))`
164
+ } else {
165
+ scaledSpacing[key] = value
166
+ }
167
+ })
168
+
169
+ return scaledSpacing
170
+ },
171
+
172
+ // Extend Tailwind's fontSize scale to use CSS variables
173
+ fontSize: ({ theme }) => {
174
+ const baseFontSize = theme('fontSize')
175
+ const scaledFontSize = {}
176
+
177
+ Object.entries(baseFontSize).forEach(([key, value]) => {
178
+ if (Array.isArray(value)) {
179
+ // fontSize with lineHeight: ['16px', { lineHeight: '24px' }]
180
+ const [size, config] = value
181
+ if (typeof size === 'string' && size.match(/^[\d.]+rem$/)) {
182
+ const numValue = parseFloat(size)
183
+ const scaledSize = `calc(${numValue}rem * var(--scale-text))`
184
+
185
+ // Scale line-height if present
186
+ if (config && config.lineHeight && typeof config.lineHeight === 'string' && config.lineHeight.match(/^[\d.]+rem$/)) {
187
+ const lhValue = parseFloat(config.lineHeight)
188
+ scaledFontSize[key] = [
189
+ scaledSize,
190
+ {
191
+ ...config,
192
+ lineHeight: `calc(${lhValue}rem * var(--scale-line-height))`
193
+ }
194
+ ]
195
+ } else {
196
+ scaledFontSize[key] = [scaledSize, config]
197
+ }
198
+ } else {
199
+ scaledFontSize[key] = value
200
+ }
201
+ } else if (typeof value === 'string' && value.match(/^[\d.]+rem$/)) {
202
+ // Simple fontSize: '16px'
203
+ const numValue = parseFloat(value)
204
+ scaledFontSize[key] = `calc(${numValue}rem * var(--scale-text))`
205
+ } else {
206
+ scaledFontSize[key] = value
207
+ }
208
+ })
209
+
210
+ return scaledFontSize
211
+ },
212
+
213
+ // Extend line-height to use CSS variables
214
+ lineHeight: ({ theme }) => {
215
+ const baseLineHeight = theme('lineHeight')
216
+ const scaledLineHeight = {}
217
+
218
+ Object.entries(baseLineHeight).forEach(([key, value]) => {
219
+ if (typeof value === 'string' && value.match(/^[\d.]+rem$/)) {
220
+ const numValue = parseFloat(value)
221
+ scaledLineHeight[key] = `calc(${numValue}rem * var(--scale-line-height))`
222
+ } else if (typeof value === 'string' && !isNaN(parseFloat(value)) && !value.includes('rem') && !value.includes('px')) {
223
+ // Unitless values (like '1.5') - scale them
224
+ const numValue = parseFloat(value)
225
+ scaledLineHeight[key] = `calc(${numValue} * var(--scale-line-height))`
226
+ } else {
227
+ scaledLineHeight[key] = value
228
+ }
229
+ })
230
+
231
+ return scaledLineHeight
232
+ },
233
+
234
+ // Extend letter-spacing to use CSS variables
235
+ letterSpacing: ({ theme }) => {
236
+ const baseLetterSpacing = theme('letterSpacing')
237
+ const scaledLetterSpacing = {}
238
+
239
+ Object.entries(baseLetterSpacing).forEach(([key, value]) => {
240
+ if (typeof value === 'string' && (value.match(/^[\d.]+rem$/) || value.match(/^-?[\d.]+em$/))) {
241
+ const numValue = parseFloat(value)
242
+ const unit = value.includes('rem') ? 'rem' : 'em'
243
+ scaledLetterSpacing[key] = `calc(${numValue}${unit} * var(--scale-letter-spacing))`
244
+ } else {
245
+ scaledLetterSpacing[key] = value
246
+ }
247
+ })
248
+
249
+ return scaledLetterSpacing
250
+ },
251
+
252
+ // Extend box-shadow to use CSS variables
253
+ boxShadow: ({ theme }) => {
254
+ const baseBoxShadow = theme('boxShadow')
255
+ const scaledBoxShadow = {}
256
+
257
+ Object.entries(baseBoxShadow).forEach(([key, value]) => {
258
+ if (typeof value === 'string' && value !== 'none') {
259
+ // Scale shadow blur and spread
260
+ // Shadow format: "0 4px 6px -1px rgb(0 0 0 / 0.1)"
261
+ const scaledValue = value.replace(
262
+ /([\d.]+)px/g,
263
+ (match, num) => `calc(${num}px * var(--scale-shadow))`
264
+ )
265
+ scaledBoxShadow[key] = scaledValue
266
+ } else {
267
+ scaledBoxShadow[key] = value
268
+ }
269
+ })
270
+
271
+ return scaledBoxShadow
272
+ },
273
+
274
+ // Extend border-width to use CSS variables (if enabled)
275
+ borderWidth: ({ theme }) => {
276
+ const baseBorderWidth = theme('borderWidth')
277
+ const scaledBorderWidth = {}
278
+
279
+ Object.entries(baseBorderWidth).forEach(([key, value]) => {
280
+ if (typeof value === 'string' && value.match(/^[\d.]+px$/)) {
281
+ const numValue = parseFloat(value)
282
+ scaledBorderWidth[key] = `calc(${numValue}px * var(--scale-border))`
283
+ } else {
284
+ scaledBorderWidth[key] = value
285
+ }
286
+ })
287
+
288
+ return scaledBorderWidth
289
+ }
290
+ }
291
+ }
292
+ })
293
+ }
294
+
295
+ module.exports = createResponsiveScalePlugin
296
+ module.exports.defaultConfig = defaultConfig