ui-optago 1.0.0 → 1.0.2
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/README.md +14 -2
- package/package.json +1 -1
- package/ui-optago.css +94 -39
- package/ui-optago.html +93 -34
- package/ui-optago.js +52 -1
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# UI Óptago
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/ui-optago)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
|
|
6
|
+
Design System da **[Óptago](https://optago.com.br)** — componentes UI em **CSS puro** + **JS vanilla**, sem Tailwind e sem build obrigatório. Tema escuro por padrão, tema claro automático, verde-lima `#C0FF6B` como cor de destaque e o octógono da marca como motivo visual.
|
|
4
7
|
|
|
5
8
|
## Instalação
|
|
6
9
|
|
|
@@ -15,13 +18,22 @@ npm install ui-optago
|
|
|
15
18
|
<script src="node_modules/ui-optago/ui-optago.js"></script>
|
|
16
19
|
```
|
|
17
20
|
|
|
18
|
-
**Via CDN (
|
|
21
|
+
**Via CDN** (não precisa instalar nada — adicione ao `<head>`):
|
|
19
22
|
|
|
20
23
|
```html
|
|
21
24
|
<link rel="stylesheet" href="https://unpkg.com/ui-optago/ui-optago.css">
|
|
22
25
|
<script src="https://unpkg.com/ui-optago/ui-optago.js"></script>
|
|
23
26
|
```
|
|
24
27
|
|
|
28
|
+
Em produção, fixe a versão para não sofrer quebras em atualizações:
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<link rel="stylesheet" href="https://unpkg.com/ui-optago@1.0.0/ui-optago.css">
|
|
32
|
+
<script src="https://unpkg.com/ui-optago@1.0.0/ui-optago.js"></script>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
> Também funciona via jsDelivr: `https://cdn.jsdelivr.net/npm/ui-optago/ui-optago.css`
|
|
36
|
+
|
|
25
37
|
**Ou copie os arquivos direto** (`ui-optago.css` e `ui-optago.js`) para o seu projeto:
|
|
26
38
|
|
|
27
39
|
```html
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ui-optago",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Design System Óptago — componentes UI em CSS puro + JS vanilla, com tema claro/escuro, verde-lima (#C0FF6B) e app shell com sidebar colapsável.",
|
|
5
5
|
"author": "Óptago <cowork@optago.com.br> (https://optago.com.br)",
|
|
6
6
|
"license": "MIT",
|
package/ui-optago.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
|
-
UI ÓPTAGO — Design System v1.0
|
|
2
|
+
UI ÓPTAGO — Design System v1.0.2
|
|
3
3
|
CSS puro, sem dependências. Tema escuro por padrão.
|
|
4
4
|
Para tema claro: adicione a classe "light" ao <html> (o ui-optago.js
|
|
5
5
|
gerencia isso automaticamente via localStorage).
|
|
@@ -74,12 +74,12 @@
|
|
|
74
74
|
|
|
75
75
|
/* Superfícies — TEMA CLARO */
|
|
76
76
|
html.light {
|
|
77
|
-
--op-bg: #
|
|
78
|
-
--op-panel: #
|
|
79
|
-
--op-panel-2: #
|
|
80
|
-
--op-panel-3: #
|
|
81
|
-
--op-border: #
|
|
82
|
-
--op-border-2: #
|
|
77
|
+
--op-bg: #E3E9F0;
|
|
78
|
+
--op-panel: #F8FAFC;
|
|
79
|
+
--op-panel-2: #EEF2F7;
|
|
80
|
+
--op-panel-3: #E6EBF2;
|
|
81
|
+
--op-border: #D6DEE7;
|
|
82
|
+
--op-border-2: #BDC9D8;
|
|
83
83
|
--op-text: #334155;
|
|
84
84
|
--op-strong: #0F172A;
|
|
85
85
|
--op-muted: #64748B;
|
|
@@ -100,9 +100,9 @@ html.light {
|
|
|
100
100
|
/* Fundo do tema claro: gradiente suave com um toque de verde-lima no topo */
|
|
101
101
|
html.light body {
|
|
102
102
|
background:
|
|
103
|
-
radial-gradient(900px 420px at 75% -10%, rgba(192,255,107,.
|
|
104
|
-
radial-gradient(700px 380px at 10% 110%, rgba(192,255,107,.
|
|
105
|
-
linear-gradient(180deg, #
|
|
103
|
+
radial-gradient(900px 420px at 75% -10%, rgba(192,255,107,.20) 0%, transparent 60%),
|
|
104
|
+
radial-gradient(700px 380px at 10% 110%, rgba(192,255,107,.10) 0%, transparent 60%),
|
|
105
|
+
linear-gradient(180deg, #E7ECF2 0%, #DEE5EC 100%);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/* ----------------------------------------------------------------------------
|
|
@@ -140,7 +140,9 @@ h4 { font-size: 1rem; }
|
|
|
140
140
|
|
|
141
141
|
p { margin: 0 0 1em; }
|
|
142
142
|
a { color: var(--op-accent); }
|
|
143
|
-
html.light a {
|
|
143
|
+
html.light a:not(.op-btn) {
|
|
144
|
+
color: #3F6212;
|
|
145
|
+
}
|
|
144
146
|
code, kbd { font-family: var(--op-font-mono); font-size: .85em; }
|
|
145
147
|
|
|
146
148
|
kbd {
|
|
@@ -206,6 +208,7 @@ html.light :focus-visible {
|
|
|
206
208
|
height: 100vh;
|
|
207
209
|
height: 100dvh;
|
|
208
210
|
overflow: hidden;
|
|
211
|
+
overflow: clip;
|
|
209
212
|
}
|
|
210
213
|
|
|
211
214
|
.op-app-body {
|
|
@@ -214,6 +217,11 @@ html.light :focus-visible {
|
|
|
214
217
|
display: flex;
|
|
215
218
|
flex-direction: column;
|
|
216
219
|
position: relative;
|
|
220
|
+
/* "clip" impede que .op-glow (ou qualquer filho absoluto) vaze para fora e
|
|
221
|
+
torne o documento rolável — sem isso, clicar em âncoras rola o viewport
|
|
222
|
+
e esconde o header. Nota: overflow no <body> é propagado ao viewport
|
|
223
|
+
pelo navegador, então o clip do .op-app sozinho não resolve. */
|
|
224
|
+
overflow: clip;
|
|
217
225
|
}
|
|
218
226
|
|
|
219
227
|
/* Header */
|
|
@@ -258,13 +266,8 @@ html.light .op-header { box-shadow: 0 8px 24px -14px rgba(15,23,42,.18); }
|
|
|
258
266
|
display: flex; align-items: center; justify-content: center;
|
|
259
267
|
flex-shrink: 0;
|
|
260
268
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
width: 10px; height: 10px;
|
|
264
|
-
background: #000;
|
|
265
|
-
-webkit-clip-path: var(--op-oct); clip-path: var(--op-oct);
|
|
266
|
-
}
|
|
267
|
-
html.light .op-brand-mark { background: #000; }
|
|
269
|
+
|
|
270
|
+
|
|
268
271
|
html.light .op-brand-mark::after { background: var(--op-accent); }
|
|
269
272
|
.op-brand-name {
|
|
270
273
|
font-family: var(--op-font-display);
|
|
@@ -278,12 +281,12 @@ html.light .op-brand-mark::after { background: var(--op-accent); }
|
|
|
278
281
|
.op-main {
|
|
279
282
|
flex: 1;
|
|
280
283
|
overflow-y: auto;
|
|
281
|
-
padding:
|
|
284
|
+
padding: 1.5rem;
|
|
282
285
|
scroll-behavior: smooth;
|
|
283
286
|
position: relative;
|
|
284
287
|
z-index: 1; /* mantém o conteúdo acima dos .op-glow do fundo */
|
|
285
288
|
}
|
|
286
|
-
@media (min-width: 1024px) { .op-main { padding:
|
|
289
|
+
@media (min-width: 1024px) { .op-main { padding: 1.75rem 2rem; } }
|
|
287
290
|
|
|
288
291
|
.op-container { max-width: 1100px; margin: 0 auto; }
|
|
289
292
|
|
|
@@ -357,25 +360,28 @@ html.light .op-brand-mark::after { background: var(--op-accent); }
|
|
|
357
360
|
align-items: center;
|
|
358
361
|
gap: .75rem;
|
|
359
362
|
padding: .625rem .75rem;
|
|
363
|
+
border: 1px solid transparent;
|
|
360
364
|
border-radius: var(--op-radius);
|
|
361
365
|
color: var(--op-text);
|
|
362
366
|
text-decoration: none;
|
|
363
367
|
font-weight: 600;
|
|
364
368
|
font-size: .875rem;
|
|
365
369
|
white-space: nowrap;
|
|
366
|
-
transition: background .2s ease, color .2s ease;
|
|
370
|
+
transition: background .2s ease, color .2s ease, border-color .2s ease;
|
|
367
371
|
}
|
|
368
372
|
.op-nav-item i { font-size: 1.25rem; flex-shrink: 0; }
|
|
369
373
|
.op-nav-item:hover {
|
|
370
374
|
background: color-mix(in srgb, var(--op-strong) 6%, transparent);
|
|
375
|
+
border-color: var(--op-border-2);
|
|
371
376
|
color: var(--op-strong);
|
|
372
377
|
}
|
|
373
378
|
.op-nav-item.is-active {
|
|
374
|
-
background: color-mix(in srgb, var(--op-accent)
|
|
379
|
+
background: color-mix(in srgb, var(--op-accent) 15%, transparent);
|
|
380
|
+
border-color: color-mix(in srgb, var(--op-accent) 45%, transparent);
|
|
375
381
|
color: var(--op-strong);
|
|
376
382
|
box-shadow: inset -3px 0 0 var(--op-accent);
|
|
377
383
|
}
|
|
378
|
-
html.light .op-nav-item.is-active { box-shadow: inset -3px 0 0 #84CC16; }
|
|
384
|
+
html.light .op-nav-item.is-active { box-shadow: inset -3px 0 0 #84CC16; border-color: color-mix(in srgb, #84CC16 45%, transparent); }
|
|
379
385
|
.op-nav-item.is-active i { color: var(--op-accent); }
|
|
380
386
|
html.light .op-nav-item.is-active i { color: #3F6212; }
|
|
381
387
|
|
|
@@ -384,7 +390,7 @@ html.light .op-nav-item.is-active i { color: #3F6212; }
|
|
|
384
390
|
.op-sidebar.is-collapsed .op-nav-text,
|
|
385
391
|
.op-sidebar.is-collapsed .op-sidebar-label,
|
|
386
392
|
.op-sidebar.is-collapsed .op-sidebar-header-text { display: none; }
|
|
387
|
-
.op-sidebar.is-collapsed .op-nav-item { justify-content: center; padding
|
|
393
|
+
.op-sidebar.is-collapsed .op-nav-item { justify-content: center; padding: .625rem; }
|
|
388
394
|
|
|
389
395
|
/* Tooltip do item (aparece à esquerda quando colapsada).
|
|
390
396
|
position:fixed — o JS calcula top/right no hover, pois o overflow-y:auto
|
|
@@ -1488,17 +1494,53 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1488
1494
|
.op-toast-danger .op-toast-icon { background: color-mix(in srgb, var(--op-danger) 15%, transparent); color: var(--op-danger); border-color: color-mix(in srgb, var(--op-danger) 30%, transparent); }
|
|
1489
1495
|
|
|
1490
1496
|
/* ----------------------------------------------------------------------------
|
|
1491
|
-
20.
|
|
1497
|
+
20. TELA DE CARREGAMENTO (overlay em tela cheia)
|
|
1498
|
+
Uso: OptagoUI.showLoading('Mensagem...') / OptagoUI.hideLoading()
|
|
1499
|
+
ou data-op-loading-form no <form> para acionar sozinho no submit.
|
|
1500
|
+
---------------------------------------------------------------------------- */
|
|
1501
|
+
.op-loading-overlay {
|
|
1502
|
+
position: fixed;
|
|
1503
|
+
inset: 0;
|
|
1504
|
+
z-index: 150;
|
|
1505
|
+
display: none;
|
|
1506
|
+
flex-direction: column;
|
|
1507
|
+
align-items: center;
|
|
1508
|
+
justify-content: center;
|
|
1509
|
+
gap: 1.25rem;
|
|
1510
|
+
background: color-mix(in srgb, var(--op-bg) 85%, transparent);
|
|
1511
|
+
backdrop-filter: blur(8px);
|
|
1512
|
+
-webkit-backdrop-filter: blur(8px);
|
|
1513
|
+
opacity: 0;
|
|
1514
|
+
transition: opacity .25s var(--op-ease);
|
|
1515
|
+
}
|
|
1516
|
+
.op-loading-overlay.is-open { display: flex; }
|
|
1517
|
+
.op-loading-overlay.is-visible { opacity: 1; }
|
|
1518
|
+
.op-loading-overlay .op-spinner { width: 46px; height: 46px; border-width: 3px; }
|
|
1519
|
+
.op-loading-message {
|
|
1520
|
+
max-width: 320px;
|
|
1521
|
+
padding: 0 1.5rem;
|
|
1522
|
+
font-family: var(--op-font-mono);
|
|
1523
|
+
font-size: .875rem;
|
|
1524
|
+
font-weight: 600;
|
|
1525
|
+
letter-spacing: .01em;
|
|
1526
|
+
text-align: center;
|
|
1527
|
+
color: var(--op-strong);
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
/* ----------------------------------------------------------------------------
|
|
1531
|
+
21. BLOCO DE DEMONSTRAÇÃO (showcase: preview + copiar + ver código)
|
|
1492
1532
|
---------------------------------------------------------------------------- */
|
|
1493
1533
|
.op-demo {
|
|
1494
1534
|
background: var(--op-panel);
|
|
1495
1535
|
border: 1px solid var(--op-border);
|
|
1496
1536
|
border-radius: var(--op-radius-lg);
|
|
1497
|
-
overflow: hidden;
|
|
1498
1537
|
box-shadow: var(--op-shadow);
|
|
1499
1538
|
}
|
|
1539
|
+
/* Sem overflow:hidden no container: dropdowns/tooltips exibidos dentro do
|
|
1540
|
+
preview não podem ser cortados. O arredondamento é feito nos filhos. */
|
|
1500
1541
|
.op-demo-preview {
|
|
1501
|
-
padding:
|
|
1542
|
+
padding: 1.5rem;
|
|
1543
|
+
border-radius: var(--op-radius-lg) var(--op-radius-lg) 0 0;
|
|
1502
1544
|
background:
|
|
1503
1545
|
radial-gradient(color-mix(in srgb, var(--op-border) 55%, transparent) 1px, transparent 1px);
|
|
1504
1546
|
background-size: 22px 22px;
|
|
@@ -1510,7 +1552,11 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1510
1552
|
padding: .625rem .875rem;
|
|
1511
1553
|
border-top: 1px solid var(--op-border);
|
|
1512
1554
|
background: var(--op-panel-2);
|
|
1555
|
+
border-radius: 0 0 var(--op-radius-lg) var(--op-radius-lg);
|
|
1513
1556
|
}
|
|
1557
|
+
/* Quando o código-fonte está visível, ele passa a ser o último bloco:
|
|
1558
|
+
a barra perde o arredondamento inferior e o código assume. */
|
|
1559
|
+
.op-demo-bar:has(+ .op-demo-code.is-visible) { border-radius: 0; }
|
|
1514
1560
|
.op-demo-code {
|
|
1515
1561
|
display: none;
|
|
1516
1562
|
margin: 0;
|
|
@@ -1524,6 +1570,7 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1524
1570
|
overflow-x: auto;
|
|
1525
1571
|
tab-size: 2;
|
|
1526
1572
|
white-space: pre;
|
|
1573
|
+
border-radius: 0 0 var(--op-radius-lg) var(--op-radius-lg);
|
|
1527
1574
|
}
|
|
1528
1575
|
.op-demo-code.is-visible { display: block; }
|
|
1529
1576
|
|
|
@@ -1532,14 +1579,14 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1532
1579
|
display: flex;
|
|
1533
1580
|
align-items: center;
|
|
1534
1581
|
gap: .75rem;
|
|
1535
|
-
padding-bottom:
|
|
1536
|
-
margin-bottom: 1.
|
|
1582
|
+
padding-bottom: .75rem;
|
|
1583
|
+
margin-bottom: 1.125rem;
|
|
1537
1584
|
border-bottom: 1px solid var(--op-border);
|
|
1538
1585
|
}
|
|
1539
1586
|
.op-section-head i {
|
|
1540
|
-
font-size: 1.
|
|
1587
|
+
font-size: 1.25rem;
|
|
1541
1588
|
color: var(--op-accent);
|
|
1542
|
-
width:
|
|
1589
|
+
width: 38px; height: 38px;
|
|
1543
1590
|
display: flex;
|
|
1544
1591
|
align-items: center;
|
|
1545
1592
|
justify-content: center;
|
|
@@ -1547,7 +1594,7 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1547
1594
|
-webkit-clip-path: var(--op-oct); clip-path: var(--op-oct);
|
|
1548
1595
|
flex-shrink: 0;
|
|
1549
1596
|
}
|
|
1550
|
-
html.light .op-section-head i { color: #3F6212; background:
|
|
1597
|
+
html.light .op-section-head i { color: #3F6212; background: var(--op-accent); }
|
|
1551
1598
|
.op-section-head h2 { margin: 0; font-size: 1.5rem; }
|
|
1552
1599
|
|
|
1553
1600
|
/* ----------------------------------------------------------------------------
|
|
@@ -1567,13 +1614,21 @@ html.light .op-section-head i { color: #3F6212; background: #EDFBD4; }
|
|
|
1567
1614
|
pointer-events: none;
|
|
1568
1615
|
z-index: 0;
|
|
1569
1616
|
}
|
|
1570
|
-
html.light .op-glow { opacity: .22; }
|
|
1571
1617
|
.op-glow-info { background: var(--op-info); }
|
|
1572
|
-
html.light .op-glow-info { opacity: .14; }
|
|
1573
1618
|
.op-glow-sm { width: 260px; height: 200px; }
|
|
1574
1619
|
.op-glow-lg { width: 700px; height: 460px; }
|
|
1575
1620
|
.op-glow-strong { opacity: .12; }
|
|
1576
|
-
|
|
1621
|
+
|
|
1622
|
+
/* No tema claro o verde-lima #C0FF6B é claro demais para aparecer sobre fundo
|
|
1623
|
+
branco com opacidade baixa. Usamos um verde mais saturado + mix-blend-mode:
|
|
1624
|
+
multiply (tinge o fundo em vez de clarear) para o glow ficar visível. */
|
|
1625
|
+
html.light .op-glow {
|
|
1626
|
+
background: #9AE600;
|
|
1627
|
+
opacity: .40;
|
|
1628
|
+
mix-blend-mode: multiply;
|
|
1629
|
+
}
|
|
1630
|
+
html.light .op-glow-info { background: #3B82F6; opacity: .28; }
|
|
1631
|
+
html.light .op-glow-strong { opacity: .55; }
|
|
1577
1632
|
|
|
1578
1633
|
/* ----------------------------------------------------------------------------
|
|
1579
1634
|
20c. MODAIS — VARIANTES EXTRAS
|
|
@@ -1858,7 +1913,7 @@ html.light .op-tabulator.tabulator .tabulator-footer .tabulator-page.active {
|
|
|
1858
1913
|
.op-tabulator .op-progress { min-width: 90px; }
|
|
1859
1914
|
|
|
1860
1915
|
/* ----------------------------------------------------------------------------
|
|
1861
|
-
|
|
1916
|
+
22. UTILITÁRIOS
|
|
1862
1917
|
---------------------------------------------------------------------------- */
|
|
1863
1918
|
.op-row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
|
|
1864
1919
|
.op-stack { display: flex; flex-direction: column; gap: 1rem; }
|
|
@@ -1877,11 +1932,11 @@ html.light .op-text-accent { color: #3F6212; }
|
|
|
1877
1932
|
.op-text-sm { font-size: .8125rem; }
|
|
1878
1933
|
.op-text-xs { font-size: .6875rem; }
|
|
1879
1934
|
|
|
1880
|
-
.op-mt-1 { margin-top: .5rem; } .op-mt-2 { margin-top: 1rem; } .op-mt-3 { margin-top: 1.5rem; } .op-mt-4 { margin-top:
|
|
1881
|
-
.op-mb-1 { margin-bottom: .5rem; } .op-mb-2 { margin-bottom: 1rem; } .op-mb-3 { margin-bottom: 1.5rem; } .op-mb-4 { margin-bottom:
|
|
1935
|
+
.op-mt-1 { margin-top: .5rem; } .op-mt-2 { margin-top: 1rem; } .op-mt-3 { margin-top: 1.5rem; } .op-mt-4 { margin-top: 1.75rem; }
|
|
1936
|
+
.op-mb-1 { margin-bottom: .5rem; } .op-mb-2 { margin-bottom: 1rem; } .op-mb-3 { margin-bottom: 1.5rem; } .op-mb-4 { margin-bottom: 1.75rem; }
|
|
1882
1937
|
|
|
1883
1938
|
/* ----------------------------------------------------------------------------
|
|
1884
|
-
|
|
1939
|
+
23. ANIMAÇÕES
|
|
1885
1940
|
---------------------------------------------------------------------------- */
|
|
1886
1941
|
@keyframes op-spin { to { transform: rotate(360deg); } }
|
|
1887
1942
|
@keyframes op-bounce {
|
package/ui-optago.html
CHANGED
|
@@ -3,11 +3,31 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>UI Óptago — Design System</title>
|
|
7
6
|
|
|
8
|
-
<!--
|
|
9
|
-
<
|
|
10
|
-
<
|
|
7
|
+
<!-- SEO -->
|
|
8
|
+
<title>UI Óptago | Design System em CSS puro & JS vanilla</title>
|
|
9
|
+
<meta name="description" content="Design System da Óptago: biblioteca de componentes UI em CSS puro e JavaScript vanilla, com tema claro/escuro, verde-lima #C0FF6B e app shell com sidebar colapsável. Sem Tailwind, sem build.">
|
|
10
|
+
<meta name="keywords" content="design system, ui, css puro, componentes, vanilla js, dark mode, óptago">
|
|
11
|
+
<meta name="author" content="Óptago">
|
|
12
|
+
<meta name="theme-color" content="#050505" media="(prefers-color-scheme: dark)">
|
|
13
|
+
<meta name="theme-color" content="#EEF2F7" media="(prefers-color-scheme: light)">
|
|
14
|
+
<link rel="canonical" href="https://optago.com.br/">
|
|
15
|
+
|
|
16
|
+
<!-- Open Graph / redes sociais -->
|
|
17
|
+
<meta property="og:type" content="website">
|
|
18
|
+
<meta property="og:title" content="UI Óptago Design System">
|
|
19
|
+
<meta property="og:description" content="Componentes UI em CSS puro e JS vanilla, com tema claro/escuro e o verde-lima da marca Óptago.">
|
|
20
|
+
<meta property="og:locale" content="pt_BR">
|
|
21
|
+
<meta property="og:site_name" content="Óptago">
|
|
22
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
23
|
+
<meta name="twitter:title" content="UI Óptago Design System">
|
|
24
|
+
<meta name="twitter:description" content="Componentes UI em CSS puro e JS vanilla, com tema claro/escuro e o verde-lima da marca Óptago.">
|
|
25
|
+
|
|
26
|
+
<!-- Favicon: octógono verde-lima da marca, embutido em SVG (sem arquivo externo) -->
|
|
27
|
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><polygon points=%2230,4 70,4 96,30 96,70 70,96 30,96 4,70 4,30%22 fill=%22%23C0FF6B%22/></svg>">
|
|
28
|
+
|
|
29
|
+
<link rel="stylesheet" href="./ui-optago.css">
|
|
30
|
+
<script src="./ui-optago.js"></script>
|
|
11
31
|
</head>
|
|
12
32
|
|
|
13
33
|
<body class="op-app">
|
|
@@ -15,7 +35,7 @@
|
|
|
15
35
|
<!-- ==================== COLUNA PRINCIPAL (header + main + footer) ==================== -->
|
|
16
36
|
<div class="op-app-body">
|
|
17
37
|
|
|
18
|
-
<!-- Glows de fundo (verde-lima desfocado)
|
|
38
|
+
<!-- Glows de fundo (verde-lima desfocado) ficam atrás do conteúdo -->
|
|
19
39
|
<div class="op-glow op-glow-lg" style="top:-140px; left:22%;"></div>
|
|
20
40
|
<div class="op-glow op-glow-sm" style="bottom:10%; left:-80px;"></div>
|
|
21
41
|
<div class="op-glow op-glow-info op-glow-sm" style="bottom:-60px; right:8%;"></div>
|
|
@@ -29,8 +49,8 @@
|
|
|
29
49
|
</div>
|
|
30
50
|
<div class="op-header-divider"></div>
|
|
31
51
|
<div class="op-header-group">
|
|
32
|
-
<strong style="font-family:var(--op-font-display); font-size:.875rem;">UI
|
|
33
|
-
<span class="op-badge op-badge-brand op-badge-pill"><span class="op-dot op-dot-pulse"></span>v1.0</span>
|
|
52
|
+
<strong style="font-family:var(--op-font-display); font-size:.875rem;">UI</strong>
|
|
53
|
+
<span class="op-badge op-badge-brand op-badge-pill"><span class="op-dot op-dot-pulse"></span>v1.0.2</span>
|
|
34
54
|
</div>
|
|
35
55
|
</div>
|
|
36
56
|
<div class="op-header-group">
|
|
@@ -38,6 +58,7 @@
|
|
|
38
58
|
<i class="ph ph-moon op-icon-moon"></i>
|
|
39
59
|
<i class="ph ph-sun op-icon-sun" style="display:none"></i>
|
|
40
60
|
</button>
|
|
61
|
+
|
|
41
62
|
<!-- Hamburguer: aparece só no mobile para abrir o drawer -->
|
|
42
63
|
<button class="op-btn op-btn-icon op-mobile-only" data-op-sidebar-mobile>
|
|
43
64
|
<i class="ph ph-list"></i>
|
|
@@ -52,11 +73,21 @@
|
|
|
52
73
|
<section class="op-mb-4">
|
|
53
74
|
<h1>Design System Óptago</h1>
|
|
54
75
|
<p class="op-text-muted" style="max-width:640px;">
|
|
55
|
-
Biblioteca completa de componentes em <strong>CSS puro</strong>
|
|
76
|
+
Biblioteca completa de componentes em <strong>CSS puro</strong> sem Tailwind, sem build.
|
|
56
77
|
Inclua <code>ui-optago.css</code> e <code>ui-optago.js</code> no seu projeto e use as classes
|
|
57
78
|
com prefixo <code>op-</code>. Em cada bloco abaixo, use <strong>Copiar</strong> para levar o
|
|
58
79
|
HTML direto pro seu projeto, ou <strong>Ver código</strong> para inspecionar.
|
|
59
80
|
</p>
|
|
81
|
+
|
|
82
|
+
<div class="op-alert op-alert-info op-mt-2 ">
|
|
83
|
+
<i class="ph ph-cloud-arrow-down"></i>
|
|
84
|
+
<div style="min-width:0; flex:1;">
|
|
85
|
+
<p class="op-alert-title">Usar via CDN</p>
|
|
86
|
+
<p class="op-alert-text op-mb-1">Sem baixar nada adicione as duas linhas ao <code><head></code>:</p>
|
|
87
|
+
<pre class="op-demo-code is-visible" style="border:1px solid var(--op-border); border-radius:var(--op-radius-sm); margin:0;"><link rel="stylesheet" href="https://unpkg.com/ui-optago/ui-optago.css">
|
|
88
|
+
<script src="https://unpkg.com/ui-optago/ui-optago.js"></script></pre>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
60
91
|
</section>
|
|
61
92
|
|
|
62
93
|
<!-- ==================== 1. CORES ==================== -->
|
|
@@ -68,19 +99,19 @@
|
|
|
68
99
|
<div class="op-grid-4 op-mb-4">
|
|
69
100
|
<div class="op-card op-card-hover" style="padding:0; overflow:hidden;">
|
|
70
101
|
<div style="height:72px; background:#000;"></div>
|
|
71
|
-
<div style="padding:.875rem 1rem;"><strong>Preto
|
|
102
|
+
<div style="padding:.875rem 1rem;"><strong>Preto Base</strong><br><code class="op-text-muted op-text-xs">#000000</code></div>
|
|
72
103
|
</div>
|
|
73
104
|
<div class="op-card op-card-hover" style="padding:0; overflow:hidden;">
|
|
74
105
|
<div style="height:72px; background:#C0FF6B;"></div>
|
|
75
|
-
<div style="padding:.875rem 1rem;"><strong>Verde-lima
|
|
106
|
+
<div style="padding:.875rem 1rem;"><strong>Verde-lima Destaque</strong><br><code class="op-text-muted op-text-xs">#C0FF6B · --op-accent</code></div>
|
|
76
107
|
</div>
|
|
77
108
|
<div class="op-card op-card-hover" style="padding:0; overflow:hidden;">
|
|
78
109
|
<div style="height:72px; background:#D5D5D5;"></div>
|
|
79
|
-
<div style="padding:.875rem 1rem;"><strong>Cinza-claro
|
|
110
|
+
<div style="padding:.875rem 1rem;"><strong>Cinza-claro Texto</strong><br><code class="op-text-muted op-text-xs">#D5D5D5 · --op-text</code></div>
|
|
80
111
|
</div>
|
|
81
112
|
<div class="op-card op-card-hover" style="padding:0; overflow:hidden;">
|
|
82
113
|
<div style="height:72px; background:#656565;"></div>
|
|
83
|
-
<div style="padding:.875rem 1rem;"><strong>Cinza-chumbo
|
|
114
|
+
<div style="padding:.875rem 1rem;"><strong>Cinza-chumbo Apoio</strong><br><code class="op-text-muted op-text-xs">#656565 · --op-muted</code></div>
|
|
84
115
|
</div>
|
|
85
116
|
</div>
|
|
86
117
|
|
|
@@ -116,14 +147,14 @@
|
|
|
116
147
|
</div>
|
|
117
148
|
<div class="op-demo">
|
|
118
149
|
<div class="op-demo-preview" id="d-tipografia">
|
|
119
|
-
<h1>Heading 1
|
|
120
|
-
<h2>Heading 2
|
|
121
|
-
<h3>Heading 3
|
|
122
|
-
<h4>Heading 4
|
|
150
|
+
<h1>Heading 1 Chakra Petch</h1>
|
|
151
|
+
<h2>Heading 2 Seções</h2>
|
|
152
|
+
<h3>Heading 3 Cards e blocos</h3>
|
|
153
|
+
<h4>Heading 4 Subtítulos</h4>
|
|
123
154
|
<p>Parágrafo padrão em <strong>Inter</strong>. Criamos e mantemos produtos próprios e sob medida,
|
|
124
155
|
sempre com a mesma régua: proteger dados, reduzir atrito e manter tudo no ar.</p>
|
|
125
156
|
<p class="op-text-muted">Texto secundário / muted para descrições e apoio.</p>
|
|
126
|
-
<p class="op-text-mono op-text-sm">JetBrains Mono
|
|
157
|
+
<p class="op-text-mono op-text-sm">JetBrains Mono dados técnicos, códigos e rótulos. <span class="op-text-accent">optago.com.br</span></p>
|
|
127
158
|
<p>Atalho de teclado: <kbd>Ctrl</kbd> + <kbd>K</kbd> · código inline: <code>--op-accent: #C0FF6B</code></p>
|
|
128
159
|
</div>
|
|
129
160
|
<div class="op-demo-bar">
|
|
@@ -318,7 +349,7 @@
|
|
|
318
349
|
<label class="op-switch"><input type="checkbox"> <span>Modo manutenção</span></label>
|
|
319
350
|
</div>
|
|
320
351
|
<div class="op-field" style="max-width:320px;">
|
|
321
|
-
<label class="op-label" for="f-range">Range
|
|
352
|
+
<label class="op-label" for="f-range">Range 75%</label>
|
|
322
353
|
<input class="op-range" id="f-range" type="range" min="0" max="100" value="75">
|
|
323
354
|
</div>
|
|
324
355
|
</div>
|
|
@@ -412,12 +443,12 @@
|
|
|
412
443
|
</div>
|
|
413
444
|
</div>
|
|
414
445
|
|
|
415
|
-
<h3 class="op-mt-3 op-mb-2"><i class="ph ph-lightning op-text-accent"></i> Tabela avançada
|
|
446
|
+
<h3 class="op-mt-3 op-mb-2"><i class="ph ph-lightning op-text-accent"></i> Tabela avançada Tabulator</h3>
|
|
416
447
|
<p class="op-text-muted op-text-sm op-mb-2">
|
|
417
448
|
Para tabelas com ordenação, paginação e filtros, use a variante com
|
|
418
449
|
<a href="https://tabulator.info" target="_blank" rel="noopener">Tabulator</a> e tema Óptago.
|
|
419
450
|
A biblioteca é carregada sob demanda: <code>OptagoUI.tabulator('#minhaTabela', opções)</code>
|
|
420
|
-
|
|
451
|
+
clique nos cabeçalhos para ordenar.
|
|
421
452
|
</p>
|
|
422
453
|
<div class="op-demo">
|
|
423
454
|
<div class="op-demo-preview" id="d-tabulator-wrap">
|
|
@@ -638,7 +669,7 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
638
669
|
<p class="op-text-muted" style="margin:0;">Ajuste preferências, chaves de API e integrações.</p>
|
|
639
670
|
</div>
|
|
640
671
|
<div class="op-tab-panel" data-op-tab-panel="logs">
|
|
641
|
-
<p class="op-text-mono op-text-sm" style="margin:0;">[12:04:31] INFO
|
|
672
|
+
<p class="op-text-mono op-text-sm" style="margin:0;">[12:04:31] INFO serviço reiniciado com sucesso</p>
|
|
642
673
|
</div>
|
|
643
674
|
</div>
|
|
644
675
|
<div data-op-tab-group="exemplo2" class="op-mb-3">
|
|
@@ -704,11 +735,11 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
704
735
|
<div class="op-accordion">
|
|
705
736
|
<details open>
|
|
706
737
|
<summary>O que é a Óptago?</summary>
|
|
707
|
-
<div class="op-accordion-body">Criamos e mantemos produtos próprios (Comanda Rápida, Stats Rails, Brasil Buscador) e prestamos serviços sob medida
|
|
738
|
+
<div class="op-accordion-body">Criamos e mantemos produtos próprios (Comanda Rápida, Stats Rails, Brasil Buscador) e prestamos serviços sob medida sempre com a mesma régua: segurança, privacidade e performance.</div>
|
|
708
739
|
</details>
|
|
709
740
|
<details>
|
|
710
741
|
<summary>O site usa cookies?</summary>
|
|
711
|
-
<div class="op-accordion-body">
|
|
742
|
+
<div class="op-accordion-body">Usamos apenas 1 cookie, para lembrar se você prefere o tema claro ou escuro. Nenhum rastreador ou coleta de dados além disso.</div>
|
|
712
743
|
</details>
|
|
713
744
|
<details>
|
|
714
745
|
<summary>Como funciona o suporte?</summary>
|
|
@@ -829,7 +860,7 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
829
860
|
<span class="op-timeline-marker is-warning"></span>
|
|
830
861
|
<span class="op-timeline-time">Hoje · 11:20</span>
|
|
831
862
|
<p class="op-timeline-title">Alerta de uso de disco</p>
|
|
832
|
-
<p class="op-timeline-text">Volume principal atingiu 85%
|
|
863
|
+
<p class="op-timeline-text">Volume principal atingiu 85% limpeza automática agendada.</p>
|
|
833
864
|
</li>
|
|
834
865
|
<li class="op-timeline-item">
|
|
835
866
|
<span class="op-timeline-marker is-danger"></span>
|
|
@@ -856,22 +887,22 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
856
887
|
<section id="efeitos" class="op-mb-4" style="scroll-margin-top:1rem;">
|
|
857
888
|
<div class="op-section-head">
|
|
858
889
|
<i class="ph ph-sparkle"></i>
|
|
859
|
-
<h2>Efeitos
|
|
890
|
+
<h2>Efeitos Glow verde-lima</h2>
|
|
860
891
|
</div>
|
|
861
892
|
<p class="op-text-muted op-text-sm op-mb-2">
|
|
862
|
-
Manchas desfocadas de verde-lima para dar profundidade ao fundo
|
|
893
|
+
Manchas desfocadas de verde-lima para dar profundidade ao fundo esta própria página usa três
|
|
863
894
|
(topo e cantos). Posicione <code>.op-glow</code> dentro de um container com
|
|
864
895
|
<code>position:relative</code>; o conteúdo por cima deve ter <code>z-index</code> maior.
|
|
865
896
|
Variações: <code>op-glow-sm</code>, <code>op-glow-lg</code>, <code>op-glow-strong</code>, <code>op-glow-info</code>.
|
|
866
897
|
</p>
|
|
867
898
|
<div class="op-demo">
|
|
868
899
|
<div class="op-demo-preview" style="padding:0;">
|
|
869
|
-
<div id="d-efeitos" style="position:relative; overflow:
|
|
900
|
+
<div id="d-efeitos" style="position:relative; overflow:clip; padding:3.5rem 2rem; border-radius:0;">
|
|
870
901
|
<div class="op-glow op-glow-strong" style="top:-120px; left:-60px;"></div>
|
|
871
902
|
<div class="op-glow op-glow-sm op-glow-strong" style="bottom:-100px; right:10%;"></div>
|
|
872
903
|
<div style="position:relative; z-index:1; text-align:center; max-width:520px; margin:0 auto;">
|
|
873
904
|
<h2 style="margin-bottom:.5rem;">Hero com glow de fundo</h2>
|
|
874
|
-
<p class="op-text-muted op-mb-2">Segurança, privacidade e performance
|
|
905
|
+
<p class="op-text-muted op-mb-2">Segurança, privacidade e performance a mesma régua em todos os produtos.</p>
|
|
875
906
|
<button class="op-btn op-btn-primary"><i class="ph ph-rocket-launch"></i> Começar agora</button>
|
|
876
907
|
</div>
|
|
877
908
|
</div>
|
|
@@ -906,7 +937,34 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
906
937
|
</div>
|
|
907
938
|
</section>
|
|
908
939
|
|
|
909
|
-
<!-- ==================== 17.
|
|
940
|
+
<!-- ==================== 17. CARREGAMENTO ==================== -->
|
|
941
|
+
<section id="carregamento" class="op-mb-4" style="scroll-margin-top:1rem;">
|
|
942
|
+
<div class="op-section-head">
|
|
943
|
+
<i class="ph ph-circle-notch"></i>
|
|
944
|
+
<h2>Tela de carregamento</h2>
|
|
945
|
+
</div>
|
|
946
|
+
<div class="op-demo">
|
|
947
|
+
<div class="op-demo-preview" id="d-carregamento">
|
|
948
|
+
<p class="op-text-muted op-text-sm" style="margin-top:0;">Overlay em tela cheia para usar ao submeter formulários ou aguardar uma ação. API: <code>OptagoUI.showLoading(mensagem)</code> / <code>OptagoUI.hideLoading()</code>.</p>
|
|
949
|
+
<div class="op-row">
|
|
950
|
+
<button class="op-btn op-btn-primary" onclick="OptagoUI.showLoading('Salvando alterações...'); setTimeout(OptagoUI.hideLoading, 2200)">
|
|
951
|
+
<i class="ph ph-floppy-disk"></i> Disparar via JS
|
|
952
|
+
</button>
|
|
953
|
+
<form data-op-loading-form data-op-loading-message="Enviando formulário..." onsubmit="event.preventDefault(); setTimeout(OptagoUI.hideLoading, 2200)">
|
|
954
|
+
<button class="op-btn op-btn-secondary" type="submit">
|
|
955
|
+
<i class="ph ph-paper-plane-tilt"></i> Disparar via submit do form
|
|
956
|
+
</button>
|
|
957
|
+
</form>
|
|
958
|
+
</div>
|
|
959
|
+
</div>
|
|
960
|
+
<div class="op-demo-bar">
|
|
961
|
+
<button class="op-btn op-btn-ghost op-btn-sm" data-op-code="#d-carregamento"><i class="ph ph-code"></i> Ver código</button>
|
|
962
|
+
<button class="op-btn op-btn-secondary op-btn-sm" data-op-copy="#d-carregamento"><i class="ph ph-copy"></i> Copiar</button>
|
|
963
|
+
</div>
|
|
964
|
+
</div>
|
|
965
|
+
</section>
|
|
966
|
+
|
|
967
|
+
<!-- ==================== 18. MODAIS ==================== -->
|
|
910
968
|
<section id="modais" class="op-mb-4" style="scroll-margin-top:1rem;">
|
|
911
969
|
<div class="op-section-head">
|
|
912
970
|
<i class="ph ph-app-window"></i>
|
|
@@ -939,17 +997,17 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
939
997
|
</div>
|
|
940
998
|
</section>
|
|
941
999
|
|
|
942
|
-
<!-- ====================
|
|
1000
|
+
<!-- ==================== 19. LAYOUT ==================== -->
|
|
943
1001
|
<section id="layout" class="op-mb-4" style="scroll-margin-top:1rem;">
|
|
944
1002
|
<div class="op-section-head">
|
|
945
1003
|
<i class="ph ph-layout"></i>
|
|
946
|
-
<h2>Layout
|
|
1004
|
+
<h2>Layout App Shell</h2>
|
|
947
1005
|
</div>
|
|
948
1006
|
<div class="op-alert op-alert-info op-mb-2">
|
|
949
1007
|
<i class="ph ph-info"></i>
|
|
950
1008
|
<div>
|
|
951
1009
|
<p class="op-alert-title">Esta própria página usa o app shell</p>
|
|
952
|
-
<p class="op-alert-text">Header, footer e sidebar (direita) são fixos
|
|
1010
|
+
<p class="op-alert-text">Header, footer e sidebar (direita) são fixos apenas o conteúdo central rola. A sidebar colapsa no desktop (só ícones + tooltip) e vira drawer no mobile.</p>
|
|
953
1011
|
</div>
|
|
954
1012
|
</div>
|
|
955
1013
|
<div class="op-demo">
|
|
@@ -979,8 +1037,8 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
979
1037
|
|
|
980
1038
|
<!-- FOOTER (fixo) -->
|
|
981
1039
|
<footer class="op-footer">
|
|
982
|
-
<span>ÓPTAGO © 2026
|
|
983
|
-
<span>optago.com.br ·
|
|
1040
|
+
<span>ÓPTAGO © 2026 Design System v1.0.2</span>
|
|
1041
|
+
<span><a href="https://optago.com.br" target="_blank" rel="noopener">optago.com.br</a> · 1 cookie (só p/ tema)</span>
|
|
984
1042
|
</footer>
|
|
985
1043
|
</div>
|
|
986
1044
|
|
|
@@ -1014,6 +1072,7 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
1014
1072
|
<a class="op-nav-item" href="#efeitos"><i class="ph ph-sparkle"></i><span class="op-nav-text">Efeitos / Glow</span><span class="op-nav-tooltip">Efeitos / Glow</span></a>
|
|
1015
1073
|
<div class="op-sidebar-label">Interativos</div>
|
|
1016
1074
|
<a class="op-nav-item" href="#toasts"><i class="ph ph-bell-ringing"></i><span class="op-nav-text">Toasts</span><span class="op-nav-tooltip">Toasts</span></a>
|
|
1075
|
+
<a class="op-nav-item" href="#carregamento"><i class="ph ph-circle-notch"></i><span class="op-nav-text">Carregamento</span><span class="op-nav-tooltip">Carregamento</span></a>
|
|
1017
1076
|
<a class="op-nav-item" href="#modais"><i class="ph ph-app-window"></i><span class="op-nav-text">Modais</span><span class="op-nav-tooltip">Modais</span></a>
|
|
1018
1077
|
<a class="op-nav-item" href="#layout"><i class="ph ph-layout"></i><span class="op-nav-text">Layout</span><span class="op-nav-tooltip">Layout</span></a>
|
|
1019
1078
|
</nav>
|
package/ui-optago.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
|
-
UI ÓPTAGO — Design System v1.0 (JavaScript)
|
|
2
|
+
UI ÓPTAGO — Design System v1.0.2 (JavaScript)
|
|
3
3
|
Sem dependências de build. Carregue no <head> SEM defer para evitar
|
|
4
4
|
flash de tema errado (FOUC):
|
|
5
5
|
|
|
@@ -21,9 +21,13 @@
|
|
|
21
21
|
data-op-dismiss → remove o elemento pai .op-alert
|
|
22
22
|
data-op-copy="#seletor" → copia o HTML do elemento alvo
|
|
23
23
|
data-op-code="#seletor" → mostra/esconde o código-fonte do alvo
|
|
24
|
+
data-op-loading-form → no <form>: mostra a tela de carregamento
|
|
25
|
+
sozinho ao submeter (mensagem opcional em
|
|
26
|
+
data-op-loading-message="Enviando...")
|
|
24
27
|
|
|
25
28
|
API global: OptagoUI.toast(msg, tipo, ms) · OptagoUI.openModal(sel)
|
|
26
29
|
OptagoUI.closeModal(sel) · OptagoUI.setTheme('dark'|'light')
|
|
30
|
+
OptagoUI.showLoading(msg) · OptagoUI.hideLoading()
|
|
27
31
|
============================================================================ */
|
|
28
32
|
(function () {
|
|
29
33
|
'use strict';
|
|
@@ -241,6 +245,45 @@
|
|
|
241
245
|
});
|
|
242
246
|
};
|
|
243
247
|
|
|
248
|
+
/* --------------------------------------------------------------------------
|
|
249
|
+
5c. TELA DE CARREGAMENTO — overlay em tela cheia
|
|
250
|
+
Uso: OptagoUI.showLoading('Salvando...') ... OptagoUI.hideLoading()
|
|
251
|
+
ou data-op-loading-form no <form> para acionar sozinho no submit.
|
|
252
|
+
-------------------------------------------------------------------------- */
|
|
253
|
+
var LOADING_ID = 'opLoadingOverlay';
|
|
254
|
+
|
|
255
|
+
function getLoadingOverlay() {
|
|
256
|
+
var ov = document.getElementById(LOADING_ID);
|
|
257
|
+
if (!ov) {
|
|
258
|
+
ov = document.createElement('div');
|
|
259
|
+
ov.id = LOADING_ID;
|
|
260
|
+
ov.className = 'op-loading-overlay';
|
|
261
|
+
ov.setAttribute('role', 'alert');
|
|
262
|
+
ov.setAttribute('aria-live', 'assertive');
|
|
263
|
+
ov.innerHTML =
|
|
264
|
+
'<span class="op-spinner"></span>' +
|
|
265
|
+
'<span class="op-loading-message"></span>';
|
|
266
|
+
document.body.appendChild(ov);
|
|
267
|
+
}
|
|
268
|
+
return ov;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
OptagoUI.showLoading = function (message) {
|
|
272
|
+
var ov = getLoadingOverlay();
|
|
273
|
+
ov.querySelector('.op-loading-message').textContent = message || 'Carregando...';
|
|
274
|
+
ov.classList.add('is-open');
|
|
275
|
+
requestAnimationFrame(function () {
|
|
276
|
+
requestAnimationFrame(function () { ov.classList.add('is-visible'); });
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
OptagoUI.hideLoading = function () {
|
|
281
|
+
var ov = document.getElementById(LOADING_ID);
|
|
282
|
+
if (!ov) return;
|
|
283
|
+
ov.classList.remove('is-visible');
|
|
284
|
+
setTimeout(function () { ov.classList.remove('is-open'); }, 250);
|
|
285
|
+
};
|
|
286
|
+
|
|
244
287
|
/* --------------------------------------------------------------------------
|
|
245
288
|
6. HELPERS DO SHOWCASE — copiar HTML / ver código
|
|
246
289
|
-------------------------------------------------------------------------- */
|
|
@@ -395,6 +438,14 @@
|
|
|
395
438
|
tip.style.left = 'auto';
|
|
396
439
|
});
|
|
397
440
|
|
|
441
|
+
// Formulário com data-op-loading-form: mostra a tela de carregamento
|
|
442
|
+
// sozinho ao submeter (mensagem em data-op-loading-message, se houver).
|
|
443
|
+
document.addEventListener('submit', function (e) {
|
|
444
|
+
var form = e.target.closest('[data-op-loading-form]');
|
|
445
|
+
if (!form) return;
|
|
446
|
+
OptagoUI.showLoading(form.getAttribute('data-op-loading-message'));
|
|
447
|
+
});
|
|
448
|
+
|
|
398
449
|
// ESC fecha modais e dropdowns
|
|
399
450
|
document.addEventListener('keydown', function (e) {
|
|
400
451
|
if (e.key !== 'Escape') return;
|