@thibezer/ui-components-kit 2.17.0 → 2.17.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.
@@ -0,0 +1,405 @@
1
+ var M = Object.defineProperty;
2
+ var A = (s, t, a) => t in s ? M(s, t, { enumerable: !0, configurable: !0, writable: !0, value: a }) : s[t] = a;
3
+ var d = (s, t, a) => A(s, typeof t != "symbol" ? t + "" : t, a);
4
+ import { d as q, S as P } from "./ssr-safe-5cWfJP-s.js";
5
+ import { L as j } from "./listener-bag-DQgv7OON.js";
6
+ const O = ':host{--_t: var(--ui-cor-texto, #e1e1e6);--_t2: var(--ui-cor-texto-secundario, #9696a6);--_linha: var(--ui-cor-borda, rgba(255, 255, 255, .12));--_realce: color-mix(in srgb, var(--_t) 8%, transparent);--_realce-forte: color-mix(in srgb, var(--_t) 16%, transparent);--_campo: color-mix(in srgb, var(--ui-cor-fundo, #0b0b0d) 70%, transparent);--_destaque: var(--ui-cor-primaria, #00e08a);--_sobre-destaque: var(--ui-cor-texto-sobre-primaria, #000000);--_vermelho: #ef4444;position:fixed;top:0;left:0;z-index:var(--ui-seletor-cor-z, 10000);display:block;width:268px;max-height:calc(100vh - 20px);overflow-y:auto;box-sizing:border-box;padding:13px;background:var(--ui-seletor-cor-fundo, color-mix(in srgb, var(--ui-cor-fundo-menu, #16161a) 96%, transparent));backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);border:1px solid var(--_linha);border-radius:12px;box-shadow:var(--ui-sombra-lg, 0 20px 48px -4px rgba(0, 0, 0, .7));color:var(--_t);font-family:var(--ui-fonte-base, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);font-size:12px;-webkit-user-select:none;user-select:none;animation:ui-seletor-cor-entrada .18s cubic-bezier(.16,1,.3,1)}:host([hidden]){display:none}:host([inline]),:host([embutido]){position:relative;top:auto;left:auto;z-index:auto;animation:none;box-shadow:var(--ui-sombra-md, 0 8px 24px rgba(0, 0, 0, .45))}:host(:focus),:host(:focus-visible){outline:none}*,*:before,*:after{box-sizing:border-box}@keyframes ui-seletor-cor-entrada{0%{opacity:0;transform:scale(.96) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}button{font-family:inherit}.cabecalho{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--_linha)}.titulo{display:flex;align-items:center;gap:7px;font-weight:600;font-size:12.5px;color:var(--_t);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;letter-spacing:.15px}.titulo svg{flex-shrink:0;color:var(--_destaque)}.fechar{display:flex;align-items:center;justify-content:center;width:22px;height:22px;flex-shrink:0;padding:0;background:transparent;border:none;border-radius:5px;color:var(--_t2);font-size:13px;cursor:pointer;transition:all .15s ease}.fechar:hover{background:var(--_realce-forte);color:var(--_t)}.abas{display:flex;gap:3px;margin-bottom:11px;padding:3px;background:var(--_campo);border:1px solid var(--_linha);border-radius:8px}.aba{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:5px 8px;background:transparent;border:none;border-radius:6px;color:var(--_t2);font-size:11px;font-weight:600;cursor:pointer;transition:all .15s ease}.aba:hover{background:var(--_realce);color:var(--_t)}.aba[aria-selected=true]{background:var(--_realce-forte);color:var(--_t);box-shadow:0 1px 3px #00000059}.aba-amostra{width:12px;height:12px;border:1px solid var(--_linha);border-radius:3px;flex-shrink:0}.aba-amostra--sem-cor{background:linear-gradient(to top right,transparent calc(50% - 1px),var(--_vermelho) calc(50% - 1px),var(--_vermelho) calc(50% + 1px),transparent calc(50% + 1px)),var(--_realce-forte)}.aba-amostra--traco{border:2.5px solid #ffffff;background:transparent}.previa{display:flex;height:42px;margin-bottom:11px;overflow:hidden;background:var(--_campo);border:1px solid var(--_linha);border-radius:8px;box-shadow:inset 0 1px 3px #0000004d}.previa-metade{flex:1;position:relative;display:flex;align-items:center;justify-content:center;background-image:linear-gradient(45deg,rgba(255,255,255,.05) 25%,transparent 25%),linear-gradient(-45deg,rgba(255,255,255,.05) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,rgba(255,255,255,.05) 75%),linear-gradient(-45deg,transparent 75%,rgba(255,255,255,.05) 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0;overflow:hidden}.previa-metade+.previa-metade{border-left:1px solid var(--_linha)}.previa-metade--nova{cursor:pointer}.previa-metade--nova:hover span.previa-badge{background:#000000e0;border-color:#ffffff47;color:#fff}.previa-cor{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;transition:background-color .12s ease}.previa-cor--sem-cor{background:transparent!important}.previa-cor--sem-cor:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(to top right,transparent calc(50% - 1px),var(--_vermelho) calc(50% - 1px),var(--_vermelho) calc(50% + 1px),transparent calc(50% + 1px));opacity:.85}.previa-linha-traco{width:78%;height:var(--traco-px, 2.5px);min-height:1px;max-height:22px;background-color:var(--traco-cor, #ffffff);border-radius:999px;box-shadow:0 1px 3px #0006;transition:height .12s ease,background-color .12s ease}.previa-linha-traco--sem-cor{background:repeating-linear-gradient(90deg,var(--_vermelho) 0,var(--_vermelho) 4px,transparent 4px,transparent 8px);height:2px!important;opacity:.9}.previa-metade span.previa-badge{position:absolute;bottom:4px;z-index:3;padding:1px 5px;background:#000000b8;border:1px solid rgba(255,255,255,.1);border-radius:4px;font-size:9px;font-weight:700;letter-spacing:.4px;color:#ffffffe6;pointer-events:none}.linha-hex{display:flex;align-items:center;gap:8px;margin-bottom:11px}.hex{flex:1;position:relative;display:flex;align-items:center}.hex-prefixo{position:absolute;left:9px;color:var(--_t2);font-weight:600;font-size:11px;pointer-events:none}.hex input{width:100%;height:30px;padding:0 8px 0 21px;background:var(--_campo);border:1px solid var(--_linha);border-radius:6px;outline:none;color:var(--_t);font-family:var(--ui-fonte-codigo, ui-monospace, "Cascadia Mono", Consolas, monospace);font-size:12px;letter-spacing:.5px;text-transform:uppercase;-webkit-user-select:text;user-select:text;transition:border-color .15s ease,box-shadow .15s ease}.hex input::placeholder{color:var(--_t2);opacity:.7}.hex input:hover{border-color:color-mix(in srgb,var(--_t) 35%,transparent)}.hex input:focus{border-color:var(--_destaque);box-shadow:0 0 0 2px color-mix(in srgb,var(--_destaque) 25%,transparent)}.nativo{position:relative;display:flex;align-items:center;justify-content:center;width:30px;height:30px;flex-shrink:0;overflow:hidden;background:var(--_realce);border:1px solid var(--_linha);border-radius:6px;color:var(--_t2);cursor:pointer;transition:border-color .15s ease,color .15s ease,transform .1s ease}.nativo:hover,.nativo:focus-within{border-color:color-mix(in srgb,var(--_t) 45%,transparent);color:var(--_t);transform:scale(1.04)}.nativo input{position:absolute;top:-8px;right:-8px;bottom:-8px;left:-8px;width:150%;height:150%;opacity:0;cursor:pointer}.ajustes{display:flex;flex-direction:column;gap:6px;margin-bottom:11px}.ajustes:not(:has(.ajuste:not([hidden]))){display:none}.ajuste{display:flex;align-items:center;justify-content:space-between;gap:8px}.ajuste[hidden]{display:none}.ajuste-rotulo{color:var(--_t2);font-size:11px;font-weight:500}.ajuste-campo{display:flex;align-items:stretch;width:96px;height:26px;overflow:hidden;background:var(--_campo);border:1px solid var(--_linha);border-radius:6px;transition:border-color .15s ease,box-shadow .15s ease}.ajuste-campo:hover{border-color:color-mix(in srgb,var(--_t) 35%,transparent)}.ajuste-campo:focus-within{border-color:var(--_destaque);box-shadow:0 0 0 2px color-mix(in srgb,var(--_destaque) 25%,transparent)}.ajuste-passos{display:flex;flex-direction:column;flex-shrink:0;border-right:1px solid var(--_linha)}.ajuste-passos button{display:flex;flex:1;align-items:center;justify-content:center;width:16px;padding:0;background:transparent;border:none;color:var(--_t2);cursor:pointer}.ajuste-passos button:hover{background:var(--_realce-forte);color:var(--_t)}.ajuste-campo input{flex:1;min-width:0;padding:0 2px 0 7px;background:transparent;border:none;outline:none;color:var(--_t);font-family:var(--ui-fonte-codigo, ui-monospace, "Cascadia Mono", Consolas, monospace);font-size:12px;font-variant-numeric:tabular-nums;text-align:right;-webkit-user-select:text;user-select:text}.ajuste-unidade{display:flex;align-items:center;padding-right:7px;color:var(--_t2);font-size:11px;pointer-events:none}.sem-cor{width:30px;height:30px;flex-shrink:0;padding:0;background:linear-gradient(to top right,transparent calc(50% - 1px),var(--_vermelho) calc(50% - 1px),var(--_vermelho) calc(50% + 1px),transparent calc(50% + 1px)),var(--_campo);border:1px solid var(--_linha);border-radius:6px;cursor:pointer;transition:border-color .15s ease,box-shadow .15s ease}.sem-cor:hover{border-color:color-mix(in srgb,var(--_t) 45%,transparent)}.sem-cor.ativo{border-color:var(--_vermelho);box-shadow:0 0 0 2px color-mix(in srgb,var(--_vermelho) 40%,transparent)}.rodape{display:flex;justify-content:flex-end;gap:6px;margin-top:11px;padding-top:9px;border-top:1px solid var(--_linha)}.rodape button{padding:6px 14px;border:none;border-radius:6px;font-size:11.5px;font-weight:600;cursor:pointer;transition:all .15s ease}.botao-concluir{background:var(--_destaque);color:var(--_sobre-destaque);box-shadow:0 1px 3px #0000004d}.botao-concluir:hover{filter:brightness(1.1);transform:translateY(-.5px)}.botao-concluir:active{transform:translateY(0)}.botao-cancelar{background:var(--_realce);color:var(--_t2)}.botao-cancelar:hover{background:var(--_realce-forte);color:var(--_t)}button:focus-visible,input:focus-visible,.nativo:focus-within{outline:2px solid var(--_destaque);outline-offset:1px}.hex input:focus-visible,.ajuste-campo input:focus-visible{outline:none}@media (prefers-reduced-motion: reduce){:host{animation:none}.ajuste-campo{transition:none}}', H = [
7
+ "#00e08a",
8
+ "#38bdf8",
9
+ "#3b82f6",
10
+ "#6366f1",
11
+ "#a855f7",
12
+ "#ec4899",
13
+ "#ef4444",
14
+ "#f97316",
15
+ "#eab308",
16
+ "#84cc16",
17
+ "#14b8a6",
18
+ "#ffffff",
19
+ "#94a3b8",
20
+ "#0f172a"
21
+ ];
22
+ function w(s) {
23
+ if (typeof s != "string") return null;
24
+ const t = s.trim().toLowerCase();
25
+ if (t === "none" || t === "transparent") return "none";
26
+ if (/^#[0-9a-f]{6}$/.test(t)) return t;
27
+ const a = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(t);
28
+ return a ? `#${a[1]}${a[1]}${a[2]}${a[2]}${a[3]}${a[3]}` : null;
29
+ }
30
+ function z(s, t = 0.35) {
31
+ const a = typeof s == "string" ? parseFloat(s) : Number(s);
32
+ return Number.isFinite(a) ? Math.max(0, Math.min(1, a)) : t;
33
+ }
34
+ function $(s, t = 2.5) {
35
+ const a = typeof s == "string" ? parseFloat(s) : Number(s);
36
+ if (!Number.isFinite(a)) return t;
37
+ const e = Math.round(a * 10) / 10;
38
+ return Math.max(0.5, Math.min(50, e));
39
+ }
40
+ function U(s) {
41
+ if (!Array.isArray(s)) return [];
42
+ const t = /* @__PURE__ */ new Set();
43
+ for (const a of s) {
44
+ const e = w(a);
45
+ e && e !== "none" && t.add(e);
46
+ }
47
+ return [...t];
48
+ }
49
+ function L(s) {
50
+ return String(s ?? "").replace(/[&<>"']/g, (t) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[t]);
51
+ }
52
+ const N = { opacidade: 1, espessura: 0.5 };
53
+ class F extends P {
54
+ constructor() {
55
+ super();
56
+ d(this, "raiz");
57
+ d(this, "listeners", new j());
58
+ /** @internal Aberto por `abrirSeletorCor()`: solta os ouvintes de `window` se alguém remover o elemento. */
59
+ d(this, "aoDesconectar", null);
60
+ d(this, "_titulo", "Seletor de cor");
61
+ d(this, "_duplo", !0);
62
+ d(this, "_alvo", "preenchimento");
63
+ d(this, "_preenchimento", "#00e08a");
64
+ d(this, "_traco", "#ffffff");
65
+ d(this, "_opacidade", 0.35);
66
+ d(this, "_mostrarOpacidade");
67
+ d(this, "_espessura", 2.5);
68
+ d(this, "_mostrarEspessura");
69
+ d(this, "_misto", !1);
70
+ d(this, "inicial", {
71
+ preenchimento: "#00e08a",
72
+ traco: "#ffffff",
73
+ opacidade: 0.35,
74
+ espessuraTraco: 2.5
75
+ });
76
+ this.raiz = this.attachShadow({ mode: "open" });
77
+ }
78
+ connectedCallback() {
79
+ this.hasAttribute("role") || this.setAttribute("role", "dialog"), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "-1"), this.renderizar();
80
+ }
81
+ disconnectedCallback() {
82
+ var a;
83
+ this.listeners.cleanup(), (a = this.aoDesconectar) == null || a.call(this);
84
+ }
85
+ /* ---------- API pública ---------- */
86
+ /** Define o estado inicial (também usado pelo "Cancelar" para restaurar). */
87
+ configurar(a = {}) {
88
+ this._titulo = a.titulo || "Seletor de cor";
89
+ const e = a.preenchimento !== void 0 && a.traco !== void 0;
90
+ this._duplo = a.modo ? a.modo === "duplo" : e, this._alvo = a.alvo === "traco" ? "traco" : "preenchimento";
91
+ const o = w(a.cor);
92
+ this._preenchimento = w(a.preenchimento) ?? (this._alvo === "preenchimento" ? o : null) ?? "#00e08a", this._traco = w(a.traco) ?? (this._alvo === "traco" ? o : null) ?? "#ffffff", this._opacidade = z(a.opacidade), this._mostrarOpacidade = a.mostrarOpacidade, this._espessura = $(a.espessuraTraco, 2.5), this._mostrarEspessura = a.mostrarEspessura, this._misto = a.misto === !0, this.inicial = {
93
+ preenchimento: this._preenchimento,
94
+ traco: this._traco,
95
+ opacidade: this._opacidade,
96
+ espessuraTraco: this._espessura
97
+ }, this.isConnected && this.renderizar();
98
+ }
99
+ get alvo() {
100
+ return this._alvo;
101
+ }
102
+ /** Cor do alvo em edição. */
103
+ get cor() {
104
+ return this._alvo === "traco" ? this._traco : this._preenchimento;
105
+ }
106
+ get opacidade() {
107
+ return this._opacidade;
108
+ }
109
+ get espessura() {
110
+ return this._espessura;
111
+ }
112
+ obterEstado() {
113
+ return {
114
+ alvo: this._alvo,
115
+ cor: this.cor,
116
+ preenchimento: this._preenchimento,
117
+ traco: this._traco,
118
+ opacidade: this._opacidade,
119
+ espessuraTraco: this._espessura
120
+ };
121
+ }
122
+ /** Alterna entre Preenchimento e Traço (só no modo duplo). */
123
+ trocarAlvo(a) {
124
+ const e = a === "traco" ? "traco" : "preenchimento";
125
+ !this._duplo || e === this._alvo || (this._alvo = e, this.atualizarVisual(), this.emitir("ui-alvo-change", { alvo: e }));
126
+ }
127
+ /** Aplica uma cor ao alvo em edição e emite `ui-cor-input`. Cores inválidas são ignoradas. */
128
+ definirCor(a) {
129
+ const e = w(a);
130
+ e && (this._alvo === "traco" ? this._traco = e : this._preenchimento = e, this._misto = !1, this.atualizarVisual(), this.emitir("ui-cor-input", this.obterEstado()));
131
+ }
132
+ /** Opacidade do preenchimento (0 a 1); emite `ui-cor-input`. */
133
+ definirOpacidade(a) {
134
+ this._opacidade = z(a, this._opacidade), this.atualizarVisual(), this.emitir("ui-cor-input", this.obterEstado());
135
+ }
136
+ /** Espessura do traço em pixels (0.5 a 50); emite `ui-cor-input`. */
137
+ definirEspessura(a) {
138
+ this._espessura = $(a, this._espessura), this.atualizarVisual(), this.emitir("ui-cor-input", this.obterEstado());
139
+ }
140
+ confirmar() {
141
+ this.emitir("ui-cor-confirmar", this.obterEstado());
142
+ }
143
+ /** Restaura os valores iniciais (emitindo `ui-cor-input`) e emite `ui-cor-cancelar`. */
144
+ cancelar() {
145
+ this._preenchimento = this.inicial.preenchimento, this._traco = this.inicial.traco, this._opacidade = this.inicial.opacidade, this._espessura = this.inicial.espessuraTraco, this.atualizarVisual(), this.emitir("ui-cor-input", this.obterEstado()), this.emitir("ui-cor-cancelar", this.obterEstado());
146
+ }
147
+ /* ---------- Renderização ---------- */
148
+ get opacidadeVisivel() {
149
+ return this._mostrarOpacidade ?? this._alvo === "preenchimento";
150
+ }
151
+ get espessuraVisivel() {
152
+ return this._mostrarEspessura ?? this._alvo === "traco";
153
+ }
154
+ renderizar() {
155
+ this.listeners.cleanup(), this.setAttribute("aria-label", this._titulo);
156
+ const a = (e, o, l, i, n, m) => `
157
+ <div class="ajuste ${e}">
158
+ <label class="ajuste-rotulo" for="${e}-entrada">${o}</label>
159
+ <div class="ajuste-campo">
160
+ <span class="ajuste-passos">
161
+ <button type="button" tabindex="-1" data-passo="${e}" data-direcao="1" aria-label="Aumentar ${o.toLowerCase()}">
162
+ <svg viewBox="0 0 10 6" width="8" height="5" aria-hidden="true"><path d="M1 5l4-4 4 4" fill="none" stroke="currentColor" stroke-width="1.6"/></svg>
163
+ </button>
164
+ <button type="button" tabindex="-1" data-passo="${e}" data-direcao="-1" aria-label="Diminuir ${o.toLowerCase()}">
165
+ <svg viewBox="0 0 10 6" width="8" height="5" aria-hidden="true"><path d="M1 1l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.6"/></svg>
166
+ </button>
167
+ </span>
168
+ <input type="text" id="${e}-entrada" class="${e}-entrada" inputmode="decimal" spellcheck="false" autocomplete="off"
169
+ role="spinbutton" aria-valuemin="${n}" aria-valuemax="${m}" aria-label="${i}" />
170
+ <span class="ajuste-unidade" aria-hidden="true">${l}</span>
171
+ </div>
172
+ </div>
173
+ `;
174
+ this.raiz.innerHTML = `
175
+ <style>${O}</style>
176
+ <div class="cabecalho">
177
+ <span class="titulo">
178
+ <svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
179
+ <path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z"/>
180
+ </svg>
181
+ <span>${L(this._titulo)}</span>
182
+ </span>
183
+ <button type="button" class="fechar" data-acao="fechar" title="Fechar (Esc)" aria-label="Fechar">✕</button>
184
+ </div>
185
+
186
+ ${this._duplo ? `
187
+ <div class="abas" role="tablist" aria-label="Alvo da cor">
188
+ <button type="button" class="aba" role="tab" data-alvo="preenchimento" title="Preenchimento">
189
+ <span class="aba-amostra aba-amostra--preenchimento"></span>
190
+ Preenchimento
191
+ </button>
192
+ <button type="button" class="aba" role="tab" data-alvo="traco" title="Traço / contorno">
193
+ <span class="aba-amostra aba-amostra--traco"></span>
194
+ Traço
195
+ </button>
196
+ </div>
197
+ ` : ""}
198
+
199
+ <div class="previa" aria-label="Comparativo de cor antes e depois">
200
+ <div class="previa-metade previa-metade--original" title="Cor original">
201
+ <div class="previa-cor previa-cor--original">
202
+ <div class="previa-linha-traco previa-linha-traco--original"></div>
203
+ </div>
204
+ <span class="previa-badge">ORIGINAL</span>
205
+ </div>
206
+ <div class="previa-metade previa-metade--nova" data-acao="abrir-nativo" title="Nova cor — clique para escolher no seletor do sistema">
207
+ <div class="previa-cor previa-cor--nova">
208
+ <div class="previa-linha-traco previa-linha-traco--nova"></div>
209
+ </div>
210
+ <span class="previa-badge previa-rotulo-nova">NOVA</span>
211
+ </div>
212
+ </div>
213
+
214
+ <div class="linha-hex">
215
+ <label class="hex">
216
+ <span class="hex-prefixo">#</span>
217
+ <input type="text" class="hex-entrada" maxlength="7" spellcheck="false" autocomplete="off" aria-label="Cor em hexadecimal" />
218
+ </label>
219
+ <label class="nativo" title="Escolher cor no seletor do sistema">
220
+ <svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
221
+ <path d="m2 22 1-1h3l9-9"/>
222
+ <path d="M3 21v-3l9-9"/>
223
+ <path d="m15 6 3.4-3.4a2.1 2.1 0 1 1 3 3L18 9l.4.4a2.1 2.1 0 1 1-3 3l-3.8-3.8a2.1 2.1 0 1 1 3-3l.4.4Z"/>
224
+ </svg>
225
+ <input type="color" class="nativo-entrada" aria-label="Seletor de cor do sistema" />
226
+ </label>
227
+ <button type="button" class="sem-cor" data-cor="none" aria-pressed="false" title="Sem cor (vazado / transparente)" aria-label="Sem cor (vazado / transparente)"></button>
228
+ </div>
229
+
230
+ <div class="ajustes">
231
+ ${a("espessura", "Espessura", "px", "Espessura do traçado em pixels", 0.5, 50)}
232
+ ${a("opacidade", "Opacidade", "%", "Opacidade do preenchimento em porcentagem", 0, 100)}
233
+ </div>
234
+
235
+ <div class="rodape">
236
+ <button type="button" class="botao-cancelar" data-acao="cancelar">Cancelar</button>
237
+ <button type="button" class="botao-concluir" data-acao="concluir">Concluir</button>
238
+ </div>
239
+ `, this.vincularEventos(), this.atualizarVisual();
240
+ }
241
+ atualizarVisual() {
242
+ const a = (v) => this.raiz.querySelector(v), e = this.cor, o = e === "none", l = this._alvo === "traco";
243
+ this.raiz.querySelectorAll("[data-alvo]").forEach((v) => {
244
+ v.setAttribute("aria-selected", String(v.dataset.alvo === this._alvo));
245
+ });
246
+ const i = a(".aba-amostra--preenchimento");
247
+ i && (i.classList.toggle("aba-amostra--sem-cor", this._preenchimento === "none"), i.style.backgroundColor = this._preenchimento === "none" ? "" : this._preenchimento);
248
+ const n = a(".aba-amostra--traco");
249
+ n && (n.style.borderColor = this._traco === "none" ? "#ef4444" : this._traco, n.style.borderWidth = `${Math.max(1.5, Math.min(3.5, this._espessura))}px`);
250
+ const m = a(".opacidade");
251
+ m && (m.hidden = !this.opacidadeVisivel);
252
+ const c = a(".espessura");
253
+ c && (c.hidden = !this.espessuraVisivel);
254
+ const b = l ? this.inicial.traco : this.inicial.preenchimento, f = b === "none", p = a(".previa-cor--original"), r = a(".previa-cor--nova"), u = a(".previa-linha-traco--original"), h = a(".previa-linha-traco--nova");
255
+ if (l)
256
+ p && (p.style.backgroundColor = "transparent", p.classList.remove("previa-cor--sem-cor")), r && (r.style.backgroundColor = "transparent", r.classList.remove("previa-cor--sem-cor")), u && (u.style.display = "block", u.classList.toggle("previa-linha-traco--sem-cor", f), u.style.setProperty("--traco-px", `${Math.max(1, this.inicial.espessuraTraco)}px`), u.style.setProperty("--traco-cor", f ? "" : b)), h && (h.style.display = "block", h.classList.toggle("previa-linha-traco--sem-cor", o), h.style.setProperty("--traco-px", `${Math.max(1, this._espessura)}px`), h.style.setProperty("--traco-cor", o ? "" : e));
257
+ else {
258
+ u && (u.style.display = "none"), h && (h.style.display = "none");
259
+ const v = this.opacidadeVisivel;
260
+ p && (p.classList.toggle("previa-cor--sem-cor", f), p.style.backgroundColor = f ? "" : b, p.style.opacity = f || !v ? "" : String(this.inicial.opacidade)), r && (r.classList.toggle("previa-cor--sem-cor", o), r.style.backgroundColor = o ? "" : e, r.style.opacity = o || !v ? "" : String(this._opacidade));
261
+ }
262
+ const _ = a(".previa-rotulo-nova");
263
+ _ && (_.textContent = this._misto ? "MISTO (?)" : "NOVA");
264
+ const k = a(".hex-entrada");
265
+ k && !this.campoEmFoco(k) && (k.value = o ? "" : e.slice(1).toUpperCase(), k.placeholder = o ? "NENHUM" : "00E08A");
266
+ const E = a(".nativo-entrada");
267
+ E && (E.value = o ? "#00e08a" : e), ["espessura", "opacidade"].forEach((v) => {
268
+ const y = a(`.${v}-entrada`);
269
+ if (!y) return;
270
+ const C = this.valorCampo(v);
271
+ this.campoEmFoco(y) || (y.value = C), y.setAttribute("aria-valuenow", C), y.setAttribute("aria-valuetext", v === "opacidade" ? `${C}%` : `${C} px`);
272
+ });
273
+ const g = a(".sem-cor");
274
+ g == null || g.classList.toggle("ativo", o), g == null || g.setAttribute("aria-pressed", String(o));
275
+ }
276
+ /** `activeElement` lança em alguns DOMs simulados quando o foco está em outra árvore de sombra. */
277
+ campoEmFoco(a) {
278
+ try {
279
+ return this.raiz.activeElement === a;
280
+ } catch {
281
+ return !1;
282
+ }
283
+ }
284
+ vincularEventos() {
285
+ const a = this.raiz;
286
+ a.querySelectorAll("[data-alvo]").forEach((i) => {
287
+ this.listeners.add(i, "click", () => this.trocarAlvo(i.dataset.alvo));
288
+ }), a.querySelectorAll("[data-cor]").forEach((i) => {
289
+ this.listeners.add(i, "click", () => this.definirCor(i.dataset.cor || ""));
290
+ }), a.querySelectorAll("[data-passo]").forEach((i) => {
291
+ this.listeners.add(i, "click", (n) => {
292
+ this.ajustarPor(i.dataset.passo, Number(i.dataset.direcao), n.shiftKey);
293
+ });
294
+ }), ["espessura", "opacidade"].forEach((i) => {
295
+ const n = a.querySelector(`.${i}-entrada`);
296
+ if (!n) return;
297
+ const m = (c, b) => {
298
+ this.ajustarPor(i, c, b), n.value = this.valorCampo(i);
299
+ };
300
+ this.listeners.add(n, "change", () => this.lerCampo(i, n)), this.listeners.add(n, "keydown", (c) => {
301
+ c.key === "Enter" ? (c.preventDefault(), this.lerCampo(i, n), n.select()) : (c.key === "ArrowUp" || c.key === "ArrowDown") && (c.preventDefault(), m(c.key === "ArrowUp" ? 1 : -1, c.shiftKey), n.select());
302
+ }), this.listeners.add(n, "wheel", (c) => {
303
+ !this.campoEmFoco(n) || c.deltaY === 0 || (c.preventDefault(), m(c.deltaY < 0 ? 1 : -1, c.shiftKey));
304
+ }, { passive: !1 });
305
+ });
306
+ const e = a.querySelector(".hex-entrada"), o = (i) => {
307
+ const n = e.value.trim().replace(/^#/, "");
308
+ (/^[0-9a-f]{6}$/i.test(n) || i && /^[0-9a-f]{3}$/i.test(n)) && this.definirCor(`#${n}`);
309
+ };
310
+ e && (this.listeners.add(e, "input", () => o(!1)), this.listeners.add(e, "change", () => {
311
+ o(!0), this.atualizarVisual();
312
+ }), this.listeners.add(e, "keydown", (i) => {
313
+ i.key === "Enter" && (i.preventDefault(), o(!0), this.confirmar());
314
+ }));
315
+ const l = a.querySelector(".nativo-entrada");
316
+ l && (this.listeners.add(l, "input", () => this.definirCor(l.value)), this.listeners.add(a.querySelector('[data-acao="abrir-nativo"]'), "click", () => {
317
+ l.click();
318
+ })), this.listeners.add(a.querySelector('[data-acao="fechar"]'), "click", () => this.confirmar()), this.listeners.add(a.querySelector('[data-acao="concluir"]'), "click", () => this.confirmar()), this.listeners.add(a.querySelector('[data-acao="cancelar"]'), "click", () => this.cancelar());
319
+ }
320
+ /** Texto exibido no campo: opacidade em % inteira, espessura em px. */
321
+ valorCampo(a) {
322
+ return String(a === "opacidade" ? Math.round(this._opacidade * 100) : this._espessura);
323
+ }
324
+ /** Soma um passo do campo no sentido de `direcao` (com `grande`, dez passos). */
325
+ ajustarPor(a, e, o = !1) {
326
+ if (!Number.isFinite(e) || e === 0) return;
327
+ const l = Math.sign(e) * N[a] * (o ? 10 : 1);
328
+ a === "opacidade" ? this.definirOpacidade((Math.round(this._opacidade * 100) + l) / 100) : this.definirEspessura(this._espessura + l);
329
+ }
330
+ /** Aplica o texto do campo ("50", "50%", "2,5 px"…); texto inválido volta ao valor atual sem emitir. */
331
+ lerCampo(a, e) {
332
+ const o = parseFloat(e.value.replace(",", ".").replace(/[^\d.+-]/g, ""));
333
+ Number.isFinite(o) && (a === "opacidade" ? this.definirOpacidade(o / 100) : this.definirEspessura(o)), e.value = this.valorCampo(a);
334
+ }
335
+ emitir(a, e) {
336
+ this.dispatchEvent(new CustomEvent(a, { detail: e, bubbles: !0, composed: !0 }));
337
+ }
338
+ }
339
+ q("ui-seletor-cor", F);
340
+ let x = null;
341
+ function B(s) {
342
+ x == null || x.descartar();
343
+ const t = document.createElement("ui-seletor-cor"), { ancora: a, focar: e, aoAlterar: o, aoConfirmar: l, aoCancelar: i, aoTrocarAlvo: n, ...m } = s;
344
+ t.configurar(m);
345
+ const c = new j();
346
+ let b = !0;
347
+ const f = () => {
348
+ if (!b) return !1;
349
+ b = !1, c.cleanup();
350
+ const r = document.activeElement === t;
351
+ return t.remove(), r && a instanceof HTMLElement && a.isConnected && a.focus({ preventScroll: !0 }), x === p && (x = null), !0;
352
+ };
353
+ t.aoDesconectar = () => f();
354
+ const p = {
355
+ elemento: t,
356
+ get aberto() {
357
+ return b;
358
+ },
359
+ fechar(r = !0) {
360
+ r ? t.confirmar() : f();
361
+ },
362
+ descartar() {
363
+ f();
364
+ }
365
+ };
366
+ return c.add(t, "ui-cor-input", (r) => o == null ? void 0 : o(r.detail)), c.add(t, "ui-cor-confirmar", (r) => {
367
+ f() && (l == null || l(r.detail));
368
+ }), c.add(t, "ui-cor-cancelar", (r) => {
369
+ f() && (i == null || i(r.detail));
370
+ }), c.add(t, "ui-alvo-change", (r) => {
371
+ r.stopPropagation(), n == null || n(r.detail.alvo);
372
+ }), c.add(t, "pointerdown", (r) => r.stopPropagation()), c.add(t, "click", (r) => r.stopPropagation()), document.body.appendChild(t), S(t, a), x = p, e && t.focus({ preventScroll: !0 }), c.add(window, "resize", () => S(t, a)), c.add(window, "pointerdown", (r) => {
373
+ const u = r.composedPath();
374
+ !u.includes(t) && !u.includes(a) && p.fechar(!0);
375
+ }, !0), c.add(window, "keydown", (r) => {
376
+ var h, _;
377
+ if (r.key === "Escape") {
378
+ r.preventDefault(), r.stopPropagation(), p.fechar(!0);
379
+ return;
380
+ }
381
+ const u = (_ = (h = r.composedPath()[0]) == null ? void 0 : h.matches) == null ? void 0 : _.call(h, 'input[type="text"]');
382
+ (r.key === "x" || r.key === "X") && !r.ctrlKey && !r.metaKey && !r.altKey && !r.shiftKey && !u && (r.preventDefault(), r.stopPropagation(), t.trocarAlvo(t.alvo === "preenchimento" ? "traco" : "preenchimento"));
383
+ }, !0), p;
384
+ }
385
+ function K(s = !0) {
386
+ x == null || x.fechar(s);
387
+ }
388
+ function S(s, t) {
389
+ const e = t.getBoundingClientRect(), o = s.offsetWidth, l = s.offsetHeight;
390
+ let i = e.right + 10;
391
+ i + o > window.innerWidth - 10 && (i = Math.max(10, e.left - o - 10));
392
+ let n = e.top;
393
+ n + l > window.innerHeight - 10 && (n = Math.max(10, window.innerHeight - l - 10)), s.style.left = `${Math.round(i)}px`, s.style.top = `${Math.round(n)}px`;
394
+ }
395
+ export {
396
+ H as P,
397
+ F as U,
398
+ B as a,
399
+ $ as b,
400
+ U as c,
401
+ z as d,
402
+ L as e,
403
+ K as f,
404
+ w as n
405
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thibezer/ui-components-kit",
3
- "version": "2.17.0",
3
+ "version": "2.17.1",
4
4
  "description": "Web Components nativos (W3C Custom Elements + Shadow DOM) para interfaces densas de GIS, CAD e formulários, sem dependência de framework.",
5
5
  "keywords": [
6
6
  "web-components",