@yakuzaa/jade 0.1.10 → 0.1.12
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/commands/html.js +123 -51
- package/package.json +2 -2
package/commands/html.js
CHANGED
|
@@ -90,36 +90,36 @@ function gerarCSS(tema = {}) {
|
|
|
90
90
|
${gerarVariaveisCSS(tema)}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
body {
|
|
93
|
+
html, body {
|
|
94
|
+
height: 100%;
|
|
94
95
|
font-family: var(--jade-fonte);
|
|
95
96
|
background: var(--jade-cor-fundo);
|
|
96
97
|
color: var(--jade-cor-texto);
|
|
97
|
-
min-height: 100dvh;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
/* Layout principal */
|
|
100
|
+
/* Layout principal — ocupa toda a tela, sem rolar o body */
|
|
101
101
|
#jade-app {
|
|
102
102
|
display: flex;
|
|
103
|
-
|
|
103
|
+
height: 100dvh;
|
|
104
|
+
overflow: hidden;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
/* Nav lateral */
|
|
107
|
+
/* Nav lateral (desktop sempre visível) */
|
|
107
108
|
#jade-nav {
|
|
108
109
|
width: 240px;
|
|
109
|
-
|
|
110
|
+
height: 100%;
|
|
110
111
|
background: var(--jade-cor-fundo-nav);
|
|
111
112
|
display: flex;
|
|
112
113
|
flex-direction: column;
|
|
113
114
|
flex-shrink: 0;
|
|
114
|
-
position: sticky;
|
|
115
|
-
top: 0;
|
|
116
|
-
height: 100dvh;
|
|
117
115
|
overflow-y: auto;
|
|
116
|
+
z-index: 10;
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
#jade-nav-header {
|
|
121
120
|
padding: 20px 16px 12px;
|
|
122
121
|
border-bottom: 1px solid rgba(255,255,255,0.08);
|
|
122
|
+
flex-shrink: 0;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
#jade-nav-titulo {
|
|
@@ -138,10 +138,11 @@ function gerarCSS(tema = {}) {
|
|
|
138
138
|
|
|
139
139
|
#jade-nav-lista {
|
|
140
140
|
flex: 1;
|
|
141
|
-
padding: 8px
|
|
141
|
+
padding: 8px;
|
|
142
142
|
display: flex;
|
|
143
143
|
flex-direction: column;
|
|
144
144
|
gap: 2px;
|
|
145
|
+
overflow-y: auto;
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
.jade-nav-item {
|
|
@@ -159,6 +160,7 @@ function gerarCSS(tema = {}) {
|
|
|
159
160
|
cursor: pointer;
|
|
160
161
|
text-align: left;
|
|
161
162
|
transition: background 0.15s, color 0.15s;
|
|
163
|
+
flex-shrink: 0;
|
|
162
164
|
}
|
|
163
165
|
|
|
164
166
|
.jade-nav-item:hover {
|
|
@@ -173,6 +175,51 @@ function gerarCSS(tema = {}) {
|
|
|
173
175
|
|
|
174
176
|
.jade-nav-icone { display: flex; align-items: center; }
|
|
175
177
|
|
|
178
|
+
/* Área de conteúdo — rola de forma independente */
|
|
179
|
+
#jade-conteudo {
|
|
180
|
+
flex: 1;
|
|
181
|
+
min-width: 0;
|
|
182
|
+
height: 100%;
|
|
183
|
+
padding: 24px;
|
|
184
|
+
overflow-y: auto;
|
|
185
|
+
overflow-x: hidden;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Overlay escuro para o drawer no mobile */
|
|
189
|
+
#jade-overlay {
|
|
190
|
+
display: none;
|
|
191
|
+
position: fixed;
|
|
192
|
+
inset: 0;
|
|
193
|
+
background: rgba(0,0,0,0.45);
|
|
194
|
+
z-index: 199;
|
|
195
|
+
opacity: 0;
|
|
196
|
+
transition: opacity 0.25s;
|
|
197
|
+
}
|
|
198
|
+
#jade-overlay.visivel {
|
|
199
|
+
display: block;
|
|
200
|
+
opacity: 1;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Botão hambúrguer — só aparece no mobile */
|
|
204
|
+
#jade-hamburger {
|
|
205
|
+
display: none;
|
|
206
|
+
position: fixed;
|
|
207
|
+
top: 12px;
|
|
208
|
+
left: 12px;
|
|
209
|
+
z-index: 198;
|
|
210
|
+
width: 40px;
|
|
211
|
+
height: 40px;
|
|
212
|
+
border: none;
|
|
213
|
+
border-radius: var(--jade-raio);
|
|
214
|
+
background: var(--jade-cor-fundo-nav);
|
|
215
|
+
color: #fff;
|
|
216
|
+
cursor: pointer;
|
|
217
|
+
align-items: center;
|
|
218
|
+
justify-content: center;
|
|
219
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
|
|
220
|
+
flex-shrink: 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
176
223
|
/* Toolbar */
|
|
177
224
|
.jade-toolbar {
|
|
178
225
|
display: flex;
|
|
@@ -186,6 +233,7 @@ function gerarCSS(tema = {}) {
|
|
|
186
233
|
.jade-busca-form { display: flex; gap: 0; }
|
|
187
234
|
.jade-busca-input {
|
|
188
235
|
flex: 1;
|
|
236
|
+
min-width: 0;
|
|
189
237
|
min-height: 44px;
|
|
190
238
|
padding: 10px 14px;
|
|
191
239
|
border: 1.5px solid var(--jade-cor-borda);
|
|
@@ -232,20 +280,12 @@ function gerarCSS(tema = {}) {
|
|
|
232
280
|
letter-spacing: 0.05em;
|
|
233
281
|
}
|
|
234
282
|
|
|
235
|
-
/* Área de conteúdo */
|
|
236
|
-
#jade-conteudo {
|
|
237
|
-
flex: 1;
|
|
238
|
-
min-width: 0;
|
|
239
|
-
padding: 24px;
|
|
240
|
-
overflow-y: auto;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
283
|
/* Carregando */
|
|
244
284
|
#jade-carregando {
|
|
245
285
|
display: flex;
|
|
246
286
|
align-items: center;
|
|
247
287
|
justify-content: center;
|
|
248
|
-
|
|
288
|
+
height: 100dvh;
|
|
249
289
|
color: var(--jade-cor-texto-muted);
|
|
250
290
|
font-size: 0.9rem;
|
|
251
291
|
gap: 10px;
|
|
@@ -261,41 +301,29 @@ function gerarCSS(tema = {}) {
|
|
|
261
301
|
|
|
262
302
|
@keyframes jade-giro { to { transform: rotate(360deg); } }
|
|
263
303
|
|
|
264
|
-
/* Mobile:
|
|
265
|
-
@media (max-width:
|
|
266
|
-
#jade-
|
|
304
|
+
/* Mobile: hamburger + drawer overlay */
|
|
305
|
+
@media (max-width: 768px) {
|
|
306
|
+
#jade-hamburger { display: flex; }
|
|
267
307
|
|
|
268
308
|
#jade-nav {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
309
|
+
position: fixed;
|
|
310
|
+
top: 0;
|
|
311
|
+
left: 0;
|
|
312
|
+
height: 100dvh;
|
|
313
|
+
z-index: 200;
|
|
314
|
+
transform: translateX(-100%);
|
|
315
|
+
transition: transform 0.25s ease;
|
|
316
|
+
box-shadow: 4px 0 16px rgba(0,0,0,0.3);
|
|
276
317
|
}
|
|
277
318
|
|
|
278
|
-
#jade-nav-
|
|
279
|
-
|
|
280
|
-
#jade-nav-lista {
|
|
281
|
-
flex-direction: row;
|
|
282
|
-
overflow-x: auto;
|
|
283
|
-
padding: 6px 8px;
|
|
284
|
-
gap: 4px;
|
|
319
|
+
#jade-nav.jade-nav-aberto {
|
|
320
|
+
transform: translateX(0);
|
|
285
321
|
}
|
|
286
322
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
padding: 6px 12px;
|
|
291
|
-
font-size: 0.7rem;
|
|
292
|
-
white-space: nowrap;
|
|
293
|
-
flex-shrink: 0;
|
|
323
|
+
#jade-conteudo {
|
|
324
|
+
padding: 16px;
|
|
325
|
+
padding-top: 64px;
|
|
294
326
|
}
|
|
295
|
-
|
|
296
|
-
.jade-nav-icone { font-size: 1.2rem; }
|
|
297
|
-
|
|
298
|
-
#jade-conteudo { padding: 16px; }
|
|
299
327
|
}
|
|
300
328
|
`.trim();
|
|
301
329
|
}
|
|
@@ -402,6 +430,40 @@ async function iniciar() {
|
|
|
402
430
|
document.getElementById('jade-carregando')?.remove();
|
|
403
431
|
document.getElementById('jade-app').style.display = '';
|
|
404
432
|
|
|
433
|
+
// ── Hamburger (mobile) ──────────────────────────────────────────────────────
|
|
434
|
+
const hamburger = document.getElementById('jade-hamburger');
|
|
435
|
+
const overlay = document.getElementById('jade-overlay');
|
|
436
|
+
const navEl = document.getElementById('jade-nav');
|
|
437
|
+
|
|
438
|
+
// Mostra o botão (estava display:none para não piscar antes do app carregar)
|
|
439
|
+
hamburger.style.display = '';
|
|
440
|
+
|
|
441
|
+
const iconeMenu = criarElementoIcone('menu', 22);
|
|
442
|
+
const iconeFechar = criarElementoIcone('fechar', 22);
|
|
443
|
+
if (iconeMenu) hamburger.appendChild(iconeMenu);
|
|
444
|
+
|
|
445
|
+
function abrirDrawer() {
|
|
446
|
+
navEl.classList.add('jade-nav-aberto');
|
|
447
|
+
overlay.classList.add('visivel');
|
|
448
|
+
hamburger.setAttribute('aria-expanded', 'true');
|
|
449
|
+
if (iconeMenu && iconeFechar) {
|
|
450
|
+
hamburger.replaceChild(iconeFechar, hamburger.firstChild);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function fecharDrawer() {
|
|
454
|
+
navEl.classList.remove('jade-nav-aberto');
|
|
455
|
+
overlay.classList.remove('visivel');
|
|
456
|
+
hamburger.setAttribute('aria-expanded', 'false');
|
|
457
|
+
if (iconeMenu && hamburger.firstChild !== iconeMenu) {
|
|
458
|
+
hamburger.replaceChild(iconeMenu, hamburger.firstChild);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
hamburger.addEventListener('click', () =>
|
|
463
|
+
navEl.classList.contains('jade-nav-aberto') ? fecharDrawer() : abrirDrawer()
|
|
464
|
+
);
|
|
465
|
+
overlay.addEventListener('click', fecharDrawer);
|
|
466
|
+
|
|
405
467
|
if (telas.length === 0) {
|
|
406
468
|
document.getElementById('jade-conteudo').innerHTML =
|
|
407
469
|
'<p style="color:var(--jade-cor-texto-muted);padding:2rem">Nenhuma tela declarada.</p>';
|
|
@@ -417,6 +479,7 @@ async function iniciar() {
|
|
|
417
479
|
const btn = document.createElement('button');
|
|
418
480
|
btn.className = 'jade-nav-item' + (i === 0 ? ' jade-nav-ativo' : '');
|
|
419
481
|
btn.dataset.tela = tela.nome;
|
|
482
|
+
btn.setAttribute('role', 'listitem');
|
|
420
483
|
|
|
421
484
|
const svgIcone = criarElementoIcone(nomeIcone(tela.nome), 18);
|
|
422
485
|
const spanIcone = document.createElement('span');
|
|
@@ -428,7 +491,10 @@ async function iniciar() {
|
|
|
428
491
|
spanLabel.textContent = tela.titulo || tela.nome;
|
|
429
492
|
btn.appendChild(spanLabel);
|
|
430
493
|
|
|
431
|
-
btn.addEventListener('click', () =>
|
|
494
|
+
btn.addEventListener('click', () => {
|
|
495
|
+
mudarTela(tela.nome, telas, db, ui, navItems);
|
|
496
|
+
fecharDrawer(); // fecha o drawer no mobile após navegar
|
|
497
|
+
});
|
|
432
498
|
nav.appendChild(btn);
|
|
433
499
|
navItems.push(btn);
|
|
434
500
|
});
|
|
@@ -436,7 +502,10 @@ async function iniciar() {
|
|
|
436
502
|
// Handler: jade:navegar — gaveta e navegar disparam este evento
|
|
437
503
|
window.addEventListener('jade:navegar', (e) => {
|
|
438
504
|
const nomeTela = e.detail?.tela;
|
|
439
|
-
if (nomeTela)
|
|
505
|
+
if (nomeTela) {
|
|
506
|
+
mudarTela(nomeTela, telas, db, ui, navItems);
|
|
507
|
+
fecharDrawer();
|
|
508
|
+
}
|
|
440
509
|
});
|
|
441
510
|
|
|
442
511
|
// Handler: jade:acao — dispara jade:acao:concluido após processar
|
|
@@ -496,13 +565,16 @@ ${gerarCSS(tema)}
|
|
|
496
565
|
Carregando...
|
|
497
566
|
</div>
|
|
498
567
|
|
|
568
|
+
<button id="jade-hamburger" aria-label="Abrir menu" aria-expanded="false" style="display:none"></button>
|
|
569
|
+
<div id="jade-overlay" role="presentation"></div>
|
|
570
|
+
|
|
499
571
|
<div id="jade-app" style="display:none">
|
|
500
|
-
<nav id="jade-nav">
|
|
572
|
+
<nav id="jade-nav" aria-label="Menu de navegação">
|
|
501
573
|
<div id="jade-nav-header">
|
|
502
574
|
<div id="jade-nav-titulo">${nome}</div>
|
|
503
575
|
<div id="jade-nav-versao">feito com Jade DSL</div>
|
|
504
576
|
</div>
|
|
505
|
-
<div id="jade-nav-lista"></div>
|
|
577
|
+
<div id="jade-nav-lista" role="list"></div>
|
|
506
578
|
</nav>
|
|
507
579
|
<main id="jade-conteudo"></main>
|
|
508
580
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yakuzaa/jade",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Jade DSL — linguagem empresarial em português compilada para WebAssembly. Instala compilador + runtime + CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"postinstall": "node postinstall.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@yakuzaa/jade-compiler": "^0.1.
|
|
20
|
+
"@yakuzaa/jade-compiler": "^0.1.14",
|
|
21
21
|
"@yakuzaa/jade-runtime": "^0.1.8"
|
|
22
22
|
},
|
|
23
23
|
"keywords": [
|