ui-optago 1.0.1 → 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/package.json +1 -1
- package/ui-optago.css +74 -28
- package/ui-optago.html +37 -9
- package/ui-optago.js +52 -1
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 {
|
|
@@ -279,12 +281,12 @@ html.light .op-brand-mark::after { background: var(--op-accent); }
|
|
|
279
281
|
.op-main {
|
|
280
282
|
flex: 1;
|
|
281
283
|
overflow-y: auto;
|
|
282
|
-
padding:
|
|
284
|
+
padding: 1.5rem;
|
|
283
285
|
scroll-behavior: smooth;
|
|
284
286
|
position: relative;
|
|
285
287
|
z-index: 1; /* mantém o conteúdo acima dos .op-glow do fundo */
|
|
286
288
|
}
|
|
287
|
-
@media (min-width: 1024px) { .op-main { padding:
|
|
289
|
+
@media (min-width: 1024px) { .op-main { padding: 1.75rem 2rem; } }
|
|
288
290
|
|
|
289
291
|
.op-container { max-width: 1100px; margin: 0 auto; }
|
|
290
292
|
|
|
@@ -358,25 +360,28 @@ html.light .op-brand-mark::after { background: var(--op-accent); }
|
|
|
358
360
|
align-items: center;
|
|
359
361
|
gap: .75rem;
|
|
360
362
|
padding: .625rem .75rem;
|
|
363
|
+
border: 1px solid transparent;
|
|
361
364
|
border-radius: var(--op-radius);
|
|
362
365
|
color: var(--op-text);
|
|
363
366
|
text-decoration: none;
|
|
364
367
|
font-weight: 600;
|
|
365
368
|
font-size: .875rem;
|
|
366
369
|
white-space: nowrap;
|
|
367
|
-
transition: background .2s ease, color .2s ease;
|
|
370
|
+
transition: background .2s ease, color .2s ease, border-color .2s ease;
|
|
368
371
|
}
|
|
369
372
|
.op-nav-item i { font-size: 1.25rem; flex-shrink: 0; }
|
|
370
373
|
.op-nav-item:hover {
|
|
371
374
|
background: color-mix(in srgb, var(--op-strong) 6%, transparent);
|
|
375
|
+
border-color: var(--op-border-2);
|
|
372
376
|
color: var(--op-strong);
|
|
373
377
|
}
|
|
374
378
|
.op-nav-item.is-active {
|
|
375
|
-
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);
|
|
376
381
|
color: var(--op-strong);
|
|
377
382
|
box-shadow: inset -3px 0 0 var(--op-accent);
|
|
378
383
|
}
|
|
379
|
-
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); }
|
|
380
385
|
.op-nav-item.is-active i { color: var(--op-accent); }
|
|
381
386
|
html.light .op-nav-item.is-active i { color: #3F6212; }
|
|
382
387
|
|
|
@@ -385,7 +390,7 @@ html.light .op-nav-item.is-active i { color: #3F6212; }
|
|
|
385
390
|
.op-sidebar.is-collapsed .op-nav-text,
|
|
386
391
|
.op-sidebar.is-collapsed .op-sidebar-label,
|
|
387
392
|
.op-sidebar.is-collapsed .op-sidebar-header-text { display: none; }
|
|
388
|
-
.op-sidebar.is-collapsed .op-nav-item { justify-content: center; padding
|
|
393
|
+
.op-sidebar.is-collapsed .op-nav-item { justify-content: center; padding: .625rem; }
|
|
389
394
|
|
|
390
395
|
/* Tooltip do item (aparece à esquerda quando colapsada).
|
|
391
396
|
position:fixed — o JS calcula top/right no hover, pois o overflow-y:auto
|
|
@@ -1489,17 +1494,53 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1489
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); }
|
|
1490
1495
|
|
|
1491
1496
|
/* ----------------------------------------------------------------------------
|
|
1492
|
-
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)
|
|
1493
1532
|
---------------------------------------------------------------------------- */
|
|
1494
1533
|
.op-demo {
|
|
1495
1534
|
background: var(--op-panel);
|
|
1496
1535
|
border: 1px solid var(--op-border);
|
|
1497
1536
|
border-radius: var(--op-radius-lg);
|
|
1498
|
-
overflow: hidden;
|
|
1499
1537
|
box-shadow: var(--op-shadow);
|
|
1500
1538
|
}
|
|
1539
|
+
/* Sem overflow:hidden no container: dropdowns/tooltips exibidos dentro do
|
|
1540
|
+
preview não podem ser cortados. O arredondamento é feito nos filhos. */
|
|
1501
1541
|
.op-demo-preview {
|
|
1502
|
-
padding:
|
|
1542
|
+
padding: 1.5rem;
|
|
1543
|
+
border-radius: var(--op-radius-lg) var(--op-radius-lg) 0 0;
|
|
1503
1544
|
background:
|
|
1504
1545
|
radial-gradient(color-mix(in srgb, var(--op-border) 55%, transparent) 1px, transparent 1px);
|
|
1505
1546
|
background-size: 22px 22px;
|
|
@@ -1511,7 +1552,11 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1511
1552
|
padding: .625rem .875rem;
|
|
1512
1553
|
border-top: 1px solid var(--op-border);
|
|
1513
1554
|
background: var(--op-panel-2);
|
|
1555
|
+
border-radius: 0 0 var(--op-radius-lg) var(--op-radius-lg);
|
|
1514
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; }
|
|
1515
1560
|
.op-demo-code {
|
|
1516
1561
|
display: none;
|
|
1517
1562
|
margin: 0;
|
|
@@ -1525,6 +1570,7 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1525
1570
|
overflow-x: auto;
|
|
1526
1571
|
tab-size: 2;
|
|
1527
1572
|
white-space: pre;
|
|
1573
|
+
border-radius: 0 0 var(--op-radius-lg) var(--op-radius-lg);
|
|
1528
1574
|
}
|
|
1529
1575
|
.op-demo-code.is-visible { display: block; }
|
|
1530
1576
|
|
|
@@ -1533,14 +1579,14 @@ html.light .op-modal { background: rgba(15,23,42,.5); }
|
|
|
1533
1579
|
display: flex;
|
|
1534
1580
|
align-items: center;
|
|
1535
1581
|
gap: .75rem;
|
|
1536
|
-
padding-bottom:
|
|
1537
|
-
margin-bottom: 1.
|
|
1582
|
+
padding-bottom: .75rem;
|
|
1583
|
+
margin-bottom: 1.125rem;
|
|
1538
1584
|
border-bottom: 1px solid var(--op-border);
|
|
1539
1585
|
}
|
|
1540
1586
|
.op-section-head i {
|
|
1541
|
-
font-size: 1.
|
|
1587
|
+
font-size: 1.25rem;
|
|
1542
1588
|
color: var(--op-accent);
|
|
1543
|
-
width:
|
|
1589
|
+
width: 38px; height: 38px;
|
|
1544
1590
|
display: flex;
|
|
1545
1591
|
align-items: center;
|
|
1546
1592
|
justify-content: center;
|
|
@@ -1867,7 +1913,7 @@ html.light .op-tabulator.tabulator .tabulator-footer .tabulator-page.active {
|
|
|
1867
1913
|
.op-tabulator .op-progress { min-width: 90px; }
|
|
1868
1914
|
|
|
1869
1915
|
/* ----------------------------------------------------------------------------
|
|
1870
|
-
|
|
1916
|
+
22. UTILITÁRIOS
|
|
1871
1917
|
---------------------------------------------------------------------------- */
|
|
1872
1918
|
.op-row { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
|
|
1873
1919
|
.op-stack { display: flex; flex-direction: column; gap: 1rem; }
|
|
@@ -1886,11 +1932,11 @@ html.light .op-text-accent { color: #3F6212; }
|
|
|
1886
1932
|
.op-text-sm { font-size: .8125rem; }
|
|
1887
1933
|
.op-text-xs { font-size: .6875rem; }
|
|
1888
1934
|
|
|
1889
|
-
.op-mt-1 { margin-top: .5rem; } .op-mt-2 { margin-top: 1rem; } .op-mt-3 { margin-top: 1.5rem; } .op-mt-4 { margin-top:
|
|
1890
|
-
.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; }
|
|
1891
1937
|
|
|
1892
1938
|
/* ----------------------------------------------------------------------------
|
|
1893
|
-
|
|
1939
|
+
23. ANIMAÇÕES
|
|
1894
1940
|
---------------------------------------------------------------------------- */
|
|
1895
1941
|
@keyframes op-spin { to { transform: rotate(360deg); } }
|
|
1896
1942
|
@keyframes op-bounce {
|
package/ui-optago.html
CHANGED
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
<!-- Favicon: octógono verde-lima da marca, embutido em SVG (sem arquivo externo) -->
|
|
27
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
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
<link rel="stylesheet" href="./ui-optago.css">
|
|
30
|
+
<script src="./ui-optago.js"></script>
|
|
31
31
|
</head>
|
|
32
32
|
|
|
33
33
|
<body class="op-app">
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
<div class="op-header-divider"></div>
|
|
51
51
|
<div class="op-header-group">
|
|
52
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.
|
|
53
|
+
<span class="op-badge op-badge-brand op-badge-pill"><span class="op-dot op-dot-pulse"></span>v1.0.2</span>
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
56
56
|
<div class="op-header-group">
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
<p>Parágrafo padrão em <strong>Inter</strong>. Criamos e mantemos produtos próprios e sob medida,
|
|
155
155
|
sempre com a mesma régua: proteger dados, reduzir atrito e manter tudo no ar.</p>
|
|
156
156
|
<p class="op-text-muted">Texto secundário / muted para descrições e apoio.</p>
|
|
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
|
|
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>
|
|
158
158
|
<p>Atalho de teclado: <kbd>Ctrl</kbd> + <kbd>K</kbd> · código inline: <code>--op-accent: #C0FF6B</code></p>
|
|
159
159
|
</div>
|
|
160
160
|
<div class="op-demo-bar">
|
|
@@ -739,7 +739,7 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
739
739
|
</details>
|
|
740
740
|
<details>
|
|
741
741
|
<summary>O site usa cookies?</summary>
|
|
742
|
-
<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>
|
|
743
743
|
</details>
|
|
744
744
|
<details>
|
|
745
745
|
<summary>Como funciona o suporte?</summary>
|
|
@@ -937,7 +937,34 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
937
937
|
</div>
|
|
938
938
|
</section>
|
|
939
939
|
|
|
940
|
-
<!-- ==================== 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 ==================== -->
|
|
941
968
|
<section id="modais" class="op-mb-4" style="scroll-margin-top:1rem;">
|
|
942
969
|
<div class="op-section-head">
|
|
943
970
|
<i class="ph ph-app-window"></i>
|
|
@@ -970,7 +997,7 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
970
997
|
</div>
|
|
971
998
|
</section>
|
|
972
999
|
|
|
973
|
-
<!-- ====================
|
|
1000
|
+
<!-- ==================== 19. LAYOUT ==================== -->
|
|
974
1001
|
<section id="layout" class="op-mb-4" style="scroll-margin-top:1rem;">
|
|
975
1002
|
<div class="op-section-head">
|
|
976
1003
|
<i class="ph ph-layout"></i>
|
|
@@ -1010,8 +1037,8 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
1010
1037
|
|
|
1011
1038
|
<!-- FOOTER (fixo) -->
|
|
1012
1039
|
<footer class="op-footer">
|
|
1013
|
-
<span>ÓPTAGO © 2026 Design System v1.0.
|
|
1014
|
-
<span><a href="https://optago.com.br" target="_blank" rel="noopener">optago.com.br</a> ·
|
|
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>
|
|
1015
1042
|
</footer>
|
|
1016
1043
|
</div>
|
|
1017
1044
|
|
|
@@ -1045,6 +1072,7 @@ OptagoUI.tabulator('#minhaTabela', {
|
|
|
1045
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>
|
|
1046
1073
|
<div class="op-sidebar-label">Interativos</div>
|
|
1047
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>
|
|
1048
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>
|
|
1049
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>
|
|
1050
1078
|
</nav>
|
package/ui-optago.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* ============================================================================
|
|
2
|
-
UI ÓPTAGO — Design System v1.0.
|
|
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;
|