responsive-system 1.1.5 → 1.2.1

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 (36) hide show
  1. package/package.json +2 -1
  2. package/scripts/postinstall.js +2 -3
  3. package/src/App.css +42 -0
  4. package/src/App.tsx +29 -0
  5. package/src/assets/react.svg +1 -0
  6. package/src/components/LayoutSwitcher.tsx +62 -0
  7. package/src/components/ResponsiveDemo.tsx +282 -0
  8. package/src/components/layout/Footer.tsx +90 -0
  9. package/src/components/layout/Header.tsx +105 -0
  10. package/src/components/layout/Navigation.tsx +96 -0
  11. package/src/components/layout/Sidebar.tsx +108 -0
  12. package/src/components/layout/index.ts +4 -0
  13. package/src/config/layout.ts +61 -0
  14. package/src/constants/breakpoints.ts +48 -0
  15. package/src/context/NavigationContext.tsx +32 -0
  16. package/src/context/ResponsiveLayoutContext.tsx +37 -0
  17. package/src/context/SidebarContext.tsx +26 -0
  18. package/src/context/index.ts +4 -0
  19. package/src/hooks/index.ts +4 -0
  20. package/src/hooks/useLayout.ts +27 -0
  21. package/src/hooks/useResponsive.ts +189 -0
  22. package/src/hooks/useResponsiveLayout.ts +51 -0
  23. package/src/index.css +1 -0
  24. package/src/index.ts +100 -0
  25. package/src/layouts/DashboardLayout.tsx +76 -0
  26. package/src/layouts/DefaultLayout.tsx +30 -0
  27. package/src/layouts/MainLayout.tsx +38 -0
  28. package/src/layouts/MinimalLayout.tsx +20 -0
  29. package/src/layouts/SidebarLayout.tsx +36 -0
  30. package/src/layouts/index.ts +5 -0
  31. package/src/main.tsx +10 -0
  32. package/src/pages/ResponsiveTestPage.tsx +400 -0
  33. package/src/providers/ResponsiveLayoutProvider.tsx +92 -0
  34. package/src/providers/ResponsiveProvider.tsx +18 -0
  35. package/src/providers/index.ts +3 -0
  36. package/src/types/responsive.ts +64 -0
