responsive-system 1.6.0 → 1.6.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responsive-system.cjs","sources":["../src/providers/ResponsiveProvider.tsx","../src/constants/breakpoints.ts","../src/hooks/useResponsive.ts","../src/context/ResponsiveLayoutContext.tsx","../src/context/SidebarContext.tsx","../src/context/NavigationContext.tsx","../src/hooks/useResponsiveLayout.ts","../src/hooks/useLayout.ts","../src/config/layout.ts","../src/providers/ResponsiveLayoutProvider.tsx","../src/layouts/MainLayout.tsx","../src/components/layout/Header.tsx","../src/components/layout/Sidebar.tsx","../src/components/layout/Footer.tsx","../src/components/layout/Navigation.tsx","../src/layouts/DefaultLayout.tsx","../src/layouts/SidebarLayout.tsx","../src/layouts/DashboardLayout.tsx","../src/layouts/MinimalLayout.tsx","../src/components/LayoutSwitcher.tsx"],"sourcesContent":["import React from 'react'\r\nimport type { ResponsiveProviderProps } from '../types/responsive'\r\n\r\n/**\r\n * ResponsiveProvider - Provider simplificado para el sistema responsive\r\n * \r\n * Nota: Con el sistema de auto-scaling mediante plugin de Tailwind,\r\n * este Provider es OPCIONAL y solo se necesita si quieres acceder\r\n * al hook useResponsive() en tus componentes.\r\n */\r\nexport const ResponsiveProvider: React.FC<ResponsiveProviderProps> = ({\r\n children,\r\n debug: _debug = false\r\n}) => {\r\n // El Provider ahora solo envuelve children sin context\r\n // El auto-scaling funciona mediante el plugin de Tailwind\r\n return <>{children}</>\r\n}\r\n","import type { Breakpoint } from '../types/responsive'\r\n\r\n/**\r\n * Default breakpoint values\r\n * Deben coincidir con tailwind.config.js\r\n */\r\nexport const DEFAULT_BREAKPOINTS: Record<Breakpoint, number> = {\r\n xs: 475,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n '2xl': 1536,\r\n '3xl': 1920,\r\n '4xl': 2560,\r\n '5xl': 3840\r\n}\r\n\r\n/**\r\n * Get current breakpoint based on window width\r\n */\r\nexport const getCurrentBreakpoint = (width: number): Breakpoint => {\r\n if (width >= DEFAULT_BREAKPOINTS['5xl']) return '5xl'\r\n if (width >= DEFAULT_BREAKPOINTS['4xl']) return '4xl'\r\n if (width >= DEFAULT_BREAKPOINTS['3xl']) return '3xl'\r\n if (width >= DEFAULT_BREAKPOINTS['2xl']) return '2xl'\r\n if (width >= DEFAULT_BREAKPOINTS.xl) return 'xl'\r\n if (width >= DEFAULT_BREAKPOINTS.lg) return 'lg'\r\n if (width >= DEFAULT_BREAKPOINTS.md) return 'md'\r\n if (width >= DEFAULT_BREAKPOINTS.sm) return 'sm'\r\n return 'xs'\r\n}\r\n\r\n/**\r\n * Get breakpoint index (for comparisons)\r\n */\r\nexport const getBreakpointIndex = (breakpoint: Breakpoint): number => {\r\n const breakpoints: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl']\r\n return breakpoints.indexOf(breakpoint)\r\n}\r\n\r\n/**\r\n * Get breakpoint value in pixels\r\n */\r\nexport const getBreakpointValue = (breakpoint: Breakpoint): number => {\r\n return DEFAULT_BREAKPOINTS[breakpoint]\r\n}\r\n\r\n","import { useState, useEffect, useCallback, useMemo } from 'react'\r\nimport type { \r\n ResponsiveState, \r\n Breakpoint\r\n} from '../types/responsive'\r\nimport { \r\n getCurrentBreakpoint,\r\n getBreakpointIndex\r\n} from '../constants/breakpoints'\r\n\r\n/**\r\n * Debounce utility\r\n */\r\nfunction debounce<T extends (...args: unknown[]) => void>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: ReturnType<typeof setTimeout> | null = null\r\n return (...args: Parameters<T>) => {\r\n if (timeout) clearTimeout(timeout)\r\n timeout = setTimeout(() => func(...args), wait)\r\n }\r\n}\r\n\r\n/**\r\n * Get orientation based on dimensions\r\n */\r\nfunction getOrientation(width: number, height: number): 'landscape' | 'portrait' {\r\n return width >= height ? 'landscape' : 'portrait'\r\n}\r\n\r\n/**\r\n * Hook principal useResponsive\r\n * Provee información sobre el breakpoint actual y helpers para responsive\r\n */\r\nexport const useResponsive = (): ResponsiveState => {\r\n const [dimensions, setDimensions] = useState({\r\n width: typeof window !== 'undefined' ? window.innerWidth : 1024,\r\n height: typeof window !== 'undefined' ? window.innerHeight : 768\r\n })\r\n\r\n // Función para actualizar dimensiones\r\n const updateDimensions = useCallback(() => {\r\n setDimensions({\r\n width: window.innerWidth,\r\n height: window.innerHeight\r\n })\r\n }, [])\r\n\r\n // Debounced update para optimizar performance\r\n const debouncedUpdateDimensions = useMemo(\r\n () => debounce(updateDimensions, 100),\r\n [updateDimensions]\r\n )\r\n\r\n // Effect para escuchar cambios de tamaño\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return\r\n\r\n window.addEventListener('resize', debouncedUpdateDimensions)\r\n \r\n return () => {\r\n window.removeEventListener('resize', debouncedUpdateDimensions)\r\n }\r\n }, [debouncedUpdateDimensions])\r\n\r\n const { width, height } = dimensions\r\n\r\n // Calcular breakpoint actual\r\n const breakpoint = useMemo(() => getCurrentBreakpoint(width), [width])\r\n \r\n // Calcular orientación\r\n const orientation = useMemo(() => getOrientation(width, height), [width, height])\r\n\r\n // Helpers booleanos por breakpoint específico\r\n const isXs = breakpoint === 'xs'\r\n const isSm = breakpoint === 'sm'\r\n const isMd = breakpoint === 'md'\r\n const isLg = breakpoint === 'lg'\r\n const isXl = breakpoint === 'xl'\r\n const is2Xl = breakpoint === '2xl'\r\n const is3Xl = breakpoint === '3xl'\r\n const is4Xl = breakpoint === '4xl'\r\n const is5Xl = breakpoint === '5xl'\r\n\r\n // Helpers booleanos agrupados\r\n const isMobile = isXs || isSm\r\n const isTablet = isMd\r\n const isDesktop = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isSmall = isXs || isSm || isMd\r\n const isLarge = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isUltraWide = is3Xl || is4Xl || is5Xl\r\n const is4K = is4Xl || is5Xl\r\n const is5K = is5Xl\r\n\r\n // Helpers de orientación\r\n const isPortrait = orientation === 'portrait'\r\n const isLandscape = orientation === 'landscape'\r\n\r\n // Funciones de comparación de breakpoints\r\n const isBreakpointUp = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) >= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointDown = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) <= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointBetween = useCallback((min: Breakpoint, max: Breakpoint): boolean => {\r\n const current = getBreakpointIndex(breakpoint)\r\n return current >= getBreakpointIndex(min) && current <= getBreakpointIndex(max)\r\n }, [breakpoint])\r\n\r\n // Funciones de comparación de ancho\r\n const isWidthUp = useCallback((minWidth: number): boolean => {\r\n return width >= minWidth\r\n }, [width])\r\n\r\n const isWidthDown = useCallback((maxWidth: number): boolean => {\r\n return width <= maxWidth\r\n }, [width])\r\n\r\n const isWidthBetween = useCallback((minWidth: number, maxWidth: number): boolean => {\r\n return width >= minWidth && width <= maxWidth\r\n }, [width])\r\n\r\n // Funciones de comparación de altura\r\n const isHeightUp = useCallback((minHeight: number): boolean => {\r\n return height >= minHeight\r\n }, [height])\r\n\r\n const isHeightDown = useCallback((maxHeight: number): boolean => {\r\n return height <= maxHeight\r\n }, [height])\r\n\r\n const isHeightBetween = useCallback((minHeight: number, maxHeight: number): boolean => {\r\n return height >= minHeight && height <= maxHeight\r\n }, [height])\r\n\r\n // Debug mode\r\n const debug = false\r\n\r\n return {\r\n // Estado básico\r\n breakpoint,\r\n width,\r\n height,\r\n orientation,\r\n \r\n // Helpers booleanos específicos\r\n isXs,\r\n isSm,\r\n isMd,\r\n isLg,\r\n isXl,\r\n is2Xl,\r\n is3Xl,\r\n is4Xl,\r\n is5Xl,\r\n \r\n // Helpers booleanos agrupados\r\n isMobile,\r\n isTablet,\r\n isDesktop,\r\n isSmall,\r\n isLarge,\r\n isUltraWide,\r\n is4K,\r\n is5K,\r\n \r\n // Helpers de orientación\r\n isPortrait,\r\n isLandscape,\r\n \r\n // Funciones de comparación\r\n isBreakpointUp,\r\n isBreakpointDown,\r\n isBreakpointBetween,\r\n isWidthUp,\r\n isWidthDown,\r\n isWidthBetween,\r\n isHeightUp,\r\n isHeightDown,\r\n isHeightBetween,\r\n \r\n // Debug\r\n debug\r\n }\r\n}\r\n","import { createContext, useContext } from 'react'\r\nimport type { ResponsiveState } from '../types/responsive'\r\nimport type { LayoutConfig } from '../config/layout'\r\n\r\nexport interface ResponsiveLayoutState {\r\n // Estado del sistema responsivo\r\n responsive: ResponsiveState\r\n \r\n // Estado del layout\r\n layout: {\r\n current: string\r\n config: LayoutConfig\r\n setLayout: (layout: string) => void\r\n }\r\n \r\n // Utilidades de layout\r\n layoutUtils: {\r\n getContainerClass: () => string\r\n getMainClass: () => string\r\n hasSidebar: () => boolean\r\n hasHeader: () => boolean\r\n hasFooter: () => boolean\r\n hasNavigation: () => boolean\r\n }\r\n}\r\n\r\nconst ResponsiveLayoutContext = createContext<ResponsiveLayoutState | undefined>(undefined)\r\n\r\nexport const useResponsiveLayoutContext = () => {\r\n const context = useContext(ResponsiveLayoutContext)\r\n if (!context) {\r\n throw new Error('useResponsiveLayoutContext must be used within a ResponsiveLayoutProvider')\r\n }\r\n return context\r\n}\r\n\r\nexport { ResponsiveLayoutContext }\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface SidebarContextType {\r\n sidebarOpen: boolean\r\n setSidebarOpen: (open: boolean) => void\r\n}\r\n\r\nconst SidebarContext = createContext<SidebarContextType | undefined>(undefined)\r\n\r\nexport const SidebarProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n const [sidebarOpen, setSidebarOpen] = useState(false)\r\n\r\n return (\r\n <SidebarContext.Provider value={{ sidebarOpen, setSidebarOpen }}>\r\n {children}\r\n </SidebarContext.Provider>\r\n )\r\n}\r\n\r\nexport const useSidebar = () => {\r\n const context = useContext(SidebarContext)\r\n if (!context) {\r\n throw new Error('useSidebar must be used within a SidebarProvider')\r\n }\r\n return context\r\n}\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface NavigationContextType {\r\n currentPage: 'demo' | 'test'\r\n setCurrentPage: (page: 'demo' | 'test') => void\r\n}\r\n\r\nconst NavigationContext = createContext<NavigationContextType>({\r\n currentPage: 'test',\r\n setCurrentPage: () => {}\r\n})\r\n\r\nexport const useNavigation = () => useContext(NavigationContext)\r\n\r\ninterface NavigationProviderProps {\r\n children: React.ReactNode\r\n defaultPage?: 'demo' | 'test'\r\n}\r\n\r\nexport const NavigationProvider: React.FC<NavigationProviderProps> = ({ \r\n children, \r\n defaultPage = 'test' \r\n}) => {\r\n const [currentPage, setCurrentPage] = useState<'demo' | 'test'>(defaultPage)\r\n\r\n return (\r\n <NavigationContext.Provider value={{ currentPage, setCurrentPage }}>\r\n {children}\r\n </NavigationContext.Provider>\r\n )\r\n}\r\n\r\n","import { useResponsiveLayoutContext } from '../context'\r\n\r\nexport const useResponsiveLayout = () => {\r\n const context = useResponsiveLayoutContext()\r\n \r\n return {\r\n // Todo el sistema responsivo original\r\n ...context.responsive,\r\n \r\n // Sistema de layout\r\n layout: {\r\n current: context.layout.current,\r\n config: context.layout.config,\r\n setLayout: context.layout.setLayout,\r\n },\r\n \r\n // Utilidades de layout\r\n layoutUtils: context.layoutUtils,\r\n \r\n // Helpers específicos del layout\r\n isDefaultLayout: () => context.layout.current === 'default',\r\n isSidebarLayout: () => context.layout.current === 'sidebar',\r\n isDashboardLayout: () => context.layout.current === 'dashboard',\r\n isMinimalLayout: () => context.layout.current === 'minimal',\r\n \r\n // Grid helpers que usan el sistema auto-escalable\r\n grid: {\r\n auto: (minWidth = 'md') => `grid-cols-auto-${minWidth}`,\r\n responsive: (breakpoints: Record<string, number>) => {\r\n const classes: string[] = []\r\n Object.entries(breakpoints).forEach(([breakpoint, cols]) => {\r\n if (breakpoint === 'base') {\r\n classes.push(`grid-cols-${cols}`)\r\n } else {\r\n classes.push(`${breakpoint}:grid-cols-${cols}`)\r\n }\r\n })\r\n return classes.join(' ')\r\n },\r\n fixed: (cols: number) => `grid-cols-${cols}`,\r\n },\r\n \r\n // Spacing helpers que escalan automáticamente\r\n spacing: {\r\n container: context.layoutUtils.getContainerClass(),\r\n section: 'mb-6',\r\n card: 'p-6',\r\n gap: 'gap-4',\r\n },\r\n }\r\n}\r\n","import { useResponsiveLayout } from './index'\r\n\r\nexport const useLayout = () => {\r\n const responsiveLayout = useResponsiveLayout()\r\n \r\n return {\r\n // Layout actual\r\n current: responsiveLayout.layout.current,\r\n config: responsiveLayout.layout.config,\r\n setLayout: responsiveLayout.layout.setLayout,\r\n \r\n // Utilidades\r\n ...responsiveLayout.layoutUtils,\r\n \r\n // Helpers específicos\r\n isDefaultLayout: responsiveLayout.isDefaultLayout(),\r\n isSidebarLayout: responsiveLayout.isSidebarLayout(),\r\n isDashboardLayout: responsiveLayout.isDashboardLayout(),\r\n isMinimalLayout: responsiveLayout.isMinimalLayout(),\r\n \r\n // Grid helpers\r\n grid: responsiveLayout.grid,\r\n \r\n // Spacing helpers\r\n spacing: responsiveLayout.spacing,\r\n }\r\n}\r\n","export interface LayoutConfig {\r\n name: string\r\n description: string\r\n components: string[]\r\n spacing: string\r\n responsive: {\r\n mobile: string\r\n tablet: string\r\n desktop: string\r\n }\r\n}\r\n\r\nexport const LAYOUT_CONFIG: Record<string, LayoutConfig> = {\r\n default: {\r\n name: 'Default',\r\n description: 'Navbar arriba, body central, footer abajo',\r\n components: ['Navigation', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n sidebar: {\r\n name: 'Sidebar',\r\n description: 'Sidebar izquierda, contenido principal',\r\n components: ['Sidebar'],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n },\r\n dashboard: {\r\n name: 'Dashboard',\r\n description: 'Header + Sidebar + Main + Footer',\r\n components: ['Header', 'Sidebar', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n minimal: {\r\n name: 'Minimal',\r\n description: 'Solo contenido, sin navegación',\r\n components: [],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n }\r\n}\r\n\r\nexport const DEFAULT_LAYOUT = 'default'\r\nexport const AVAILABLE_LAYOUTS = Object.keys(LAYOUT_CONFIG)\r\n","import React, { useState } from 'react'\r\nimport { ResponsiveProvider } from './index'\r\nimport { useResponsive } from '../hooks'\r\nimport { ResponsiveLayoutContext } from '../context'\r\nimport { LAYOUT_CONFIG, DEFAULT_LAYOUT } from '../config/layout'\r\nimport type { ResponsiveState } from '../types/responsive'\r\n\r\ninterface ResponsiveLayoutProviderProps {\r\n children: React.ReactNode\r\n defaultLayout?: string\r\n /**\r\n * Hook responsivo personalizado del proyecto consumidor.\r\n * Si se proporciona, se usará en lugar del hook interno del paquete.\r\n * Debe retornar un objeto compatible con ResponsiveState.\r\n */\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\ninterface ResponsiveLayoutProviderInnerProps {\r\n children: React.ReactNode\r\n defaultLayout: string\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\nconst ResponsiveLayoutProviderInner: React.FC<ResponsiveLayoutProviderInnerProps> = ({ \r\n children, \r\n defaultLayout,\r\n useResponsiveHook\r\n}) => {\r\n // Usar hook personalizado si se proporciona, sino usar el hook interno\r\n const internalResponsive = useResponsive()\r\n const customResponsive = useResponsiveHook?.()\r\n const responsive = customResponsive || internalResponsive\r\n \r\n // Inicializar el estado con el layout normalizado usando función inicializadora\r\n // Esto asegura que solo se ejecute una vez, incluso con React.StrictMode\r\n const [currentLayout, setCurrentLayout] = useState(() => {\r\n // Validar y normalizar el defaultLayout directamente en la función inicializadora\r\n if (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout]) {\r\n return defaultLayout\r\n }\r\n return DEFAULT_LAYOUT\r\n })\r\n \r\n const layoutConfig = LAYOUT_CONFIG[currentLayout] || LAYOUT_CONFIG[DEFAULT_LAYOUT]\r\n \r\n const layoutUtils = {\r\n getContainerClass: () => {\r\n if (responsive.isMobile) return layoutConfig.responsive.mobile\r\n if (responsive.isTablet) return layoutConfig.responsive.tablet\r\n return layoutConfig.responsive.desktop\r\n },\r\n \r\n getMainClass: () => {\r\n const baseClass = 'min-h-screen bg-black'\r\n if (currentLayout === 'sidebar' || currentLayout === 'dashboard') {\r\n return `${baseClass} flex`\r\n }\r\n return baseClass\r\n },\r\n \r\n hasSidebar: () => currentLayout === 'sidebar' || currentLayout === 'dashboard',\r\n hasHeader: () => currentLayout === 'dashboard',\r\n hasFooter: () => currentLayout === 'default' || currentLayout === 'dashboard',\r\n hasNavigation: () => currentLayout === 'default',\r\n }\r\n \r\n const contextValue = {\r\n responsive,\r\n layout: {\r\n current: currentLayout,\r\n config: layoutConfig,\r\n setLayout: setCurrentLayout,\r\n },\r\n layoutUtils,\r\n }\r\n \r\n return (\r\n <ResponsiveLayoutContext.Provider value={contextValue}>\r\n {children}\r\n </ResponsiveLayoutContext.Provider>\r\n )\r\n}\r\n\r\nexport const ResponsiveLayoutProvider: React.FC<ResponsiveLayoutProviderProps> = ({ \r\n children, \r\n defaultLayout = DEFAULT_LAYOUT,\r\n useResponsiveHook\r\n}) => {\r\n // Normalizar el defaultLayout antes de pasarlo al componente interno\r\n const normalizedDefaultLayout = (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout])\r\n ? defaultLayout\r\n : DEFAULT_LAYOUT\r\n \r\n return (\r\n <ResponsiveProvider>\r\n <ResponsiveLayoutProviderInner \r\n defaultLayout={normalizedDefaultLayout}\r\n useResponsiveHook={useResponsiveHook}\r\n >\r\n {children}\r\n </ResponsiveLayoutProviderInner>\r\n </ResponsiveProvider>\r\n )\r\n}\r\n","import React from 'react'\r\nimport { useResponsiveLayout } from '../hooks'\r\nimport { \r\n DefaultLayout, \r\n SidebarLayout, \r\n DashboardLayout, \r\n MinimalLayout \r\n} from './index'\r\n\r\ninterface MainLayoutProps {\r\n children: React.ReactNode\r\n /**\r\n * Layout específico a usar. Si se proporciona, sobrescribe el layout del contexto.\r\n * Valores posibles: 'default', 'sidebar', 'dashboard', 'minimal'\r\n */\r\n layout?: 'default' | 'sidebar' | 'dashboard' | 'minimal'\r\n}\r\n\r\nconst MainLayout: React.FC<MainLayoutProps> = ({ children, layout: layoutProp }) => {\r\n const { layout } = useResponsiveLayout()\r\n \r\n // Mapa de layouts disponibles\r\n const layouts = {\r\n default: DefaultLayout,\r\n sidebar: SidebarLayout,\r\n dashboard: DashboardLayout,\r\n minimal: MinimalLayout,\r\n }\r\n \r\n // Determinar qué layout usar: prop > contexto > default\r\n const layoutToUse = layoutProp || layout.current || 'default'\r\n \r\n // Validar que el layout sea válido, si no usar default\r\n const validLayout = (layoutToUse && layouts[layoutToUse as keyof typeof layouts])\r\n ? layoutToUse\r\n : 'default'\r\n \r\n // Obtener el componente de layout\r\n const LayoutComponent = layouts[validLayout as keyof typeof layouts] || DefaultLayout\r\n \r\n return <LayoutComponent>{children}</LayoutComponent>\r\n}\r\n\r\nexport default MainLayout\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useNavigation, useSidebar } from '../../context'\r\n\r\nconst Header = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n const { currentPage, setCurrentPage } = useNavigation()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'test', label: 'Suite de Test' },\r\n { id: 'demo', label: 'Demo' },\r\n ]\r\n \r\n return (\r\n <div className=\"sticky top-0 z-50\">\r\n <header className=\"bg-gradient-to-r from-gray-900 via-black to-gray-900 border-b border-cyan-500/20 shadow-2xl relative\">\r\n <div className=\"w-full\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-2\">\r\n {/* Hamburger button para móvil - A LA IZQUIERDA */}\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"p-2 rounded-lg text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n <div className=\"w-1.5 h-1.5 bg-cyan-400 rounded-full shadow-lg shadow-cyan-400/50 animate-pulse\"></div>\r\n <h3 className=\"text-base font-black text-white tracking-tight\">\r\n Sistema Responsivo\r\n </h3>\r\n </div>\r\n <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\">\r\n DASHBOARD\r\n </div>\r\n </div>\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n {/* Botones visibles solo en desktop */}\r\n {!isMobile && menuItems.map((page) => (\r\n <button\r\n key={page.id}\r\n onClick={() => setCurrentPage(page.id as 'demo' | 'test')}\r\n className={`px-3 py-1.5 rounded-lg transition-all font-bold text-xs tracking-wide border ${\r\n currentPage === page.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border-cyan-500/50' \r\n : 'bg-black/50 text-gray-400 hover:text-gray-300 border-gray-700 hover:border-gray-600'\r\n }`}\r\n >\r\n {page.label}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n {/* Sidebar móvil desplegable */}\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gradient-to-b from-gray-900 to-black border-r border-cyan-500/20\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n {/* Logo */}\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-cyan-500 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">RS</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Sistema Responsivo</span>\r\n </div>\r\n \r\n {/* Navigation */}\r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => {\r\n setCurrentPage(item.id as 'demo' | 'test')\r\n setSidebarOpen(false)\r\n }}\r\n className={`w-full flex items-center px-4 py-3 rounded-lg transition-all group text-left ${\r\n currentPage === item.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border border-cyan-500/50' \r\n : 'text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10'\r\n }`}\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport default Header\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useSidebar } from '../../context'\r\n\r\nconst Sidebar = () => {\r\n const { isMobile, isTablet } = useResponsiveLayout()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'home', label: 'Inicio' },\r\n { id: 'about', label: 'Acerca' },\r\n { id: 'contact', label: 'Contacto' },\r\n ]\r\n \r\n return (\r\n <>\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"fixed top-4 left-4 z-50 p-2 rounded-lg text-gray-300 hover:text-white hover:bg-gray-800 bg-gray-900 border border-gray-700\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n\r\n <aside className={`bg-gray-900 border-r border-gray-800 ${isMobile ? 'hidden' : 'w-64 flex-shrink-0'} ${isTablet ? 'w-56' : 'w-64'}`}>\r\n <div className=\"p-6 flex flex-col h-full\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </aside>\r\n\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gray-900 border-r border-gray-800\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => setSidebarOpen(false)}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )\r\n}\r\n\r\nexport default Sidebar\r\n","const Footer = () => {\r\n return (\r\n <footer className=\"bg-gray-900 border-t border-gray-800\">\r\n <div className=\"px-4 py-6\">\r\n <div className=\"max-w-7xl mx-auto text-center\">\r\n <p className=\"text-gray-400 text-sm\">\r\n © {new Date().getFullYear()} Tu Aplicación. Todos los derechos reservados.\r\n </p>\r\n </div>\r\n </div>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default Footer\r\n","import { useResponsiveLayout } from '../../hooks'\r\n\r\nconst Navigation = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n \r\n return (\r\n <nav className=\"sticky top-0 z-50 bg-gray-900 border-b border-gray-800\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-3\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <h1 className=\"text-white font-semibold text-lg\">Tu Aplicación</h1>\r\n </div>\r\n \r\n {isMobile && (\r\n <button className=\"p-2 text-gray-400 hover:text-white\">\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </nav>\r\n )\r\n}\r\n\r\nexport default Navigation\r\n","import React from 'react'\r\nimport { Navigation, Footer } from '../components/layout'\r\n\r\ninterface DefaultLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Navigation fijo arriba */}\r\n <Navigation />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1\">\r\n {children}\r\n </main>\r\n \r\n {/* Footer fijo abajo */}\r\n <Footer />\r\n </div>\r\n )\r\n}\r\n\r\nexport default DefaultLayout\r\n","import React from 'react'\r\nimport { Sidebar } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface SidebarLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst SidebarLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto\">\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nconst SidebarLayout: React.FC<SidebarLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <SidebarLayoutContent>{children}</SidebarLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default SidebarLayout\r\n","import React from 'react'\r\nimport { Sidebar, Footer } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface DashboardLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DashboardLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Content area con sidebar */}\r\n <div className=\"flex flex-1\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto flex flex-col\">\r\n <div className=\"flex-1\">\r\n {children}\r\n </div>\r\n \r\n {/* Footer */}\r\n <Footer />\r\n </main>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nconst DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <DashboardLayoutContent>{children}</DashboardLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default DashboardLayout\r\n","import React from 'react'\r\n\r\ninterface MinimalLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst MinimalLayout: React.FC<MinimalLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50\">\r\n <main>\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nexport default MinimalLayout\r\n","import { useLayout } from '../hooks'\r\nimport { LAYOUT_CONFIG } from '../config/layout'\r\n\r\ninterface LayoutSwitcherProps {\r\n compact?: boolean\r\n}\r\n\r\nconst LayoutSwitcher = ({ compact = false }: LayoutSwitcherProps) => {\r\n const { current, setLayout, config } = useLayout()\r\n \r\n if (compact) {\r\n return (\r\n <div className=\"bg-black/50 rounded-lg p-3 border border-gray-700\">\r\n <div className=\"text-xs text-gray-500 mb-2\">Layout:</div>\r\n <select\r\n value={current}\r\n onChange={(e) => setLayout(e.target.value)}\r\n className=\"w-full bg-gray-800 text-white text-sm p-2 rounded border border-gray-600 focus:ring-1 focus:ring-cyan-500 focus:border-transparent\"\r\n >\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <option key={key} value={key}>\r\n {layoutConfig.name}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n )\r\n }\r\n \r\n return (\r\n <div className=\"bg-black/50 backdrop-blur-sm rounded-lg p-4 border border-cyan-500/30\">\r\n <h3 className=\"text-white font-semibold mb-3\">Cambiar Layout</h3>\r\n \r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <button\r\n key={key}\r\n onClick={() => setLayout(key)}\r\n className={`\r\n p-4 rounded-lg border transition-all text-left\r\n ${current === key \r\n ? 'border-cyan-500 bg-cyan-500/10 text-cyan-400' \r\n : 'border-gray-700 bg-black/30 text-gray-300 hover:border-gray-600'\r\n }\r\n `}\r\n >\r\n <div className=\"font-semibold mb-1\">{layoutConfig.name}</div>\r\n <div className=\"text-xs opacity-75\">{layoutConfig.description}</div>\r\n </button>\r\n ))}\r\n </div>\r\n \r\n <div className=\"mt-4 p-3 bg-gray-900/50 rounded-lg\">\r\n <div className=\"text-xs text-gray-500 mb-1\">Layout Actual:</div>\r\n <div className=\"text-sm text-cyan-400 font-medium\">{config.name}</div>\r\n <div className=\"text-xs text-gray-400\">{config.description}</div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default LayoutSwitcher\r\n"],"names":["ResponsiveProvider","children","_debug","DEFAULT_BREAKPOINTS","getCurrentBreakpoint","width","getBreakpointIndex","breakpoint","getBreakpointValue","debounce","func","wait","timeout","args","getOrientation","height","useResponsive","dimensions","setDimensions","useState","updateDimensions","useCallback","debouncedUpdateDimensions","useMemo","useEffect","orientation","isXs","isSm","isMd","isLg","isXl","is2Xl","is3Xl","is4Xl","is5Xl","isMobile","isTablet","isDesktop","isSmall","isLarge","isUltraWide","is4K","is5K","isPortrait","isLandscape","isBreakpointUp","bp","isBreakpointDown","isBreakpointBetween","min","max","current","isWidthUp","minWidth","isWidthDown","maxWidth","isWidthBetween","isHeightUp","minHeight","isHeightDown","maxHeight","isHeightBetween","ResponsiveLayoutContext","createContext","useResponsiveLayoutContext","context","useContext","SidebarContext","SidebarProvider","sidebarOpen","setSidebarOpen","jsx","useSidebar","NavigationContext","useNavigation","NavigationProvider","defaultPage","currentPage","setCurrentPage","useResponsiveLayout","breakpoints","classes","cols","useLayout","responsiveLayout","LAYOUT_CONFIG","DEFAULT_LAYOUT","AVAILABLE_LAYOUTS","ResponsiveLayoutProviderInner","defaultLayout","useResponsiveHook","internalResponsive","responsive","currentLayout","setCurrentLayout","layoutConfig","contextValue","baseClass","ResponsiveLayoutProvider","normalizedDefaultLayout","MainLayout","layoutProp","layout","layouts","DefaultLayout","SidebarLayout","DashboardLayout","MinimalLayout","layoutToUse","validLayout","LayoutComponent","Header","menuItems","jsxs","page","item","Sidebar","Fragment","Footer","Navigation","SidebarLayoutContent","DashboardLayoutContent","LayoutSwitcher","compact","setLayout","config","e","key"],"mappings":"wIAUaA,EAAwD,CAAC,CACpE,SAAAC,EACA,MAAOC,EAAS,EAClB,sBAGY,SAAAD,EAAS,ECVRE,EAAkD,CAC7D,GAAI,IACJ,GAAI,IACJ,GAAI,IACJ,GAAI,KACJ,GAAI,KACJ,MAAO,KACP,MAAO,KACP,MAAO,KACP,MAAO,IACT,EAKaC,EAAwBC,GAC/BA,GAASF,EAAoB,KAAK,EAAU,MAC5CE,GAASF,EAAoB,KAAK,EAAU,MAC5CE,GAASF,EAAoB,KAAK,EAAU,MAC5CE,GAASF,EAAoB,KAAK,EAAU,MAC5CE,GAASF,EAAoB,GAAW,KACxCE,GAASF,EAAoB,GAAW,KACxCE,GAASF,EAAoB,GAAW,KACxCE,GAASF,EAAoB,GAAW,KACrC,KAMIG,EAAsBC,GACC,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,MAAO,MAAO,KAAK,EACxE,QAAQA,CAAU,EAM1BC,GAAsBD,GAC1BJ,EAAoBI,CAAU,EChCvC,SAASE,GACPC,EACAC,EACkC,CAClC,IAAIC,EAAgD,KACpD,MAAO,IAAIC,IAAwB,CAC7BD,gBAAsBA,CAAO,EACjCA,EAAU,WAAW,IAAMF,EAAK,GAAGG,CAAI,EAAGF,CAAI,CAChD,CACF,CAKA,SAASG,GAAeT,EAAeU,EAA0C,CAC/E,OAAOV,GAASU,EAAS,YAAc,UACzC,CAMO,MAAMC,EAAgB,IAAuB,CAClD,KAAM,CAACC,EAAYC,CAAa,EAAIC,WAAS,CAC3C,MAAO,OAAO,OAAW,IAAc,OAAO,WAAa,KAC3D,OAAQ,OAAO,OAAW,IAAc,OAAO,YAAc,GAAA,CAC9D,EAGKC,EAAmBC,EAAAA,YAAY,IAAM,CACzCH,EAAc,CACZ,MAAO,OAAO,WACd,OAAQ,OAAO,WAAA,CAChB,CACH,EAAG,CAAA,CAAE,EAGCI,EAA4BC,EAAAA,QAChC,IAAMd,GAASW,EAAkB,GAAG,EACpC,CAACA,CAAgB,CAAA,EAInBI,EAAAA,UAAU,IAAM,CACd,GAAI,SAAO,OAAW,KAEtB,cAAO,iBAAiB,SAAUF,CAAyB,EAEpD,IAAM,CACX,OAAO,oBAAoB,SAAUA,CAAyB,CAChE,CACF,EAAG,CAACA,CAAyB,CAAC,EAE9B,KAAM,CAAE,MAAAjB,EAAO,OAAAU,CAAA,EAAWE,EAGpBV,EAAagB,EAAAA,QAAQ,IAAMnB,EAAqBC,CAAK,EAAG,CAACA,CAAK,CAAC,EAG/DoB,EAAcF,UAAQ,IAAMT,GAAeT,EAAOU,CAAM,EAAG,CAACV,EAAOU,CAAM,CAAC,EAG1EW,EAAOnB,IAAe,KACtBoB,EAAOpB,IAAe,KACtBqB,EAAOrB,IAAe,KACtBsB,EAAOtB,IAAe,KACtBuB,EAAOvB,IAAe,KACtBwB,EAAQxB,IAAe,MACvByB,EAAQzB,IAAe,MACvB0B,EAAQ1B,IAAe,MACvB2B,EAAQ3B,IAAe,MAGvB4B,EAAWT,GAAQC,EACnBS,EAAWR,EACXS,EAAYR,GAAQC,GAAQC,GAASC,GAASC,GAASC,EACvDI,EAAUZ,GAAQC,GAAQC,EAC1BW,EAAUV,GAAQC,GAAQC,GAASC,GAASC,GAASC,EACrDM,EAAcR,GAASC,GAASC,EAChCO,EAAOR,GAASC,EAChBQ,EAAOR,EAGPS,EAAalB,IAAgB,WAC7BmB,GAAcnB,IAAgB,YAG9BoB,GAAiBxB,cAAayB,GAC3BxC,EAAmBC,CAAU,GAAKD,EAAmBwC,CAAE,EAC7D,CAACvC,CAAU,CAAC,EAETwC,GAAmB1B,cAAayB,GAC7BxC,EAAmBC,CAAU,GAAKD,EAAmBwC,CAAE,EAC7D,CAACvC,CAAU,CAAC,EAETyC,GAAsB3B,EAAAA,YAAY,CAAC4B,EAAiBC,IAA6B,CACrF,MAAMC,EAAU7C,EAAmBC,CAAU,EAC7C,OAAO4C,GAAW7C,EAAmB2C,CAAG,GAAKE,GAAW7C,EAAmB4C,CAAG,CAChF,EAAG,CAAC3C,CAAU,CAAC,EAGT6C,GAAY/B,cAAagC,GACtBhD,GAASgD,EACf,CAAChD,CAAK,CAAC,EAEJiD,GAAcjC,cAAakC,GACxBlD,GAASkD,EACf,CAAClD,CAAK,CAAC,EAEJmD,GAAiBnC,EAAAA,YAAY,CAACgC,EAAkBE,IAC7ClD,GAASgD,GAAYhD,GAASkD,EACpC,CAAClD,CAAK,CAAC,EAGJoD,GAAapC,cAAaqC,GACvB3C,GAAU2C,EAChB,CAAC3C,CAAM,CAAC,EAEL4C,GAAetC,cAAauC,GACzB7C,GAAU6C,EAChB,CAAC7C,CAAM,CAAC,EAEL8C,GAAkBxC,EAAAA,YAAY,CAACqC,EAAmBE,IAC/C7C,GAAU2C,GAAa3C,GAAU6C,EACvC,CAAC7C,CAAM,CAAC,EAKX,MAAO,CAEL,WAAAR,EACA,MAAAF,EACA,OAAAU,EACA,YAAAU,EAGA,KAAAC,EACA,KAAAC,EACA,KAAAC,EACA,KAAAC,EACA,KAAAC,EACA,MAAAC,EACA,MAAAC,EACA,MAAAC,EACA,MAAAC,EAGA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,QAAAC,EACA,QAAAC,EACA,YAAAC,EACA,KAAAC,EACA,KAAAC,EAGA,WAAAC,EACA,YAAAC,GAGA,eAAAC,GACA,iBAAAE,GACA,oBAAAC,GACA,UAAAI,GACA,YAAAE,GACA,eAAAE,GACA,WAAAC,GACA,aAAAE,GACA,gBAAAE,GAGA,MA9CY,EA8CZ,CAEJ,EClKMC,EAA0BC,EAAAA,cAAiD,MAAS,EAE7EC,EAA6B,IAAM,CAC9C,MAAMC,EAAUC,EAAAA,WAAWJ,CAAuB,EAClD,GAAI,CAACG,EACH,MAAM,IAAI,MAAM,2EAA2E,EAE7F,OAAOA,CACT,EC3BME,EAAiBJ,EAAAA,cAA8C,MAAS,EAEjEK,EAA2D,CAAC,CAAE,SAAAnE,KAAe,CACxF,KAAM,CAACoE,EAAaC,CAAc,EAAInD,EAAAA,SAAS,EAAK,EAEpD,OACEoD,EAAAA,IAACJ,EAAe,SAAf,CAAwB,MAAO,CAAE,YAAAE,EAAa,eAAAC,GAC5C,SAAArE,EACH,CAEJ,EAEauE,EAAa,IAAM,CAC9B,MAAMP,EAAUC,EAAAA,WAAWC,CAAc,EACzC,GAAI,CAACF,EACH,MAAM,IAAI,MAAM,kDAAkD,EAEpE,OAAOA,CACT,EClBMQ,EAAoBV,EAAAA,cAAqC,CAC7D,YAAa,OACb,eAAgB,IAAM,CAAC,CACzB,CAAC,EAEYW,EAAgB,IAAMR,EAAAA,WAAWO,CAAiB,EAOlDE,GAAwD,CAAC,CACpE,SAAA1E,EACA,YAAA2E,EAAc,MAChB,IAAM,CACJ,KAAM,CAACC,EAAaC,CAAc,EAAI3D,EAAAA,SAA0ByD,CAAW,EAE3E,OACEL,EAAAA,IAACE,EAAkB,SAAlB,CAA2B,MAAO,CAAE,YAAAI,EAAa,eAAAC,GAC/C,SAAA7E,EACH,CAEJ,EC5Ba8E,EAAsB,IAAM,CACvC,MAAMd,EAAUD,EAAA,EAEhB,MAAO,CAEL,GAAGC,EAAQ,WAGX,OAAQ,CACN,QAASA,EAAQ,OAAO,QACxB,OAAQA,EAAQ,OAAO,OACvB,UAAWA,EAAQ,OAAO,SAAA,EAI5B,YAAaA,EAAQ,YAGrB,gBAAiB,IAAMA,EAAQ,OAAO,UAAY,UAClD,gBAAiB,IAAMA,EAAQ,OAAO,UAAY,UAClD,kBAAmB,IAAMA,EAAQ,OAAO,UAAY,YACpD,gBAAiB,IAAMA,EAAQ,OAAO,UAAY,UAGlD,KAAM,CACJ,KAAM,CAACZ,EAAW,OAAS,kBAAkBA,CAAQ,GACrD,WAAa2B,GAAwC,CACnD,MAAMC,EAAoB,CAAA,EAC1B,cAAO,QAAQD,CAAW,EAAE,QAAQ,CAAC,CAACzE,EAAY2E,CAAI,IAAM,CACtD3E,IAAe,OACjB0E,EAAQ,KAAK,aAAaC,CAAI,EAAE,EAEhCD,EAAQ,KAAK,GAAG1E,CAAU,cAAc2E,CAAI,EAAE,CAElD,CAAC,EACMD,EAAQ,KAAK,GAAG,CACzB,EACA,MAAQC,GAAiB,aAAaA,CAAI,EAAA,EAI5C,QAAS,CACP,UAAWjB,EAAQ,YAAY,kBAAA,EAC/B,QAAS,OACT,KAAM,MACN,IAAK,OAAA,CACP,CAEJ,EChDakB,EAAY,IAAM,CAC7B,MAAMC,EAAmBL,EAAA,EAEzB,MAAO,CAEL,QAASK,EAAiB,OAAO,QACjC,OAAQA,EAAiB,OAAO,OAChC,UAAWA,EAAiB,OAAO,UAGnC,GAAGA,EAAiB,YAGpB,gBAAiBA,EAAiB,gBAAA,EAClC,gBAAiBA,EAAiB,gBAAA,EAClC,kBAAmBA,EAAiB,kBAAA,EACpC,gBAAiBA,EAAiB,gBAAA,EAGlC,KAAMA,EAAiB,KAGvB,QAASA,EAAiB,OAAA,CAE9B,ECdaC,EAA8C,CACzD,QAAS,CACP,KAAM,UACN,YAAa,4CACb,WAAY,CAAC,aAAc,QAAQ,EACnC,QAAS,oBACT,WAAY,CACV,OAAQ,MACR,OAAQ,MACR,QAAS,KAAA,CACX,EAEF,QAAS,CACP,KAAM,UACN,YAAa,yCACb,WAAY,CAAC,SAAS,EACtB,QAAS,aACT,WAAY,CACV,OAAQ,MACR,OAAQ,MACR,QAAS,KAAA,CACX,EAEF,UAAW,CACT,KAAM,YACN,YAAa,mCACb,WAAY,CAAC,SAAU,UAAW,QAAQ,EAC1C,QAAS,oBACT,WAAY,CACV,OAAQ,MACR,OAAQ,MACR,QAAS,KAAA,CACX,EAEF,QAAS,CACP,KAAM,UACN,YAAa,iCACb,WAAY,CAAA,EACZ,QAAS,aACT,WAAY,CACV,OAAQ,MACR,OAAQ,MACR,QAAS,KAAA,CACX,CAEJ,EAEaC,EAAiB,UACjBC,GAAoB,OAAO,KAAKF,CAAa,ECpCpDG,GAA8E,CAAC,CACnF,SAAAvF,EACA,cAAAwF,EACA,kBAAAC,CACF,IAAM,CAEJ,MAAMC,EAAqB3E,EAAA,EAErB4E,EADmBF,IAAA,GACcC,EAIjC,CAACE,EAAeC,CAAgB,EAAI3E,EAAAA,SAAS,IAE7CsE,GAAiB,OAAOA,GAAkB,UAAYJ,EAAcI,CAAa,EAC5EA,EAEFH,CACR,EAEKS,EAAeV,EAAcQ,CAAa,GAAKR,EAAcC,CAAc,EAuB3EU,EAAe,CACnB,WAAAJ,EACA,OAAQ,CACN,QAASC,EACT,OAAQE,EACR,UAAWD,CAAA,EAEb,YA5BkB,CAClB,kBAAmB,IACbF,EAAW,SAAiBG,EAAa,WAAW,OACpDH,EAAW,SAAiBG,EAAa,WAAW,OACjDA,EAAa,WAAW,QAGjC,aAAc,IAAM,CAClB,MAAME,EAAY,wBAClB,OAAIJ,IAAkB,WAAaA,IAAkB,YAC5C,GAAGI,CAAS,QAEdA,CACT,EAEA,WAAY,IAAMJ,IAAkB,WAAaA,IAAkB,YACnE,UAAW,IAAMA,IAAkB,YACnC,UAAW,IAAMA,IAAkB,WAAaA,IAAkB,YAClE,cAAe,IAAMA,IAAkB,SAAA,CAUvC,EAGF,aACG/B,EAAwB,SAAxB,CAAiC,MAAOkC,EACtC,SAAA/F,EACH,CAEJ,EAEaiG,GAAoE,CAAC,CAChF,SAAAjG,EACA,cAAAwF,EAAgBH,EAChB,kBAAAI,CACF,IAAM,CAEJ,MAAMS,EAA2BV,GAAiB,OAAOA,GAAkB,UAAYJ,EAAcI,CAAa,EAC9GA,EACAH,EAEJ,aACGtF,EAAA,CACC,SAAAuE,EAAAA,IAACiB,GAAA,CACC,cAAeW,EACf,kBAAAT,EAEC,SAAAzF,CAAA,CAAA,EAEL,CAEJ,ECtFMmG,GAAwC,CAAC,CAAE,SAAAnG,EAAU,OAAQoG,KAAiB,CAClF,KAAM,CAAE,OAAAC,CAAA,EAAWvB,EAAA,EAGbwB,EAAU,CACd,QAASC,EACT,QAASC,EACT,UAAWC,EACX,QAASC,CAAA,EAILC,EAAcP,GAAcC,EAAO,SAAW,UAG9CO,EAA8BN,EAAQK,CAAmC,EAC3EA,EACA,UAGEE,EAAkBP,EAAQM,CAAmC,GAAKL,EAExE,OAAOjC,MAACuC,GAAiB,SAAA7G,EAAS,CACpC,ECtCM8G,GAAS,IAAM,CACnB,KAAM,CAAE,SAAA5E,CAAA,EAAa4C,EAAA,EACf,CAAE,YAAAF,EAAa,eAAAC,CAAA,EAAmBJ,EAAA,EAClC,CAAE,YAAAL,EAAa,eAAAC,CAAA,EAAmBE,EAAA,EAElCwC,EAAY,CAChB,CAAE,GAAI,OAAQ,MAAO,eAAA,EACrB,CAAE,GAAI,OAAQ,MAAO,MAAA,CAAO,EAG9B,OACEC,EAAAA,KAAC,MAAA,CAAI,UAAU,oBACb,SAAA,CAAA1C,MAAC,SAAA,CAAO,UAAU,uGAChB,SAAAA,EAAAA,IAAC,OAAI,UAAU,SACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,YACb,SAAA0C,OAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,8BAEZ,SAAA,CAAA9E,GACCoC,EAAAA,IAAC,SAAA,CACC,QAAS,IAAMD,EAAe,EAAI,EAClC,UAAU,0FAEV,SAAAC,EAAAA,IAAC,OAAI,UAAU,UAAU,KAAK,OAAO,OAAO,eAAe,QAAQ,YACjE,eAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,0BAA0B,CAAA,CACjG,CAAA,CAAA,EAIJ0C,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,iFAAA,CAAkF,EACjGA,EAAAA,IAAC,KAAA,CAAG,UAAU,iDAAiD,SAAA,oBAAA,CAE/D,CAAA,EACF,EACAA,EAAAA,IAAC,MAAA,CAAI,UAAU,sHAAsH,SAAA,WAAA,CAErI,CAAA,EACF,EAEAA,EAAAA,IAAC,OAAI,UAAU,8BAEZ,UAACpC,GAAY6E,EAAU,IAAKE,GAC3B3C,EAAAA,IAAC,SAAA,CAEC,QAAS,IAAMO,EAAeoC,EAAK,EAAqB,EACxD,UAAW,gFACTrC,IAAgBqC,EAAK,GACjB,kDACA,qFACN,GAEC,SAAAA,EAAK,KAAA,EARDA,EAAK,EAAA,CAUb,CAAA,CACH,CAAA,EACF,CAAA,CACF,EACF,EACF,EAGC/E,GAAYkC,GACXE,MAAC,OAAI,UAAU,iCAAiC,QAAS,IAAMD,EAAe,EAAK,EACjF,eAAC,MAAA,CAAI,UAAU,qGACb,SAAA2C,OAAC,MAAA,CAAI,UAAU,iCAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,kEACb,SAAAA,EAAAA,IAAC,QAAK,UAAU,+BAA+B,cAAE,CAAA,CACnD,EACAA,EAAAA,IAAC,OAAA,CAAK,UAAU,+BAA+B,SAAA,oBAAA,CAAkB,CAAA,EACnE,QAGC,MAAA,CAAI,UAAU,YACZ,SAAAyC,EAAU,IAAKG,GACd5C,EAAAA,IAAC,SAAA,CAEC,QAAS,IAAM,CACbO,EAAeqC,EAAK,EAAqB,EACzC7C,EAAe,EAAK,CACtB,EACA,UAAW,gFACTO,IAAgBsC,EAAK,GACjB,yDACA,wDACN,GAEA,SAAA5C,EAAAA,IAAC,OAAA,CAAK,UAAU,cAAe,WAAK,KAAA,CAAM,CAAA,EAXrC4C,EAAK,EAAA,CAab,CAAA,CACH,CAAA,CAAA,CACF,EACF,CAAA,CACF,CAAA,EAEJ,CAEJ,ECnGMC,EAAU,IAAM,CACpB,KAAM,CAAE,SAAAjF,EAAU,SAAAC,CAAA,EAAa2C,EAAA,EACzB,CAAE,YAAAV,EAAa,eAAAC,CAAA,EAAmBE,EAAA,EAElCwC,EAAY,CAChB,CAAE,GAAI,OAAQ,MAAO,QAAA,EACrB,CAAE,GAAI,QAAS,MAAO,QAAA,EACtB,CAAE,GAAI,UAAW,MAAO,UAAA,CAAW,EAGrC,OACEC,EAAAA,KAAAI,WAAA,CACG,SAAA,CAAAlF,GACCoC,EAAAA,IAAC,SAAA,CACC,QAAS,IAAMD,EAAe,EAAI,EAClC,UAAU,6HAEV,SAAAC,EAAAA,IAAC,OAAI,UAAU,UAAU,KAAK,OAAO,OAAO,eAAe,QAAQ,YACjE,eAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,0BAA0B,CAAA,CACjG,CAAA,CAAA,EAIJA,MAAC,QAAA,CAAM,UAAW,wCAAwCpC,EAAW,SAAW,oBAAoB,IAAIC,EAAW,OAAS,MAAM,GAChI,SAAA6E,EAAAA,KAAC,MAAA,CAAI,UAAU,2BACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,kEACb,SAAAA,EAAAA,IAAC,QAAK,UAAU,+BAA+B,cAAE,CAAA,CACnD,EACAA,EAAAA,IAAC,OAAA,CAAK,UAAU,+BAA+B,SAAA,eAAA,CAAa,CAAA,EAC9D,QAEC,MAAA,CAAI,UAAU,YACZ,SAAAyC,EAAU,IAAKG,GACd5C,EAAAA,IAAC,SAAA,CAEC,UAAU,0HAEV,SAAAA,EAAAA,IAAC,OAAA,CAAK,UAAU,cAAe,WAAK,KAAA,CAAM,CAAA,EAHrC4C,EAAK,EAAA,CAKb,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,EAEChF,GAAYkC,GACXE,MAAC,OAAI,UAAU,iCAAiC,QAAS,IAAMD,EAAe,EAAK,EACjF,eAAC,MAAA,CAAI,UAAU,sEACb,SAAA2C,OAAC,MAAA,CAAI,UAAU,iCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,kEACb,SAAAA,EAAAA,IAAC,QAAK,UAAU,+BAA+B,cAAE,CAAA,CACnD,EACAA,EAAAA,IAAC,OAAA,CAAK,UAAU,+BAA+B,SAAA,eAAA,CAAa,CAAA,EAC9D,QAEC,MAAA,CAAI,UAAU,YACZ,SAAAyC,EAAU,IAAKG,GACd5C,EAAAA,IAAC,SAAA,CAEC,QAAS,IAAMD,EAAe,EAAK,EACnC,UAAU,0HAEV,SAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,cAAe,WAAK,KAAA,CAAM,CAAA,EAJrC4C,EAAK,EAAA,CAMb,CAAA,CACH,CAAA,CAAA,CACF,EACF,CAAA,CACF,CAAA,EAEJ,CAEJ,EC5EMG,EAAS,IAEX/C,MAAC,SAAA,CAAO,UAAU,uCAChB,eAAC,MAAA,CAAI,UAAU,YACb,SAAAA,EAAAA,IAAC,OAAI,UAAU,gCACb,SAAA0C,OAAC,IAAA,CAAE,UAAU,wBAAwB,SAAA,CAAA,KAChC,IAAI,KAAA,EAAO,YAAA,EAAc,gDAAA,EAC9B,CAAA,CACF,EACF,EACF,ECREM,EAAa,IAAM,CACvB,KAAM,CAAE,SAAApF,CAAA,EAAa4C,EAAA,EAErB,OACER,EAAAA,IAAC,MAAA,CAAI,UAAU,yDACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,YACb,SAAA0C,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,kEACb,SAAAA,EAAAA,IAAC,QAAK,UAAU,+BAA+B,cAAE,CAAA,CACnD,EACAA,EAAAA,IAAC,KAAA,CAAG,UAAU,mCAAmC,SAAA,eAAA,CAAa,CAAA,EAChE,EAECpC,GACCoC,EAAAA,IAAC,SAAA,CAAO,UAAU,qCAChB,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,UAAU,KAAK,OAAO,OAAO,eAAe,QAAQ,YACjE,SAAAA,EAAAA,IAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,yBAAA,CAA0B,CAAA,CACjG,CAAA,CACF,CAAA,CAAA,CAEJ,EACF,EACF,CAEJ,ECpBMiC,EAA8C,CAAC,CAAE,SAAAvG,KAEnDgH,EAAAA,KAAC,MAAA,CAAI,UAAU,wCAEb,SAAA,CAAA1C,EAAAA,IAACgD,EAAA,EAAW,EAGZhD,EAAAA,IAAC,OAAA,CAAK,UAAU,SACb,SAAAtE,CAAA,CACH,QAGCqH,EAAA,CAAA,CAAO,CAAA,EACV,ECZEE,GAAgE,CAAC,CAAE,SAAAvH,KAErEgH,EAAAA,KAAC,MAAA,CAAI,UAAU,+BAEb,SAAA,CAAA1C,EAAAA,IAAC6C,EAAA,EAAQ,EAGT7C,EAAAA,IAAC,OAAA,CAAK,UAAU,uBACb,SAAAtE,CAAA,CACH,CAAA,EACF,EAIEwG,EAA8C,CAAC,CAAE,SAAAxG,KAEnDsE,EAAAA,IAACH,EAAA,CACC,SAAAG,EAAAA,IAACiD,GAAA,CAAsB,SAAAvH,EAAS,EAClC,EClBEwH,GAAkE,CAAC,CAAE,SAAAxH,WAEtE,MAAA,CAAI,UAAU,wCAEb,SAAAgH,EAAAA,KAAC,MAAA,CAAI,UAAU,cAEb,SAAA,CAAA1C,EAAAA,IAAC6C,EAAA,EAAQ,EAGTH,EAAAA,KAAC,OAAA,CAAK,UAAU,qCACd,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,SACZ,SAAAtE,CAAA,CACH,QAGCqH,EAAA,CAAA,CAAO,CAAA,CAAA,CACV,CAAA,CAAA,CACF,CAAA,CACF,EAIEZ,EAAkD,CAAC,CAAE,SAAAzG,KAEvDsE,EAAAA,IAACH,EAAA,CACC,SAAAG,EAAAA,IAACkD,GAAA,CAAwB,SAAAxH,EAAS,EACpC,EC5BE0G,EAA8C,CAAC,CAAE,SAAA1G,WAElD,MAAA,CAAI,UAAU,0BACb,SAAAsE,EAAAA,IAAC,OAAA,CACE,SAAAtE,EACH,CAAA,CACF,ECLEyH,GAAiB,CAAC,CAAE,QAAAC,EAAU,MAAiC,CACnE,KAAM,CAAE,QAAAxE,EAAS,UAAAyE,EAAW,OAAAC,CAAA,EAAW1C,EAAA,EAEvC,OAAIwC,EAEAV,EAAAA,KAAC,MAAA,CAAI,UAAU,oDACb,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,6BAA6B,SAAA,UAAO,EACnDA,EAAAA,IAAC,SAAA,CACC,MAAOpB,EACP,SAAW2E,GAAMF,EAAUE,EAAE,OAAO,KAAK,EACzC,UAAU,qIAET,gBAAO,QAAQzC,CAAa,EAAE,IAAI,CAAC,CAAC0C,EAAKhC,CAAY,UACnD,SAAA,CAAiB,MAAOgC,EACtB,SAAAhC,EAAa,IAAA,EADHgC,CAEb,CACD,CAAA,CAAA,CACH,EACF,EAKFd,EAAAA,KAAC,MAAA,CAAI,UAAU,wEACb,SAAA,CAAA1C,EAAAA,IAAC,KAAA,CAAG,UAAU,gCAAgC,SAAA,iBAAc,EAE5DA,EAAAA,IAAC,MAAA,CAAI,UAAU,uDACZ,SAAA,OAAO,QAAQc,CAAa,EAAE,IAAI,CAAC,CAAC0C,EAAKhC,CAAY,IACpDkB,EAAAA,KAAC,SAAA,CAEC,QAAS,IAAMW,EAAUG,CAAG,EAC5B,UAAW;AAAA;AAAA,gBAEP5E,IAAY4E,EACV,+CACA,iEACJ;AAAA,cAGF,SAAA,CAAAxD,EAAAA,IAAC,MAAA,CAAI,UAAU,qBAAsB,SAAAwB,EAAa,KAAK,EACvDxB,EAAAA,IAAC,MAAA,CAAI,UAAU,qBAAsB,WAAa,WAAA,CAAY,CAAA,CAAA,EAXzDwD,CAAA,CAaR,EACH,EAEAd,EAAAA,KAAC,MAAA,CAAI,UAAU,qCACb,SAAA,CAAA1C,EAAAA,IAAC,MAAA,CAAI,UAAU,6BAA6B,SAAA,iBAAc,EAC1DA,EAAAA,IAAC,MAAA,CAAI,UAAU,oCAAqC,WAAO,KAAK,EAChEA,EAAAA,IAAC,MAAA,CAAI,UAAU,wBAAyB,WAAO,WAAA,CAAY,CAAA,CAAA,CAC7D,CAAA,EACF,CAEJ"}
|
|
1
|
+
{"version":3,"file":"responsive-system.cjs","sources":["../src/providers/ResponsiveProvider.tsx","../src/constants/breakpoints.ts","../src/hooks/useResponsive.ts","../src/context/ResponsiveLayoutContext.tsx","../src/context/SidebarContext.tsx","../src/context/NavigationContext.tsx","../src/hooks/useResponsiveLayout.ts","../src/hooks/useLayout.ts","../src/config/layout.ts","../src/providers/ResponsiveLayoutProvider.tsx","../src/layouts/MainLayout.tsx","../src/components/layout/Header.tsx","../src/components/layout/Sidebar.tsx","../src/components/layout/Footer.tsx","../src/components/layout/Navigation.tsx","../src/layouts/DefaultLayout.tsx","../src/layouts/SidebarLayout.tsx","../src/layouts/DashboardLayout.tsx","../src/layouts/MinimalLayout.tsx","../src/components/LayoutSwitcher.tsx"],"sourcesContent":["import React from 'react'\r\nimport type { ResponsiveProviderProps } from '../types/responsive'\r\n\r\n/**\r\n * ResponsiveProvider - Provider simplificado para el sistema responsive\r\n * \r\n * Nota: Con el sistema de auto-scaling mediante plugin de Tailwind,\r\n * este Provider es OPCIONAL y solo se necesita si quieres acceder\r\n * al hook useResponsive() en tus componentes.\r\n */\r\nexport const ResponsiveProvider: React.FC<ResponsiveProviderProps> = ({\r\n children,\r\n debug: _debug = false\r\n}) => {\r\n // El Provider ahora solo envuelve children sin context\r\n // El auto-scaling funciona mediante el plugin de Tailwind\r\n return <>{children}</>\r\n}\r\n","import type { Breakpoint } from '../types/responsive'\r\n\r\n/**\r\n * Default breakpoint values\r\n * Deben coincidir con tailwind.config.js\r\n */\r\nexport const DEFAULT_BREAKPOINTS: Record<Breakpoint, number> = {\r\n xs: 475,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n '2xl': 1536,\r\n '3xl': 1920,\r\n '4xl': 2560,\r\n '5xl': 3840\r\n}\r\n\r\n/**\r\n * Get current breakpoint based on window width\r\n */\r\nexport const getCurrentBreakpoint = (width: number): Breakpoint => {\r\n if (width >= DEFAULT_BREAKPOINTS['5xl']) return '5xl'\r\n if (width >= DEFAULT_BREAKPOINTS['4xl']) return '4xl'\r\n if (width >= DEFAULT_BREAKPOINTS['3xl']) return '3xl'\r\n if (width >= DEFAULT_BREAKPOINTS['2xl']) return '2xl'\r\n if (width >= DEFAULT_BREAKPOINTS.xl) return 'xl'\r\n if (width >= DEFAULT_BREAKPOINTS.lg) return 'lg'\r\n if (width >= DEFAULT_BREAKPOINTS.md) return 'md'\r\n if (width >= DEFAULT_BREAKPOINTS.sm) return 'sm'\r\n return 'xs'\r\n}\r\n\r\n/**\r\n * Get breakpoint index (for comparisons)\r\n */\r\nexport const getBreakpointIndex = (breakpoint: Breakpoint): number => {\r\n const breakpoints: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl']\r\n return breakpoints.indexOf(breakpoint)\r\n}\r\n\r\n/**\r\n * Get breakpoint value in pixels\r\n */\r\nexport const getBreakpointValue = (breakpoint: Breakpoint): number => {\r\n return DEFAULT_BREAKPOINTS[breakpoint]\r\n}\r\n\r\n","import { useState, useEffect, useCallback, useMemo } from 'react'\r\nimport type { \r\n ResponsiveState, \r\n Breakpoint\r\n} from '../types/responsive'\r\nimport { \r\n getCurrentBreakpoint,\r\n getBreakpointIndex\r\n} from '../constants/breakpoints'\r\n\r\n/**\r\n * Debounce utility\r\n */\r\nfunction debounce<T extends (...args: unknown[]) => void>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: ReturnType<typeof setTimeout> | null = null\r\n return (...args: Parameters<T>) => {\r\n if (timeout) clearTimeout(timeout)\r\n timeout = setTimeout(() => func(...args), wait)\r\n }\r\n}\r\n\r\n/**\r\n * Get orientation based on dimensions\r\n */\r\nfunction getOrientation(width: number, height: number): 'landscape' | 'portrait' {\r\n return width >= height ? 'landscape' : 'portrait'\r\n}\r\n\r\n/**\r\n * Hook principal useResponsive\r\n * Provee información sobre el breakpoint actual y helpers para responsive\r\n */\r\nexport const useResponsive = (): ResponsiveState => {\r\n const [dimensions, setDimensions] = useState({\r\n width: typeof window !== 'undefined' ? window.innerWidth : 1024,\r\n height: typeof window !== 'undefined' ? window.innerHeight : 768\r\n })\r\n\r\n // Función para actualizar dimensiones\r\n const updateDimensions = useCallback(() => {\r\n setDimensions({\r\n width: window.innerWidth,\r\n height: window.innerHeight\r\n })\r\n }, [])\r\n\r\n // Debounced update para optimizar performance\r\n const debouncedUpdateDimensions = useMemo(\r\n () => debounce(updateDimensions, 100),\r\n [updateDimensions]\r\n )\r\n\r\n // Effect para escuchar cambios de tamaño\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return\r\n\r\n window.addEventListener('resize', debouncedUpdateDimensions)\r\n \r\n return () => {\r\n window.removeEventListener('resize', debouncedUpdateDimensions)\r\n }\r\n }, [debouncedUpdateDimensions])\r\n\r\n const { width, height } = dimensions\r\n\r\n // Calcular breakpoint actual\r\n const breakpoint = useMemo(() => getCurrentBreakpoint(width), [width])\r\n \r\n // Calcular orientación\r\n const orientation = useMemo(() => getOrientation(width, height), [width, height])\r\n\r\n // Helpers booleanos por breakpoint específico\r\n const isXs = breakpoint === 'xs'\r\n const isSm = breakpoint === 'sm'\r\n const isMd = breakpoint === 'md'\r\n const isLg = breakpoint === 'lg'\r\n const isXl = breakpoint === 'xl'\r\n const is2Xl = breakpoint === '2xl'\r\n const is3Xl = breakpoint === '3xl'\r\n const is4Xl = breakpoint === '4xl'\r\n const is5Xl = breakpoint === '5xl'\r\n\r\n // Helpers booleanos agrupados\r\n const isMobile = isXs || isSm\r\n const isTablet = isMd\r\n const isDesktop = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isSmall = isXs || isSm || isMd\r\n const isLarge = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isUltraWide = is3Xl || is4Xl || is5Xl\r\n const is4K = is4Xl || is5Xl\r\n const is5K = is5Xl\r\n\r\n // Helpers de orientación\r\n const isPortrait = orientation === 'portrait'\r\n const isLandscape = orientation === 'landscape'\r\n\r\n // Funciones de comparación de breakpoints\r\n const isBreakpointUp = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) >= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointDown = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) <= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointBetween = useCallback((min: Breakpoint, max: Breakpoint): boolean => {\r\n const current = getBreakpointIndex(breakpoint)\r\n return current >= getBreakpointIndex(min) && current <= getBreakpointIndex(max)\r\n }, [breakpoint])\r\n\r\n // Funciones de comparación de ancho\r\n const isWidthUp = useCallback((minWidth: number): boolean => {\r\n return width >= minWidth\r\n }, [width])\r\n\r\n const isWidthDown = useCallback((maxWidth: number): boolean => {\r\n return width <= maxWidth\r\n }, [width])\r\n\r\n const isWidthBetween = useCallback((minWidth: number, maxWidth: number): boolean => {\r\n return width >= minWidth && width <= maxWidth\r\n }, [width])\r\n\r\n // Funciones de comparación de altura\r\n const isHeightUp = useCallback((minHeight: number): boolean => {\r\n return height >= minHeight\r\n }, [height])\r\n\r\n const isHeightDown = useCallback((maxHeight: number): boolean => {\r\n return height <= maxHeight\r\n }, [height])\r\n\r\n const isHeightBetween = useCallback((minHeight: number, maxHeight: number): boolean => {\r\n return height >= minHeight && height <= maxHeight\r\n }, [height])\r\n\r\n // Debug mode\r\n const debug = false\r\n\r\n return {\r\n // Estado básico\r\n breakpoint,\r\n width,\r\n height,\r\n orientation,\r\n \r\n // Helpers booleanos específicos\r\n isXs,\r\n isSm,\r\n isMd,\r\n isLg,\r\n isXl,\r\n is2Xl,\r\n is3Xl,\r\n is4Xl,\r\n is5Xl,\r\n \r\n // Helpers booleanos agrupados\r\n isMobile,\r\n isTablet,\r\n isDesktop,\r\n isSmall,\r\n isLarge,\r\n isUltraWide,\r\n is4K,\r\n is5K,\r\n \r\n // Helpers de orientación\r\n isPortrait,\r\n isLandscape,\r\n \r\n // Funciones de comparación\r\n isBreakpointUp,\r\n isBreakpointDown,\r\n isBreakpointBetween,\r\n isWidthUp,\r\n isWidthDown,\r\n isWidthBetween,\r\n isHeightUp,\r\n isHeightDown,\r\n isHeightBetween,\r\n \r\n // Debug\r\n debug\r\n }\r\n}\r\n","import { createContext, useContext } from 'react'\r\nimport type { ResponsiveState } from '../types/responsive'\r\nimport type { LayoutConfig } from '../config/layout'\r\n\r\nexport interface ResponsiveLayoutState {\r\n // Estado del sistema responsivo\r\n responsive: ResponsiveState\r\n \r\n // Estado del layout\r\n layout: {\r\n current: string\r\n config: LayoutConfig\r\n setLayout: (layout: string) => void\r\n }\r\n \r\n // Utilidades de layout\r\n layoutUtils: {\r\n getContainerClass: () => string\r\n getMainClass: () => string\r\n hasSidebar: () => boolean\r\n hasHeader: () => boolean\r\n hasFooter: () => boolean\r\n hasNavigation: () => boolean\r\n }\r\n}\r\n\r\nconst ResponsiveLayoutContext = createContext<ResponsiveLayoutState | undefined>(undefined)\r\n\r\nexport const useResponsiveLayoutContext = () => {\r\n const context = useContext(ResponsiveLayoutContext)\r\n if (!context) {\r\n throw new Error('useResponsiveLayoutContext must be used within a ResponsiveLayoutProvider')\r\n }\r\n return context\r\n}\r\n\r\nexport { ResponsiveLayoutContext }\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface SidebarContextType {\r\n sidebarOpen: boolean\r\n setSidebarOpen: (open: boolean) => void\r\n}\r\n\r\nconst SidebarContext = createContext<SidebarContextType | undefined>(undefined)\r\n\r\nexport const SidebarProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n const [sidebarOpen, setSidebarOpen] = useState(false)\r\n\r\n return (\r\n <SidebarContext.Provider value={{ sidebarOpen, setSidebarOpen }}>\r\n {children}\r\n </SidebarContext.Provider>\r\n )\r\n}\r\n\r\nexport const useSidebar = () => {\r\n const context = useContext(SidebarContext)\r\n if (!context) {\r\n throw new Error('useSidebar must be used within a SidebarProvider')\r\n }\r\n return context\r\n}\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface NavigationContextType {\r\n currentPage: 'demo' | 'test'\r\n setCurrentPage: (page: 'demo' | 'test') => void\r\n}\r\n\r\nconst NavigationContext = createContext<NavigationContextType>({\r\n currentPage: 'test',\r\n setCurrentPage: () => {}\r\n})\r\n\r\nexport const useNavigation = () => useContext(NavigationContext)\r\n\r\ninterface NavigationProviderProps {\r\n children: React.ReactNode\r\n defaultPage?: 'demo' | 'test'\r\n}\r\n\r\nexport const NavigationProvider: React.FC<NavigationProviderProps> = ({ \r\n children, \r\n defaultPage = 'test' \r\n}) => {\r\n const [currentPage, setCurrentPage] = useState<'demo' | 'test'>(defaultPage)\r\n\r\n return (\r\n <NavigationContext.Provider value={{ currentPage, setCurrentPage }}>\r\n {children}\r\n </NavigationContext.Provider>\r\n )\r\n}\r\n\r\n","import { useResponsiveLayoutContext } from '../context'\r\n\r\nexport const useResponsiveLayout = () => {\r\n const context = useResponsiveLayoutContext()\r\n \r\n return {\r\n // Todo el sistema responsivo original\r\n ...context.responsive,\r\n \r\n // Sistema de layout\r\n layout: {\r\n current: context.layout.current,\r\n config: context.layout.config,\r\n setLayout: context.layout.setLayout,\r\n },\r\n \r\n // Utilidades de layout\r\n layoutUtils: context.layoutUtils,\r\n \r\n // Helpers específicos del layout\r\n isDefaultLayout: () => context.layout.current === 'default',\r\n isSidebarLayout: () => context.layout.current === 'sidebar',\r\n isDashboardLayout: () => context.layout.current === 'dashboard',\r\n isMinimalLayout: () => context.layout.current === 'minimal',\r\n \r\n // Grid helpers que usan el sistema auto-escalable\r\n grid: {\r\n auto: (minWidth = 'md') => `grid-cols-auto-${minWidth}`,\r\n responsive: (breakpoints: Record<string, number>) => {\r\n const classes: string[] = []\r\n Object.entries(breakpoints).forEach(([breakpoint, cols]) => {\r\n if (breakpoint === 'base') {\r\n classes.push(`grid-cols-${cols}`)\r\n } else {\r\n classes.push(`${breakpoint}:grid-cols-${cols}`)\r\n }\r\n })\r\n return classes.join(' ')\r\n },\r\n fixed: (cols: number) => `grid-cols-${cols}`,\r\n },\r\n \r\n // Spacing helpers que escalan automáticamente\r\n spacing: {\r\n container: context.layoutUtils.getContainerClass(),\r\n section: 'mb-6',\r\n card: 'p-6',\r\n gap: 'gap-4',\r\n },\r\n }\r\n}\r\n","import { useResponsiveLayout } from './index'\r\n\r\nexport const useLayout = () => {\r\n const responsiveLayout = useResponsiveLayout()\r\n \r\n return {\r\n // Layout actual\r\n current: responsiveLayout.layout.current,\r\n config: responsiveLayout.layout.config,\r\n setLayout: responsiveLayout.layout.setLayout,\r\n \r\n // Utilidades\r\n ...responsiveLayout.layoutUtils,\r\n \r\n // Helpers específicos\r\n isDefaultLayout: responsiveLayout.isDefaultLayout(),\r\n isSidebarLayout: responsiveLayout.isSidebarLayout(),\r\n isDashboardLayout: responsiveLayout.isDashboardLayout(),\r\n isMinimalLayout: responsiveLayout.isMinimalLayout(),\r\n \r\n // Grid helpers\r\n grid: responsiveLayout.grid,\r\n \r\n // Spacing helpers\r\n spacing: responsiveLayout.spacing,\r\n }\r\n}\r\n","export interface LayoutConfig {\r\n name: string\r\n description: string\r\n components: string[]\r\n spacing: string\r\n responsive: {\r\n mobile: string\r\n tablet: string\r\n desktop: string\r\n }\r\n}\r\n\r\nexport const LAYOUT_CONFIG: Record<string, LayoutConfig> = {\r\n default: {\r\n name: 'Default',\r\n description: 'Navbar arriba, body central, footer abajo',\r\n components: ['Navigation', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n sidebar: {\r\n name: 'Sidebar',\r\n description: 'Sidebar izquierda, contenido principal',\r\n components: ['Sidebar'],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n },\r\n dashboard: {\r\n name: 'Dashboard',\r\n description: 'Header + Sidebar + Main + Footer',\r\n components: ['Header', 'Sidebar', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n minimal: {\r\n name: 'Minimal',\r\n description: 'Solo contenido, sin navegación',\r\n components: [],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n }\r\n}\r\n\r\nexport const DEFAULT_LAYOUT = 'default'\r\nexport const AVAILABLE_LAYOUTS = Object.keys(LAYOUT_CONFIG)\r\n","import React, { useState } from 'react'\r\nimport { ResponsiveProvider } from './index'\r\nimport { useResponsive } from '../hooks'\r\nimport { ResponsiveLayoutContext } from '../context'\r\nimport { LAYOUT_CONFIG, DEFAULT_LAYOUT } from '../config/layout'\r\nimport type { ResponsiveState } from '../types/responsive'\r\n\r\ninterface ResponsiveLayoutProviderProps {\r\n children: React.ReactNode\r\n defaultLayout?: string\r\n /**\r\n * Hook responsivo personalizado del proyecto consumidor.\r\n * Si se proporciona, se usará en lugar del hook interno del paquete.\r\n * Debe retornar un objeto compatible con ResponsiveState.\r\n */\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\ninterface ResponsiveLayoutProviderInnerProps {\r\n children: React.ReactNode\r\n defaultLayout: string\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\nconst ResponsiveLayoutProviderInner: React.FC<ResponsiveLayoutProviderInnerProps> = ({ \r\n children, \r\n defaultLayout,\r\n useResponsiveHook\r\n}) => {\r\n // Usar hook personalizado si se proporciona, sino usar el hook interno\r\n const internalResponsive = useResponsive()\r\n const customResponsive = useResponsiveHook?.()\r\n const responsive = customResponsive || internalResponsive\r\n \r\n // Inicializar el estado con el layout normalizado usando función inicializadora\r\n // Esto asegura que solo se ejecute una vez, incluso con React.StrictMode\r\n const [currentLayout, setCurrentLayout] = useState(() => {\r\n // Validar y normalizar el defaultLayout directamente en la función inicializadora\r\n if (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout]) {\r\n return defaultLayout\r\n }\r\n return DEFAULT_LAYOUT\r\n })\r\n \r\n const layoutConfig = LAYOUT_CONFIG[currentLayout] || LAYOUT_CONFIG[DEFAULT_LAYOUT]\r\n \r\n const layoutUtils = {\r\n getContainerClass: () => {\r\n if (responsive.isMobile) return layoutConfig.responsive.mobile\r\n if (responsive.isTablet) return layoutConfig.responsive.tablet\r\n return layoutConfig.responsive.desktop\r\n },\r\n \r\n getMainClass: () => {\r\n const baseClass = 'min-h-screen bg-black'\r\n if (currentLayout === 'sidebar' || currentLayout === 'dashboard') {\r\n return `${baseClass} flex`\r\n }\r\n return baseClass\r\n },\r\n \r\n hasSidebar: () => currentLayout === 'sidebar' || currentLayout === 'dashboard',\r\n hasHeader: () => currentLayout === 'dashboard',\r\n hasFooter: () => currentLayout === 'default' || currentLayout === 'dashboard',\r\n hasNavigation: () => currentLayout === 'default',\r\n }\r\n \r\n const contextValue = {\r\n responsive,\r\n layout: {\r\n current: currentLayout,\r\n config: layoutConfig,\r\n setLayout: setCurrentLayout,\r\n },\r\n layoutUtils,\r\n }\r\n \r\n return (\r\n <ResponsiveLayoutContext.Provider value={contextValue}>\r\n {children}\r\n </ResponsiveLayoutContext.Provider>\r\n )\r\n}\r\n\r\nexport const ResponsiveLayoutProvider: React.FC<ResponsiveLayoutProviderProps> = ({ \r\n children, \r\n defaultLayout = DEFAULT_LAYOUT,\r\n useResponsiveHook\r\n}) => {\r\n // Normalizar el defaultLayout antes de pasarlo al componente interno\r\n const normalizedDefaultLayout = (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout])\r\n ? defaultLayout\r\n : DEFAULT_LAYOUT\r\n \r\n return (\r\n <ResponsiveProvider>\r\n <ResponsiveLayoutProviderInner \r\n defaultLayout={normalizedDefaultLayout}\r\n useResponsiveHook={useResponsiveHook}\r\n >\r\n {children}\r\n </ResponsiveLayoutProviderInner>\r\n </ResponsiveProvider>\r\n )\r\n}\r\n","import React from 'react'\r\nimport { useResponsiveLayout } from '../hooks'\r\nimport { \r\n DefaultLayout, \r\n SidebarLayout, \r\n DashboardLayout, \r\n MinimalLayout \r\n} from './index'\r\n\r\ninterface MainLayoutProps {\r\n children: React.ReactNode\r\n /**\r\n * Layout específico a usar. Si se proporciona, sobrescribe el layout del contexto.\r\n * Valores posibles: 'default', 'sidebar', 'dashboard', 'minimal'\r\n */\r\n layout?: 'default' | 'sidebar' | 'dashboard' | 'minimal'\r\n}\r\n\r\nconst MainLayout: React.FC<MainLayoutProps> = ({ children, layout: layoutProp }) => {\r\n const { layout } = useResponsiveLayout()\r\n \r\n // Mapa de layouts disponibles\r\n const layouts = {\r\n default: DefaultLayout,\r\n sidebar: SidebarLayout,\r\n dashboard: DashboardLayout,\r\n minimal: MinimalLayout,\r\n }\r\n \r\n // Determinar qué layout usar: prop > contexto > default\r\n const layoutToUse = layoutProp || layout.current || 'default'\r\n \r\n // Validar que el layout sea válido, si no usar default\r\n const validLayout = (layoutToUse && layouts[layoutToUse as keyof typeof layouts])\r\n ? layoutToUse\r\n : 'default'\r\n \r\n // Obtener el componente de layout\r\n const LayoutComponent = layouts[validLayout as keyof typeof layouts] || DefaultLayout\r\n \r\n return <LayoutComponent>{children}</LayoutComponent>\r\n}\r\n\r\nexport default MainLayout\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useNavigation, useSidebar } from '../../context'\r\n\r\nconst Header = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n const { currentPage, setCurrentPage } = useNavigation()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'test', label: 'Suite de Test' },\r\n { id: 'demo', label: 'Demo' },\r\n ]\r\n \r\n return (\r\n <div className=\"sticky top-0 z-50\">\r\n <header className=\"bg-gradient-to-r from-gray-900 via-black to-gray-900 border-b border-cyan-500/20 shadow-2xl relative\">\r\n <div className=\"w-full\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-2\">\r\n {/* Hamburger button para móvil - A LA IZQUIERDA */}\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"p-2 rounded-lg text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n <div className=\"w-1.5 h-1.5 bg-cyan-400 rounded-full shadow-lg shadow-cyan-400/50 animate-pulse\"></div>\r\n <h3 className=\"text-base font-black text-white tracking-tight\">\r\n Sistema Responsivo\r\n </h3>\r\n </div>\r\n <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\">\r\n DASHBOARD\r\n </div>\r\n </div>\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n {/* Botones visibles solo en desktop */}\r\n {!isMobile && menuItems.map((page) => (\r\n <button\r\n key={page.id}\r\n onClick={() => setCurrentPage(page.id as 'demo' | 'test')}\r\n className={`px-3 py-1.5 rounded-lg transition-all font-bold text-xs tracking-wide border ${\r\n currentPage === page.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border-cyan-500/50' \r\n : 'bg-black/50 text-gray-400 hover:text-gray-300 border-gray-700 hover:border-gray-600'\r\n }`}\r\n >\r\n {page.label}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n {/* Sidebar móvil desplegable */}\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gradient-to-b from-gray-900 to-black border-r border-cyan-500/20\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n {/* Logo */}\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-cyan-500 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">RS</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Sistema Responsivo</span>\r\n </div>\r\n \r\n {/* Navigation */}\r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => {\r\n setCurrentPage(item.id as 'demo' | 'test')\r\n setSidebarOpen(false)\r\n }}\r\n className={`w-full flex items-center px-4 py-3 rounded-lg transition-all group text-left ${\r\n currentPage === item.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border border-cyan-500/50' \r\n : 'text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10'\r\n }`}\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport default Header\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useSidebar } from '../../context'\r\n\r\nconst Sidebar = () => {\r\n const { isMobile, isTablet } = useResponsiveLayout()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'home', label: 'Inicio' },\r\n { id: 'about', label: 'Acerca' },\r\n { id: 'contact', label: 'Contacto' },\r\n ]\r\n \r\n return (\r\n <>\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"fixed top-4 left-4 z-50 p-2 rounded-lg text-gray-300 hover:text-white hover:bg-gray-800 bg-gray-900 border border-gray-700\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n\r\n <aside className={`bg-gray-900 border-r border-gray-800 ${isMobile ? 'hidden' : 'w-64 flex-shrink-0'} ${isTablet ? 'w-56' : 'w-64'}`}>\r\n <div className=\"p-6 flex flex-col h-full\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </aside>\r\n\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gray-900 border-r border-gray-800\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => setSidebarOpen(false)}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )\r\n}\r\n\r\nexport default Sidebar\r\n","const Footer = () => {\r\n return (\r\n <footer className=\"bg-gray-900 border-t border-gray-800\">\r\n <div className=\"px-4 py-6\">\r\n <div className=\"max-w-7xl mx-auto text-center\">\r\n <p className=\"text-gray-400 text-sm\">\r\n © {new Date().getFullYear()} Tu Aplicación. Todos los derechos reservados.\r\n </p>\r\n </div>\r\n </div>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default Footer\r\n","import { useResponsiveLayout } from '../../hooks'\r\n\r\nconst Navigation = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n \r\n return (\r\n <nav className=\"sticky top-0 z-50 bg-gray-900 border-b border-gray-800\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-3\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <h1 className=\"text-white font-semibold text-lg\">Tu Aplicación</h1>\r\n </div>\r\n \r\n {isMobile && (\r\n <button className=\"p-2 text-gray-400 hover:text-white\">\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </nav>\r\n )\r\n}\r\n\r\nexport default Navigation\r\n","import React from 'react'\r\nimport { Navigation, Footer } from '../components/layout'\r\n\r\ninterface DefaultLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Navigation fijo arriba */}\r\n <Navigation />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1\">\r\n {children}\r\n </main>\r\n \r\n {/* Footer fijo abajo */}\r\n <Footer />\r\n </div>\r\n )\r\n}\r\n\r\nexport default DefaultLayout\r\n","import React from 'react'\r\nimport { Sidebar } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface SidebarLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst SidebarLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto\">\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nconst SidebarLayout: React.FC<SidebarLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <SidebarLayoutContent>{children}</SidebarLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default SidebarLayout\r\n","import React from 'react'\r\nimport { Sidebar, Footer } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface DashboardLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DashboardLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Content area con sidebar */}\r\n <div className=\"flex flex-1\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto flex flex-col\">\r\n <div className=\"flex-1\">\r\n {children}\r\n </div>\r\n \r\n {/* Footer */}\r\n <Footer />\r\n </main>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nconst DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <DashboardLayoutContent>{children}</DashboardLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default DashboardLayout\r\n","import React from 'react'\r\n\r\ninterface MinimalLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst MinimalLayout: React.FC<MinimalLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50\">\r\n <main>\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nexport default MinimalLayout\r\n","import { useLayout } from '../hooks'\r\nimport { LAYOUT_CONFIG } from '../config/layout'\r\n\r\ninterface LayoutSwitcherProps {\r\n compact?: boolean\r\n}\r\n\r\nconst LayoutSwitcher = ({ compact = false }: LayoutSwitcherProps) => {\r\n const { current, setLayout, config } = useLayout()\r\n \r\n if (compact) {\r\n return (\r\n <div className=\"bg-black/50 rounded-lg p-3 border border-gray-700\">\r\n <div className=\"text-xs text-gray-500 mb-2\">Layout:</div>\r\n <select\r\n value={current}\r\n onChange={(e) => setLayout(e.target.value)}\r\n className=\"w-full bg-gray-800 text-white text-sm p-2 rounded border border-gray-600 focus:ring-1 focus:ring-cyan-500 focus:border-transparent\"\r\n >\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <option key={key} value={key}>\r\n {layoutConfig.name}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n )\r\n }\r\n \r\n return (\r\n <div className=\"bg-black/50 backdrop-blur-sm rounded-lg p-4 border border-cyan-500/30\">\r\n <h3 className=\"text-white font-semibold mb-3\">Cambiar Layout</h3>\r\n \r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <button\r\n key={key}\r\n onClick={() => setLayout(key)}\r\n className={`\r\n p-4 rounded-lg border transition-all text-left\r\n ${current === key \r\n ? 'border-cyan-500 bg-cyan-500/10 text-cyan-400' \r\n : 'border-gray-700 bg-black/30 text-gray-300 hover:border-gray-600'\r\n }\r\n `}\r\n >\r\n <div className=\"font-semibold mb-1\">{layoutConfig.name}</div>\r\n <div className=\"text-xs opacity-75\">{layoutConfig.description}</div>\r\n </button>\r\n ))}\r\n </div>\r\n \r\n <div className=\"mt-4 p-3 bg-gray-900/50 rounded-lg\">\r\n <div className=\"text-xs text-gray-500 mb-1\">Layout Actual:</div>\r\n <div className=\"text-sm text-cyan-400 font-medium\">{config.name}</div>\r\n <div className=\"text-xs text-gray-400\">{config.description}</div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default LayoutSwitcher\r\n"],"names":["ResponsiveProvider","children","_debug","DEFAULT_BREAKPOINTS","getCurrentBreakpoint","width","getBreakpointIndex","breakpoint","getBreakpointValue","debounce","func","wait","timeout","args","getOrientation","height","useResponsive","dimensions","setDimensions","useState","updateDimensions","useCallback","debouncedUpdateDimensions","useMemo","useEffect","orientation","isXs","isSm","isMd","isLg","isXl","is2Xl","is3Xl","is4Xl","is5Xl","isMobile","isTablet","isDesktop","isSmall","isLarge","isUltraWide","is4K","is5K","isPortrait","isLandscape","isBreakpointUp","bp","isBreakpointDown","isBreakpointBetween","min","max","current","isWidthUp","minWidth","isWidthDown","maxWidth","isWidthBetween","isHeightUp","minHeight","isHeightDown","maxHeight","isHeightBetween","ResponsiveLayoutContext","createContext","useResponsiveLayoutContext","context","useContext","SidebarContext","SidebarProvider","sidebarOpen","setSidebarOpen","jsx","useSidebar","NavigationContext","useNavigation","NavigationProvider","defaultPage","currentPage","setCurrentPage","useResponsiveLayout","breakpoints","classes","cols","useLayout","responsiveLayout","LAYOUT_CONFIG","DEFAULT_LAYOUT","AVAILABLE_LAYOUTS","ResponsiveLayoutProviderInner","defaultLayout","useResponsiveHook","internalResponsive","responsive","currentLayout","setCurrentLayout","layoutConfig","contextValue","baseClass","ResponsiveLayoutProvider","normalizedDefaultLayout","MainLayout","layoutProp","layout","layouts","DefaultLayout","SidebarLayout","DashboardLayout","MinimalLayout","layoutToUse","validLayout","LayoutComponent","Header","menuItems","jsxs","page","item","Sidebar","Fragment","Footer","Navigation","SidebarLayoutContent","DashboardLayoutContent","LayoutSwitcher","compact","setLayout","config","e","key"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responsive-system.mjs","sources":["../src/providers/ResponsiveProvider.tsx","../src/constants/breakpoints.ts","../src/hooks/useResponsive.ts","../src/context/ResponsiveLayoutContext.tsx","../src/context/SidebarContext.tsx","../src/context/NavigationContext.tsx","../src/hooks/useResponsiveLayout.ts","../src/hooks/useLayout.ts","../src/config/layout.ts","../src/providers/ResponsiveLayoutProvider.tsx","../src/layouts/MainLayout.tsx","../src/components/layout/Header.tsx","../src/components/layout/Sidebar.tsx","../src/components/layout/Footer.tsx","../src/components/layout/Navigation.tsx","../src/layouts/DefaultLayout.tsx","../src/layouts/SidebarLayout.tsx","../src/layouts/DashboardLayout.tsx","../src/layouts/MinimalLayout.tsx","../src/components/LayoutSwitcher.tsx"],"sourcesContent":["import React from 'react'\r\nimport type { ResponsiveProviderProps } from '../types/responsive'\r\n\r\n/**\r\n * ResponsiveProvider - Provider simplificado para el sistema responsive\r\n * \r\n * Nota: Con el sistema de auto-scaling mediante plugin de Tailwind,\r\n * este Provider es OPCIONAL y solo se necesita si quieres acceder\r\n * al hook useResponsive() en tus componentes.\r\n */\r\nexport const ResponsiveProvider: React.FC<ResponsiveProviderProps> = ({\r\n children,\r\n debug: _debug = false\r\n}) => {\r\n // El Provider ahora solo envuelve children sin context\r\n // El auto-scaling funciona mediante el plugin de Tailwind\r\n return <>{children}</>\r\n}\r\n","import type { Breakpoint } from '../types/responsive'\r\n\r\n/**\r\n * Default breakpoint values\r\n * Deben coincidir con tailwind.config.js\r\n */\r\nexport const DEFAULT_BREAKPOINTS: Record<Breakpoint, number> = {\r\n xs: 475,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n '2xl': 1536,\r\n '3xl': 1920,\r\n '4xl': 2560,\r\n '5xl': 3840\r\n}\r\n\r\n/**\r\n * Get current breakpoint based on window width\r\n */\r\nexport const getCurrentBreakpoint = (width: number): Breakpoint => {\r\n if (width >= DEFAULT_BREAKPOINTS['5xl']) return '5xl'\r\n if (width >= DEFAULT_BREAKPOINTS['4xl']) return '4xl'\r\n if (width >= DEFAULT_BREAKPOINTS['3xl']) return '3xl'\r\n if (width >= DEFAULT_BREAKPOINTS['2xl']) return '2xl'\r\n if (width >= DEFAULT_BREAKPOINTS.xl) return 'xl'\r\n if (width >= DEFAULT_BREAKPOINTS.lg) return 'lg'\r\n if (width >= DEFAULT_BREAKPOINTS.md) return 'md'\r\n if (width >= DEFAULT_BREAKPOINTS.sm) return 'sm'\r\n return 'xs'\r\n}\r\n\r\n/**\r\n * Get breakpoint index (for comparisons)\r\n */\r\nexport const getBreakpointIndex = (breakpoint: Breakpoint): number => {\r\n const breakpoints: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl']\r\n return breakpoints.indexOf(breakpoint)\r\n}\r\n\r\n/**\r\n * Get breakpoint value in pixels\r\n */\r\nexport const getBreakpointValue = (breakpoint: Breakpoint): number => {\r\n return DEFAULT_BREAKPOINTS[breakpoint]\r\n}\r\n\r\n","import { useState, useEffect, useCallback, useMemo } from 'react'\r\nimport type { \r\n ResponsiveState, \r\n Breakpoint\r\n} from '../types/responsive'\r\nimport { \r\n getCurrentBreakpoint,\r\n getBreakpointIndex\r\n} from '../constants/breakpoints'\r\n\r\n/**\r\n * Debounce utility\r\n */\r\nfunction debounce<T extends (...args: unknown[]) => void>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: ReturnType<typeof setTimeout> | null = null\r\n return (...args: Parameters<T>) => {\r\n if (timeout) clearTimeout(timeout)\r\n timeout = setTimeout(() => func(...args), wait)\r\n }\r\n}\r\n\r\n/**\r\n * Get orientation based on dimensions\r\n */\r\nfunction getOrientation(width: number, height: number): 'landscape' | 'portrait' {\r\n return width >= height ? 'landscape' : 'portrait'\r\n}\r\n\r\n/**\r\n * Hook principal useResponsive\r\n * Provee información sobre el breakpoint actual y helpers para responsive\r\n */\r\nexport const useResponsive = (): ResponsiveState => {\r\n const [dimensions, setDimensions] = useState({\r\n width: typeof window !== 'undefined' ? window.innerWidth : 1024,\r\n height: typeof window !== 'undefined' ? window.innerHeight : 768\r\n })\r\n\r\n // Función para actualizar dimensiones\r\n const updateDimensions = useCallback(() => {\r\n setDimensions({\r\n width: window.innerWidth,\r\n height: window.innerHeight\r\n })\r\n }, [])\r\n\r\n // Debounced update para optimizar performance\r\n const debouncedUpdateDimensions = useMemo(\r\n () => debounce(updateDimensions, 100),\r\n [updateDimensions]\r\n )\r\n\r\n // Effect para escuchar cambios de tamaño\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return\r\n\r\n window.addEventListener('resize', debouncedUpdateDimensions)\r\n \r\n return () => {\r\n window.removeEventListener('resize', debouncedUpdateDimensions)\r\n }\r\n }, [debouncedUpdateDimensions])\r\n\r\n const { width, height } = dimensions\r\n\r\n // Calcular breakpoint actual\r\n const breakpoint = useMemo(() => getCurrentBreakpoint(width), [width])\r\n \r\n // Calcular orientación\r\n const orientation = useMemo(() => getOrientation(width, height), [width, height])\r\n\r\n // Helpers booleanos por breakpoint específico\r\n const isXs = breakpoint === 'xs'\r\n const isSm = breakpoint === 'sm'\r\n const isMd = breakpoint === 'md'\r\n const isLg = breakpoint === 'lg'\r\n const isXl = breakpoint === 'xl'\r\n const is2Xl = breakpoint === '2xl'\r\n const is3Xl = breakpoint === '3xl'\r\n const is4Xl = breakpoint === '4xl'\r\n const is5Xl = breakpoint === '5xl'\r\n\r\n // Helpers booleanos agrupados\r\n const isMobile = isXs || isSm\r\n const isTablet = isMd\r\n const isDesktop = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isSmall = isXs || isSm || isMd\r\n const isLarge = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isUltraWide = is3Xl || is4Xl || is5Xl\r\n const is4K = is4Xl || is5Xl\r\n const is5K = is5Xl\r\n\r\n // Helpers de orientación\r\n const isPortrait = orientation === 'portrait'\r\n const isLandscape = orientation === 'landscape'\r\n\r\n // Funciones de comparación de breakpoints\r\n const isBreakpointUp = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) >= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointDown = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) <= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointBetween = useCallback((min: Breakpoint, max: Breakpoint): boolean => {\r\n const current = getBreakpointIndex(breakpoint)\r\n return current >= getBreakpointIndex(min) && current <= getBreakpointIndex(max)\r\n }, [breakpoint])\r\n\r\n // Funciones de comparación de ancho\r\n const isWidthUp = useCallback((minWidth: number): boolean => {\r\n return width >= minWidth\r\n }, [width])\r\n\r\n const isWidthDown = useCallback((maxWidth: number): boolean => {\r\n return width <= maxWidth\r\n }, [width])\r\n\r\n const isWidthBetween = useCallback((minWidth: number, maxWidth: number): boolean => {\r\n return width >= minWidth && width <= maxWidth\r\n }, [width])\r\n\r\n // Funciones de comparación de altura\r\n const isHeightUp = useCallback((minHeight: number): boolean => {\r\n return height >= minHeight\r\n }, [height])\r\n\r\n const isHeightDown = useCallback((maxHeight: number): boolean => {\r\n return height <= maxHeight\r\n }, [height])\r\n\r\n const isHeightBetween = useCallback((minHeight: number, maxHeight: number): boolean => {\r\n return height >= minHeight && height <= maxHeight\r\n }, [height])\r\n\r\n // Debug mode\r\n const debug = false\r\n\r\n return {\r\n // Estado básico\r\n breakpoint,\r\n width,\r\n height,\r\n orientation,\r\n \r\n // Helpers booleanos específicos\r\n isXs,\r\n isSm,\r\n isMd,\r\n isLg,\r\n isXl,\r\n is2Xl,\r\n is3Xl,\r\n is4Xl,\r\n is5Xl,\r\n \r\n // Helpers booleanos agrupados\r\n isMobile,\r\n isTablet,\r\n isDesktop,\r\n isSmall,\r\n isLarge,\r\n isUltraWide,\r\n is4K,\r\n is5K,\r\n \r\n // Helpers de orientación\r\n isPortrait,\r\n isLandscape,\r\n \r\n // Funciones de comparación\r\n isBreakpointUp,\r\n isBreakpointDown,\r\n isBreakpointBetween,\r\n isWidthUp,\r\n isWidthDown,\r\n isWidthBetween,\r\n isHeightUp,\r\n isHeightDown,\r\n isHeightBetween,\r\n \r\n // Debug\r\n debug\r\n }\r\n}\r\n","import { createContext, useContext } from 'react'\r\nimport type { ResponsiveState } from '../types/responsive'\r\nimport type { LayoutConfig } from '../config/layout'\r\n\r\nexport interface ResponsiveLayoutState {\r\n // Estado del sistema responsivo\r\n responsive: ResponsiveState\r\n \r\n // Estado del layout\r\n layout: {\r\n current: string\r\n config: LayoutConfig\r\n setLayout: (layout: string) => void\r\n }\r\n \r\n // Utilidades de layout\r\n layoutUtils: {\r\n getContainerClass: () => string\r\n getMainClass: () => string\r\n hasSidebar: () => boolean\r\n hasHeader: () => boolean\r\n hasFooter: () => boolean\r\n hasNavigation: () => boolean\r\n }\r\n}\r\n\r\nconst ResponsiveLayoutContext = createContext<ResponsiveLayoutState | undefined>(undefined)\r\n\r\nexport const useResponsiveLayoutContext = () => {\r\n const context = useContext(ResponsiveLayoutContext)\r\n if (!context) {\r\n throw new Error('useResponsiveLayoutContext must be used within a ResponsiveLayoutProvider')\r\n }\r\n return context\r\n}\r\n\r\nexport { ResponsiveLayoutContext }\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface SidebarContextType {\r\n sidebarOpen: boolean\r\n setSidebarOpen: (open: boolean) => void\r\n}\r\n\r\nconst SidebarContext = createContext<SidebarContextType | undefined>(undefined)\r\n\r\nexport const SidebarProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n const [sidebarOpen, setSidebarOpen] = useState(false)\r\n\r\n return (\r\n <SidebarContext.Provider value={{ sidebarOpen, setSidebarOpen }}>\r\n {children}\r\n </SidebarContext.Provider>\r\n )\r\n}\r\n\r\nexport const useSidebar = () => {\r\n const context = useContext(SidebarContext)\r\n if (!context) {\r\n throw new Error('useSidebar must be used within a SidebarProvider')\r\n }\r\n return context\r\n}\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface NavigationContextType {\r\n currentPage: 'demo' | 'test'\r\n setCurrentPage: (page: 'demo' | 'test') => void\r\n}\r\n\r\nconst NavigationContext = createContext<NavigationContextType>({\r\n currentPage: 'test',\r\n setCurrentPage: () => {}\r\n})\r\n\r\nexport const useNavigation = () => useContext(NavigationContext)\r\n\r\ninterface NavigationProviderProps {\r\n children: React.ReactNode\r\n defaultPage?: 'demo' | 'test'\r\n}\r\n\r\nexport const NavigationProvider: React.FC<NavigationProviderProps> = ({ \r\n children, \r\n defaultPage = 'test' \r\n}) => {\r\n const [currentPage, setCurrentPage] = useState<'demo' | 'test'>(defaultPage)\r\n\r\n return (\r\n <NavigationContext.Provider value={{ currentPage, setCurrentPage }}>\r\n {children}\r\n </NavigationContext.Provider>\r\n )\r\n}\r\n\r\n","import { useResponsiveLayoutContext } from '../context'\r\n\r\nexport const useResponsiveLayout = () => {\r\n const context = useResponsiveLayoutContext()\r\n \r\n return {\r\n // Todo el sistema responsivo original\r\n ...context.responsive,\r\n \r\n // Sistema de layout\r\n layout: {\r\n current: context.layout.current,\r\n config: context.layout.config,\r\n setLayout: context.layout.setLayout,\r\n },\r\n \r\n // Utilidades de layout\r\n layoutUtils: context.layoutUtils,\r\n \r\n // Helpers específicos del layout\r\n isDefaultLayout: () => context.layout.current === 'default',\r\n isSidebarLayout: () => context.layout.current === 'sidebar',\r\n isDashboardLayout: () => context.layout.current === 'dashboard',\r\n isMinimalLayout: () => context.layout.current === 'minimal',\r\n \r\n // Grid helpers que usan el sistema auto-escalable\r\n grid: {\r\n auto: (minWidth = 'md') => `grid-cols-auto-${minWidth}`,\r\n responsive: (breakpoints: Record<string, number>) => {\r\n const classes: string[] = []\r\n Object.entries(breakpoints).forEach(([breakpoint, cols]) => {\r\n if (breakpoint === 'base') {\r\n classes.push(`grid-cols-${cols}`)\r\n } else {\r\n classes.push(`${breakpoint}:grid-cols-${cols}`)\r\n }\r\n })\r\n return classes.join(' ')\r\n },\r\n fixed: (cols: number) => `grid-cols-${cols}`,\r\n },\r\n \r\n // Spacing helpers que escalan automáticamente\r\n spacing: {\r\n container: context.layoutUtils.getContainerClass(),\r\n section: 'mb-6',\r\n card: 'p-6',\r\n gap: 'gap-4',\r\n },\r\n }\r\n}\r\n","import { useResponsiveLayout } from './index'\r\n\r\nexport const useLayout = () => {\r\n const responsiveLayout = useResponsiveLayout()\r\n \r\n return {\r\n // Layout actual\r\n current: responsiveLayout.layout.current,\r\n config: responsiveLayout.layout.config,\r\n setLayout: responsiveLayout.layout.setLayout,\r\n \r\n // Utilidades\r\n ...responsiveLayout.layoutUtils,\r\n \r\n // Helpers específicos\r\n isDefaultLayout: responsiveLayout.isDefaultLayout(),\r\n isSidebarLayout: responsiveLayout.isSidebarLayout(),\r\n isDashboardLayout: responsiveLayout.isDashboardLayout(),\r\n isMinimalLayout: responsiveLayout.isMinimalLayout(),\r\n \r\n // Grid helpers\r\n grid: responsiveLayout.grid,\r\n \r\n // Spacing helpers\r\n spacing: responsiveLayout.spacing,\r\n }\r\n}\r\n","export interface LayoutConfig {\r\n name: string\r\n description: string\r\n components: string[]\r\n spacing: string\r\n responsive: {\r\n mobile: string\r\n tablet: string\r\n desktop: string\r\n }\r\n}\r\n\r\nexport const LAYOUT_CONFIG: Record<string, LayoutConfig> = {\r\n default: {\r\n name: 'Default',\r\n description: 'Navbar arriba, body central, footer abajo',\r\n components: ['Navigation', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n sidebar: {\r\n name: 'Sidebar',\r\n description: 'Sidebar izquierda, contenido principal',\r\n components: ['Sidebar'],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n },\r\n dashboard: {\r\n name: 'Dashboard',\r\n description: 'Header + Sidebar + Main + Footer',\r\n components: ['Header', 'Sidebar', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n minimal: {\r\n name: 'Minimal',\r\n description: 'Solo contenido, sin navegación',\r\n components: [],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n }\r\n}\r\n\r\nexport const DEFAULT_LAYOUT = 'default'\r\nexport const AVAILABLE_LAYOUTS = Object.keys(LAYOUT_CONFIG)\r\n","import React, { useState } from 'react'\r\nimport { ResponsiveProvider } from './index'\r\nimport { useResponsive } from '../hooks'\r\nimport { ResponsiveLayoutContext } from '../context'\r\nimport { LAYOUT_CONFIG, DEFAULT_LAYOUT } from '../config/layout'\r\nimport type { ResponsiveState } from '../types/responsive'\r\n\r\ninterface ResponsiveLayoutProviderProps {\r\n children: React.ReactNode\r\n defaultLayout?: string\r\n /**\r\n * Hook responsivo personalizado del proyecto consumidor.\r\n * Si se proporciona, se usará en lugar del hook interno del paquete.\r\n * Debe retornar un objeto compatible con ResponsiveState.\r\n */\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\ninterface ResponsiveLayoutProviderInnerProps {\r\n children: React.ReactNode\r\n defaultLayout: string\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\nconst ResponsiveLayoutProviderInner: React.FC<ResponsiveLayoutProviderInnerProps> = ({ \r\n children, \r\n defaultLayout,\r\n useResponsiveHook\r\n}) => {\r\n // Usar hook personalizado si se proporciona, sino usar el hook interno\r\n const internalResponsive = useResponsive()\r\n const customResponsive = useResponsiveHook?.()\r\n const responsive = customResponsive || internalResponsive\r\n \r\n // Inicializar el estado con el layout normalizado usando función inicializadora\r\n // Esto asegura que solo se ejecute una vez, incluso con React.StrictMode\r\n const [currentLayout, setCurrentLayout] = useState(() => {\r\n // Validar y normalizar el defaultLayout directamente en la función inicializadora\r\n if (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout]) {\r\n return defaultLayout\r\n }\r\n return DEFAULT_LAYOUT\r\n })\r\n \r\n const layoutConfig = LAYOUT_CONFIG[currentLayout] || LAYOUT_CONFIG[DEFAULT_LAYOUT]\r\n \r\n const layoutUtils = {\r\n getContainerClass: () => {\r\n if (responsive.isMobile) return layoutConfig.responsive.mobile\r\n if (responsive.isTablet) return layoutConfig.responsive.tablet\r\n return layoutConfig.responsive.desktop\r\n },\r\n \r\n getMainClass: () => {\r\n const baseClass = 'min-h-screen bg-black'\r\n if (currentLayout === 'sidebar' || currentLayout === 'dashboard') {\r\n return `${baseClass} flex`\r\n }\r\n return baseClass\r\n },\r\n \r\n hasSidebar: () => currentLayout === 'sidebar' || currentLayout === 'dashboard',\r\n hasHeader: () => currentLayout === 'dashboard',\r\n hasFooter: () => currentLayout === 'default' || currentLayout === 'dashboard',\r\n hasNavigation: () => currentLayout === 'default',\r\n }\r\n \r\n const contextValue = {\r\n responsive,\r\n layout: {\r\n current: currentLayout,\r\n config: layoutConfig,\r\n setLayout: setCurrentLayout,\r\n },\r\n layoutUtils,\r\n }\r\n \r\n return (\r\n <ResponsiveLayoutContext.Provider value={contextValue}>\r\n {children}\r\n </ResponsiveLayoutContext.Provider>\r\n )\r\n}\r\n\r\nexport const ResponsiveLayoutProvider: React.FC<ResponsiveLayoutProviderProps> = ({ \r\n children, \r\n defaultLayout = DEFAULT_LAYOUT,\r\n useResponsiveHook\r\n}) => {\r\n // Normalizar el defaultLayout antes de pasarlo al componente interno\r\n const normalizedDefaultLayout = (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout])\r\n ? defaultLayout\r\n : DEFAULT_LAYOUT\r\n \r\n return (\r\n <ResponsiveProvider>\r\n <ResponsiveLayoutProviderInner \r\n defaultLayout={normalizedDefaultLayout}\r\n useResponsiveHook={useResponsiveHook}\r\n >\r\n {children}\r\n </ResponsiveLayoutProviderInner>\r\n </ResponsiveProvider>\r\n )\r\n}\r\n","import React from 'react'\r\nimport { useResponsiveLayout } from '../hooks'\r\nimport { \r\n DefaultLayout, \r\n SidebarLayout, \r\n DashboardLayout, \r\n MinimalLayout \r\n} from './index'\r\n\r\ninterface MainLayoutProps {\r\n children: React.ReactNode\r\n /**\r\n * Layout específico a usar. Si se proporciona, sobrescribe el layout del contexto.\r\n * Valores posibles: 'default', 'sidebar', 'dashboard', 'minimal'\r\n */\r\n layout?: 'default' | 'sidebar' | 'dashboard' | 'minimal'\r\n}\r\n\r\nconst MainLayout: React.FC<MainLayoutProps> = ({ children, layout: layoutProp }) => {\r\n const { layout } = useResponsiveLayout()\r\n \r\n // Mapa de layouts disponibles\r\n const layouts = {\r\n default: DefaultLayout,\r\n sidebar: SidebarLayout,\r\n dashboard: DashboardLayout,\r\n minimal: MinimalLayout,\r\n }\r\n \r\n // Determinar qué layout usar: prop > contexto > default\r\n const layoutToUse = layoutProp || layout.current || 'default'\r\n \r\n // Validar que el layout sea válido, si no usar default\r\n const validLayout = (layoutToUse && layouts[layoutToUse as keyof typeof layouts])\r\n ? layoutToUse\r\n : 'default'\r\n \r\n // Obtener el componente de layout\r\n const LayoutComponent = layouts[validLayout as keyof typeof layouts] || DefaultLayout\r\n \r\n return <LayoutComponent>{children}</LayoutComponent>\r\n}\r\n\r\nexport default MainLayout\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useNavigation, useSidebar } from '../../context'\r\n\r\nconst Header = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n const { currentPage, setCurrentPage } = useNavigation()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'test', label: 'Suite de Test' },\r\n { id: 'demo', label: 'Demo' },\r\n ]\r\n \r\n return (\r\n <div className=\"sticky top-0 z-50\">\r\n <header className=\"bg-gradient-to-r from-gray-900 via-black to-gray-900 border-b border-cyan-500/20 shadow-2xl relative\">\r\n <div className=\"w-full\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-2\">\r\n {/* Hamburger button para móvil - A LA IZQUIERDA */}\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"p-2 rounded-lg text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n <div className=\"w-1.5 h-1.5 bg-cyan-400 rounded-full shadow-lg shadow-cyan-400/50 animate-pulse\"></div>\r\n <h3 className=\"text-base font-black text-white tracking-tight\">\r\n Sistema Responsivo\r\n </h3>\r\n </div>\r\n <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\">\r\n DASHBOARD\r\n </div>\r\n </div>\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n {/* Botones visibles solo en desktop */}\r\n {!isMobile && menuItems.map((page) => (\r\n <button\r\n key={page.id}\r\n onClick={() => setCurrentPage(page.id as 'demo' | 'test')}\r\n className={`px-3 py-1.5 rounded-lg transition-all font-bold text-xs tracking-wide border ${\r\n currentPage === page.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border-cyan-500/50' \r\n : 'bg-black/50 text-gray-400 hover:text-gray-300 border-gray-700 hover:border-gray-600'\r\n }`}\r\n >\r\n {page.label}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n {/* Sidebar móvil desplegable */}\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gradient-to-b from-gray-900 to-black border-r border-cyan-500/20\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n {/* Logo */}\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-cyan-500 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">RS</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Sistema Responsivo</span>\r\n </div>\r\n \r\n {/* Navigation */}\r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => {\r\n setCurrentPage(item.id as 'demo' | 'test')\r\n setSidebarOpen(false)\r\n }}\r\n className={`w-full flex items-center px-4 py-3 rounded-lg transition-all group text-left ${\r\n currentPage === item.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border border-cyan-500/50' \r\n : 'text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10'\r\n }`}\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport default Header\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useSidebar } from '../../context'\r\n\r\nconst Sidebar = () => {\r\n const { isMobile, isTablet } = useResponsiveLayout()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'home', label: 'Inicio' },\r\n { id: 'about', label: 'Acerca' },\r\n { id: 'contact', label: 'Contacto' },\r\n ]\r\n \r\n return (\r\n <>\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"fixed top-4 left-4 z-50 p-2 rounded-lg text-gray-300 hover:text-white hover:bg-gray-800 bg-gray-900 border border-gray-700\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n\r\n <aside className={`bg-gray-900 border-r border-gray-800 ${isMobile ? 'hidden' : 'w-64 flex-shrink-0'} ${isTablet ? 'w-56' : 'w-64'}`}>\r\n <div className=\"p-6 flex flex-col h-full\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </aside>\r\n\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gray-900 border-r border-gray-800\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => setSidebarOpen(false)}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )\r\n}\r\n\r\nexport default Sidebar\r\n","const Footer = () => {\r\n return (\r\n <footer className=\"bg-gray-900 border-t border-gray-800\">\r\n <div className=\"px-4 py-6\">\r\n <div className=\"max-w-7xl mx-auto text-center\">\r\n <p className=\"text-gray-400 text-sm\">\r\n © {new Date().getFullYear()} Tu Aplicación. Todos los derechos reservados.\r\n </p>\r\n </div>\r\n </div>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default Footer\r\n","import { useResponsiveLayout } from '../../hooks'\r\n\r\nconst Navigation = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n \r\n return (\r\n <nav className=\"sticky top-0 z-50 bg-gray-900 border-b border-gray-800\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-3\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <h1 className=\"text-white font-semibold text-lg\">Tu Aplicación</h1>\r\n </div>\r\n \r\n {isMobile && (\r\n <button className=\"p-2 text-gray-400 hover:text-white\">\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </nav>\r\n )\r\n}\r\n\r\nexport default Navigation\r\n","import React from 'react'\r\nimport { Navigation, Footer } from '../components/layout'\r\n\r\ninterface DefaultLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Navigation fijo arriba */}\r\n <Navigation />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1\">\r\n {children}\r\n </main>\r\n \r\n {/* Footer fijo abajo */}\r\n <Footer />\r\n </div>\r\n )\r\n}\r\n\r\nexport default DefaultLayout\r\n","import React from 'react'\r\nimport { Sidebar } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface SidebarLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst SidebarLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto\">\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nconst SidebarLayout: React.FC<SidebarLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <SidebarLayoutContent>{children}</SidebarLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default SidebarLayout\r\n","import React from 'react'\r\nimport { Sidebar, Footer } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface DashboardLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DashboardLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Content area con sidebar */}\r\n <div className=\"flex flex-1\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto flex flex-col\">\r\n <div className=\"flex-1\">\r\n {children}\r\n </div>\r\n \r\n {/* Footer */}\r\n <Footer />\r\n </main>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nconst DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <DashboardLayoutContent>{children}</DashboardLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default DashboardLayout\r\n","import React from 'react'\r\n\r\ninterface MinimalLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst MinimalLayout: React.FC<MinimalLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50\">\r\n <main>\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nexport default MinimalLayout\r\n","import { useLayout } from '../hooks'\r\nimport { LAYOUT_CONFIG } from '../config/layout'\r\n\r\ninterface LayoutSwitcherProps {\r\n compact?: boolean\r\n}\r\n\r\nconst LayoutSwitcher = ({ compact = false }: LayoutSwitcherProps) => {\r\n const { current, setLayout, config } = useLayout()\r\n \r\n if (compact) {\r\n return (\r\n <div className=\"bg-black/50 rounded-lg p-3 border border-gray-700\">\r\n <div className=\"text-xs text-gray-500 mb-2\">Layout:</div>\r\n <select\r\n value={current}\r\n onChange={(e) => setLayout(e.target.value)}\r\n className=\"w-full bg-gray-800 text-white text-sm p-2 rounded border border-gray-600 focus:ring-1 focus:ring-cyan-500 focus:border-transparent\"\r\n >\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <option key={key} value={key}>\r\n {layoutConfig.name}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n )\r\n }\r\n \r\n return (\r\n <div className=\"bg-black/50 backdrop-blur-sm rounded-lg p-4 border border-cyan-500/30\">\r\n <h3 className=\"text-white font-semibold mb-3\">Cambiar Layout</h3>\r\n \r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <button\r\n key={key}\r\n onClick={() => setLayout(key)}\r\n className={`\r\n p-4 rounded-lg border transition-all text-left\r\n ${current === key \r\n ? 'border-cyan-500 bg-cyan-500/10 text-cyan-400' \r\n : 'border-gray-700 bg-black/30 text-gray-300 hover:border-gray-600'\r\n }\r\n `}\r\n >\r\n <div className=\"font-semibold mb-1\">{layoutConfig.name}</div>\r\n <div className=\"text-xs opacity-75\">{layoutConfig.description}</div>\r\n </button>\r\n ))}\r\n </div>\r\n \r\n <div className=\"mt-4 p-3 bg-gray-900/50 rounded-lg\">\r\n <div className=\"text-xs text-gray-500 mb-1\">Layout Actual:</div>\r\n <div className=\"text-sm text-cyan-400 font-medium\">{config.name}</div>\r\n <div className=\"text-xs text-gray-400\">{config.description}</div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default LayoutSwitcher\r\n"],"names":["ResponsiveProvider","children","_debug","DEFAULT_BREAKPOINTS","getCurrentBreakpoint","width","getBreakpointIndex","breakpoint","getBreakpointValue","debounce","func","wait","timeout","args","getOrientation","height","useResponsive","dimensions","setDimensions","useState","updateDimensions","useCallback","debouncedUpdateDimensions","useMemo","useEffect","orientation","isXs","isSm","isMd","isLg","isXl","is2Xl","is3Xl","is4Xl","is5Xl","isMobile","isTablet","isDesktop","isSmall","isLarge","isUltraWide","is4K","is5K","isPortrait","isLandscape","isBreakpointUp","bp","isBreakpointDown","isBreakpointBetween","min","max","current","isWidthUp","minWidth","isWidthDown","maxWidth","isWidthBetween","isHeightUp","minHeight","isHeightDown","maxHeight","isHeightBetween","ResponsiveLayoutContext","createContext","useResponsiveLayoutContext","context","useContext","SidebarContext","SidebarProvider","sidebarOpen","setSidebarOpen","jsx","useSidebar","NavigationContext","useNavigation","NavigationProvider","defaultPage","currentPage","setCurrentPage","useResponsiveLayout","breakpoints","classes","cols","useLayout","responsiveLayout","LAYOUT_CONFIG","DEFAULT_LAYOUT","AVAILABLE_LAYOUTS","ResponsiveLayoutProviderInner","defaultLayout","useResponsiveHook","internalResponsive","responsive","currentLayout","setCurrentLayout","layoutConfig","contextValue","baseClass","ResponsiveLayoutProvider","normalizedDefaultLayout","MainLayout","layoutProp","layout","layouts","DefaultLayout","SidebarLayout","DashboardLayout","MinimalLayout","layoutToUse","validLayout","LayoutComponent","Header","menuItems","jsxs","page","item","Sidebar","Fragment","Footer","Navigation","SidebarLayoutContent","DashboardLayoutContent","LayoutSwitcher","compact","setLayout","config","e","key"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"responsive-system.mjs","sources":["../src/providers/ResponsiveProvider.tsx","../src/constants/breakpoints.ts","../src/hooks/useResponsive.ts","../src/context/ResponsiveLayoutContext.tsx","../src/context/SidebarContext.tsx","../src/context/NavigationContext.tsx","../src/hooks/useResponsiveLayout.ts","../src/hooks/useLayout.ts","../src/config/layout.ts","../src/providers/ResponsiveLayoutProvider.tsx","../src/layouts/MainLayout.tsx","../src/components/layout/Header.tsx","../src/components/layout/Sidebar.tsx","../src/components/layout/Footer.tsx","../src/components/layout/Navigation.tsx","../src/layouts/DefaultLayout.tsx","../src/layouts/SidebarLayout.tsx","../src/layouts/DashboardLayout.tsx","../src/layouts/MinimalLayout.tsx","../src/components/LayoutSwitcher.tsx"],"sourcesContent":["import React from 'react'\r\nimport type { ResponsiveProviderProps } from '../types/responsive'\r\n\r\n/**\r\n * ResponsiveProvider - Provider simplificado para el sistema responsive\r\n * \r\n * Nota: Con el sistema de auto-scaling mediante plugin de Tailwind,\r\n * este Provider es OPCIONAL y solo se necesita si quieres acceder\r\n * al hook useResponsive() en tus componentes.\r\n */\r\nexport const ResponsiveProvider: React.FC<ResponsiveProviderProps> = ({\r\n children,\r\n debug: _debug = false\r\n}) => {\r\n // El Provider ahora solo envuelve children sin context\r\n // El auto-scaling funciona mediante el plugin de Tailwind\r\n return <>{children}</>\r\n}\r\n","import type { Breakpoint } from '../types/responsive'\r\n\r\n/**\r\n * Default breakpoint values\r\n * Deben coincidir con tailwind.config.js\r\n */\r\nexport const DEFAULT_BREAKPOINTS: Record<Breakpoint, number> = {\r\n xs: 475,\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n '2xl': 1536,\r\n '3xl': 1920,\r\n '4xl': 2560,\r\n '5xl': 3840\r\n}\r\n\r\n/**\r\n * Get current breakpoint based on window width\r\n */\r\nexport const getCurrentBreakpoint = (width: number): Breakpoint => {\r\n if (width >= DEFAULT_BREAKPOINTS['5xl']) return '5xl'\r\n if (width >= DEFAULT_BREAKPOINTS['4xl']) return '4xl'\r\n if (width >= DEFAULT_BREAKPOINTS['3xl']) return '3xl'\r\n if (width >= DEFAULT_BREAKPOINTS['2xl']) return '2xl'\r\n if (width >= DEFAULT_BREAKPOINTS.xl) return 'xl'\r\n if (width >= DEFAULT_BREAKPOINTS.lg) return 'lg'\r\n if (width >= DEFAULT_BREAKPOINTS.md) return 'md'\r\n if (width >= DEFAULT_BREAKPOINTS.sm) return 'sm'\r\n return 'xs'\r\n}\r\n\r\n/**\r\n * Get breakpoint index (for comparisons)\r\n */\r\nexport const getBreakpointIndex = (breakpoint: Breakpoint): number => {\r\n const breakpoints: Breakpoint[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl']\r\n return breakpoints.indexOf(breakpoint)\r\n}\r\n\r\n/**\r\n * Get breakpoint value in pixels\r\n */\r\nexport const getBreakpointValue = (breakpoint: Breakpoint): number => {\r\n return DEFAULT_BREAKPOINTS[breakpoint]\r\n}\r\n\r\n","import { useState, useEffect, useCallback, useMemo } from 'react'\r\nimport type { \r\n ResponsiveState, \r\n Breakpoint\r\n} from '../types/responsive'\r\nimport { \r\n getCurrentBreakpoint,\r\n getBreakpointIndex\r\n} from '../constants/breakpoints'\r\n\r\n/**\r\n * Debounce utility\r\n */\r\nfunction debounce<T extends (...args: unknown[]) => void>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: ReturnType<typeof setTimeout> | null = null\r\n return (...args: Parameters<T>) => {\r\n if (timeout) clearTimeout(timeout)\r\n timeout = setTimeout(() => func(...args), wait)\r\n }\r\n}\r\n\r\n/**\r\n * Get orientation based on dimensions\r\n */\r\nfunction getOrientation(width: number, height: number): 'landscape' | 'portrait' {\r\n return width >= height ? 'landscape' : 'portrait'\r\n}\r\n\r\n/**\r\n * Hook principal useResponsive\r\n * Provee información sobre el breakpoint actual y helpers para responsive\r\n */\r\nexport const useResponsive = (): ResponsiveState => {\r\n const [dimensions, setDimensions] = useState({\r\n width: typeof window !== 'undefined' ? window.innerWidth : 1024,\r\n height: typeof window !== 'undefined' ? window.innerHeight : 768\r\n })\r\n\r\n // Función para actualizar dimensiones\r\n const updateDimensions = useCallback(() => {\r\n setDimensions({\r\n width: window.innerWidth,\r\n height: window.innerHeight\r\n })\r\n }, [])\r\n\r\n // Debounced update para optimizar performance\r\n const debouncedUpdateDimensions = useMemo(\r\n () => debounce(updateDimensions, 100),\r\n [updateDimensions]\r\n )\r\n\r\n // Effect para escuchar cambios de tamaño\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return\r\n\r\n window.addEventListener('resize', debouncedUpdateDimensions)\r\n \r\n return () => {\r\n window.removeEventListener('resize', debouncedUpdateDimensions)\r\n }\r\n }, [debouncedUpdateDimensions])\r\n\r\n const { width, height } = dimensions\r\n\r\n // Calcular breakpoint actual\r\n const breakpoint = useMemo(() => getCurrentBreakpoint(width), [width])\r\n \r\n // Calcular orientación\r\n const orientation = useMemo(() => getOrientation(width, height), [width, height])\r\n\r\n // Helpers booleanos por breakpoint específico\r\n const isXs = breakpoint === 'xs'\r\n const isSm = breakpoint === 'sm'\r\n const isMd = breakpoint === 'md'\r\n const isLg = breakpoint === 'lg'\r\n const isXl = breakpoint === 'xl'\r\n const is2Xl = breakpoint === '2xl'\r\n const is3Xl = breakpoint === '3xl'\r\n const is4Xl = breakpoint === '4xl'\r\n const is5Xl = breakpoint === '5xl'\r\n\r\n // Helpers booleanos agrupados\r\n const isMobile = isXs || isSm\r\n const isTablet = isMd\r\n const isDesktop = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isSmall = isXs || isSm || isMd\r\n const isLarge = isLg || isXl || is2Xl || is3Xl || is4Xl || is5Xl\r\n const isUltraWide = is3Xl || is4Xl || is5Xl\r\n const is4K = is4Xl || is5Xl\r\n const is5K = is5Xl\r\n\r\n // Helpers de orientación\r\n const isPortrait = orientation === 'portrait'\r\n const isLandscape = orientation === 'landscape'\r\n\r\n // Funciones de comparación de breakpoints\r\n const isBreakpointUp = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) >= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointDown = useCallback((bp: Breakpoint): boolean => {\r\n return getBreakpointIndex(breakpoint) <= getBreakpointIndex(bp)\r\n }, [breakpoint])\r\n\r\n const isBreakpointBetween = useCallback((min: Breakpoint, max: Breakpoint): boolean => {\r\n const current = getBreakpointIndex(breakpoint)\r\n return current >= getBreakpointIndex(min) && current <= getBreakpointIndex(max)\r\n }, [breakpoint])\r\n\r\n // Funciones de comparación de ancho\r\n const isWidthUp = useCallback((minWidth: number): boolean => {\r\n return width >= minWidth\r\n }, [width])\r\n\r\n const isWidthDown = useCallback((maxWidth: number): boolean => {\r\n return width <= maxWidth\r\n }, [width])\r\n\r\n const isWidthBetween = useCallback((minWidth: number, maxWidth: number): boolean => {\r\n return width >= minWidth && width <= maxWidth\r\n }, [width])\r\n\r\n // Funciones de comparación de altura\r\n const isHeightUp = useCallback((minHeight: number): boolean => {\r\n return height >= minHeight\r\n }, [height])\r\n\r\n const isHeightDown = useCallback((maxHeight: number): boolean => {\r\n return height <= maxHeight\r\n }, [height])\r\n\r\n const isHeightBetween = useCallback((minHeight: number, maxHeight: number): boolean => {\r\n return height >= minHeight && height <= maxHeight\r\n }, [height])\r\n\r\n // Debug mode\r\n const debug = false\r\n\r\n return {\r\n // Estado básico\r\n breakpoint,\r\n width,\r\n height,\r\n orientation,\r\n \r\n // Helpers booleanos específicos\r\n isXs,\r\n isSm,\r\n isMd,\r\n isLg,\r\n isXl,\r\n is2Xl,\r\n is3Xl,\r\n is4Xl,\r\n is5Xl,\r\n \r\n // Helpers booleanos agrupados\r\n isMobile,\r\n isTablet,\r\n isDesktop,\r\n isSmall,\r\n isLarge,\r\n isUltraWide,\r\n is4K,\r\n is5K,\r\n \r\n // Helpers de orientación\r\n isPortrait,\r\n isLandscape,\r\n \r\n // Funciones de comparación\r\n isBreakpointUp,\r\n isBreakpointDown,\r\n isBreakpointBetween,\r\n isWidthUp,\r\n isWidthDown,\r\n isWidthBetween,\r\n isHeightUp,\r\n isHeightDown,\r\n isHeightBetween,\r\n \r\n // Debug\r\n debug\r\n }\r\n}\r\n","import { createContext, useContext } from 'react'\r\nimport type { ResponsiveState } from '../types/responsive'\r\nimport type { LayoutConfig } from '../config/layout'\r\n\r\nexport interface ResponsiveLayoutState {\r\n // Estado del sistema responsivo\r\n responsive: ResponsiveState\r\n \r\n // Estado del layout\r\n layout: {\r\n current: string\r\n config: LayoutConfig\r\n setLayout: (layout: string) => void\r\n }\r\n \r\n // Utilidades de layout\r\n layoutUtils: {\r\n getContainerClass: () => string\r\n getMainClass: () => string\r\n hasSidebar: () => boolean\r\n hasHeader: () => boolean\r\n hasFooter: () => boolean\r\n hasNavigation: () => boolean\r\n }\r\n}\r\n\r\nconst ResponsiveLayoutContext = createContext<ResponsiveLayoutState | undefined>(undefined)\r\n\r\nexport const useResponsiveLayoutContext = () => {\r\n const context = useContext(ResponsiveLayoutContext)\r\n if (!context) {\r\n throw new Error('useResponsiveLayoutContext must be used within a ResponsiveLayoutProvider')\r\n }\r\n return context\r\n}\r\n\r\nexport { ResponsiveLayoutContext }\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface SidebarContextType {\r\n sidebarOpen: boolean\r\n setSidebarOpen: (open: boolean) => void\r\n}\r\n\r\nconst SidebarContext = createContext<SidebarContextType | undefined>(undefined)\r\n\r\nexport const SidebarProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n const [sidebarOpen, setSidebarOpen] = useState(false)\r\n\r\n return (\r\n <SidebarContext.Provider value={{ sidebarOpen, setSidebarOpen }}>\r\n {children}\r\n </SidebarContext.Provider>\r\n )\r\n}\r\n\r\nexport const useSidebar = () => {\r\n const context = useContext(SidebarContext)\r\n if (!context) {\r\n throw new Error('useSidebar must be used within a SidebarProvider')\r\n }\r\n return context\r\n}\r\n","import React, { createContext, useContext, useState } from 'react'\r\n\r\ninterface NavigationContextType {\r\n currentPage: 'demo' | 'test'\r\n setCurrentPage: (page: 'demo' | 'test') => void\r\n}\r\n\r\nconst NavigationContext = createContext<NavigationContextType>({\r\n currentPage: 'test',\r\n setCurrentPage: () => {}\r\n})\r\n\r\nexport const useNavigation = () => useContext(NavigationContext)\r\n\r\ninterface NavigationProviderProps {\r\n children: React.ReactNode\r\n defaultPage?: 'demo' | 'test'\r\n}\r\n\r\nexport const NavigationProvider: React.FC<NavigationProviderProps> = ({ \r\n children, \r\n defaultPage = 'test' \r\n}) => {\r\n const [currentPage, setCurrentPage] = useState<'demo' | 'test'>(defaultPage)\r\n\r\n return (\r\n <NavigationContext.Provider value={{ currentPage, setCurrentPage }}>\r\n {children}\r\n </NavigationContext.Provider>\r\n )\r\n}\r\n\r\n","import { useResponsiveLayoutContext } from '../context'\r\n\r\nexport const useResponsiveLayout = () => {\r\n const context = useResponsiveLayoutContext()\r\n \r\n return {\r\n // Todo el sistema responsivo original\r\n ...context.responsive,\r\n \r\n // Sistema de layout\r\n layout: {\r\n current: context.layout.current,\r\n config: context.layout.config,\r\n setLayout: context.layout.setLayout,\r\n },\r\n \r\n // Utilidades de layout\r\n layoutUtils: context.layoutUtils,\r\n \r\n // Helpers específicos del layout\r\n isDefaultLayout: () => context.layout.current === 'default',\r\n isSidebarLayout: () => context.layout.current === 'sidebar',\r\n isDashboardLayout: () => context.layout.current === 'dashboard',\r\n isMinimalLayout: () => context.layout.current === 'minimal',\r\n \r\n // Grid helpers que usan el sistema auto-escalable\r\n grid: {\r\n auto: (minWidth = 'md') => `grid-cols-auto-${minWidth}`,\r\n responsive: (breakpoints: Record<string, number>) => {\r\n const classes: string[] = []\r\n Object.entries(breakpoints).forEach(([breakpoint, cols]) => {\r\n if (breakpoint === 'base') {\r\n classes.push(`grid-cols-${cols}`)\r\n } else {\r\n classes.push(`${breakpoint}:grid-cols-${cols}`)\r\n }\r\n })\r\n return classes.join(' ')\r\n },\r\n fixed: (cols: number) => `grid-cols-${cols}`,\r\n },\r\n \r\n // Spacing helpers que escalan automáticamente\r\n spacing: {\r\n container: context.layoutUtils.getContainerClass(),\r\n section: 'mb-6',\r\n card: 'p-6',\r\n gap: 'gap-4',\r\n },\r\n }\r\n}\r\n","import { useResponsiveLayout } from './index'\r\n\r\nexport const useLayout = () => {\r\n const responsiveLayout = useResponsiveLayout()\r\n \r\n return {\r\n // Layout actual\r\n current: responsiveLayout.layout.current,\r\n config: responsiveLayout.layout.config,\r\n setLayout: responsiveLayout.layout.setLayout,\r\n \r\n // Utilidades\r\n ...responsiveLayout.layoutUtils,\r\n \r\n // Helpers específicos\r\n isDefaultLayout: responsiveLayout.isDefaultLayout(),\r\n isSidebarLayout: responsiveLayout.isSidebarLayout(),\r\n isDashboardLayout: responsiveLayout.isDashboardLayout(),\r\n isMinimalLayout: responsiveLayout.isMinimalLayout(),\r\n \r\n // Grid helpers\r\n grid: responsiveLayout.grid,\r\n \r\n // Spacing helpers\r\n spacing: responsiveLayout.spacing,\r\n }\r\n}\r\n","export interface LayoutConfig {\r\n name: string\r\n description: string\r\n components: string[]\r\n spacing: string\r\n responsive: {\r\n mobile: string\r\n tablet: string\r\n desktop: string\r\n }\r\n}\r\n\r\nexport const LAYOUT_CONFIG: Record<string, LayoutConfig> = {\r\n default: {\r\n name: 'Default',\r\n description: 'Navbar arriba, body central, footer abajo',\r\n components: ['Navigation', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n sidebar: {\r\n name: 'Sidebar',\r\n description: 'Sidebar izquierda, contenido principal',\r\n components: ['Sidebar'],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n },\r\n dashboard: {\r\n name: 'Dashboard',\r\n description: 'Header + Sidebar + Main + Footer',\r\n components: ['Header', 'Sidebar', 'Footer'],\r\n spacing: 'p-4 md:p-6 lg:p-8',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-8'\r\n }\r\n },\r\n minimal: {\r\n name: 'Minimal',\r\n description: 'Solo contenido, sin navegación',\r\n components: [],\r\n spacing: 'p-4 md:p-6',\r\n responsive: {\r\n mobile: 'p-4',\r\n tablet: 'p-6',\r\n desktop: 'p-6'\r\n }\r\n }\r\n}\r\n\r\nexport const DEFAULT_LAYOUT = 'default'\r\nexport const AVAILABLE_LAYOUTS = Object.keys(LAYOUT_CONFIG)\r\n","import React, { useState } from 'react'\r\nimport { ResponsiveProvider } from './index'\r\nimport { useResponsive } from '../hooks'\r\nimport { ResponsiveLayoutContext } from '../context'\r\nimport { LAYOUT_CONFIG, DEFAULT_LAYOUT } from '../config/layout'\r\nimport type { ResponsiveState } from '../types/responsive'\r\n\r\ninterface ResponsiveLayoutProviderProps {\r\n children: React.ReactNode\r\n defaultLayout?: string\r\n /**\r\n * Hook responsivo personalizado del proyecto consumidor.\r\n * Si se proporciona, se usará en lugar del hook interno del paquete.\r\n * Debe retornar un objeto compatible con ResponsiveState.\r\n */\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\ninterface ResponsiveLayoutProviderInnerProps {\r\n children: React.ReactNode\r\n defaultLayout: string\r\n useResponsiveHook?: () => ResponsiveState\r\n}\r\n\r\nconst ResponsiveLayoutProviderInner: React.FC<ResponsiveLayoutProviderInnerProps> = ({ \r\n children, \r\n defaultLayout,\r\n useResponsiveHook\r\n}) => {\r\n // Usar hook personalizado si se proporciona, sino usar el hook interno\r\n const internalResponsive = useResponsive()\r\n const customResponsive = useResponsiveHook?.()\r\n const responsive = customResponsive || internalResponsive\r\n \r\n // Inicializar el estado con el layout normalizado usando función inicializadora\r\n // Esto asegura que solo se ejecute una vez, incluso con React.StrictMode\r\n const [currentLayout, setCurrentLayout] = useState(() => {\r\n // Validar y normalizar el defaultLayout directamente en la función inicializadora\r\n if (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout]) {\r\n return defaultLayout\r\n }\r\n return DEFAULT_LAYOUT\r\n })\r\n \r\n const layoutConfig = LAYOUT_CONFIG[currentLayout] || LAYOUT_CONFIG[DEFAULT_LAYOUT]\r\n \r\n const layoutUtils = {\r\n getContainerClass: () => {\r\n if (responsive.isMobile) return layoutConfig.responsive.mobile\r\n if (responsive.isTablet) return layoutConfig.responsive.tablet\r\n return layoutConfig.responsive.desktop\r\n },\r\n \r\n getMainClass: () => {\r\n const baseClass = 'min-h-screen bg-black'\r\n if (currentLayout === 'sidebar' || currentLayout === 'dashboard') {\r\n return `${baseClass} flex`\r\n }\r\n return baseClass\r\n },\r\n \r\n hasSidebar: () => currentLayout === 'sidebar' || currentLayout === 'dashboard',\r\n hasHeader: () => currentLayout === 'dashboard',\r\n hasFooter: () => currentLayout === 'default' || currentLayout === 'dashboard',\r\n hasNavigation: () => currentLayout === 'default',\r\n }\r\n \r\n const contextValue = {\r\n responsive,\r\n layout: {\r\n current: currentLayout,\r\n config: layoutConfig,\r\n setLayout: setCurrentLayout,\r\n },\r\n layoutUtils,\r\n }\r\n \r\n return (\r\n <ResponsiveLayoutContext.Provider value={contextValue}>\r\n {children}\r\n </ResponsiveLayoutContext.Provider>\r\n )\r\n}\r\n\r\nexport const ResponsiveLayoutProvider: React.FC<ResponsiveLayoutProviderProps> = ({ \r\n children, \r\n defaultLayout = DEFAULT_LAYOUT,\r\n useResponsiveHook\r\n}) => {\r\n // Normalizar el defaultLayout antes de pasarlo al componente interno\r\n const normalizedDefaultLayout = (defaultLayout && typeof defaultLayout === 'string' && LAYOUT_CONFIG[defaultLayout])\r\n ? defaultLayout\r\n : DEFAULT_LAYOUT\r\n \r\n return (\r\n <ResponsiveProvider>\r\n <ResponsiveLayoutProviderInner \r\n defaultLayout={normalizedDefaultLayout}\r\n useResponsiveHook={useResponsiveHook}\r\n >\r\n {children}\r\n </ResponsiveLayoutProviderInner>\r\n </ResponsiveProvider>\r\n )\r\n}\r\n","import React from 'react'\r\nimport { useResponsiveLayout } from '../hooks'\r\nimport { \r\n DefaultLayout, \r\n SidebarLayout, \r\n DashboardLayout, \r\n MinimalLayout \r\n} from './index'\r\n\r\ninterface MainLayoutProps {\r\n children: React.ReactNode\r\n /**\r\n * Layout específico a usar. Si se proporciona, sobrescribe el layout del contexto.\r\n * Valores posibles: 'default', 'sidebar', 'dashboard', 'minimal'\r\n */\r\n layout?: 'default' | 'sidebar' | 'dashboard' | 'minimal'\r\n}\r\n\r\nconst MainLayout: React.FC<MainLayoutProps> = ({ children, layout: layoutProp }) => {\r\n const { layout } = useResponsiveLayout()\r\n \r\n // Mapa de layouts disponibles\r\n const layouts = {\r\n default: DefaultLayout,\r\n sidebar: SidebarLayout,\r\n dashboard: DashboardLayout,\r\n minimal: MinimalLayout,\r\n }\r\n \r\n // Determinar qué layout usar: prop > contexto > default\r\n const layoutToUse = layoutProp || layout.current || 'default'\r\n \r\n // Validar que el layout sea válido, si no usar default\r\n const validLayout = (layoutToUse && layouts[layoutToUse as keyof typeof layouts])\r\n ? layoutToUse\r\n : 'default'\r\n \r\n // Obtener el componente de layout\r\n const LayoutComponent = layouts[validLayout as keyof typeof layouts] || DefaultLayout\r\n \r\n return <LayoutComponent>{children}</LayoutComponent>\r\n}\r\n\r\nexport default MainLayout\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useNavigation, useSidebar } from '../../context'\r\n\r\nconst Header = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n const { currentPage, setCurrentPage } = useNavigation()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'test', label: 'Suite de Test' },\r\n { id: 'demo', label: 'Demo' },\r\n ]\r\n \r\n return (\r\n <div className=\"sticky top-0 z-50\">\r\n <header className=\"bg-gradient-to-r from-gray-900 via-black to-gray-900 border-b border-cyan-500/20 shadow-2xl relative\">\r\n <div className=\"w-full\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-2\">\r\n {/* Hamburger button para móvil - A LA IZQUIERDA */}\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"p-2 rounded-lg text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10 transition-colors\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n <div className=\"w-1.5 h-1.5 bg-cyan-400 rounded-full shadow-lg shadow-cyan-400/50 animate-pulse\"></div>\r\n <h3 className=\"text-base font-black text-white tracking-tight\">\r\n Sistema Responsivo\r\n </h3>\r\n </div>\r\n <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\">\r\n DASHBOARD\r\n </div>\r\n </div>\r\n \r\n <div className=\"flex items-center space-x-2\">\r\n {/* Botones visibles solo en desktop */}\r\n {!isMobile && menuItems.map((page) => (\r\n <button\r\n key={page.id}\r\n onClick={() => setCurrentPage(page.id as 'demo' | 'test')}\r\n className={`px-3 py-1.5 rounded-lg transition-all font-bold text-xs tracking-wide border ${\r\n currentPage === page.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border-cyan-500/50' \r\n : 'bg-black/50 text-gray-400 hover:text-gray-300 border-gray-700 hover:border-gray-600'\r\n }`}\r\n >\r\n {page.label}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n {/* Sidebar móvil desplegable */}\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gradient-to-b from-gray-900 to-black border-r border-cyan-500/20\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n {/* Logo */}\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-cyan-500 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">RS</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Sistema Responsivo</span>\r\n </div>\r\n \r\n {/* Navigation */}\r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => {\r\n setCurrentPage(item.id as 'demo' | 'test')\r\n setSidebarOpen(false)\r\n }}\r\n className={`w-full flex items-center px-4 py-3 rounded-lg transition-all group text-left ${\r\n currentPage === item.id \r\n ? 'bg-cyan-500/20 text-cyan-400 border border-cyan-500/50' \r\n : 'text-gray-300 hover:text-cyan-400 hover:bg-cyan-500/10'\r\n }`}\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport default Header\r\n","import { useResponsiveLayout } from '../../hooks'\r\nimport { useSidebar } from '../../context'\r\n\r\nconst Sidebar = () => {\r\n const { isMobile, isTablet } = useResponsiveLayout()\r\n const { sidebarOpen, setSidebarOpen } = useSidebar()\r\n \r\n const menuItems = [\r\n { id: 'home', label: 'Inicio' },\r\n { id: 'about', label: 'Acerca' },\r\n { id: 'contact', label: 'Contacto' },\r\n ]\r\n \r\n return (\r\n <>\r\n {isMobile && (\r\n <button\r\n onClick={() => setSidebarOpen(true)}\r\n className=\"fixed top-4 left-4 z-50 p-2 rounded-lg text-gray-300 hover:text-white hover:bg-gray-800 bg-gray-900 border border-gray-700\"\r\n >\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n\r\n <aside className={`bg-gray-900 border-r border-gray-800 ${isMobile ? 'hidden' : 'w-64 flex-shrink-0'} ${isTablet ? 'w-56' : 'w-64'}`}>\r\n <div className=\"p-6 flex flex-col h-full\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </aside>\r\n\r\n {isMobile && sidebarOpen && (\r\n <div className=\"fixed inset-0 z-40 bg-black/50\" onClick={() => setSidebarOpen(false)}>\r\n <div className=\"fixed top-0 left-0 w-64 h-full bg-gray-900 border-r border-gray-800\">\r\n <div className=\"p-6 flex flex-col h-full pt-20\">\r\n <div className=\"flex items-center space-x-3 mb-8\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <span className=\"text-white font-bold text-lg\">Tu Aplicación</span>\r\n </div>\r\n \r\n <nav className=\"space-y-2\">\r\n {menuItems.map((item) => (\r\n <button\r\n key={item.id}\r\n onClick={() => setSidebarOpen(false)}\r\n className=\"w-full flex items-center px-4 py-3 rounded-lg transition-all text-left text-gray-300 hover:text-white hover:bg-gray-800\"\r\n >\r\n <span className=\"font-medium\">{item.label}</span>\r\n </button>\r\n ))}\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n )\r\n}\r\n\r\nexport default Sidebar\r\n","const Footer = () => {\r\n return (\r\n <footer className=\"bg-gray-900 border-t border-gray-800\">\r\n <div className=\"px-4 py-6\">\r\n <div className=\"max-w-7xl mx-auto text-center\">\r\n <p className=\"text-gray-400 text-sm\">\r\n © {new Date().getFullYear()} Tu Aplicación. Todos los derechos reservados.\r\n </p>\r\n </div>\r\n </div>\r\n </footer>\r\n )\r\n}\r\n\r\nexport default Footer\r\n","import { useResponsiveLayout } from '../../hooks'\r\n\r\nconst Navigation = () => {\r\n const { isMobile } = useResponsiveLayout()\r\n \r\n return (\r\n <nav className=\"sticky top-0 z-50 bg-gray-900 border-b border-gray-800\">\r\n <div className=\"px-4 py-4\">\r\n <div className=\"flex items-center justify-between\">\r\n <div className=\"flex items-center space-x-3\">\r\n <div className=\"w-8 h-8 bg-gray-700 rounded-lg flex items-center justify-center\">\r\n <span className=\"text-white font-bold text-sm\">LO</span>\r\n </div>\r\n <h1 className=\"text-white font-semibold text-lg\">Tu Aplicación</h1>\r\n </div>\r\n \r\n {isMobile && (\r\n <button className=\"p-2 text-gray-400 hover:text-white\">\r\n <svg className=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\r\n </svg>\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </nav>\r\n )\r\n}\r\n\r\nexport default Navigation\r\n","import React from 'react'\r\nimport { Navigation, Footer } from '../components/layout'\r\n\r\ninterface DefaultLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Navigation fijo arriba */}\r\n <Navigation />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1\">\r\n {children}\r\n </main>\r\n \r\n {/* Footer fijo abajo */}\r\n <Footer />\r\n </div>\r\n )\r\n}\r\n\r\nexport default DefaultLayout\r\n","import React from 'react'\r\nimport { Sidebar } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface SidebarLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst SidebarLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto\">\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nconst SidebarLayout: React.FC<SidebarLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <SidebarLayoutContent>{children}</SidebarLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default SidebarLayout\r\n","import React from 'react'\r\nimport { Sidebar, Footer } from '../components/layout'\r\nimport { SidebarProvider } from '../context'\r\n\r\ninterface DashboardLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst DashboardLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50 flex flex-col\">\r\n {/* Content area con sidebar */}\r\n <div className=\"flex flex-1\">\r\n {/* Sidebar */}\r\n <Sidebar />\r\n \r\n {/* Main content */}\r\n <main className=\"flex-1 overflow-auto flex flex-col\">\r\n <div className=\"flex-1\">\r\n {children}\r\n </div>\r\n \r\n {/* Footer */}\r\n <Footer />\r\n </main>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nconst DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {\r\n return (\r\n <SidebarProvider>\r\n <DashboardLayoutContent>{children}</DashboardLayoutContent>\r\n </SidebarProvider>\r\n )\r\n}\r\n\r\nexport default DashboardLayout\r\n","import React from 'react'\r\n\r\ninterface MinimalLayoutProps {\r\n children: React.ReactNode\r\n}\r\n\r\nconst MinimalLayout: React.FC<MinimalLayoutProps> = ({ children }) => {\r\n return (\r\n <div className=\"min-h-screen bg-gray-50\">\r\n <main>\r\n {children}\r\n </main>\r\n </div>\r\n )\r\n}\r\n\r\nexport default MinimalLayout\r\n","import { useLayout } from '../hooks'\r\nimport { LAYOUT_CONFIG } from '../config/layout'\r\n\r\ninterface LayoutSwitcherProps {\r\n compact?: boolean\r\n}\r\n\r\nconst LayoutSwitcher = ({ compact = false }: LayoutSwitcherProps) => {\r\n const { current, setLayout, config } = useLayout()\r\n \r\n if (compact) {\r\n return (\r\n <div className=\"bg-black/50 rounded-lg p-3 border border-gray-700\">\r\n <div className=\"text-xs text-gray-500 mb-2\">Layout:</div>\r\n <select\r\n value={current}\r\n onChange={(e) => setLayout(e.target.value)}\r\n className=\"w-full bg-gray-800 text-white text-sm p-2 rounded border border-gray-600 focus:ring-1 focus:ring-cyan-500 focus:border-transparent\"\r\n >\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <option key={key} value={key}>\r\n {layoutConfig.name}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n )\r\n }\r\n \r\n return (\r\n <div className=\"bg-black/50 backdrop-blur-sm rounded-lg p-4 border border-cyan-500/30\">\r\n <h3 className=\"text-white font-semibold mb-3\">Cambiar Layout</h3>\r\n \r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n {Object.entries(LAYOUT_CONFIG).map(([key, layoutConfig]) => (\r\n <button\r\n key={key}\r\n onClick={() => setLayout(key)}\r\n className={`\r\n p-4 rounded-lg border transition-all text-left\r\n ${current === key \r\n ? 'border-cyan-500 bg-cyan-500/10 text-cyan-400' \r\n : 'border-gray-700 bg-black/30 text-gray-300 hover:border-gray-600'\r\n }\r\n `}\r\n >\r\n <div className=\"font-semibold mb-1\">{layoutConfig.name}</div>\r\n <div className=\"text-xs opacity-75\">{layoutConfig.description}</div>\r\n </button>\r\n ))}\r\n </div>\r\n \r\n <div className=\"mt-4 p-3 bg-gray-900/50 rounded-lg\">\r\n <div className=\"text-xs text-gray-500 mb-1\">Layout Actual:</div>\r\n <div className=\"text-sm text-cyan-400 font-medium\">{config.name}</div>\r\n <div className=\"text-xs text-gray-400\">{config.description}</div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default LayoutSwitcher\r\n"],"names":["ResponsiveProvider","children","_debug","DEFAULT_BREAKPOINTS","getCurrentBreakpoint","width","getBreakpointIndex","breakpoint","getBreakpointValue","debounce","func","wait","timeout","args","getOrientation","height","useResponsive","dimensions","setDimensions","useState","updateDimensions","useCallback","debouncedUpdateDimensions","useMemo","useEffect","orientation","isXs","isSm","isMd","isLg","isXl","is2Xl","is3Xl","is4Xl","is5Xl","isMobile","isTablet","isDesktop","isSmall","isLarge","isUltraWide","is4K","is5K","isPortrait","isLandscape","isBreakpointUp","bp","isBreakpointDown","isBreakpointBetween","min","max","current","isWidthUp","minWidth","isWidthDown","maxWidth","isWidthBetween","isHeightUp","minHeight","isHeightDown","maxHeight","isHeightBetween","ResponsiveLayoutContext","createContext","useResponsiveLayoutContext","context","useContext","SidebarContext","SidebarProvider","sidebarOpen","setSidebarOpen","jsx","useSidebar","NavigationContext","useNavigation","NavigationProvider","defaultPage","currentPage","setCurrentPage","useResponsiveLayout","breakpoints","classes","cols","useLayout","responsiveLayout","LAYOUT_CONFIG","DEFAULT_LAYOUT","AVAILABLE_LAYOUTS","ResponsiveLayoutProviderInner","defaultLayout","useResponsiveHook","internalResponsive","responsive","currentLayout","setCurrentLayout","layoutConfig","contextValue","baseClass","ResponsiveLayoutProvider","normalizedDefaultLayout","MainLayout","layoutProp","layout","layouts","DefaultLayout","SidebarLayout","DashboardLayout","MinimalLayout","layoutToUse","validLayout","LayoutComponent","Header","menuItems","jsxs","page","item","Sidebar","Fragment","Footer","Navigation","SidebarLayoutContent","DashboardLayoutContent","LayoutSwitcher","compact","setLayout","config","e","key"],"mappings":";;AAUO,MAAMA,KAAwD,CAAC;AAAA,EACpE,UAAAC;AAAA,EACA,OAAOC,IAAS;AAClB,6BAGY,UAAAD,GAAS,GCVRE,IAAkD;AAAA,EAC7D,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT,GAKaC,KAAuB,CAACC,MAC/BA,KAASF,EAAoB,KAAK,IAAU,QAC5CE,KAASF,EAAoB,KAAK,IAAU,QAC5CE,KAASF,EAAoB,KAAK,IAAU,QAC5CE,KAASF,EAAoB,KAAK,IAAU,QAC5CE,KAASF,EAAoB,KAAW,OACxCE,KAASF,EAAoB,KAAW,OACxCE,KAASF,EAAoB,KAAW,OACxCE,KAASF,EAAoB,KAAW,OACrC,MAMIG,IAAqB,CAACC,MACC,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO,OAAO,OAAO,KAAK,EACxE,QAAQA,CAAU,GAM1BC,KAAqB,CAACD,MAC1BJ,EAAoBI,CAAU;AChCvC,SAASE,GACPC,GACAC,GACkC;AAClC,MAAIC,IAAgD;AACpD,SAAO,IAAIC,MAAwB;AACjC,IAAID,kBAAsBA,CAAO,GACjCA,IAAU,WAAW,MAAMF,EAAK,GAAGG,CAAI,GAAGF,CAAI;AAAA,EAChD;AACF;AAKA,SAASG,GAAeT,GAAeU,GAA0C;AAC/E,SAAOV,KAASU,IAAS,cAAc;AACzC;AAMO,MAAMC,KAAgB,MAAuB;AAClD,QAAM,CAACC,GAAYC,CAAa,IAAIC,EAAS;AAAA,IAC3C,OAAO,OAAO,SAAW,MAAc,OAAO,aAAa;AAAA,IAC3D,QAAQ,OAAO,SAAW,MAAc,OAAO,cAAc;AAAA,EAAA,CAC9D,GAGKC,IAAmBC,EAAY,MAAM;AACzC,IAAAH,EAAc;AAAA,MACZ,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,IAAA,CAChB;AAAA,EACH,GAAG,CAAA,CAAE,GAGCI,IAA4BC;AAAA,IAChC,MAAMd,GAASW,GAAkB,GAAG;AAAA,IACpC,CAACA,CAAgB;AAAA,EAAA;AAInB,EAAAI,GAAU,MAAM;AACd,QAAI,SAAO,SAAW;AAEtB,oBAAO,iBAAiB,UAAUF,CAAyB,GAEpD,MAAM;AACX,eAAO,oBAAoB,UAAUA,CAAyB;AAAA,MAChE;AAAA,EACF,GAAG,CAACA,CAAyB,CAAC;AAE9B,QAAM,EAAE,OAAAjB,GAAO,QAAAU,EAAA,IAAWE,GAGpBV,IAAagB,EAAQ,MAAMnB,GAAqBC,CAAK,GAAG,CAACA,CAAK,CAAC,GAG/DoB,IAAcF,EAAQ,MAAMT,GAAeT,GAAOU,CAAM,GAAG,CAACV,GAAOU,CAAM,CAAC,GAG1EW,IAAOnB,MAAe,MACtBoB,IAAOpB,MAAe,MACtBqB,IAAOrB,MAAe,MACtBsB,IAAOtB,MAAe,MACtBuB,IAAOvB,MAAe,MACtBwB,IAAQxB,MAAe,OACvByB,IAAQzB,MAAe,OACvB0B,IAAQ1B,MAAe,OACvB2B,IAAQ3B,MAAe,OAGvB4B,IAAWT,KAAQC,GACnBS,IAAWR,GACXS,IAAYR,KAAQC,KAAQC,KAASC,KAASC,KAASC,GACvDI,IAAUZ,KAAQC,KAAQC,GAC1BW,IAAUV,KAAQC,KAAQC,KAASC,KAASC,KAASC,GACrDM,IAAcR,KAASC,KAASC,GAChCO,IAAOR,KAASC,GAChBQ,IAAOR,GAGPS,IAAalB,MAAgB,YAC7BmB,IAAcnB,MAAgB,aAG9BoB,IAAiBxB,EAAY,CAACyB,MAC3BxC,EAAmBC,CAAU,KAAKD,EAAmBwC,CAAE,GAC7D,CAACvC,CAAU,CAAC,GAETwC,IAAmB1B,EAAY,CAACyB,MAC7BxC,EAAmBC,CAAU,KAAKD,EAAmBwC,CAAE,GAC7D,CAACvC,CAAU,CAAC,GAETyC,IAAsB3B,EAAY,CAAC4B,GAAiBC,MAA6B;AACrF,UAAMC,IAAU7C,EAAmBC,CAAU;AAC7C,WAAO4C,KAAW7C,EAAmB2C,CAAG,KAAKE,KAAW7C,EAAmB4C,CAAG;AAAA,EAChF,GAAG,CAAC3C,CAAU,CAAC,GAGT6C,KAAY/B,EAAY,CAACgC,MACtBhD,KAASgD,GACf,CAAChD,CAAK,CAAC,GAEJiD,KAAcjC,EAAY,CAACkC,MACxBlD,KAASkD,GACf,CAAClD,CAAK,CAAC,GAEJmD,KAAiBnC,EAAY,CAACgC,GAAkBE,MAC7ClD,KAASgD,KAAYhD,KAASkD,GACpC,CAAClD,CAAK,CAAC,GAGJoD,KAAapC,EAAY,CAACqC,MACvB3C,KAAU2C,GAChB,CAAC3C,CAAM,CAAC,GAEL4C,KAAetC,EAAY,CAACuC,MACzB7C,KAAU6C,GAChB,CAAC7C,CAAM,CAAC,GAEL8C,KAAkBxC,EAAY,CAACqC,GAAmBE,MAC/C7C,KAAU2C,KAAa3C,KAAU6C,GACvC,CAAC7C,CAAM,CAAC;AAKX,SAAO;AAAA;AAAA,IAEL,YAAAR;AAAA,IACA,OAAAF;AAAA,IACA,QAAAU;AAAA,IACA,aAAAU;AAAA;AAAA,IAGA,MAAAC;AAAA,IACA,MAAAC;AAAA,IACA,MAAAC;AAAA,IACA,MAAAC;AAAA,IACA,MAAAC;AAAA,IACA,OAAAC;AAAA,IACA,OAAAC;AAAA,IACA,OAAAC;AAAA,IACA,OAAAC;AAAA;AAAA,IAGA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,WAAAC;AAAA,IACA,SAAAC;AAAA,IACA,SAAAC;AAAA,IACA,aAAAC;AAAA,IACA,MAAAC;AAAA,IACA,MAAAC;AAAA;AAAA,IAGA,YAAAC;AAAA,IACA,aAAAC;AAAA;AAAA,IAGA,gBAAAC;AAAA,IACA,kBAAAE;AAAA,IACA,qBAAAC;AAAA,IACA,WAAAI;AAAA,IACA,aAAAE;AAAA,IACA,gBAAAE;AAAA,IACA,YAAAC;AAAA,IACA,cAAAE;AAAA,IACA,iBAAAE;AAAA;AAAA,IAGA,OA9CY;AAAA,EA8CZ;AAEJ,GClKMC,IAA0BC,EAAiD,MAAS,GAE7EC,KAA6B,MAAM;AAC9C,QAAMC,IAAUC,EAAWJ,CAAuB;AAClD,MAAI,CAACG;AACH,UAAM,IAAI,MAAM,2EAA2E;AAE7F,SAAOA;AACT,GC3BME,IAAiBJ,EAA8C,MAAS,GAEjEK,IAA2D,CAAC,EAAE,UAAAnE,QAAe;AACxF,QAAM,CAACoE,GAAaC,CAAc,IAAInD,EAAS,EAAK;AAEpD,SACE,gBAAAoD,EAACJ,EAAe,UAAf,EAAwB,OAAO,EAAE,aAAAE,GAAa,gBAAAC,KAC5C,UAAArE,GACH;AAEJ,GAEauE,IAAa,MAAM;AAC9B,QAAMP,IAAUC,EAAWC,CAAc;AACzC,MAAI,CAACF;AACH,UAAM,IAAI,MAAM,kDAAkD;AAEpE,SAAOA;AACT,GClBMQ,IAAoBV,EAAqC;AAAA,EAC7D,aAAa;AAAA,EACb,gBAAgB,MAAM;AAAA,EAAC;AACzB,CAAC,GAEYW,KAAgB,MAAMR,EAAWO,CAAiB,GAOlDE,KAAwD,CAAC;AAAA,EACpE,UAAA1E;AAAA,EACA,aAAA2E,IAAc;AAChB,MAAM;AACJ,QAAM,CAACC,GAAaC,CAAc,IAAI3D,EAA0ByD,CAAW;AAE3E,SACE,gBAAAL,EAACE,EAAkB,UAAlB,EAA2B,OAAO,EAAE,aAAAI,GAAa,gBAAAC,KAC/C,UAAA7E,GACH;AAEJ,GC5Ba8E,IAAsB,MAAM;AACvC,QAAMd,IAAUD,GAAA;AAEhB,SAAO;AAAA;AAAA,IAEL,GAAGC,EAAQ;AAAA;AAAA,IAGX,QAAQ;AAAA,MACN,SAASA,EAAQ,OAAO;AAAA,MACxB,QAAQA,EAAQ,OAAO;AAAA,MACvB,WAAWA,EAAQ,OAAO;AAAA,IAAA;AAAA;AAAA,IAI5B,aAAaA,EAAQ;AAAA;AAAA,IAGrB,iBAAiB,MAAMA,EAAQ,OAAO,YAAY;AAAA,IAClD,iBAAiB,MAAMA,EAAQ,OAAO,YAAY;AAAA,IAClD,mBAAmB,MAAMA,EAAQ,OAAO,YAAY;AAAA,IACpD,iBAAiB,MAAMA,EAAQ,OAAO,YAAY;AAAA;AAAA,IAGlD,MAAM;AAAA,MACJ,MAAM,CAACZ,IAAW,SAAS,kBAAkBA,CAAQ;AAAA,MACrD,YAAY,CAAC2B,MAAwC;AACnD,cAAMC,IAAoB,CAAA;AAC1B,sBAAO,QAAQD,CAAW,EAAE,QAAQ,CAAC,CAACzE,GAAY2E,CAAI,MAAM;AAC1D,UAAI3E,MAAe,SACjB0E,EAAQ,KAAK,aAAaC,CAAI,EAAE,IAEhCD,EAAQ,KAAK,GAAG1E,CAAU,cAAc2E,CAAI,EAAE;AAAA,QAElD,CAAC,GACMD,EAAQ,KAAK,GAAG;AAAA,MACzB;AAAA,MACA,OAAO,CAACC,MAAiB,aAAaA,CAAI;AAAA,IAAA;AAAA;AAAA,IAI5C,SAAS;AAAA,MACP,WAAWjB,EAAQ,YAAY,kBAAA;AAAA,MAC/B,SAAS;AAAA,MACT,MAAM;AAAA,MACN,KAAK;AAAA,IAAA;AAAA,EACP;AAEJ,GChDakB,KAAY,MAAM;AAC7B,QAAMC,IAAmBL,EAAA;AAEzB,SAAO;AAAA;AAAA,IAEL,SAASK,EAAiB,OAAO;AAAA,IACjC,QAAQA,EAAiB,OAAO;AAAA,IAChC,WAAWA,EAAiB,OAAO;AAAA;AAAA,IAGnC,GAAGA,EAAiB;AAAA;AAAA,IAGpB,iBAAiBA,EAAiB,gBAAA;AAAA,IAClC,iBAAiBA,EAAiB,gBAAA;AAAA,IAClC,mBAAmBA,EAAiB,kBAAA;AAAA,IACpC,iBAAiBA,EAAiB,gBAAA;AAAA;AAAA,IAGlC,MAAMA,EAAiB;AAAA;AAAA,IAGvB,SAASA,EAAiB;AAAA,EAAA;AAE9B,GCdaC,IAA8C;AAAA,EACzD,SAAS;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY,CAAC,cAAc,QAAQ;AAAA,IACnC,SAAS;AAAA,IACT,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,SAAS;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY,CAAC,SAAS;AAAA,IACtB,SAAS;AAAA,IACT,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,WAAW;AAAA,IACT,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY,CAAC,UAAU,WAAW,QAAQ;AAAA,IAC1C,SAAS;AAAA,IACT,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,SAAS;AAAA,IACP,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY,CAAA;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GAEaC,IAAiB,WACjBC,KAAoB,OAAO,KAAKF,CAAa,GCpCpDG,KAA8E,CAAC;AAAA,EACnF,UAAAvF;AAAA,EACA,eAAAwF;AAAA,EACA,mBAAAC;AACF,MAAM;AAEJ,QAAMC,IAAqB3E,GAAA,GAErB4E,IADmBF,IAAA,KACcC,GAIjC,CAACE,GAAeC,CAAgB,IAAI3E,EAAS,MAE7CsE,KAAiB,OAAOA,KAAkB,YAAYJ,EAAcI,CAAa,IAC5EA,IAEFH,CACR,GAEKS,IAAeV,EAAcQ,CAAa,KAAKR,EAAcC,CAAc,GAuB3EU,IAAe;AAAA,IACnB,YAAAJ;AAAA,IACA,QAAQ;AAAA,MACN,SAASC;AAAA,MACT,QAAQE;AAAA,MACR,WAAWD;AAAA,IAAA;AAAA,IAEb,aA5BkB;AAAA,MAClB,mBAAmB,MACbF,EAAW,WAAiBG,EAAa,WAAW,SACpDH,EAAW,WAAiBG,EAAa,WAAW,SACjDA,EAAa,WAAW;AAAA,MAGjC,cAAc,MAAM;AAClB,cAAME,IAAY;AAClB,eAAIJ,MAAkB,aAAaA,MAAkB,cAC5C,GAAGI,CAAS,UAEdA;AAAA,MACT;AAAA,MAEA,YAAY,MAAMJ,MAAkB,aAAaA,MAAkB;AAAA,MACnE,WAAW,MAAMA,MAAkB;AAAA,MACnC,WAAW,MAAMA,MAAkB,aAAaA,MAAkB;AAAA,MAClE,eAAe,MAAMA,MAAkB;AAAA,IAAA;AAAA,EAUvC;AAGF,2BACG/B,EAAwB,UAAxB,EAAiC,OAAOkC,GACtC,UAAA/F,GACH;AAEJ,GAEaiG,KAAoE,CAAC;AAAA,EAChF,UAAAjG;AAAA,EACA,eAAAwF,IAAgBH;AAAA,EAChB,mBAAAI;AACF,MAAM;AAEJ,QAAMS,IAA2BV,KAAiB,OAAOA,KAAkB,YAAYJ,EAAcI,CAAa,IAC9GA,IACAH;AAEJ,2BACGtF,IAAA,EACC,UAAA,gBAAAuE;AAAA,IAACiB;AAAA,IAAA;AAAA,MACC,eAAeW;AAAA,MACf,mBAAAT;AAAA,MAEC,UAAAzF;AAAA,IAAA;AAAA,EAAA,GAEL;AAEJ,GCtFMmG,KAAwC,CAAC,EAAE,UAAAnG,GAAU,QAAQoG,QAAiB;AAClF,QAAM,EAAE,QAAAC,EAAA,IAAWvB,EAAA,GAGbwB,IAAU;AAAA,IACd,SAASC;AAAA,IACT,SAASC;AAAA,IACT,WAAWC;AAAA,IACX,SAASC;AAAA,EAAA,GAILC,IAAcP,KAAcC,EAAO,WAAW,WAG9CO,IAA8BN,EAAQK,CAAmC,IAC3EA,IACA,WAGEE,IAAkBP,EAAQM,CAAmC,KAAKL;AAExE,SAAO,gBAAAjC,EAACuC,KAAiB,UAAA7G,GAAS;AACpC,GCtCM8G,KAAS,MAAM;AACnB,QAAM,EAAE,UAAA5E,EAAA,IAAa4C,EAAA,GACf,EAAE,aAAAF,GAAa,gBAAAC,EAAA,IAAmBJ,GAAA,GAClC,EAAE,aAAAL,GAAa,gBAAAC,EAAA,IAAmBE,EAAA,GAElCwC,IAAY;AAAA,IAChB,EAAE,IAAI,QAAQ,OAAO,gBAAA;AAAA,IACrB,EAAE,IAAI,QAAQ,OAAO,OAAA;AAAA,EAAO;AAG9B,SACE,gBAAAC,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,IAAA,gBAAA1C,EAAC,UAAA,EAAO,WAAU,wGAChB,UAAA,gBAAAA,EAAC,SAAI,WAAU,UACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,aACb,UAAA,gBAAA0C,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,+BAEZ,UAAA;AAAA,QAAA9E,KACC,gBAAAoC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAAS,MAAMD,EAAe,EAAI;AAAA,YAClC,WAAU;AAAA,YAEV,UAAA,gBAAAC,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACjE,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,2BAA0B,EAAA,CACjG;AAAA,UAAA;AAAA,QAAA;AAAA,QAIJ,gBAAA0C,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,UAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,kFAAA,CAAkF;AAAA,UACjG,gBAAAA,EAAC,MAAA,EAAG,WAAU,kDAAiD,UAAA,qBAAA,CAE/D;AAAA,QAAA,GACF;AAAA,QACA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uHAAsH,UAAA,YAAA,CAErI;AAAA,MAAA,GACF;AAAA,MAEA,gBAAAA,EAAC,SAAI,WAAU,+BAEZ,WAACpC,KAAY6E,EAAU,IAAI,CAACE,MAC3B,gBAAA3C;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,SAAS,MAAMO,EAAeoC,EAAK,EAAqB;AAAA,UACxD,WAAW,gFACTrC,MAAgBqC,EAAK,KACjB,oDACA,qFACN;AAAA,UAEC,UAAAA,EAAK;AAAA,QAAA;AAAA,QARDA,EAAK;AAAA,MAAA,CAUb,EAAA,CACH;AAAA,IAAA,GACF,EAAA,CACF,GACF,GACF;AAAA,IAGC/E,KAAYkC,KACX,gBAAAE,EAAC,SAAI,WAAU,kCAAiC,SAAS,MAAMD,EAAe,EAAK,GACjF,4BAAC,OAAA,EAAI,WAAU,sGACb,UAAA,gBAAA2C,EAAC,OAAA,EAAI,WAAU,kCAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,QAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,mEACb,UAAA,gBAAAA,EAAC,UAAK,WAAU,gCAA+B,gBAAE,EAAA,CACnD;AAAA,QACA,gBAAAA,EAAC,QAAA,EAAK,WAAU,gCAA+B,UAAA,qBAAA,CAAkB;AAAA,MAAA,GACnE;AAAA,wBAGC,OAAA,EAAI,WAAU,aACZ,UAAAyC,EAAU,IAAI,CAACG,MACd,gBAAA5C;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,SAAS,MAAM;AACb,YAAAO,EAAeqC,EAAK,EAAqB,GACzC7C,EAAe,EAAK;AAAA,UACtB;AAAA,UACA,WAAW,gFACTO,MAAgBsC,EAAK,KACjB,2DACA,wDACN;AAAA,UAEA,UAAA,gBAAA5C,EAAC,QAAA,EAAK,WAAU,eAAe,YAAK,MAAA,CAAM;AAAA,QAAA;AAAA,QAXrC4C,EAAK;AAAA,MAAA,CAab,EAAA,CACH;AAAA,IAAA,EAAA,CACF,GACF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ,GCnGMC,IAAU,MAAM;AACpB,QAAM,EAAE,UAAAjF,GAAU,UAAAC,EAAA,IAAa2C,EAAA,GACzB,EAAE,aAAAV,GAAa,gBAAAC,EAAA,IAAmBE,EAAA,GAElCwC,IAAY;AAAA,IAChB,EAAE,IAAI,QAAQ,OAAO,SAAA;AAAA,IACrB,EAAE,IAAI,SAAS,OAAO,SAAA;AAAA,IACtB,EAAE,IAAI,WAAW,OAAO,WAAA;AAAA,EAAW;AAGrC,SACE,gBAAAC,EAAAI,GAAA,EACG,UAAA;AAAA,IAAAlF,KACC,gBAAAoC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,MAAMD,EAAe,EAAI;AAAA,QAClC,WAAU;AAAA,QAEV,UAAA,gBAAAC,EAAC,SAAI,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACjE,4BAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,2BAA0B,EAAA,CACjG;AAAA,MAAA;AAAA,IAAA;AAAA,IAIJ,gBAAAA,EAAC,SAAA,EAAM,WAAW,wCAAwCpC,IAAW,WAAW,oBAAoB,IAAIC,IAAW,SAAS,MAAM,IAChI,UAAA,gBAAA6E,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,QAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,mEACb,UAAA,gBAAAA,EAAC,UAAK,WAAU,gCAA+B,gBAAE,EAAA,CACnD;AAAA,QACA,gBAAAA,EAAC,QAAA,EAAK,WAAU,gCAA+B,UAAA,gBAAA,CAAa;AAAA,MAAA,GAC9D;AAAA,wBAEC,OAAA,EAAI,WAAU,aACZ,UAAAyC,EAAU,IAAI,CAACG,MACd,gBAAA5C;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAU;AAAA,UAEV,UAAA,gBAAAA,EAAC,QAAA,EAAK,WAAU,eAAe,YAAK,MAAA,CAAM;AAAA,QAAA;AAAA,QAHrC4C,EAAK;AAAA,MAAA,CAKb,EAAA,CACH;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,IAEChF,KAAYkC,KACX,gBAAAE,EAAC,SAAI,WAAU,kCAAiC,SAAS,MAAMD,EAAe,EAAK,GACjF,4BAAC,OAAA,EAAI,WAAU,uEACb,UAAA,gBAAA2C,EAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oCACb,UAAA;AAAA,QAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,mEACb,UAAA,gBAAAA,EAAC,UAAK,WAAU,gCAA+B,gBAAE,EAAA,CACnD;AAAA,QACA,gBAAAA,EAAC,QAAA,EAAK,WAAU,gCAA+B,UAAA,gBAAA,CAAa;AAAA,MAAA,GAC9D;AAAA,wBAEC,OAAA,EAAI,WAAU,aACZ,UAAAyC,EAAU,IAAI,CAACG,MACd,gBAAA5C;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,SAAS,MAAMD,EAAe,EAAK;AAAA,UACnC,WAAU;AAAA,UAEV,UAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,eAAe,YAAK,MAAA,CAAM;AAAA,QAAA;AAAA,QAJrC4C,EAAK;AAAA,MAAA,CAMb,EAAA,CACH;AAAA,IAAA,EAAA,CACF,GACF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ,GC5EMG,IAAS,MAEX,gBAAA/C,EAAC,UAAA,EAAO,WAAU,wCAChB,4BAAC,OAAA,EAAI,WAAU,aACb,UAAA,gBAAAA,EAAC,SAAI,WAAU,iCACb,UAAA,gBAAA0C,EAAC,KAAA,EAAE,WAAU,yBAAwB,UAAA;AAAA,EAAA;AAAA,GAChC,oBAAI,KAAA,GAAO,YAAA;AAAA,EAAc;AAAA,GAC9B,EAAA,CACF,GACF,GACF,GCREM,KAAa,MAAM;AACvB,QAAM,EAAE,UAAApF,EAAA,IAAa4C,EAAA;AAErB,SACE,gBAAAR,EAAC,OAAA,EAAI,WAAU,0DACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,aACb,UAAA,gBAAA0C,EAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,MAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,mEACb,UAAA,gBAAAA,EAAC,UAAK,WAAU,gCAA+B,gBAAE,EAAA,CACnD;AAAA,MACA,gBAAAA,EAAC,MAAA,EAAG,WAAU,oCAAmC,UAAA,gBAAA,CAAa;AAAA,IAAA,GAChE;AAAA,IAECpC,KACC,gBAAAoC,EAAC,UAAA,EAAO,WAAU,sCAChB,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,WAAU,MAAK,QAAO,QAAO,gBAAe,SAAQ,aACjE,UAAA,gBAAAA,EAAC,QAAA,EAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,0BAAA,CAA0B,EAAA,CACjG,EAAA,CACF;AAAA,EAAA,EAAA,CAEJ,GACF,GACF;AAEJ,GCpBMiC,IAA8C,CAAC,EAAE,UAAAvG,QAEnD,gBAAAgH,EAAC,OAAA,EAAI,WAAU,yCAEb,UAAA;AAAA,EAAA,gBAAA1C,EAACgD,IAAA,EAAW;AAAA,EAGZ,gBAAAhD,EAAC,QAAA,EAAK,WAAU,UACX,UAAAtE,EAAA,CACL;AAAA,oBAGCqH,GAAA,CAAA,CAAO;AAAA,GACV,GCZEE,KAAgE,CAAC,EAAE,UAAAvH,QAErE,gBAAAgH,EAAC,OAAA,EAAI,WAAU,gCAEb,UAAA;AAAA,EAAA,gBAAA1C,EAAC6C,GAAA,EAAQ;AAAA,EAGT,gBAAA7C,EAAC,QAAA,EAAK,WAAU,wBACX,UAAAtE,EAAA,CACL;AAAA,GACF,GAIEwG,KAA8C,CAAC,EAAE,UAAAxG,QAEnD,gBAAAsE,EAACH,GAAA,EACC,UAAA,gBAAAG,EAACiD,IAAA,EAAsB,UAAAvH,GAAS,GAClC,GClBEwH,KAAkE,CAAC,EAAE,UAAAxH,0BAEtE,OAAA,EAAI,WAAU,yCAEb,UAAA,gBAAAgH,EAAC,OAAA,EAAI,WAAU,eAEb,UAAA;AAAA,EAAA,gBAAA1C,EAAC6C,GAAA,EAAQ;AAAA,EAGT,gBAAAH,EAAC,QAAA,EAAK,WAAU,sCACd,UAAA;AAAA,IAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,UACZ,UAAAtE,EAAA,CACH;AAAA,sBAGCqH,GAAA,CAAA,CAAO;AAAA,EAAA,EAAA,CACV;AAAA,EAAA,CACF,EAAA,CACF,GAIEZ,KAAkD,CAAC,EAAE,UAAAzG,QAEvD,gBAAAsE,EAACH,GAAA,EACC,UAAA,gBAAAG,EAACkD,IAAA,EAAwB,UAAAxH,GAAS,GACpC,GC5BE0G,KAA8C,CAAC,EAAE,UAAA1G,0BAElD,OAAA,EAAI,WAAU,2BACb,UAAA,gBAAAsE,EAAC,QAAA,EACE,UAAAtE,GACH,EAAA,CACF,GCLEyH,KAAiB,CAAC,EAAE,SAAAC,IAAU,SAAiC;AACnE,QAAM,EAAE,SAAAxE,GAAS,WAAAyE,GAAW,QAAAC,EAAA,IAAW1C,GAAA;AAEvC,SAAIwC,IAEA,gBAAAV,EAAC,OAAA,EAAI,WAAU,qDACb,UAAA;AAAA,IAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,WAAO;AAAA,IACnD,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAOpB;AAAA,QACP,UAAU,CAAC2E,MAAMF,EAAUE,EAAE,OAAO,KAAK;AAAA,QACzC,WAAU;AAAA,QAET,iBAAO,QAAQzC,CAAa,EAAE,IAAI,CAAC,CAAC0C,GAAKhC,CAAY,wBACnD,UAAA,EAAiB,OAAOgC,GACtB,UAAAhC,EAAa,KAAA,GADHgC,CAEb,CACD;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF,IAKF,gBAAAd,EAAC,OAAA,EAAI,WAAU,yEACb,UAAA;AAAA,IAAA,gBAAA1C,EAAC,MAAA,EAAG,WAAU,iCAAgC,UAAA,kBAAc;AAAA,IAE5D,gBAAAA,EAAC,OAAA,EAAI,WAAU,wDACZ,UAAA,OAAO,QAAQc,CAAa,EAAE,IAAI,CAAC,CAAC0C,GAAKhC,CAAY,MACpD,gBAAAkB;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,SAAS,MAAMW,EAAUG,CAAG;AAAA,QAC5B,WAAW;AAAA;AAAA,gBAEP5E,MAAY4E,IACV,iDACA,iEACJ;AAAA;AAAA,QAGF,UAAA;AAAA,UAAA,gBAAAxD,EAAC,OAAA,EAAI,WAAU,sBAAsB,UAAAwB,EAAa,MAAK;AAAA,UACvD,gBAAAxB,EAAC,OAAA,EAAI,WAAU,sBAAsB,YAAa,YAAA,CAAY;AAAA,QAAA;AAAA,MAAA;AAAA,MAXzDwD;AAAA,IAAA,CAaR,GACH;AAAA,IAEA,gBAAAd,EAAC,OAAA,EAAI,WAAU,sCACb,UAAA;AAAA,MAAA,gBAAA1C,EAAC,OAAA,EAAI,WAAU,8BAA6B,UAAA,kBAAc;AAAA,MAC1D,gBAAAA,EAAC,OAAA,EAAI,WAAU,qCAAqC,YAAO,MAAK;AAAA,MAChE,gBAAAA,EAAC,OAAA,EAAI,WAAU,yBAAyB,YAAO,YAAA,CAAY;AAAA,IAAA,EAAA,CAC7D;AAAA,EAAA,GACF;AAEJ;"}
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -610,21 +610,143 @@ export default {
|
|
|
610
610
|
console.log(' ✅ Creado: index.html')
|
|
611
611
|
}
|
|
612
612
|
|
|
613
|
-
// Crear
|
|
613
|
+
// Crear layout local según el seleccionado
|
|
614
|
+
const layoutsDir = path.join(projectRoot, 'src', 'layouts')
|
|
615
|
+
if (!fs.existsSync(layoutsDir)) {
|
|
616
|
+
fs.mkdirSync(layoutsDir, { recursive: true })
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Generar layout local que use los componentes locales
|
|
620
|
+
let layoutContent = ''
|
|
621
|
+
if (selectedLayout === 'default') {
|
|
622
|
+
layoutContent = `import React from 'react'
|
|
623
|
+
import { Navigation, Footer } from '../components/layout'
|
|
624
|
+
|
|
625
|
+
interface DefaultLayoutProps {
|
|
626
|
+
children: React.ReactNode
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
|
|
630
|
+
return (
|
|
631
|
+
<div className="min-h-screen bg-gray-50 flex flex-col">
|
|
632
|
+
<Navigation />
|
|
633
|
+
<main className="flex-1">
|
|
634
|
+
{children}
|
|
635
|
+
</main>
|
|
636
|
+
<Footer />
|
|
637
|
+
</div>
|
|
638
|
+
)
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
export default DefaultLayout
|
|
642
|
+
`
|
|
643
|
+
} else if (selectedLayout === 'sidebar') {
|
|
644
|
+
layoutContent = `import React from 'react'
|
|
645
|
+
import { Sidebar } from '../components/layout'
|
|
646
|
+
import { SidebarProvider } from 'responsive-system'
|
|
647
|
+
|
|
648
|
+
interface SidebarLayoutProps {
|
|
649
|
+
children: React.ReactNode
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const SidebarLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
653
|
+
return (
|
|
654
|
+
<div className="min-h-screen bg-gray-50 flex">
|
|
655
|
+
<Sidebar />
|
|
656
|
+
<main className="flex-1 overflow-auto">
|
|
657
|
+
{children}
|
|
658
|
+
</main>
|
|
659
|
+
</div>
|
|
660
|
+
)
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const SidebarLayout: React.FC<SidebarLayoutProps> = ({ children }) => {
|
|
664
|
+
return (
|
|
665
|
+
<SidebarProvider>
|
|
666
|
+
<SidebarLayoutContent>{children}</SidebarLayoutContent>
|
|
667
|
+
</SidebarProvider>
|
|
668
|
+
)
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
export default SidebarLayout
|
|
672
|
+
`
|
|
673
|
+
} else if (selectedLayout === 'dashboard') {
|
|
674
|
+
layoutContent = `import React from 'react'
|
|
675
|
+
import { Sidebar, Footer } from '../components/layout'
|
|
676
|
+
import { SidebarProvider } from 'responsive-system'
|
|
677
|
+
|
|
678
|
+
interface DashboardLayoutProps {
|
|
679
|
+
children: React.ReactNode
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
const DashboardLayoutContent: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
683
|
+
return (
|
|
684
|
+
<div className="min-h-screen bg-gray-50 flex flex-col">
|
|
685
|
+
<div className="flex flex-1">
|
|
686
|
+
<Sidebar />
|
|
687
|
+
<main className="flex-1 overflow-auto flex flex-col">
|
|
688
|
+
<div className="flex-1">
|
|
689
|
+
{children}
|
|
690
|
+
</div>
|
|
691
|
+
<Footer />
|
|
692
|
+
</main>
|
|
693
|
+
</div>
|
|
694
|
+
</div>
|
|
695
|
+
)
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
const DashboardLayout: React.FC<DashboardLayoutProps> = ({ children }) => {
|
|
699
|
+
return (
|
|
700
|
+
<SidebarProvider>
|
|
701
|
+
<DashboardLayoutContent>{children}</DashboardLayoutContent>
|
|
702
|
+
</SidebarProvider>
|
|
703
|
+
)
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
export default DashboardLayout
|
|
707
|
+
`
|
|
708
|
+
} else { // minimal
|
|
709
|
+
layoutContent = `import React from 'react'
|
|
710
|
+
|
|
711
|
+
interface MinimalLayoutProps {
|
|
712
|
+
children: React.ReactNode
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const MinimalLayout: React.FC<MinimalLayoutProps> = ({ children }) => {
|
|
716
|
+
return (
|
|
717
|
+
<div className="min-h-screen bg-gray-50">
|
|
718
|
+
<main>
|
|
719
|
+
{children}
|
|
720
|
+
</main>
|
|
721
|
+
</div>
|
|
722
|
+
)
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
export default MinimalLayout
|
|
726
|
+
`
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const layoutPath = path.join(layoutsDir, `${selectedLayout.charAt(0).toUpperCase() + selectedLayout.slice(1)}Layout.tsx`)
|
|
730
|
+
fs.writeFileSync(layoutPath, layoutContent)
|
|
731
|
+
console.log(` ✅ Creado: src/layouts/${path.basename(layoutPath)}`)
|
|
732
|
+
|
|
733
|
+
// Crear src/main.tsx que use el layout local
|
|
614
734
|
const mainTsxPath = path.join(projectRoot, 'src', 'main.tsx')
|
|
615
735
|
if (!fs.existsSync(mainTsxPath)) {
|
|
736
|
+
const layoutName = selectedLayout.charAt(0).toUpperCase() + selectedLayout.slice(1) + 'Layout'
|
|
616
737
|
const mainTsx = `import React from 'react'
|
|
617
738
|
import ReactDOM from 'react-dom/client'
|
|
618
|
-
import { ResponsiveLayoutProvider
|
|
739
|
+
import { ResponsiveLayoutProvider } from 'responsive-system'
|
|
740
|
+
import ${layoutName} from './layouts/${layoutName}'
|
|
619
741
|
import App from './App'
|
|
620
742
|
import './index.css'
|
|
621
743
|
|
|
622
744
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
623
745
|
<React.StrictMode>
|
|
624
746
|
<ResponsiveLayoutProvider defaultLayout="${selectedLayout}">
|
|
625
|
-
|
|
747
|
+
<${layoutName}>
|
|
626
748
|
<App />
|
|
627
|
-
|
|
749
|
+
</${layoutName}>
|
|
628
750
|
</ResponsiveLayoutProvider>
|
|
629
751
|
</React.StrictMode>,
|
|
630
752
|
)
|
|
@@ -24,7 +24,27 @@ console.log('')
|
|
|
24
24
|
// Limpiar directorio de prueba si existe
|
|
25
25
|
if (fs.existsSync(testDir)) {
|
|
26
26
|
console.log('🧹 Limpiando directorio de prueba anterior...')
|
|
27
|
-
|
|
27
|
+
try {
|
|
28
|
+
fs.rmSync(testDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 1000 })
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.log(' ⚠️ No se pudo limpiar completamente, continuando...')
|
|
31
|
+
// Intentar eliminar solo los archivos importantes
|
|
32
|
+
try {
|
|
33
|
+
const importantFiles = ['package.json', 'src', 'vite.config.ts', 'tailwind.config.js', 'postcss.config.js', 'tsconfig.json', 'tsconfig.node.json', 'index.html']
|
|
34
|
+
importantFiles.forEach(file => {
|
|
35
|
+
const filePath = path.join(testDir, file)
|
|
36
|
+
if (fs.existsSync(filePath)) {
|
|
37
|
+
try {
|
|
38
|
+
fs.rmSync(filePath, { recursive: true, force: true })
|
|
39
|
+
} catch (e) {
|
|
40
|
+
// Ignorar errores individuales
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
} catch (e) {
|
|
45
|
+
// Continuar de todas formas
|
|
46
|
+
}
|
|
47
|
+
}
|
|
28
48
|
}
|
|
29
49
|
|
|
30
50
|
// Crear directorio de prueba
|