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.
- package/package.json +2 -1
- package/scripts/postinstall.js +2 -3
- package/src/App.css +42 -0
- package/src/App.tsx +29 -0
- package/src/assets/react.svg +1 -0
- package/src/components/LayoutSwitcher.tsx +62 -0
- package/src/components/ResponsiveDemo.tsx +282 -0
- package/src/components/layout/Footer.tsx +90 -0
- package/src/components/layout/Header.tsx +105 -0
- package/src/components/layout/Navigation.tsx +96 -0
- package/src/components/layout/Sidebar.tsx +108 -0
- package/src/components/layout/index.ts +4 -0
- package/src/config/layout.ts +61 -0
- package/src/constants/breakpoints.ts +48 -0
- package/src/context/NavigationContext.tsx +32 -0
- package/src/context/ResponsiveLayoutContext.tsx +37 -0
- package/src/context/SidebarContext.tsx +26 -0
- package/src/context/index.ts +4 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useLayout.ts +27 -0
- package/src/hooks/useResponsive.ts +189 -0
- package/src/hooks/useResponsiveLayout.ts +51 -0
- package/src/index.css +1 -0
- package/src/index.ts +100 -0
- package/src/layouts/DashboardLayout.tsx +76 -0
- package/src/layouts/DefaultLayout.tsx +30 -0
- package/src/layouts/MainLayout.tsx +38 -0
- package/src/layouts/MinimalLayout.tsx +20 -0
- package/src/layouts/SidebarLayout.tsx +36 -0
- package/src/layouts/index.ts +5 -0
- package/src/main.tsx +10 -0
- package/src/pages/ResponsiveTestPage.tsx +400 -0
- package/src/providers/ResponsiveLayoutProvider.tsx +92 -0
- package/src/providers/ResponsiveProvider.tsx +18 -0
- package/src/providers/index.ts +3 -0
- package/src/types/responsive.ts +64 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useResponsiveLayoutContext } from '../context'
|
|
2
|
+
|
|
3
|
+
export const useResponsiveLayout = () => {
|
|
4
|
+
const context = useResponsiveLayoutContext()
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
// Todo el sistema responsivo original
|
|
8
|
+
...context.responsive,
|
|
9
|
+
|
|
10
|
+
// Sistema de layout
|
|
11
|
+
layout: {
|
|
12
|
+
current: context.layout.current,
|
|
13
|
+
config: context.layout.config,
|
|
14
|
+
setLayout: context.layout.setLayout,
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
// Utilidades de layout
|
|
18
|
+
layoutUtils: context.layoutUtils,
|
|
19
|
+
|
|
20
|
+
// Helpers específicos del layout
|
|
21
|
+
isDefaultLayout: () => context.layout.current === 'default',
|
|
22
|
+
isSidebarLayout: () => context.layout.current === 'sidebar',
|
|
23
|
+
isDashboardLayout: () => context.layout.current === 'dashboard',
|
|
24
|
+
isMinimalLayout: () => context.layout.current === 'minimal',
|
|
25
|
+
|
|
26
|
+
// Grid helpers que usan el sistema auto-escalable
|
|
27
|
+
grid: {
|
|
28
|
+
auto: (minWidth = 'md') => `grid-cols-auto-${minWidth}`,
|
|
29
|
+
responsive: (breakpoints: Record<string, number>) => {
|
|
30
|
+
const classes: string[] = []
|
|
31
|
+
Object.entries(breakpoints).forEach(([breakpoint, cols]) => {
|
|
32
|
+
if (breakpoint === 'base') {
|
|
33
|
+
classes.push(`grid-cols-${cols}`)
|
|
34
|
+
} else {
|
|
35
|
+
classes.push(`${breakpoint}:grid-cols-${cols}`)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
return classes.join(' ')
|
|
39
|
+
},
|
|
40
|
+
fixed: (cols: number) => `grid-cols-${cols}`,
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// Spacing helpers que escalan automáticamente
|
|
44
|
+
spacing: {
|
|
45
|
+
container: context.layoutUtils.getContainerClass(),
|
|
46
|
+
section: 'mb-6',
|
|
47
|
+
card: 'p-6',
|
|
48
|
+
gap: 'gap-4',
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
}
|
package/src/index.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss";
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// ========================================
|
|
2
|
+
// SISTEMA RESPONSIVE AUTO-SCALING + LAYOUTS
|
|
3
|
+
// ========================================
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CÓMO USAR ESTE SISTEMA:
|
|
7
|
+
*
|
|
8
|
+
* 1. Instala el plugin en tailwind.config.js:
|
|
9
|
+
* import responsiveScalePlugin from './src/plugin/responsiveScalePlugin.js'
|
|
10
|
+
* plugins: [responsiveScalePlugin()]
|
|
11
|
+
*
|
|
12
|
+
* 2. Usa el ResponsiveLayoutProvider + MainLayout:
|
|
13
|
+
* <ResponsiveLayoutProvider defaultLayout="default">
|
|
14
|
+
* <MainLayout>
|
|
15
|
+
* <App />
|
|
16
|
+
* </MainLayout>
|
|
17
|
+
* </ResponsiveLayoutProvider>
|
|
18
|
+
*
|
|
19
|
+
* 3. Selección de layout (múltiples opciones):
|
|
20
|
+
* - Por prop: <MainLayout layout="dashboard">...</MainLayout>
|
|
21
|
+
* - Por contexto: const { setLayout } = useResponsiveLayout(); setLayout('sidebar')
|
|
22
|
+
* - Por defaultLayout: <ResponsiveLayoutProvider defaultLayout="dashboard">
|
|
23
|
+
*
|
|
24
|
+
* 4. Hook responsivo personalizado (opcional):
|
|
25
|
+
* <ResponsiveLayoutProvider useResponsiveHook={tuHookPersonalizado}>
|
|
26
|
+
* ...
|
|
27
|
+
* </ResponsiveLayoutProvider>
|
|
28
|
+
*
|
|
29
|
+
* 5. Usa Tailwind NORMAL en tus páginas:
|
|
30
|
+
* <div className="p-6 text-base">
|
|
31
|
+
* TODO escala automáticamente + layout consistente
|
|
32
|
+
* </div>
|
|
33
|
+
*
|
|
34
|
+
* 6. (Opcional) Usa hooks para casos avanzados:
|
|
35
|
+
* const { layout, responsive } = useResponsiveLayout()
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
// ========================================
|
|
39
|
+
// EXPORTS PRINCIPALES
|
|
40
|
+
// ========================================
|
|
41
|
+
|
|
42
|
+
// Providers
|
|
43
|
+
export { ResponsiveLayoutProvider, ResponsiveProvider } from './providers'
|
|
44
|
+
|
|
45
|
+
// Layouts
|
|
46
|
+
export {
|
|
47
|
+
MainLayout,
|
|
48
|
+
DefaultLayout,
|
|
49
|
+
SidebarLayout,
|
|
50
|
+
DashboardLayout,
|
|
51
|
+
MinimalLayout
|
|
52
|
+
} from './layouts'
|
|
53
|
+
|
|
54
|
+
// Hooks
|
|
55
|
+
export { useResponsiveLayout, useLayout, useResponsive } from './hooks'
|
|
56
|
+
|
|
57
|
+
// Componentes de layout
|
|
58
|
+
export { Header, Sidebar, Footer, Navigation } from './components/layout'
|
|
59
|
+
|
|
60
|
+
// LayoutSwitcher
|
|
61
|
+
export { default as LayoutSwitcher } from './components/LayoutSwitcher'
|
|
62
|
+
|
|
63
|
+
// Context (para casos avanzados)
|
|
64
|
+
export {
|
|
65
|
+
useResponsiveLayoutContext,
|
|
66
|
+
SidebarProvider,
|
|
67
|
+
useSidebar,
|
|
68
|
+
NavigationProvider,
|
|
69
|
+
useNavigation
|
|
70
|
+
} from './context'
|
|
71
|
+
|
|
72
|
+
// Tipos TypeScript
|
|
73
|
+
export type {
|
|
74
|
+
Breakpoint,
|
|
75
|
+
Orientation,
|
|
76
|
+
ResponsiveState,
|
|
77
|
+
ResponsiveProviderProps
|
|
78
|
+
} from './types/responsive'
|
|
79
|
+
|
|
80
|
+
// Constantes (para casos avanzados)
|
|
81
|
+
export {
|
|
82
|
+
DEFAULT_BREAKPOINTS,
|
|
83
|
+
getCurrentBreakpoint,
|
|
84
|
+
getBreakpointIndex,
|
|
85
|
+
getBreakpointValue
|
|
86
|
+
} from './constants/breakpoints'
|
|
87
|
+
|
|
88
|
+
// Configuración de layouts
|
|
89
|
+
export { LAYOUT_CONFIG, DEFAULT_LAYOUT, AVAILABLE_LAYOUTS } from './config/layout'
|
|
90
|
+
export type { LayoutConfig } from './config/layout'
|
|
91
|
+
|
|
92
|
+
// Plugin de Tailwind (importar directamente en tailwind.config.js)
|
|
93
|
+
// import responsiveScalePlugin from './src/plugin/responsiveScalePlugin.js'
|
|
94
|
+
|
|
95
|
+
// ========================================
|
|
96
|
+
// EJEMPLOS (Solo para testing en este proyecto - NO exportados en npm)
|
|
97
|
+
// ========================================
|
|
98
|
+
|
|
99
|
+
// Los ejemplos no se exportan en el paquete npm
|
|
100
|
+
// Solo están disponibles durante el desarrollo local
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useResponsiveLayout } from '../hooks'
|
|
3
|
+
import { Sidebar, Footer } from '../components/layout'
|
|
4
|
+
import { SidebarProvider, useSidebar } from '../context'
|
|
5
|
+
|
|
6
|
+
interface DashboardLayoutProps {
|
|
7
|
+
children: React.ReactNode
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const DashboardLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
11
|
+
const { layoutUtils } = useResponsiveLayout()
|
|
12
|
+
const { setSidebarOpen } = useSidebar()
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="min-h-screen bg-black flex flex-col">
|
|
16
|
+
{/* Navbar para móvil (igual que SidebarLayout) */}
|
|
17
|
+
<div className="sticky top-0 z-50">
|
|
18
|
+
<nav className="bg-gradient-to-r from-gray-900 via-black to-gray-900 border-b border-cyan-500/20 shadow-2xl relative">
|
|
19
|
+
<div className="w-full">
|
|
20
|
+
<div className="px-4 py-4">
|
|
21
|
+
<div className="flex items-center justify-between">
|
|
22
|
+
<div className="flex items-center space-x-2">
|
|
23
|
+
{/* Hamburger button para móvil - A LA IZQUIERDA */}
|
|
24
|
+
<button
|
|
25
|
+
onClick={() => setSidebarOpen(true)}
|
|
26
|
+
className="p-2 rounded-lg text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors"
|
|
27
|
+
>
|
|
28
|
+
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
29
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
|
30
|
+
</svg>
|
|
31
|
+
</button>
|
|
32
|
+
|
|
33
|
+
<div className="flex items-center space-x-2">
|
|
34
|
+
<div className="w-1.5 h-1.5 bg-cyan-400 rounded-full shadow-lg shadow-cyan-400/50 animate-pulse"></div>
|
|
35
|
+
<h3 className="text-base font-black text-white tracking-tight">
|
|
36
|
+
Sistema Responsivo
|
|
37
|
+
</h3>
|
|
38
|
+
</div>
|
|
39
|
+
<div className="px-2 py-0.5 text-cyan-400 font-mono bg-black/50 border border-cyan-500/30 rounded text-xs font-bold tracking-widest">
|
|
40
|
+
DASHBOARD
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</nav>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
{/* Content area con sidebar */}
|
|
50
|
+
<div className="flex flex-1">
|
|
51
|
+
{/* Sidebar */}
|
|
52
|
+
<Sidebar />
|
|
53
|
+
|
|
54
|
+
{/* Main content */}
|
|
55
|
+
<main className="flex-1 overflow-auto">
|
|
56
|
+
<div className={layoutUtils.getContainerClass()}>
|
|
57
|
+
{children}
|
|
58
|
+
</div>
|
|
59
|
+
</main>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
{/* Footer */}
|
|
63
|
+
<Footer />
|
|
64
|
+
</div>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
|
|
69
|
+
return (
|
|
70
|
+
<SidebarProvider>
|
|
71
|
+
<DashboardLayoutContent>{children}</DashboardLayoutContent>
|
|
72
|
+
</SidebarProvider>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default DashboardLayout
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Navigation, Footer } from '../components/layout'
|
|
3
|
+
import { useResponsiveLayout } from '../hooks'
|
|
4
|
+
|
|
5
|
+
interface DefaultLayoutProps {
|
|
6
|
+
children: React.ReactNode
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
|
|
10
|
+
const { layoutUtils } = useResponsiveLayout()
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className="min-h-screen bg-black flex flex-col">
|
|
14
|
+
{/* Navigation fijo arriba */}
|
|
15
|
+
<Navigation />
|
|
16
|
+
|
|
17
|
+
{/* Main content con padding-top para la navigation */}
|
|
18
|
+
<main className="flex-1">
|
|
19
|
+
<div className={layoutUtils.getContainerClass()}>
|
|
20
|
+
{children}
|
|
21
|
+
</div>
|
|
22
|
+
</main>
|
|
23
|
+
|
|
24
|
+
{/* Footer fijo abajo */}
|
|
25
|
+
<Footer />
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default DefaultLayout
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useResponsiveLayout } from '../hooks'
|
|
3
|
+
import {
|
|
4
|
+
DefaultLayout,
|
|
5
|
+
SidebarLayout,
|
|
6
|
+
DashboardLayout,
|
|
7
|
+
MinimalLayout
|
|
8
|
+
} from './index'
|
|
9
|
+
|
|
10
|
+
interface MainLayoutProps {
|
|
11
|
+
children: React.ReactNode
|
|
12
|
+
/**
|
|
13
|
+
* Layout específico a usar. Si se proporciona, sobrescribe el layout del contexto.
|
|
14
|
+
* Valores posibles: 'default', 'sidebar', 'dashboard', 'minimal'
|
|
15
|
+
*/
|
|
16
|
+
layout?: 'default' | 'sidebar' | 'dashboard' | 'minimal'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const MainLayout: React.FC<MainLayoutProps> = ({ children, layout: layoutProp }) => {
|
|
20
|
+
const { layout } = useResponsiveLayout()
|
|
21
|
+
|
|
22
|
+
// Usar el layout del prop si se proporciona, sino usar el del contexto
|
|
23
|
+
const currentLayout = layoutProp || layout.current
|
|
24
|
+
|
|
25
|
+
// Seleccionar el layout apropiado basado en el estado del contexto o prop
|
|
26
|
+
const layouts = {
|
|
27
|
+
default: DefaultLayout,
|
|
28
|
+
sidebar: SidebarLayout,
|
|
29
|
+
dashboard: DashboardLayout,
|
|
30
|
+
minimal: MinimalLayout,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const LayoutComponent = layouts[currentLayout as keyof typeof layouts] || DefaultLayout
|
|
34
|
+
|
|
35
|
+
return <LayoutComponent>{children}</LayoutComponent>
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default MainLayout
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useResponsiveLayout } from '../hooks'
|
|
3
|
+
|
|
4
|
+
interface MinimalLayoutProps {
|
|
5
|
+
children: React.ReactNode
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const MinimalLayout: React.FC<MinimalLayoutProps> = ({ children }) => {
|
|
9
|
+
const { layoutUtils } = useResponsiveLayout()
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className="min-h-screen bg-black">
|
|
13
|
+
<main className={layoutUtils.getContainerClass()}>
|
|
14
|
+
{children}
|
|
15
|
+
</main>
|
|
16
|
+
</div>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default MinimalLayout
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { useResponsiveLayout } from '../hooks'
|
|
3
|
+
import { Sidebar } from '../components/layout'
|
|
4
|
+
import { SidebarProvider } from '../context'
|
|
5
|
+
|
|
6
|
+
interface SidebarLayoutProps {
|
|
7
|
+
children: React.ReactNode
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const SidebarLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
11
|
+
const { layoutUtils } = useResponsiveLayout()
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className="min-h-screen bg-black flex">
|
|
15
|
+
{/* Sidebar */}
|
|
16
|
+
<Sidebar />
|
|
17
|
+
|
|
18
|
+
{/* Main content */}
|
|
19
|
+
<main className="flex-1 overflow-auto">
|
|
20
|
+
<div className={layoutUtils.getContainerClass()}>
|
|
21
|
+
{children}
|
|
22
|
+
</div>
|
|
23
|
+
</main>
|
|
24
|
+
</div>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const SidebarLayout: React.FC<SidebarLayoutProps> = ({ children }) => {
|
|
29
|
+
return (
|
|
30
|
+
<SidebarProvider>
|
|
31
|
+
<SidebarLayoutContent>{children}</SidebarLayoutContent>
|
|
32
|
+
</SidebarProvider>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default SidebarLayout
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as MainLayout } from './MainLayout'
|
|
2
|
+
export { default as DefaultLayout } from './DefaultLayout'
|
|
3
|
+
export { default as SidebarLayout } from './SidebarLayout'
|
|
4
|
+
export { default as DashboardLayout } from './DashboardLayout'
|
|
5
|
+
export { default as MinimalLayout } from './MinimalLayout'
|
package/src/main.tsx
ADDED