responsive-system 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "responsive-system",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Sistema de layout responsivo con auto-scaling para Tailwind CSS",
5
5
  "type": "module",
6
6
  "main": "./dist/responsive-system.cjs",
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Script postinstall para automatizar la configuración inicial
5
- * Instala React y Tailwind si no están presentes
4
+ * Script postinstall para automatizar la configuración inicial completa
5
+ * - Instala React, TypeScript, Tailwind automáticamente
6
+ * - Inicializa proyecto Vite si está vacío
7
+ * - Configura Tailwind
8
+ * - Crea página de ejemplo con layouts
6
9
  */
7
10
 
8
11
  import fs from 'fs'
@@ -23,90 +26,366 @@ if (!fs.existsSync(packageJsonPath)) {
23
26
  }
24
27
 
25
28
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
26
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies }
27
29
 
28
- // Verificar si React está instalado (solo en proyecto raíz, no en subdirectorios)
30
+ // Verificar si el proyecto está vacío (solo tiene responsive-system)
31
+ const isProjectEmpty = !packageJson.dependencies ||
32
+ Object.keys(packageJson.dependencies).length === 0 ||
33
+ (Object.keys(packageJson.dependencies).length === 1 && packageJson.dependencies['responsive-system'])
34
+
35
+ // Verificar qué está instalado
29
36
  const hasReact = (packageJson.dependencies && packageJson.dependencies.react) ||
30
37
  (packageJson.devDependencies && packageJson.devDependencies.react) ||
31
38
  fs.existsSync(path.join(projectRoot, 'node_modules', 'react'))
32
-
33
- const hasTailwind = (packageJson.dependencies && packageJson.dependencies.tailwindcss) ||
34
- (packageJson.devDependencies && packageJson.devDependencies.tailwindcss) ||
35
- fs.existsSync(path.join(projectRoot, 'node_modules', 'tailwindcss'))
36
-
37
- const hasTypeScript = (packageJson.dependencies && packageJson.dependencies.typescript) ||
38
- (packageJson.devDependencies && packageJson.devDependencies.typescript) ||
39
- fs.existsSync(path.join(projectRoot, 'node_modules', 'typescript'))
40
-
41
- let needsInstall = false
42
- const packagesToInstall = []
43
39
 
40
+ const hasVite = (packageJson.devDependencies && packageJson.devDependencies.vite) ||
41
+ fs.existsSync(path.join(projectRoot, 'node_modules', 'vite'))
42
+
43
+ const tailwindInDevDeps = packageJson.devDependencies && packageJson.devDependencies.tailwindcss
44
+ const typescriptInDevDeps = packageJson.devDependencies && packageJson.devDependencies.typescript
45
+
46
+ // Separar paquetes: React (dependencies) vs TypeScript/Tailwind/Vite (devDependencies)
47
+ const reactPackages = []
48
+ const devPackages = []
49
+
50
+ // React
44
51
  if (!hasReact) {
45
- packagesToInstall.push('react@^19.1.1', 'react-dom@^19.1.1')
46
- needsInstall = true
52
+ reactPackages.push('react@^19.1.1', 'react-dom@^19.1.1')
47
53
  }
48
54
 
49
- // Siempre instalar Tailwind en el proyecto raíz (aunque esté en responsive-system)
50
- // Verificar específicamente en node_modules del proyecto raíz y en devDependencies
51
- const tailwindInRoot = fs.existsSync(path.join(projectRoot, 'node_modules', 'tailwindcss'))
52
- const tailwindInDevDeps = packageJson.devDependencies && packageJson.devDependencies.tailwindcss
55
+ // Vite (si el proyecto está vacío)
56
+ if (isProjectEmpty && !hasVite) {
57
+ devPackages.push('vite@^7.1.7', '@vitejs/plugin-react@^5.0.4')
58
+ }
53
59
 
