slicejs-web-framework 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/index.js +130 -97
- package/package.json +1 -1
- package/src/Components/AppComponents/HomePage/HomePage.js +195 -195
- package/src/Components/components.js +27 -27
- package/src/sliceConfig.json +5 -6
- package/src/testing.js +888 -0
package/api/index.js
CHANGED
|
@@ -12,131 +12,164 @@ let server;
|
|
|
12
12
|
|
|
13
13
|
const app = express();
|
|
14
14
|
|
|
15
|
-
//
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
// Parsear argumentos de línea de comandos
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
let runMode = 'development'; // Default
|
|
18
|
+
|
|
19
|
+
// Detectar modo basado en argumentos
|
|
20
|
+
if (args.includes('--production') || args.includes('--prod')) {
|
|
21
|
+
runMode = 'production';
|
|
22
|
+
} else if (args.includes('--development') || args.includes('--dev')) {
|
|
23
|
+
runMode = 'development';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// También mantener compatibilidad con NODE_ENV como fallback
|
|
27
|
+
if (!args.length) {
|
|
28
|
+
const NODE_ENV = process.env.NODE_ENV || 'development';
|
|
29
|
+
runMode = NODE_ENV === 'production' ? 'production' : 'development';
|
|
30
|
+
}
|
|
19
31
|
|
|
20
|
-
//
|
|
21
|
-
|
|
32
|
+
// Obtener puerto desde sliceConfig.json, con fallback a process.env.PORT
|
|
33
|
+
const PORT = sliceConfig.server?.port || process.env.PORT || 3001;
|
|
34
|
+
|
|
35
|
+
// Determinar directorio a servir basado en argumentos
|
|
22
36
|
let folderDeployed;
|
|
23
|
-
if (
|
|
37
|
+
if (runMode === 'production') {
|
|
24
38
|
folderDeployed = 'dist';
|
|
25
|
-
} else if (NODE_ENV === 'development') {
|
|
26
|
-
folderDeployed = 'src';
|
|
27
39
|
} else {
|
|
28
|
-
|
|
29
|
-
const isProduction = sliceConfig.production === true;
|
|
30
|
-
folderDeployed = isProduction ? 'dist' : 'src';
|
|
40
|
+
folderDeployed = 'src';
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
console.log(`🚀 Starting Slice.js server in ${runMode} mode`);
|
|
44
|
+
console.log(`📁 Serving files from: /${folderDeployed}`);
|
|
35
45
|
|
|
36
|
-
//
|
|
37
|
-
app.
|
|
38
|
-
res.send(` Actual route in server: __dirname: ${__dirname} __filename: ${__filename} - checking if file exists: ${path.join(__dirname, '..', 'src','App', 'index.html')}`);
|
|
39
|
-
});
|
|
46
|
+
// Middleware para servir archivos estáticos
|
|
47
|
+
app.use(express.static(path.join(__dirname, `../${folderDeployed}`)));
|
|
40
48
|
|
|
41
|
-
//
|
|
42
|
-
app.use(express.
|
|
49
|
+
// Middleware para parsear JSON y formularios
|
|
50
|
+
app.use(express.json());
|
|
51
|
+
app.use(express.urlencoded({ extended: true }));
|
|
43
52
|
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
// Configurar headers de CORS
|
|
54
|
+
app.use((req, res, next) => {
|
|
55
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
56
|
+
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
57
|
+
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
|
58
|
+
|
|
59
|
+
if (req.method === 'OPTIONS') {
|
|
60
|
+
res.sendStatus(200);
|
|
61
|
+
} else {
|
|
62
|
+
next();
|
|
63
|
+
}
|
|
46
64
|
});
|
|
47
65
|
|
|
48
|
-
//
|
|
66
|
+
// Ruta de ejemplo para API
|
|
49
67
|
app.get('/api/status', (req, res) => {
|
|
50
|
-
res.json({
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
res.json({
|
|
69
|
+
status: 'ok',
|
|
70
|
+
mode: runMode,
|
|
71
|
+
folder: folderDeployed,
|
|
72
|
+
timestamp: new Date().toISOString(),
|
|
73
|
+
framework: 'Slice.js',
|
|
74
|
+
version: '2.0.0'
|
|
56
75
|
});
|
|
57
76
|
});
|
|
58
77
|
|
|
59
|
-
//
|
|
78
|
+
// SPA fallback - servir index.html para rutas no encontradas
|
|
60
79
|
app.get('*', (req, res) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
80
|
+
const indexPath = path.join(__dirname, `../${folderDeployed}`, 'index.html');
|
|
81
|
+
res.sendFile(indexPath, (err) => {
|
|
82
|
+
if (err) {
|
|
83
|
+
res.status(404).send(`
|
|
84
|
+
<h1>404 - Page Not Found</h1>
|
|
85
|
+
<p>The requested file could not be found in /${folderDeployed}</p>
|
|
86
|
+
<p>Make sure you've run the appropriate build command:</p>
|
|
87
|
+
<ul>
|
|
88
|
+
<li>For development: Files should be in /src</li>
|
|
89
|
+
<li>For production: Run "npm run slice:build" first</li>
|
|
90
|
+
</ul>
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
73
94
|
});
|
|
74
95
|
|
|
75
96
|
function startServer() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
97
|
+
server = app.listen(PORT, () => {
|
|
98
|
+
console.log(`✅ Server running at http://localhost:${PORT}`);
|
|
99
|
+
console.log(`📂 Mode: ${runMode} (serving from /${folderDeployed})`);
|
|
100
|
+
|
|
101
|
+
if (runMode === 'development') {
|
|
102
|
+
console.log('🔄 Development mode: Changes in /src will require server restart');
|
|
103
|
+
} else {
|
|
104
|
+
console.log('⚡ Production mode: Serving optimized files from /dist');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log('🛑 Press Ctrl+C to stop');
|
|
108
|
+
console.log('\n💡 Available commands:');
|
|
109
|
+
console.log(' - Development: npm run slice:dev');
|
|
110
|
+
console.log(' - Production: npm run slice:start');
|
|
111
|
+
console.log(' - Build: npm run slice:build');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Siempre mostrar menú interactivo
|
|
115
|
+
setTimeout(showInteractiveMenu, 1000);
|
|
87
116
|
}
|
|
88
117
|
|
|
89
|
-
async function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
message: 'Select an option:',
|
|
106
|
-
choices: ['Restart Server', 'Stop Server (Exit)']
|
|
107
|
-
}
|
|
108
|
-
]);
|
|
109
|
-
|
|
110
|
-
if (action === 'Stop Server (Exit)') {
|
|
111
|
-
console.log('\nShutting down server...');
|
|
112
|
-
server.close(() => {
|
|
113
|
-
console.log('Server stopped.');
|
|
114
|
-
process.exit(0);
|
|
115
|
-
});
|
|
116
|
-
break;
|
|
117
|
-
} else if (action === 'Restart Server') {
|
|
118
|
-
console.log('\nRestarting server...');
|
|
119
|
-
server.close(() => {
|
|
120
|
-
console.log('Server stopped. Restarting...');
|
|
121
|
-
startServer();
|
|
122
|
-
});
|
|
123
|
-
break;
|
|
118
|
+
async function showInteractiveMenu() {
|
|
119
|
+
while (true) {
|
|
120
|
+
try {
|
|
121
|
+
console.log('\n' + '='.repeat(50));
|
|
122
|
+
|
|
123
|
+
const { action } = await inquirer.prompt([
|
|
124
|
+
{
|
|
125
|
+
type: 'list',
|
|
126
|
+
name: 'action',
|
|
127
|
+
message: '🎛️ Server Control Menu',
|
|
128
|
+
choices: [
|
|
129
|
+
'📊 Server Status',
|
|
130
|
+
'🌐 Open in Browser',
|
|
131
|
+
'🔄 Restart Server',
|
|
132
|
+
'🛑 Stop Server'
|
|
133
|
+
]
|
|
124
134
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
]);
|
|
136
|
+
|
|
137
|
+
if (action === '📊 Server Status') {
|
|
138
|
+
console.log(`\n📈 Server Status:`);
|
|
139
|
+
console.log(` 🔗 URL: http://localhost:${PORT}`);
|
|
140
|
+
console.log(` 📁 Mode: ${runMode}`);
|
|
141
|
+
console.log(` 📂 Serving: /${folderDeployed}`);
|
|
142
|
+
console.log(` ⏰ Uptime: ${Math.floor(process.uptime())}s`);
|
|
143
|
+
} else if (action === '🌐 Open in Browser') {
|
|
144
|
+
const { default: open } = await import('open');
|
|
145
|
+
await open(`http://localhost:${PORT}`);
|
|
146
|
+
console.log('🌐 Opening browser...');
|
|
147
|
+
} else if (action === '🛑 Stop Server') {
|
|
148
|
+
console.log('\n🛑 Stopping server...');
|
|
149
|
+
server.close(() => {
|
|
150
|
+
console.log('✅ Server stopped successfully');
|
|
151
|
+
process.exit(0);
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
} else if (action === '🔄 Restart Server') {
|
|
155
|
+
console.log('\nRestarting server...');
|
|
156
|
+
server.close(() => {
|
|
157
|
+
console.log('Server stopped. Restarting...');
|
|
158
|
+
startServer();
|
|
159
|
+
});
|
|
128
160
|
break;
|
|
129
161
|
}
|
|
130
|
-
|
|
162
|
+
} catch (error) {
|
|
163
|
+
// Si hay error con inquirer, continuar sin menú
|
|
164
|
+
console.log('\n💡 Interactive menu not available - Press Ctrl+C to stop');
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
131
168
|
}
|
|
132
169
|
|
|
133
170
|
// Manejar cierre del proceso
|
|
134
171
|
process.on('SIGINT', () => {
|
|
135
|
-
|
|
136
|
-
console.log('\n🛑 Server stopped');
|
|
137
|
-
} else {
|
|
138
|
-
console.log('\n🛑 Slice server stopped');
|
|
139
|
-
}
|
|
172
|
+
console.log('\n🛑 Slice server stopped');
|
|
140
173
|
process.exit(0);
|
|
141
174
|
});
|
|
142
175
|
|
package/package.json
CHANGED
|
@@ -1,196 +1,196 @@
|
|
|
1
|
-
export default class HomePage extends HTMLElement {
|
|
2
|
-
constructor(props) {
|
|
3
|
-
super();
|
|
4
|
-
slice.attachTemplate(this);
|
|
5
|
-
|
|
6
|
-
this.$examplesContainer = this.querySelector('.examples-container');
|
|
7
|
-
|
|
8
|
-
slice.controller.setComponentProps(this, props);
|
|
9
|
-
this.debuggerProps = [];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async init() {
|
|
13
|
-
// Crear la barra de navegación
|
|
14
|
-
const navbar = await slice.build('Navbar', {
|
|
15
|
-
position: 'fixed',
|
|
16
|
-
logo: {
|
|
17
|
-
src: '/images/Slice.js-logo.png',
|
|
18
|
-
path: '/',
|
|
19
|
-
},
|
|
20
|
-
items: [
|
|
21
|
-
{ text: 'Home', path: '/' },
|
|
22
|
-
{ text: 'Playground', path: '/Playground' },
|
|
23
|
-
|
|
24
|
-
],
|
|
25
|
-
buttons: [
|
|
26
|
-
{
|
|
27
|
-
value: 'Change Theme',
|
|
28
|
-
onClickCallback: async () => {
|
|
29
|
-
const currentTheme = slice.stylesManager.themeManager.currentTheme;
|
|
30
|
-
if (currentTheme === 'Slice') {
|
|
31
|
-
await slice.setTheme('Light');
|
|
32
|
-
} else if (currentTheme === 'Light') {
|
|
33
|
-
await slice.setTheme('Dark');
|
|
34
|
-
} else {
|
|
35
|
-
await slice.setTheme('Slice');
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// Crear botones para la sección de llamada a la acción
|
|
43
|
-
const docsButton = await slice.build('Button', {
|
|
44
|
-
value: 'Documentation',
|
|
45
|
-
onClickCallback: () => //redirect to https://slice-js-docs.vercel.app/Documentation
|
|
46
|
-
window.open('https://slice-js-docs.vercel.app/Documentation', '_blank'),
|
|
47
|
-
customColor: {
|
|
48
|
-
button: 'var(--primary-color)',
|
|
49
|
-
label: 'var(--primary-color-contrast)'
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const componentsButton = await slice.build('Button', {
|
|
54
|
-
value: 'Components Library',
|
|
55
|
-
onClickCallback: () => window.open('https://slice-js-docs.vercel.app/Documentation/Visual', '_blank'),
|
|
56
|
-
customColor: {
|
|
57
|
-
button: 'var(--secondary-color)',
|
|
58
|
-
label: 'var(--secondary-color-contrast)'
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// Añadir botones a la sección CTA
|
|
63
|
-
this.querySelector('.cta-buttons').appendChild(docsButton);
|
|
64
|
-
this.querySelector('.cta-buttons').appendChild(componentsButton);
|
|
65
|
-
|
|
66
|
-
// Crear features section con un enfoque diferente (sin usar Cards)
|
|
67
|
-
await this.createFeatures();
|
|
68
|
-
|
|
69
|
-
// Crear ejemplos de componentes
|
|
70
|
-
await this.createComponentExamples();
|
|
71
|
-
|
|
72
|
-
// Configurar la sección de código de inicio
|
|
73
|
-
await this.setupGettingStartedSection();
|
|
74
|
-
|
|
75
|
-
// Añadir la barra de navegación al inicio del componente
|
|
76
|
-
this.insertBefore(navbar, this.firstChild);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async createFeatures() {
|
|
80
|
-
// Definir características
|
|
81
|
-
const features = [
|
|
82
|
-
{
|
|
83
|
-
title: 'Component-Based',
|
|
84
|
-
description: 'Build your app using modular, reusable components following web standards.'
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
title: 'Zero Dependencies',
|
|
88
|
-
description: 'Built with vanilla JavaScript. No external libraries required.'
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
title: 'Easy Routing',
|
|
92
|
-
description: 'Simple and powerful routing system for single page applications.'
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
title: 'Theme System',
|
|
96
|
-
description: 'Built-in theme support with easy customization through CSS variables.'
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
title: 'Developer Tools',
|
|
100
|
-
description: 'Integrated debugging and logging for faster development.'
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
title: 'Performance Focused',
|
|
104
|
-
description: 'Lightweight and optimized for fast loading and execution.'
|
|
105
|
-
}
|
|
106
|
-
];
|
|
107
|
-
|
|
108
|
-
const featureGrid = this.querySelector('.feature-grid');
|
|
109
|
-
|
|
110
|
-
// Crear y añadir cada feature como un elemento HTML simple
|
|
111
|
-
for (const feature of features) {
|
|
112
|
-
const featureElement = document.createElement('div');
|
|
113
|
-
featureElement.classList.add('feature-item');
|
|
114
|
-
|
|
115
|
-
const featureTitle = document.createElement('h3');
|
|
116
|
-
featureTitle.textContent = feature.title;
|
|
117
|
-
featureTitle.classList.add('feature-title');
|
|
118
|
-
|
|
119
|
-
const featureDescription = document.createElement('p');
|
|
120
|
-
featureDescription.textContent = feature.description;
|
|
121
|
-
featureDescription.classList.add('feature-description');
|
|
122
|
-
|
|
123
|
-
featureElement.appendChild(featureTitle);
|
|
124
|
-
featureElement.appendChild(featureDescription);
|
|
125
|
-
|
|
126
|
-
featureGrid.appendChild(featureElement);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async createComponentExamples() {
|
|
131
|
-
// Crear ejemplos para demostrar componentes
|
|
132
|
-
const inputExample = await slice.build('Input', {
|
|
133
|
-
placeholder: 'Try typing here...',
|
|
134
|
-
type: 'text'
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
const switchExample = await slice.build('Switch', {
|
|
138
|
-
label: 'Toggle me',
|
|
139
|
-
checked: true
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
const checkboxExample = await slice.build('Checkbox', {
|
|
143
|
-
label: 'Check me',
|
|
144
|
-
labelPlacement: 'right'
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
const detailsExample = await slice.build('Details', {
|
|
148
|
-
title: 'Click to expand',
|
|
149
|
-
text: 'This is a collapsible details component that can contain any content.'
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Crear sección para cada ejemplo
|
|
153
|
-
const exampleSections = [
|
|
154
|
-
{ title: 'Input Component', component: inputExample },
|
|
155
|
-
{ title: 'Switch Component', component: switchExample },
|
|
156
|
-
{ title: 'Checkbox Component', component: checkboxExample },
|
|
157
|
-
{ title: 'Details Component', component: detailsExample }
|
|
158
|
-
];
|
|
159
|
-
|
|
160
|
-
// Añadir cada ejemplo a la sección de ejemplos
|
|
161
|
-
for (const section of exampleSections) {
|
|
162
|
-
const container = document.createElement('div');
|
|
163
|
-
container.classList.add('example-item');
|
|
164
|
-
|
|
165
|
-
const title = document.createElement('h3');
|
|
166
|
-
title.textContent = section.title;
|
|
167
|
-
|
|
168
|
-
container.appendChild(title);
|
|
169
|
-
container.appendChild(section.component);
|
|
170
|
-
|
|
171
|
-
this.$examplesContainer.appendChild(container);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
async setupGettingStartedSection() {
|
|
176
|
-
// Opcionalmente podríamos mejorar esta sección usando el CodeVisualizer component
|
|
177
|
-
// en lugar del código HTML estático en el template
|
|
178
|
-
const codeVisualizer = await slice.build('CodeVisualizer', {
|
|
179
|
-
value: `// Initialize a new Slice.js project
|
|
180
|
-
npm run slice:init
|
|
181
|
-
|
|
182
|
-
// Create a new component
|
|
183
|
-
npm run slice:create
|
|
184
|
-
|
|
185
|
-
// Start your application
|
|
186
|
-
npm run slice:start`,
|
|
187
|
-
language: 'bash'
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
const codeSample = this.querySelector('.code-sample');
|
|
191
|
-
codeSample.innerHTML = ''; // Clear the static code sample
|
|
192
|
-
codeSample.appendChild(codeVisualizer);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
1
|
+
export default class HomePage extends HTMLElement {
|
|
2
|
+
constructor(props) {
|
|
3
|
+
super();
|
|
4
|
+
slice.attachTemplate(this);
|
|
5
|
+
|
|
6
|
+
this.$examplesContainer = this.querySelector('.examples-container');
|
|
7
|
+
|
|
8
|
+
slice.controller.setComponentProps(this, props);
|
|
9
|
+
this.debuggerProps = [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async init() {
|
|
13
|
+
// Crear la barra de navegación
|
|
14
|
+
const navbar = await slice.build('Navbar', {
|
|
15
|
+
position: 'fixed',
|
|
16
|
+
logo: {
|
|
17
|
+
src: '/images/Slice.js-logo.png',
|
|
18
|
+
path: '/',
|
|
19
|
+
},
|
|
20
|
+
items: [
|
|
21
|
+
{ text: 'Home', path: '/' },
|
|
22
|
+
{ text: 'Playground', path: '/Playground' },
|
|
23
|
+
|
|
24
|
+
],
|
|
25
|
+
buttons: [
|
|
26
|
+
{
|
|
27
|
+
value: 'Change Theme',
|
|
28
|
+
onClickCallback: async () => {
|
|
29
|
+
const currentTheme = slice.stylesManager.themeManager.currentTheme;
|
|
30
|
+
if (currentTheme === 'Slice') {
|
|
31
|
+
await slice.setTheme('Light');
|
|
32
|
+
} else if (currentTheme === 'Light') {
|
|
33
|
+
await slice.setTheme('Dark');
|
|
34
|
+
} else {
|
|
35
|
+
await slice.setTheme('Slice');
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Crear botones para la sección de llamada a la acción
|
|
43
|
+
const docsButton = await slice.build('Button', {
|
|
44
|
+
value: 'Documentation',
|
|
45
|
+
onClickCallback: () => //redirect to https://slice-js-docs.vercel.app/Documentation
|
|
46
|
+
window.open('https://slice-js-docs.vercel.app/Documentation', '_blank'),
|
|
47
|
+
customColor: {
|
|
48
|
+
button: 'var(--primary-color)',
|
|
49
|
+
label: 'var(--primary-color-contrast)'
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const componentsButton = await slice.build('Button', {
|
|
54
|
+
value: 'Components Library',
|
|
55
|
+
onClickCallback: () => window.open('https://slice-js-docs.vercel.app/Documentation/Visual', '_blank'),
|
|
56
|
+
customColor: {
|
|
57
|
+
button: 'var(--secondary-color)',
|
|
58
|
+
label: 'var(--secondary-color-contrast)'
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Añadir botones a la sección CTA
|
|
63
|
+
this.querySelector('.cta-buttons').appendChild(docsButton);
|
|
64
|
+
this.querySelector('.cta-buttons').appendChild(componentsButton);
|
|
65
|
+
|
|
66
|
+
// Crear features section con un enfoque diferente (sin usar Cards)
|
|
67
|
+
await this.createFeatures();
|
|
68
|
+
|
|
69
|
+
// Crear ejemplos de componentes
|
|
70
|
+
await this.createComponentExamples();
|
|
71
|
+
|
|
72
|
+
// Configurar la sección de código de inicio
|
|
73
|
+
await this.setupGettingStartedSection();
|
|
74
|
+
|
|
75
|
+
// Añadir la barra de navegación al inicio del componente
|
|
76
|
+
this.insertBefore(navbar, this.firstChild);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async createFeatures() {
|
|
80
|
+
// Definir características
|
|
81
|
+
const features = [
|
|
82
|
+
{
|
|
83
|
+
title: 'Component-Based',
|
|
84
|
+
description: 'Build your app using modular, reusable components following web standards.'
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
title: 'Zero Dependencies',
|
|
88
|
+
description: 'Built with vanilla JavaScript. No external libraries required.'
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
title: 'Easy Routing',
|
|
92
|
+
description: 'Simple and powerful routing system for single page applications.'
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: 'Theme System',
|
|
96
|
+
description: 'Built-in theme support with easy customization through CSS variables.'
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
title: 'Developer Tools',
|
|
100
|
+
description: 'Integrated debugging and logging for faster development.'
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
title: 'Performance Focused',
|
|
104
|
+
description: 'Lightweight and optimized for fast loading and execution.'
|
|
105
|
+
}
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
const featureGrid = this.querySelector('.feature-grid');
|
|
109
|
+
|
|
110
|
+
// Crear y añadir cada feature como un elemento HTML simple
|
|
111
|
+
for (const feature of features) {
|
|
112
|
+
const featureElement = document.createElement('div');
|
|
113
|
+
featureElement.classList.add('feature-item');
|
|
114
|
+
|
|
115
|
+
const featureTitle = document.createElement('h3');
|
|
116
|
+
featureTitle.textContent = feature.title;
|
|
117
|
+
featureTitle.classList.add('feature-title');
|
|
118
|
+
|
|
119
|
+
const featureDescription = document.createElement('p');
|
|
120
|
+
featureDescription.textContent = feature.description;
|
|
121
|
+
featureDescription.classList.add('feature-description');
|
|
122
|
+
|
|
123
|
+
featureElement.appendChild(featureTitle);
|
|
124
|
+
featureElement.appendChild(featureDescription);
|
|
125
|
+
|
|
126
|
+
featureGrid.appendChild(featureElement);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async createComponentExamples() {
|
|
131
|
+
// Crear ejemplos para demostrar componentes
|
|
132
|
+
const inputExample = await slice.build('Input', {
|
|
133
|
+
placeholder: 'Try typing here...',
|
|
134
|
+
type: 'text'
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const switchExample = await slice.build('Switch', {
|
|
138
|
+
label: 'Toggle me',
|
|
139
|
+
checked: true
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const checkboxExample = await slice.build('Checkbox', {
|
|
143
|
+
label: 'Check me',
|
|
144
|
+
labelPlacement: 'right'
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const detailsExample = await slice.build('Details', {
|
|
148
|
+
title: 'Click to expand',
|
|
149
|
+
text: 'This is a collapsible details component that can contain any content.'
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Crear sección para cada ejemplo
|
|
153
|
+
const exampleSections = [
|
|
154
|
+
{ title: 'Input Component', component: inputExample },
|
|
155
|
+
{ title: 'Switch Component', component: switchExample },
|
|
156
|
+
{ title: 'Checkbox Component', component: checkboxExample },
|
|
157
|
+
{ title: 'Details Component', component: detailsExample }
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
// Añadir cada ejemplo a la sección de ejemplos
|
|
161
|
+
for (const section of exampleSections) {
|
|
162
|
+
const container = document.createElement('div');
|
|
163
|
+
container.classList.add('example-item');
|
|
164
|
+
|
|
165
|
+
const title = document.createElement('h3');
|
|
166
|
+
title.textContent = section.title;
|
|
167
|
+
|
|
168
|
+
container.appendChild(title);
|
|
169
|
+
container.appendChild(section.component);
|
|
170
|
+
|
|
171
|
+
this.$examplesContainer.appendChild(container);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async setupGettingStartedSection() {
|
|
176
|
+
// Opcionalmente podríamos mejorar esta sección usando el CodeVisualizer component
|
|
177
|
+
// en lugar del código HTML estático en el template
|
|
178
|
+
const codeVisualizer = await slice.build('CodeVisualizer', {
|
|
179
|
+
value: `// Initialize a new Slice.js project
|
|
180
|
+
npm run slice:init
|
|
181
|
+
|
|
182
|
+
// Create a new component
|
|
183
|
+
npm run slice:create
|
|
184
|
+
|
|
185
|
+
// Start your application
|
|
186
|
+
npm run slice:start`,
|
|
187
|
+
language: 'bash'
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const codeSample = this.querySelector('.code-sample');
|
|
191
|
+
codeSample.innerHTML = ''; // Clear the static code sample
|
|
192
|
+
codeSample.appendChild(codeVisualizer);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
196
|
customElements.define('slice-home-page', HomePage);
|