@@ -0,0 +1,400 @@
1
+ import { useResponsiveLayout } from '../hooks'
2
+ import LayoutSwitcher from '../components/LayoutSwitcher'
3
+
4
+ // Componente de indicador de breakpoint
5
+ const BreakpointIndicator = () => {
6
+ const { breakpoint, width, height, orientation, debug } = useResponsiveLayout()
7
+
8
+ return (
9
+ <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-50">
10
+ <div className="bg-black/90 backdrop-blur-sm text-white rounded-full shadow-xl border border-white/20 px-6 py-3 flex items-center space-x-4 min-w-max">
11
+ <span className="font-bold text-blue-300 text-sm">Breakpoint: {breakpoint}</span>
12
+ <span className="text-green-300 text-sm">{width}×{height}</span>
13
+ <span className="text-purple-300 text-sm">{orientation}</span>
14
+ {debug && <span className="text-yellow-300 font-semibold text-sm">Debug</span>}
15
+ </div>
16
+ </div>
17
+ )
18
+ }
19
+
20
+ // Componente de test de helpers booleanos
21
+ const BooleanHelpersTest = () => {
22
+ const {
23
+ isXs, isSm, isMd, isLg, isXl, is2Xl, is3Xl, is4Xl, is5Xl,
24
+ isMobile, isTablet, isDesktop, isSmall, isLarge, isUltraWide, is4K, is5K
25
+ } = useResponsiveLayout()
26
+
27
+ const helpers = [
28
+ { name: 'isXs', value: isXs },
29
+ { name: 'isSm', value: isSm },
30
+ { name: 'isMd', value: isMd },
31
+ { name: 'isLg', value: isLg },
32
+ { name: 'isXl', value: isXl },
33
+ { name: 'is2Xl', value: is2Xl },
34
+ { name: 'is3Xl', value: is3Xl },
35
+ { name: 'is4Xl', value: is4Xl },
36
+ { name: 'is5Xl', value: is5Xl },
37
+ ]
38
+
39
+ const groupedHelpers = [
40
+ { name: 'isMobile', value: isMobile },
41
+ { name: 'isTablet', value: isTablet },
42
+ { name: 'isDesktop', value: isDesktop },
43
+ { name: 'isSmall', value: isSmall },
44
+ { name: 'isLarge', value: isLarge },
45
+ { name: 'isUltraWide', value: isUltraWide },
46
+ { name: 'is4K', value: is4K },
47
+ { name: 'is5K', value: is5K },
48
+ ]
49
+
50
+ return (
51
+ <div className="space-y-6">
52
+ <h2 className="text-3xl font-black text-white mb-2 tracking-tight">Boolean Helpers</h2>
53
+ <div className="w-8 h-0.5 bg-cyan-400 mb-4"></div>
54
+
55
+ <div>
56
+ <h4 className="text-sm font-bold mb-3 text-gray-500 tracking-widest uppercase">Specific Breakpoints</h4>
57
+ <div className="grid grid-cols-3 gap-2">
58
+ {helpers.map(helper => (
59
+ <div
60
+ key={helper.name}
61
+ className={`p-4 rounded-lg text-center min-h-[60px] flex flex-col justify-center border transition-all ${
62
+ helper.value
63
+ ? 'bg-cyan-500/10 text-cyan-400 border-cyan-500/30'
64
+ : 'bg-black/30 text-gray-600 border-gray-800'
65
+ }`}
66
+ >
67
+ <div className="font-bold break-words text-sm">{helper.name}</div>
68
+ <div className="text-lg font-black mt-1">{helper.value ? '●' : '○'}</div>
69
+ </div>
70
+ ))}
71
+ </div>
72
+ </div>
73
+
74
+ <div>
75
+ <h4 className="text-sm font-bold mb-3 text-gray-500 tracking-widest uppercase">Grouped Helpers</h4>
76
+ <div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
77
+ {groupedHelpers.map(helper => (
78
+ <div
79
+ key={helper.name}
80
+ className={`p-4 rounded-lg text-center min-h-[60px] flex flex-col justify-center border transition-all ${
81
+ helper.value
82
+ ? 'bg-cyan-500/10 text-cyan-400 border-cyan-500/30'
83
+ : 'bg-black/30 text-gray-600 border-gray-800'
84
+ }`}
85
+ >
86
+ <div className="font-bold break-words text-sm">{helper.name}</div>
87
+ <div className="text-lg font-black mt-1">{helper.value ? '●' : '○'}</div>
88
+ </div>
89
+ ))}
90
+ </div>
91
+ </div>
92
+ </div>
93
+ )
94
+ }
95
+
96
+ // Componente de test de comparaciones
97
+ const ComparisonTest = () => {
98
+ const {
99
+ isBreakpointUp,
100
+ isBreakpointDown,
101
+ isBreakpointBetween,
102
+ isWidthUp,
103
+ isWidthDown,
104
+ isWidthBetween
105
+ } = useResponsiveLayout()
106
+
107
+ const tests = [
108
+ { name: 'isBreakpointUp("md")', value: isBreakpointUp('md') },
109
+ { name: 'isBreakpointDown("lg")', value: isBreakpointDown('lg') },
110
+ { name: 'isBreakpointBetween("sm", "xl")', value: isBreakpointBetween('sm', 'xl') },
111
+ { name: 'isWidthUp(1024)', value: isWidthUp(1024) },
112
+ { name: 'isWidthDown(768)', value: isWidthDown(768) },
113
+ { name: 'isWidthBetween(500, 1200)', value: isWidthBetween(500, 1200) },
114
+ ]
115
+
116
+ return (
117
+ <div className="space-y-6">
118
+ <h2 className="text-3xl font-black text-white mb-2 tracking-tight">Comparison Functions</h2>
119
+ <div className="w-8 h-0.5 bg-gray-700 mb-4"></div>
120
+ <div className="grid grid-cols-auto-md gap-3">
121
+ {tests.map(test => (
122
+ <div
123
+ key={test.name}
124
+ className={`p-4 rounded-lg border min-h-[80px] flex flex-col justify-center transition-all ${
125
+ test.value
126
+ ? 'bg-cyan-500/10 text-cyan-400 border-cyan-500/30'
127
+ : 'bg-black/30 text-gray-600 border-gray-800'
128
+ }`}
129
+ >
130
+ <p className="font-mono text-xs mb-2 break-words">
131
+ {test.name}
132
+ </p>
133
+ <p className="text-lg font-black">{test.value ? 'TRUE' : 'FALSE'}</p>
134
+ </div>
135
+ ))}
136
+ </div>
137
+ </div>
138
+ )
139
+ }
140
+
141
+ // Componente de test de utilidades de Tailwind
142
+ const TailwindUtilsTest = () => {
143
+ return (
144
+ <div className="space-y-6">
145
+ <h2 className="text-3xl font-black text-white mb-2 tracking-tight">Auto-Scale Properties</h2>
146
+ <div className="w-8 h-0.5 bg-cyan-400 mb-6"></div>
147
+
148
+ {/* Fila 1: Grid Auto-responsive y Line Height */}
149
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
150
+
151
+ {/* Grid Auto-responsive */}
152
+ <div>
153
+ <h4 className="text-lg font-semibold mb-4 text-cyan-400">Grid Auto-responsive</h4>
154
+ <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
155
+ {[1, 2, 3, 4, 5, 6].map(i => (
156
+ <div key={i} className="p-4 bg-black/30 rounded-lg text-center text-sm border border-gray-700 hover:border-cyan-500/30 transition-all">
157
+ <p className="text-gray-300 font-medium">Card {i}</p>
158
+ </div>
159
+ ))}
160
+ </div>
161
+ </div>
162
+
163
+ {/* Line Height */}
164
+ <div>
165
+ <h4 className="text-lg font-semibold mb-4 text-cyan-400">Line Height (Auto-scale)</h4>
166
+ <div className="space-y-4">
167
+ <div className="bg-black/30 p-4 rounded-lg border border-gray-700">
168
+ <p className="text-base leading-relaxed text-gray-300">
169
+ Este párrafo usa <code className="bg-cyan-500/20 text-cyan-400 px-1 rounded">leading-relaxed</code>.
170
+ El line-height escala automáticamente para mejor legibilidad.
171
+ </p>
172
+ </div>
173
+ <div className="bg-black/30 p-4 rounded-lg border border-gray-700">
174
+ <p className="text-base leading-loose text-gray-300">
175
+ Este párrafo usa <code className="bg-cyan-500/20 text-cyan-400 px-1 rounded">leading-loose</code>.
176
+ Con espaciado mayor que se adapta a cada pantalla.
177
+ </p>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ </div>
182
+
183
+ {/* Fila 2: Letter Spacing y Shadows */}
184
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
185
+
186
+ {/* Letter Spacing */}
187
+ <div>
188
+ <h4 className="text-lg font-semibold mb-4 text-cyan-400">Letter Spacing (Auto-scale)</h4>
189
+ <div className="space-y-3">
190
+ <div className="bg-black/30 p-4 rounded-lg border border-gray-700">
191
+ <p className="text-base tracking-tight text-gray-300">
192
+ <code className="bg-cyan-500/20 text-cyan-400 px-1 rounded">tracking-tight</code> - Texto compacto
193
+ </p>
194
+ </div>
195
+ <div className="bg-black/30 p-4 rounded-lg border border-gray-700">
196
+ <p className="text-base tracking-normal text-gray-300">
197
+ <code className="bg-cyan-500/20 text-cyan-400 px-1 rounded">tracking-normal</code> - Espaciado normal
198
+ </p>
199
+ </div>
200
+ <div className="bg-black/30 p-4 rounded-lg border border-gray-700">
201
+ <p className="text-base tracking-wide text-gray-300">
202
+ <code className="bg-cyan-500/20 text-cyan-400 px-1 rounded">tracking-wide</code> - Espaciado amplio
203
+ </p>
204
+ </div>
205
+ </div>
206
+ </div>
207
+
208
+ {/* Shadows */}
209
+ <div>
210
+ <h4 className="text-lg font-semibold mb-4 text-cyan-400">Shadows (Auto-scale)</h4>
211
+ <div className="grid grid-cols-2 gap-3">
212
+ <div className="p-4 bg-black/30 shadow-sm rounded-lg text-center border border-gray-700">
213
+ <p className="text-sm font-medium text-gray-300">shadow-sm</p>
214
+ </div>
215
+ <div className="p-4 bg-black/30 shadow-md rounded-lg text-center border border-gray-700">
216
+ <p className="text-sm font-medium text-gray-300">shadow-md</p>
217
+ </div>
218
+ <div className="p-4 bg-black/30 shadow-lg rounded-lg text-center border border-gray-700">
219
+ <p className="text-sm font-medium text-gray-300">shadow-lg</p>
220
+ </div>
221
+ <div className="p-4 bg-black/30 shadow-xl rounded-lg text-center border border-gray-700">
222
+ <p className="text-sm font-medium text-gray-300">shadow-xl</p>
223
+ </div>
224
+ </div>
225
+ </div>
226
+ </div>
227
+
228
+ {/* Fila 3: Buttons */}
229
+ <div>
230
+ <h4 className="text-lg font-semibold mb-4 text-cyan-400">Buttons (Auto-scale)</h4>
231
+ <div className="flex flex-wrap gap-4">
232
+ <button className="px-6 py-3 bg-cyan-500 text-white rounded-lg hover:bg-cyan-600 transition-colors font-semibold">
233
+ Button Normal
234
+ </button>
235
+ <button className="px-8 py-4 bg-gray-700 text-white rounded-lg hover:bg-gray-600 transition-colors font-semibold">
236
+ Button Grande
237
+ </button>
238
+ <button className="px-4 py-2 bg-gray-800 text-gray-300 rounded-lg hover:bg-gray-700 transition-colors text-sm">
239
+ Button Pequeño
240
+ </button>
241
+ </div>
242
+ </div>
243
+ </div>
244
+ )
245
+ }
246
+
247
+ // Componente de test de orientación
248
+ const OrientationTest = () => {
249
+ const { orientation, isPortrait, isLandscape } = useResponsiveLayout()
250
+
251
+ return (
252
+ <div className="space-y-4">
253
+ <h2 className="text-3xl font-black text-white mb-2 tracking-tight">Orientation</h2>
254
+ <div className="w-8 h-0.5 bg-cyan-400 mb-6"></div>
255
+ <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
256
+ <div className="p-6 bg-black/30 rounded-lg border border-gray-700 text-center">
257
+ <p className="font-semibold text-cyan-400 text-lg mb-2">Current</p>
258
+ <p className="text-gray-300 text-base">{orientation}</p>
259
+ </div>
260
+ <div className="p-6 bg-black/30 rounded-lg border border-gray-700 text-center">
261
+ <p className="font-semibold text-cyan-400 text-lg mb-2">Portrait</p>
262
+ <p className="text-gray-300 text-base">{isPortrait ? '●' : '○'}</p>
263
+ </div>
264
+ <div className="p-6 bg-black/30 rounded-lg border border-gray-700 text-center">
265
+ <p className="font-semibold text-cyan-400 text-lg mb-2">Landscape</p>
266
+ <p className="text-gray-300 text-base">{isLandscape ? '●' : '○'}</p>
267
+ </div>
268
+ </div>
269
+ </div>
270
+ )
271
+ }
272
+
273
+ // Componente de test de grid
274
+ const GridTest = () => {
275
+ return (
276
+ <div className="space-y-4">
277
+ <h2 className="text-3xl font-black text-white mb-2 tracking-tight">Grid System</h2>
278
+ <div className="w-8 h-0.5 bg-cyan-400 mb-4"></div>
279
+
280
+ <div>
281
+ <h4 className="text-lg font-semibold mb-2 text-gray-700">Auto-responsive Grid</h4>
282
+ <div className="grid grid-cols-auto-sm gap-4">
283
+ {[1, 2, 3, 4, 5, 6].map(i => (
284
+ <div key={i} className="p-6 bg-indigo-100 rounded-lg text-center border border-indigo-200">
285
+ <p className="font-bold text-indigo-800 text-base">Item {i}</p>
286
+ </div>
287
+ ))}
288
+ </div>
289
+ </div>
290
+ </div>
291
+ )
292
+ }
293
+
294
+ // Página principal
295
+ const ResponsiveTestPage = () => {
296
+ const { debug } = useResponsiveLayout()
297
+
298
+ return (
299
+ <div>
300
+ <BreakpointIndicator />
301
+
302
+ {/* Contenedor principal */}
303
+ <div className="w-full">
304
+ {/* Header elegante */}
305
+ <header className="text-center mb-6 bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl p-6 border border-cyan-500/20">
306
+ <div className="inline-block bg-black/50 backdrop-blur-sm border border-cyan-500/30 text-cyan-400 rounded-lg px-4 py-2 mb-4">
307
+ <p className="text-xs font-bold tracking-widest uppercase">Suite de Pruebas</p>
308
+ </div>
309
+ <h1 className="text-4xl font-black text-white mb-4 tracking-tighter leading-none">
310
+ Test del Sistema
311
+ </h1>
312
+ <p className="text-base text-gray-400 mb-3 leading-relaxed tracking-wide">
313
+ Validación completa de propiedades auto-escalables
314
+ </p>
315
+ <div className="flex flex-wrap justify-center gap-2 text-sm">
316
+ <span className="text-gray-500">Tipografía</span>
317
+ <span className="text-gray-700">•</span>
318
+ <span className="text-gray-500">Espaciado</span>
319
+ <span className="text-gray-700">•</span>
320
+ <span className="text-gray-500">Alto de Línea</span>
321
+ <span className="text-gray-700">•</span>
322
+ <span className="text-gray-500">Espaciado de Letras</span>
323
+ <span className="text-gray-700">•</span>
324
+ <span className="text-gray-500">Sombras</span>
325
+ </div>
326
+ {debug && (
327
+ <div className="inline-block bg-yellow-900/30 border border-yellow-600/30 text-yellow-400 rounded-lg font-bold px-4 py-2 mt-4">
328
+ <p className="text-sm tracking-widest uppercase">Modo Debug Activo</p>
329
+ </div>
330
+ )}
331
+ </header>
332
+
333
+ {/* Layout profesional - jerarquía lógica */}
334
+ <div className="mb-6 space-y-6">
335
+
336
+ {/* Fila 1: Boolean Helpers - Ancho completo */}
337
+ <div className="bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl p-6 border border-cyan-500/20 hover:border-cyan-500/40 transition-all">
338
+ <BooleanHelpersTest />
339
+ </div>
340
+
341
+ {/* Fila 2: Auto-scale Properties - Ancho completo */}
342
+ <div className="bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl p-6 border border-gray-800 hover:border-gray-700 transition-all">
343
+ <TailwindUtilsTest />
344
+ </div>
345
+
346
+ {/* Fila 3: Orientation - Horizontal */}
347
+ <div className="bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl p-6 border border-cyan-500/20 hover:border-cyan-500/40 transition-all">
348
+ <OrientationTest />
349
+ </div>
350
+
351
+ {/* Fila 3: Comparaciones y tests principales */}
352
+ <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
353
+ <div className="bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl p-6 border border-gray-800 hover:border-gray-700 transition-all">
354
+ <ComparisonTest />
355
+ </div>
356
+
357
+ <div className="bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl p-6 border border-cyan-500/20 hover:border-cyan-500/40 transition-all">
358
+ <GridTest />
359
+ </div>
360
+ </div>
361
+
362
+ </div>
363
+
364
+ {/* Layout Switcher */}
365
+ <div className="mb-6">
366
+ <LayoutSwitcher />
367
+ </div>
368
+
369
+ {/* Footer*/}
370
+ <footer className="bg-gradient-to-br from-gray-900 to-black rounded-2xl shadow-2xl text-center p-6 border border-cyan-500/20">
371
+ <div className="space-y-4">
372
+ <div className="w-12 h-1 bg-gradient-to-r from-transparent via-cyan-400 to-transparent mx-auto"></div>
373
+ <p className="text-2xl font-black text-white leading-none tracking-tighter">
374
+ Sistema en Vivo
375
+ </p>
376
+ <p className="text-base text-gray-400 leading-relaxed tracking-wide max-w-2xl mx-auto">
377
+ Redimensiona tu ventana para observar el comportamiento de escalado automático en tiempo real
378
+ </p>
379
+ <div className="flex justify-center gap-3 flex-wrap mt-4">
380
+ <div className="bg-black/50 backdrop-blur-sm border border-cyan-500/30 px-4 py-2 rounded-lg">
381
+ <p className="text-sm font-bold tracking-widest text-cyan-400 uppercase">5 Propiedades</p>
382
+ </div>
383
+ <div className="bg-black/50 backdrop-blur-sm border border-gray-700 px-4 py-2 rounded-lg">
384
+ <p className="text-sm font-bold tracking-widest text-gray-400 uppercase">9 Breakpoints</p>
385
+ </div>
386
+ <div className="bg-black/50 backdrop-blur-sm border border-gray-700 px-4 py-2 rounded-lg">
387
+ <p className="text-sm font-bold tracking-widest text-gray-400 uppercase">Auto-Escalado</p>
388
+ </div>
389
+ </div>
390
+ <p className="text-xs text-gray-600 mt-4 leading-relaxed tracking-wide">
391
+ Indicador de breakpoint ubicado en la parte inferior central
392
+ </p>
393
+ </div>
394
+ </footer>
395
+ </div>
396
+ </div>
397
+ )
398
+ }
399
+
400
+ export default ResponsiveTestPage
@@ -0,0 +1,92 @@
1
+ import React, { useState } from 'react'
2
+ import { ResponsiveProvider } from './index'
3
+ import { useResponsive } from '../hooks'
4
+ import { ResponsiveLayoutContext } from '../context'
5
+ import { LAYOUT_CONFIG, DEFAULT_LAYOUT } from '../config/layout'
6
+ import type { ResponsiveState } from '../types/responsive'
7
+
8
+ interface ResponsiveLayoutProviderProps {
9
+ children: React.ReactNode
10
+ defaultLayout?: string
11
+ /**
12
+ * Hook responsivo personalizado del proyecto consumidor.
13
+ * Si se proporciona, se usará en lugar del hook interno del paquete.
14
+ * Debe retornar un objeto compatible con ResponsiveState.
15
+ */
16
+ useResponsiveHook?: () => ResponsiveState
17
+ }
18
+
19
+ interface ResponsiveLayoutProviderInnerProps {
20
+ children: React.ReactNode
21
+ defaultLayout: string
22
+ useResponsiveHook?: () => ResponsiveState
23
+ }
24
+
25
+ const ResponsiveLayoutProviderInner: React.FC<ResponsiveLayoutProviderInnerProps> = ({
26
+ children,
27
+ defaultLayout,
28
+ useResponsiveHook
29
+ }) => {
30
+ // Usar hook personalizado si se proporciona, sino usar el hook interno
31
+ const internalResponsive = useResponsive()
32
+ const customResponsive = useResponsiveHook?.()
33
+ const responsive = customResponsive || internalResponsive
34
+
35
+ const [currentLayout, setCurrentLayout] = useState(defaultLayout)
36
+
37
+ const layoutConfig = LAYOUT_CONFIG[currentLayout] || LAYOUT_CONFIG[DEFAULT_LAYOUT]
38
+
39
+ const layoutUtils = {
40
+ getContainerClass: () => {
41
+ if (responsive.isMobile) return layoutConfig.responsive.mobile
42
+ if (responsive.isTablet) return layoutConfig.responsive.tablet
43
+ return layoutConfig.responsive.desktop
44
+ },
45
+
46
+ getMainClass: () => {
47
+ const baseClass = 'min-h-screen bg-black'
48
+ if (currentLayout === 'sidebar' || currentLayout === 'dashboard') {
49
+ return `${baseClass} flex`
50
+ }
51
+ return baseClass
52
+ },
53
+
54
+ hasSidebar: () => currentLayout === 'sidebar' || currentLayout === 'dashboard',
55
+ hasHeader: () => currentLayout === 'dashboard',
56
+ hasFooter: () => currentLayout === 'default' || currentLayout === 'dashboard',
57
+ hasNavigation: () => currentLayout === 'default',
58
+ }
59
+
60
+ const contextValue = {
61
+ responsive,
62
+ layout: {
63
+ current: currentLayout,
64
+ config: layoutConfig,
65
+ setLayout: setCurrentLayout,
66
+ },
67
+ layoutUtils,
68
+ }
69
+
70
+ return (
71
+ <ResponsiveLayoutContext.Provider value={contextValue}>
72
+ {children}
73
+ </ResponsiveLayoutContext.Provider>
74
+ )
75
+ }
76
+
77
+ export const ResponsiveLayoutProvider: React.FC<ResponsiveLayoutProviderProps> = ({
78
+ children,
79
+ defaultLayout = DEFAULT_LAYOUT,
80
+ useResponsiveHook
81
+ }) => {
82
+ return (
83
+ <ResponsiveProvider>
84
+ <ResponsiveLayoutProviderInner
85
+ defaultLayout={defaultLayout}
86
+ useResponsiveHook={useResponsiveHook}
87
+ >
88
+ {children}
89
+ </ResponsiveLayoutProviderInner>
90
+ </ResponsiveProvider>
91
+ )
92
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react'
2
+ import type { ResponsiveProviderProps } from '../types/responsive'
3
+
4
+ /**
5
+ * ResponsiveProvider - Provider simplificado para el sistema responsive
6
+ *
7
+ * Nota: Con el sistema de auto-scaling mediante plugin de Tailwind,
8
+ * este Provider es OPCIONAL y solo se necesita si quieres acceder
9
+ * al hook useResponsive() en tus componentes.
10
+ */
11
+ export const ResponsiveProvider: React.FC<ResponsiveProviderProps> = ({
12
+ children,
13
+ debug: _debug = false
14
+ }) => {
15
+ // El Provider ahora solo envuelve children sin context
16
+ // El auto-scaling funciona mediante el plugin de Tailwind
17
+ return <>{children}</>
18
+ }
@@ -0,0 +1,3 @@
1
+ export { ResponsiveProvider } from './ResponsiveProvider'
2
+ export { ResponsiveLayoutProvider } from './ResponsiveLayoutProvider'
3
+
@@ -0,0 +1,64 @@
1
+ // Tipos para el sistema responsive
2
+ import type React from 'react'
3
+
4
+ export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl'
5
+
6
+ export type Orientation = 'portrait' | 'landscape'
7
+
8
+ // Estado del hook useResponsive (simplificado)
9
+ export interface ResponsiveState {
10
+ // Breakpoint actual
11
+ breakpoint: Breakpoint
12
+
13
+ // Dimensiones
14
+ width: number
15
+ height: number
16
+
17
+ // Orientación
18
+ orientation: Orientation
19
+ isPortrait: boolean
20
+ isLandscape: boolean
21
+
22
+ // Helpers booleanos específicos
23
+ isXs: boolean
24
+ isSm: boolean
25
+ isMd: boolean
26
+ isLg: boolean
27
+ isXl: boolean
28
+ is2Xl: boolean
29
+ is3Xl: boolean
30
+ is4Xl: boolean
31
+ is5Xl: boolean
32
+
33
+ // Helpers agrupados
34
+ isMobile: boolean
35
+ isTablet: boolean
36
+ isDesktop: boolean
37
+ isSmall: boolean
38
+ isLarge: boolean
39
+ isUltraWide: boolean
40
+ is4K: boolean
41
+ is5K: boolean
42
+
43
+ // Funciones de comparación de breakpoints
44
+ isBreakpointUp: (breakpoint: Breakpoint) => boolean
45
+ isBreakpointDown: (breakpoint: Breakpoint) => boolean
46
+ isBreakpointBetween: (min: Breakpoint, max: Breakpoint) => boolean
47
+
48
+ // Funciones de comparación de dimensiones
49
+ isWidthUp: (width: number) => boolean
50
+ isWidthDown: (width: number) => boolean
51
+ isWidthBetween: (min: number, max: number) => boolean
52
+ isHeightUp: (height: number) => boolean
53
+ isHeightDown: (height: number) => boolean
54
+ isHeightBetween: (min: number, max: number) => boolean
55
+
56
+ // Debug
57
+ debug: boolean
58
+ }
59
+
60
+ // Configuración del provider (simplificada)
61
+ export interface ResponsiveProviderProps {
62
+ children: React.ReactNode
63
+ debug?: boolean
64
+ }