54
- if (!tailwindInRoot || !tailwindInDevDeps) {
55
- // Instalar como devDependencies para que npx funcione
56
- packagesToInstall.push('tailwindcss@^4.1.14', 'postcss@^8.5.6', 'autoprefixer@^10.4.21')
57
- needsInstall = true
60
+ // TypeScript y Tailwind
61
+ if (!tailwindInDevDeps) {
62
+ devPackages.push('tailwindcss@^4.1.14', 'postcss@^8.5.6', 'autoprefixer@^10.4.21')
58
63
  }
59
64
 
60
- if (!hasTypeScript) {
61
- packagesToInstall.push('typescript@~5.9.3')
62
- needsInstall = true
65
+ if (!typescriptInDevDeps) {
66
+ devPackages.push('typescript@~5.9.3', '@types/react@^19.1.16', '@types/react-dom@^19.1.9')
63
67
  }
64
68
 
65
- if (needsInstall && packagesToInstall.length > 0) {
66
- console.log('📦 responsive-system: Instalando dependencias faltantes...')
67
- console.log(` Instalando: ${packagesToInstall.join(', ')}`)
68
-
69
+ // Instalar React como dependencies (se necesita en runtime)
70
+ if (reactPackages.length > 0) {
71
+ console.log('📦 responsive-system: Instalando React...')
72
+ console.log(` Instalando: ${reactPackages.join(', ')}`)
69
73
  try {
70
- // Separar paquetes: React (dependencies) vs TypeScript/Tailwind (devDependencies)
71
- const reactPackages = packagesToInstall.filter(pkg => pkg.includes('react'))
72
- const devPackages = packagesToInstall.filter(pkg =>
73
- pkg.includes('typescript') ||
74
- pkg.includes('tailwind') ||
75
- pkg.includes('postcss') ||
76
- pkg.includes('autoprefixer')
77
- )
78
-
79
- // Instalar React como dependencies (se necesita en runtime)
80
- if (reactPackages.length > 0) {
81
- execSync(`npm install ${reactPackages.join(' ')}`, {
82
- stdio: 'inherit',
83
- cwd: projectRoot
84
- })
85
- }
86
-
87
- // Instalar TypeScript y Tailwind como devDependencies (para que npx funcione)
88
- // Usar --force para asegurar que se instalen en el proyecto raíz
89
- if (devPackages.length > 0) {
90
- execSync(`npm install ${devPackages.join(' ')} --save-dev --force`, {
91
- stdio: 'inherit',
92
- cwd: projectRoot
93
- })
94
- }
95
-
96
- console.log('✅ responsive-system: Dependencias instaladas correctamente')
74
+ execSync(`npm install ${reactPackages.join(' ')}`, {
75
+ stdio: 'inherit',
76
+ cwd: projectRoot
77
+ })
78
+ console.log('✅ responsive-system: React instalado correctamente')
97
79
  } catch (error) {
98
- console.warn('⚠️ responsive-system: Error al instalar dependencias automáticamente')
99
- console.warn(' Por favor, instala manualmente:')
100
- console.warn(` npm install ${packagesToInstall.join(' ')}`)
80
+ console.warn('⚠️ responsive-system: Error al instalar React')
101
81
  }
102
- } else {
103
- console.log('✅ responsive-system: Todas las dependencias están instaladas')
104
82
  }
105
83
 
106
- // Verificar si tailwind.config.js existe
107
- const tailwindConfigPath = path.join(projectRoot, 'tailwind.config.js')
108
- if (!fs.existsSync(tailwindConfigPath)) {
109
- console.log('💡 responsive-system: No se encontró tailwind.config.js')
110
- console.log(' Ejecuta: npx tailwindcss init -p')
84
+ // Instalar TypeScript, Tailwind y Vite como devDependencies
85
+ if (devPackages.length > 0) {
86
+ console.log('📦 responsive-system: Instalando TypeScript, Tailwind y Vite...')
87
+ console.log(` Instalando: ${devPackages.join(', ')}`)
88
+ try {
89
+ execSync(`npm install ${devPackages.join(' ')} --save-dev`, {
90
+ stdio: 'inherit',
91
+ cwd: projectRoot
92
+ })
93
+ console.log('✅ responsive-system: Dependencias de desarrollo instaladas correctamente')
94
+ } catch (error) {
95
+ console.warn('⚠️ responsive-system: Error al instalar dependencias de desarrollo')
96
+ }
97
+ }
98
+
99
+ // Si el proyecto está vacío, crear estructura base
100
+ if (isProjectEmpty) {
101
+ console.log('📦 responsive-system: Proyecto vacío detectado, creando estructura base...')
102
+
103
+ // Crear estructura de directorios
104
+ const dirs = ['src', 'src/components', 'src/pages', 'public']
105
+ dirs.forEach(dir => {
106
+ const dirPath = path.join(projectRoot, dir)
107
+ if (!fs.existsSync(dirPath)) {
108
+ fs.mkdirSync(dirPath, { recursive: true })
109
+ }
110
+ })
111
+
112
+ // Crear vite.config.ts
113
+ const viteConfigPath = path.join(projectRoot, 'vite.config.ts')
114
+ if (!fs.existsSync(viteConfigPath)) {
115
+ const viteConfig = `import { defineConfig } from 'vite'
116
+ import react from '@vitejs/plugin-react'
117
+ import responsiveScalePlugin from 'responsive-system/plugin'
118
+
119
+ export default defineConfig({
120
+ plugins: [react()],
121
+ })
122
+ `
123
+ fs.writeFileSync(viteConfigPath, viteConfig)
124
+ console.log('✅ responsive-system: vite.config.ts creado')
125
+ }
126
+
127
+ // Crear tailwind.config.js
128
+ const tailwindConfigPath = path.join(projectRoot, 'tailwind.config.js')
129
+ if (!fs.existsSync(tailwindConfigPath)) {
130
+ const tailwindConfig = `import responsiveScalePlugin from 'responsive-system/plugin'
131
+
132
+ export default {
133
+ content: [
134
+ "./index.html",
135
+ "./src/**/*.{js,ts,jsx,tsx}",
136
+ ],
137
+ theme: {
138
+ extend: {
139
+ screens: {
140
+ 'xs': '475px', 'sm': '640px', 'md': '768px', 'lg': '1024px',
141
+ 'xl': '1280px', '2xl': '1536px', '3xl': '1920px', '4xl': '2560px', '5xl': '3840px'
142
+ }
143
+ },
144
+ },
145
+ plugins: [
146
+ responsiveScalePlugin({
147
+ scaleProperties: {
148
+ typography: true,
149
+ spacing: true,
150
+ lineHeight: true,
151
+ letterSpacing: true,
152
+ shadows: true,
153
+ borderWidth: false,
154
+ sizing: false,
155
+ borderRadius: false
156
+ },
157
+ scales: {
158
+ xs: 1.0, sm: 1.0, md: 1.0, lg: 1.0, xl: 1.0,
159
+ '2xl': 1.05, '3xl': 1.15, '4xl': 1.25, '5xl': 1.35
160
+ }
161
+ })
162
+ ],
163
+ }
164
+ `
165
+ fs.writeFileSync(tailwindConfigPath, tailwindConfig)
166
+ console.log('✅ responsive-system: tailwind.config.js creado')
167
+ }
168
+
169
+ // Crear postcss.config.js
170
+ const postcssConfigPath = path.join(projectRoot, 'postcss.config.js')
171
+ if (!fs.existsSync(postcssConfigPath)) {
172
+ const postcssConfig = `export default {
173
+ plugins: {
174
+ tailwindcss: {},
175
+ autoprefixer: {},
176
+ },
177
+ }
178
+ `
179
+ fs.writeFileSync(postcssConfigPath, postcssConfig)
180
+ console.log('✅ responsive-system: postcss.config.js creado')
181
+ }
182
+
183
+ // Crear tsconfig.json
184
+ const tsconfigPath = path.join(projectRoot, 'tsconfig.json')
185
+ if (!fs.existsSync(tsconfigPath)) {
186
+ const tsconfig = `{
187
+ "compilerOptions": {
188
+ "target": "ES2020",
189
+ "useDefineForClassFields": true,
190
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
191
+ "module": "ESNext",
192
+ "skipLibCheck": true,
193
+ "moduleResolution": "bundler",
194
+ "allowImportingTsExtensions": true,
195
+ "resolveJsonModule": true,
196
+ "isolatedModules": true,
197
+ "noEmit": true,
198
+ "jsx": "react-jsx",
199
+ "strict": true,
200
+ "noUnusedLocals": true,
201
+ "noUnusedParameters": true,
202
+ "noFallthroughCasesInSwitch": true
203
+ },
204
+ "include": ["src"],
205
+ "references": [{ "path": "./tsconfig.node.json" }]
206
+ }
207
+ `
208
+ fs.writeFileSync(tsconfigPath, tsconfig)
209
+ console.log('✅ responsive-system: tsconfig.json creado')
210
+ }
211
+
212
+ // Crear tsconfig.node.json
213
+ const tsconfigNodePath = path.join(projectRoot, 'tsconfig.node.json')
214
+ if (!fs.existsSync(tsconfigNodePath)) {
215
+ const tsconfigNode = `{
216
+ "compilerOptions": {
217
+ "composite": true,
218
+ "skipLibCheck": true,
219
+ "module": "ESNext",
220
+ "moduleResolution": "bundler",
221
+ "allowSyntheticDefaultImports": true
222
+ },
223
+ "include": ["vite.config.ts"]
224
+ }
225
+ `
226
+ fs.writeFileSync(tsconfigNodePath, tsconfigNode)
227
+ }
228
+
229
+ // Crear index.html
230
+ const indexHtmlPath = path.join(projectRoot, 'index.html')
231
+ if (!fs.existsSync(indexHtmlPath)) {
232
+ const indexHtml = `<!doctype html>
233
+ <html lang="es">
234
+ <head>
235
+ <meta charset="UTF-8" />
236
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
237
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
238
+ <title>Responsive System Demo</title>
239
+ </head>
240
+ <body>
241
+ <div id="root"></div>
242
+ <script type="module" src="/src/main.tsx"></script>
243
+ </body>
244
+ </html>
245
+ `
246
+ fs.writeFileSync(indexHtmlPath, indexHtml)
247
+ console.log('✅ responsive-system: index.html creado')
248
+ }
249
+
250
+ // Crear src/main.tsx
251
+ const mainTsxPath = path.join(projectRoot, 'src', 'main.tsx')
252
+ if (!fs.existsSync(mainTsxPath)) {
253
+ const mainTsx = `import React from 'react'
254
+ import ReactDOM from 'react-dom/client'
255
+ import { ResponsiveLayoutProvider, MainLayout } from 'responsive-system'
256
+ import App from './App'
257
+ import './index.css'
258
+
259
+ ReactDOM.createRoot(document.getElementById('root')!).render(
260
+ <React.StrictMode>
261
+ <ResponsiveLayoutProvider defaultLayout="default">
262
+ <MainLayout>
263
+ <App />
264
+ </MainLayout>
265
+ </ResponsiveLayoutProvider>
266
+ </React.StrictMode>,
267
+ )
268
+ `
269
+ fs.writeFileSync(mainTsxPath, mainTsx)
270
+ console.log('✅ responsive-system: src/main.tsx creado')
271
+ }
272
+
273
+ // Crear src/index.css
274
+ const indexCssPath = path.join(projectRoot, 'src', 'index.css')
275
+ if (!fs.existsSync(indexCssPath)) {
276
+ const indexCss = `@tailwind base;
277
+ @tailwind components;
278
+ @tailwind utilities;
279
+ `
280
+ fs.writeFileSync(indexCssPath, indexCss)
281
+ console.log('✅ responsive-system: src/index.css creado')
282
+ }
283
+
284
+ // Crear src/App.tsx con página de ejemplo
285
+ const appTsxPath = path.join(projectRoot, 'src', 'App.tsx')
286
+ if (!fs.existsSync(appTsxPath)) {
287
+ const appTsx = `import { useResponsiveLayout, LayoutSwitcher } from 'responsive-system'
288
+
289
+ function App() {
290
+ const { breakpoint, isMobile, layout } = useResponsiveLayout()
291
+
292
+ return (
293
+ <div className="min-h-screen bg-gray-50 p-6">
294
+ <div className="max-w-7xl mx-auto space-y-6">
295
+ {/* Header con información del sistema */}
296
+ <div className="bg-white rounded-lg shadow-lg p-6">
297
+ <h1 className="text-4xl font-bold mb-4">Responsive System Demo</h1>
298
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
299
+ <div className="p-4 bg-blue-50 rounded">
300
+ <p className="text-sm text-gray-600">Breakpoint actual</p>
301
+ <p className="text-2xl font-bold">{breakpoint}</p>
302
+ </div>
303
+ <div className="p-4 bg-green-50 rounded">
304
+ <p className="text-sm text-gray-600">Layout actual</p>
305
+ <p className="text-2xl font-bold capitalize">{layout.current}</p>
306
+ </div>
307
+ <div className="p-4 bg-purple-50 rounded">
308
+ <p className="text-sm text-gray-600">Dispositivo</p>
309
+ <p className="text-2xl font-bold">{isMobile ? 'Móvil' : 'Desktop'}</p>
310
+ </div>
311
+ </div>
312
+ </div>
313
+
314
+ {/* Selector de layouts */}
315
+ <div className="bg-white rounded-lg shadow-lg p-6">
316
+ <h2 className="text-2xl font-bold mb-4">Cambiar Layout</h2>
317
+ <LayoutSwitcher />
318
+ </div>
319
+
320
+ {/* Cards de ejemplo */}
321
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
322
+ {[1, 2, 3, 4, 5, 6].map((i) => (
323
+ <div key={i} className="bg-white rounded-lg shadow-lg p-6">
324
+ <h3 className="text-xl font-bold mb-2">Card {i}</h3>
325
+ <p className="text-gray-600">
326
+ Este es un ejemplo de card que escala automáticamente según el tamaño de pantalla.
327
+ Todo el texto, espaciado y sombras se ajustan automáticamente.
328
+ </p>
329
+ </div>
330
+ ))}
331
+ </div>
332
+
333
+ {/* Información */}
334
+ <div className="bg-white rounded-lg shadow-lg p-6">
335
+ <h2 className="text-2xl font-bold mb-4">Cómo funciona</h2>
336
+ <ul className="space-y-2 text-gray-700">
337
+ <li>✅ <strong>Auto-scaling:</strong> Todo escala automáticamente (texto, espaciado, sombras)</li>
338
+ <li>✅ <strong>Layouts:</strong> Cambia entre default, sidebar, dashboard y minimal</li>
339
+ <li>✅ <strong>Responsive:</strong> Se adapta automáticamente a todos los tamaños de pantalla</li>
340
+ <li>✅ <strong>Sin media queries:</strong> Usa el hook useResponsive para lógica condicional</li>
341
+ </ul>
342
+ </div>
343
+ </div>
344
+ </div>
345
+ )
111
346
  }
112
347
 
348
+ export default App
349
+ `
350
+ fs.writeFileSync(appTsxPath, appTsx)
351
+ console.log('✅ responsive-system: src/App.tsx creado con página de ejemplo')
352
+ }
353
+
354
+ // Actualizar package.json con scripts
355
+ if (!packageJson.scripts) {
356
+ packageJson.scripts = {}
357
+ }
358
+ if (!packageJson.scripts.dev) {
359
+ packageJson.scripts.dev = 'vite'
360
+ }
361
+ if (!packageJson.scripts.build) {
362
+ packageJson.scripts.build = 'tsc && vite build'
363
+ }
364
+ if (!packageJson.scripts.preview) {
365
+ packageJson.scripts.preview = 'vite preview'
366
+ }
367
+
368
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
369
+ console.log('✅ responsive-system: package.json actualizado con scripts')
370
+
371
+ console.log('')
372
+ console.log('🎉 responsive-system: Proyecto inicializado correctamente!')
373
+ console.log('')
374
+ console.log('Para empezar:')
375
+ console.log(' 1. npm run dev')
376
+ console.log(' 2. Abre http://localhost:5173')
377
+ console.log('')
378
+ }
379
+
380
+ if (reactPackages.length === 0 && devPackages.length === 0 && !isProjectEmpty) {
381
+ console.log('✅ responsive-system: Todas las dependencias están instaladas')
382
+ }
383
+
384
+ // Verificar si tailwind.config.js existe (solo si no es proyecto vacío)
385
+ if (!isProjectEmpty) {
386
+ const tailwindConfigPath = path.join(projectRoot, 'tailwind.config.js')
387
+ if (!fs.existsSync(tailwindConfigPath)) {
388
+ console.log('💡 responsive-system: No se encontró tailwind.config.js')
389
+ console.log(' Ejecuta: npx tailwindcss init -p')
390
+ }
391
+ }