@wrrdev/fenix-ui 1.1.17 → 1.3.0
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 +43 -4
- package/dist/components/datepicker/datepicker.js +4 -4
- package/dist/components/datepicker/datepicker.js.map +1 -1
- package/dist/components/editor/editor.js +3 -3
- package/dist/components/editor/editor.js.map +1 -1
- package/dist/components/floatlabel/floatlabel.d.ts +5 -0
- package/dist/components/floatlabel/floatlabel.d.ts.map +1 -1
- package/dist/components/floatlabel/floatlabel.js +52 -25
- package/dist/components/floatlabel/floatlabel.js.map +1 -1
- package/dist/components/input/input.d.ts +11 -0
- package/dist/components/input/input.d.ts.map +1 -1
- package/dist/components/input/input.js +11 -0
- package/dist/components/input/input.js.map +1 -1
- package/dist/components/multiselect/multiselect.js +1 -1
- package/dist/components/multiselect/multiselect.js.map +1 -1
- package/dist/components/orderlist/orderlist.js +1 -1
- package/dist/components/orderlist/orderlist.js.map +1 -1
- package/dist/components/picklist/picklist.js +1 -1
- package/dist/components/picklist/picklist.js.map +1 -1
- package/dist/components/select/select.js +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/table/table.d.ts.map +1 -1
- package/dist/components/table/table.js +14 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/textarea/textarea.d.ts +7 -0
- package/dist/components/textarea/textarea.d.ts.map +1 -1
- package/dist/components/textarea/textarea.js +22 -1
- package/dist/components/textarea/textarea.js.map +1 -1
- package/dist/core/jsx.d.ts +10 -0
- package/dist/core/jsx.d.ts.map +1 -1
- package/dist/core/jsx.js.map +1 -1
- package/dist/core/tokens.d.ts +2 -0
- package/dist/core/tokens.d.ts.map +1 -1
- package/dist/core/tokens.js +9 -0
- package/dist/core/tokens.js.map +1 -1
- package/dist/docs/app.d.ts.map +1 -1
- package/dist/docs/componentes/autocomplete.doc.d.ts.map +1 -1
- package/dist/docs/componentes/datepicker.doc.d.ts.map +1 -1
- package/dist/docs/componentes/editor.doc.d.ts.map +1 -1
- package/dist/docs/componentes/floatlabel.doc.d.ts.map +1 -1
- package/dist/docs/componentes/input.doc.d.ts.map +1 -1
- package/dist/docs/componentes/multiselect.doc.d.ts.map +1 -1
- package/dist/docs/componentes/orderlist.doc.d.ts.map +1 -1
- package/dist/docs/componentes/picklist.doc.d.ts.map +1 -1
- package/dist/docs/componentes/select.doc.d.ts.map +1 -1
- package/dist/docs/componentes/table.doc.d.ts.map +1 -1
- package/dist/docs/componentes/textarea.doc.d.ts.map +1 -1
- package/dist/docs/shared.d.ts +15 -0
- package/dist/docs/shared.d.ts.map +1 -1
- package/dist/docs/shell.d.ts +10 -1
- package/dist/docs/shell.d.ts.map +1 -1
- package/dist/docs/theme-reference.d.ts +53 -0
- package/dist/docs/theme-reference.d.ts.map +1 -0
- package/dist/docs/types.d.ts +2 -0
- package/dist/docs/types.d.ts.map +1 -1
- package/dist/fenix-ui.umd.min.js +200 -169
- package/dist/fenix-ui4.esm.js +119 -38
- package/dist/fenix-ui4.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/fenix-ui4.esm.js
CHANGED
|
@@ -73,6 +73,14 @@ const lightTokens = {
|
|
|
73
73
|
/** Brilho dos estados `success`/`valid` — acompanha `focus-ring` igualmente. */
|
|
74
74
|
"success-ring": "0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent)"
|
|
75
75
|
},
|
|
76
|
+
table: {
|
|
77
|
+
/** Cor do corpo do fx-table; `var()` mantém claro/escuro automáticos. */
|
|
78
|
+
text: "var(--fx-text-default)",
|
|
79
|
+
/** Cabeçalho acompanha o corpo por padrão. */
|
|
80
|
+
"header-text": "var(--fx-table-text)",
|
|
81
|
+
/** O UA aplica bold no <th>; aqui o valor fica explícito e tokenizado. */
|
|
82
|
+
"header-weight": "bold"
|
|
83
|
+
},
|
|
76
84
|
z: { base: "auto", dropdown: "1000", modal: "1100", toast: "1200" }
|
|
77
85
|
};
|
|
78
86
|
const darkTokens = {
|
|
@@ -99,6 +107,7 @@ const darkTokens = {
|
|
|
99
107
|
},
|
|
100
108
|
motion: { ...lightTokens.motion },
|
|
101
109
|
effect: { ...lightTokens.effect },
|
|
110
|
+
table: { ...lightTokens.table },
|
|
102
111
|
z: { ...lightTokens.z }
|
|
103
112
|
};
|
|
104
113
|
const defaultTokens = lightTokens;
|
|
@@ -1039,7 +1048,7 @@ const _FxSelect = class _FxSelect extends FxFormElement {
|
|
|
1039
1048
|
</span>
|
|
1040
1049
|
</span>
|
|
1041
1050
|
<div class="panel" part="panel" role="listbox">
|
|
1042
|
-
${this.hasAttr("searchable") ? `<input class="search" part="search" type="text" placeholder="${esc(this.getAttr("search-placeholder", "Pesquisar…"))}">` : ""}
|
|
1051
|
+
${this.hasAttr("searchable") ? `<input class="search" part="search" type="text" autocomplete="off" placeholder="${esc(this.getAttr("search-placeholder", "Pesquisar…"))}">` : ""}
|
|
1043
1052
|
${filtered.map((o) => `
|
|
1044
1053
|
<button type="button" class="opt" role="option" data-value="${esc(o.value)}"
|
|
1045
1054
|
aria-selected="${o.value === current}">${esc(o.label)}</button>`).join("")}
|
|
@@ -1347,6 +1356,12 @@ const _FxInput = class _FxInput extends FxFormElement {
|
|
|
1347
1356
|
"step",
|
|
1348
1357
|
"clearable",
|
|
1349
1358
|
"full",
|
|
1359
|
+
// `autocomplete` é observado porque ele vive no campo INTERNO (autofill
|
|
1360
|
+
// do navegador): mudar o atributo no host precisa refletir no <input>.
|
|
1361
|
+
// `name`/`id` idem — os dois descem para o campo interno.
|
|
1362
|
+
"autocomplete",
|
|
1363
|
+
"name",
|
|
1364
|
+
"id",
|
|
1350
1365
|
"icon",
|
|
1351
1366
|
"icon-pos",
|
|
1352
1367
|
"error",
|
|
@@ -1410,6 +1425,9 @@ const _FxInput = class _FxInput extends FxFormElement {
|
|
|
1410
1425
|
const min = this.getAttr("min");
|
|
1411
1426
|
const max = this.getAttr("max");
|
|
1412
1427
|
const step = this.getAttr("step");
|
|
1428
|
+
const autocomplete = this.getAttr("autocomplete", "off");
|
|
1429
|
+
const name = this.getAttr("name");
|
|
1430
|
+
const id = this.getAttr("id");
|
|
1413
1431
|
const icon = this.getAttr("icon");
|
|
1414
1432
|
const iconPos = this.getAttr("icon-pos", "left") === "right" ? "right" : "left";
|
|
1415
1433
|
const slottedIcon = this.querySelector('[slot="icon"]');
|
|
@@ -1420,6 +1438,8 @@ const _FxInput = class _FxInput extends FxFormElement {
|
|
|
1420
1438
|
${useIconBox ? `<div class="field-icon icon-${iconPos}">` : ""}
|
|
1421
1439
|
${useIconBox && iconPos === "left" ? iconContent : ""}
|
|
1422
1440
|
<input class="field" part="input" type="${esc(type)}"
|
|
1441
|
+
${name ? `name="${esc(name)}"` : ""} ${id ? `id="${esc(id)}"` : ""}
|
|
1442
|
+
autocomplete="${esc(autocomplete)}"
|
|
1423
1443
|
${placeholder ? `placeholder="${esc(placeholder)}"` : ""}
|
|
1424
1444
|
${min ? `min="${esc(min)}"` : ""} ${max ? `max="${esc(max)}"` : ""} ${step ? `step="${esc(step)}"` : ""}
|
|
1425
1445
|
/>
|
|
@@ -1965,7 +1985,7 @@ const _FxMultiselect = class _FxMultiselect extends FxFormElement {
|
|
|
1965
1985
|
<span class="count">${chips.length} selecionado${chips.length === 1 ? "" : "s"}</span>
|
|
1966
1986
|
${this.hasAttr("clearable") && chips.length ? '<button type="button" class="clear-all">Limpar tudo</button>' : ""}
|
|
1967
1987
|
</div>
|
|
1968
|
-
${this.hasAttr("searchable") ? `<input class="search" part="search" type="text" placeholder="${esc(this.getAttr("search-placeholder", "Pesquisar…"))}">` : ""}
|
|
1988
|
+
${this.hasAttr("searchable") ? `<input class="search" part="search" type="text" autocomplete="off" placeholder="${esc(this.getAttr("search-placeholder", "Pesquisar…"))}">` : ""}
|
|
1969
1989
|
<ul class="list">
|
|
1970
1990
|
${filtered.map((o) => `
|
|
1971
1991
|
<li><button type="button" class="opt" role="option" data-value="${esc(o.value)}"
|
|
@@ -2922,7 +2942,7 @@ const _FxDatepicker = class _FxDatepicker extends FxFormElement {
|
|
|
2922
2942
|
}
|
|
2923
2943
|
this.setTemplate(`
|
|
2924
2944
|
<div class="field" part="field">
|
|
2925
|
-
<input class="display" part="display" type="text" ${this.hasAttr("free-text") && !disabled ? "" : "readonly"}
|
|
2945
|
+
<input class="display" part="display" type="text" autocomplete="off" ${this.hasAttr("free-text") && !disabled ? "" : "readonly"}
|
|
2926
2946
|
placeholder="${esc(this.getAttr("placeholder", "dd/mm/aaaa"))}"
|
|
2927
2947
|
value="${esc(text)}" ${disabled ? "disabled" : ""}>
|
|
2928
2948
|
<button type="button" class="clear" part="clear" aria-label="Limpar"
|
|
@@ -2940,9 +2960,9 @@ const _FxDatepicker = class _FxDatepicker extends FxFormElement {
|
|
|
2940
2960
|
<div class="pop" part="popover">
|
|
2941
2961
|
<fx-calendar ${calAttrs}></fx-calendar>
|
|
2942
2962
|
${showTime ? `<div class="time-row" part="time">
|
|
2943
|
-
<input class="t-h" type="number" min="0" max="23" value="${this.time.h}" aria-label="Hora"><span class="sep">:</span>
|
|
2944
|
-
<input class="t-m" type="number" min="0" max="59" value="${this.time.m}" aria-label="Minuto"><span class="sep">:</span>
|
|
2945
|
-
<input class="t-s" type="number" min="0" max="59" value="${this.time.s}" aria-label="Segundo">
|
|
2963
|
+
<input class="t-h" type="number" autocomplete="off" min="0" max="23" value="${this.time.h}" aria-label="Hora"><span class="sep">:</span>
|
|
2964
|
+
<input class="t-m" type="number" autocomplete="off" min="0" max="59" value="${this.time.m}" aria-label="Minuto"><span class="sep">:</span>
|
|
2965
|
+
<input class="t-s" type="number" autocomplete="off" min="0" max="59" value="${this.time.s}" aria-label="Segundo">
|
|
2946
2966
|
</div>` : ""}
|
|
2947
2967
|
</div>
|
|
2948
2968
|
`);
|
|
@@ -4378,7 +4398,7 @@ const _FxTable = class _FxTable extends FxElement {
|
|
|
4378
4398
|
const activeClass = isSorted ? "active" : "";
|
|
4379
4399
|
return `<th part="header" class="${c.sortable ? "sortable" : ""}" style="text-align:${c.align}" data-field="${esc(c.field)}">${esc(c.header)}${ind ? `<span class="sort-ind ${activeClass}">${ind}</span>` : ""}</th>`;
|
|
4380
4400
|
}).join("");
|
|
4381
|
-
const filterRow = cols.some((c) => c.filterable) ? `<tr class="filter-row">${cols.map((c) => `<th style="text-align:${c.align}">${c.filterable ? `<input class="filter" data-field="${esc(c.field)}" placeholder="${esc("Filtrar…")}" value="${esc(this.filters[c.field] ?? "")}">` : ""}</th>`).join("")}</tr>` : "";
|
|
4401
|
+
const filterRow = cols.some((c) => c.filterable) ? `<tr class="filter-row">${cols.map((c) => `<th style="text-align:${c.align}">${c.filterable ? `<input class="filter" autocomplete="off" data-field="${esc(c.field)}" placeholder="${esc("Filtrar…")}" value="${esc(this.filters[c.field] ?? "")}">` : ""}</th>`).join("")}</tr>` : "";
|
|
4382
4402
|
const bodyHtml = rows.length ? rows.map(
|
|
4383
4403
|
(row, i) => `<tr part="row" data-index="${i}">${cols.map((c) => `<td part="cell" style="text-align:${c.align}">${this.cellHtml(c, row)}</td>`).join("")}</tr>`
|
|
4384
4404
|
).join("") : `<tr><td class="empty" colspan="${cols.length || 1}">${esc(this.getAttr("empty-message", "Nenhum registro encontrado"))}</td></tr>`;
|
|
@@ -4658,6 +4678,13 @@ _FxTable.styles = css`
|
|
|
4658
4678
|
border-bottom: 2px solid var(--fx-border-default);
|
|
4659
4679
|
white-space: nowrap;
|
|
4660
4680
|
user-select: none;
|
|
4681
|
+
/* Cor/peso do cabeçalho por token de TABELA. Sem isso o th herda
|
|
4682
|
+
--fx-text-default do host e o peso vem do UA (bold). */
|
|
4683
|
+
color: var(
|
|
4684
|
+
--fx-table-header-text,
|
|
4685
|
+
var(--fx-table-text, var(--fx-text-default))
|
|
4686
|
+
);
|
|
4687
|
+
font-weight: var(--fx-table-header-weight, bold);
|
|
4661
4688
|
}
|
|
4662
4689
|
th.sortable {
|
|
4663
4690
|
cursor: pointer;
|
|
@@ -4702,6 +4729,12 @@ _FxTable.styles = css`
|
|
|
4702
4729
|
td {
|
|
4703
4730
|
padding: var(--fx-space-sm) var(--fx-space-md);
|
|
4704
4731
|
border-bottom: 1px solid var(--fx-border-default);
|
|
4732
|
+
/* Texto do corpo: token próprio para não depender de
|
|
4733
|
+
--fx-text-default (que afeta TODOS os textos do app) e para
|
|
4734
|
+
não herdar o font-weight do body da página — era isso que
|
|
4735
|
+
fazia a célula parecer mais clara que o cabeçalho. */
|
|
4736
|
+
color: var(--fx-table-text, var(--fx-text-default));
|
|
4737
|
+
font-weight: var(--fx-table-text-weight, inherit);
|
|
4705
4738
|
}
|
|
4706
4739
|
tbody tr {
|
|
4707
4740
|
cursor: pointer;
|
|
@@ -4978,6 +5011,7 @@ const _FxFloatlabel = class _FxFloatlabel extends FxElement {
|
|
|
4978
5011
|
}
|
|
4979
5012
|
disconnectedCallback() {
|
|
4980
5013
|
super.disconnectedCallback();
|
|
5014
|
+
this.cancelScheduledSync();
|
|
4981
5015
|
this.observer?.disconnect();
|
|
4982
5016
|
this._labelObserver?.disconnect();
|
|
4983
5017
|
this._labelObserver = void 0;
|
|
@@ -5007,14 +5041,28 @@ const _FxFloatlabel = class _FxFloatlabel extends FxElement {
|
|
|
5007
5041
|
}
|
|
5008
5042
|
if (this.listenersReady) return;
|
|
5009
5043
|
this.listenersReady = true;
|
|
5010
|
-
this.addEventListener("focusin", () =>
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
);
|
|
5044
|
+
this.addEventListener("focusin", () => {
|
|
5045
|
+
this.cancelScheduledSync();
|
|
5046
|
+
this.syncState();
|
|
5047
|
+
});
|
|
5048
|
+
this.addEventListener("focusout", () => this.scheduleSync());
|
|
5015
5049
|
this.addEventListener("input", () => this.syncState());
|
|
5016
5050
|
this.addEventListener("change", () => this.syncState());
|
|
5017
5051
|
}
|
|
5052
|
+
/** Reavalia o estado no próximo tick (o foco já saiu do campo). */
|
|
5053
|
+
scheduleSync() {
|
|
5054
|
+
this.cancelScheduledSync();
|
|
5055
|
+
this._syncTimer = setTimeout(() => {
|
|
5056
|
+
this._syncTimer = void 0;
|
|
5057
|
+
this.syncState();
|
|
5058
|
+
}, 0);
|
|
5059
|
+
}
|
|
5060
|
+
cancelScheduledSync() {
|
|
5061
|
+
if (this._syncTimer !== void 0) {
|
|
5062
|
+
clearTimeout(this._syncTimer);
|
|
5063
|
+
this._syncTimer = void 0;
|
|
5064
|
+
}
|
|
5065
|
+
}
|
|
5018
5066
|
/** Observa mudanças de atributos do controle (value, open, values...). */
|
|
5019
5067
|
syncControlReference(control = this.targetControl) {
|
|
5020
5068
|
if (control !== this.targetControl) {
|
|
@@ -5047,18 +5095,16 @@ const _FxFloatlabel = class _FxFloatlabel extends FxElement {
|
|
|
5047
5095
|
const c = this.targetControl;
|
|
5048
5096
|
const attrValue = c.getAttribute ? (c.getAttribute("value") ?? "").trim() : "";
|
|
5049
5097
|
const attrValues = c.getAttribute ? (c.getAttribute("values") ?? "").trim() : "";
|
|
5098
|
+
const isOpen = Boolean(c.hasAttribute?.("open"));
|
|
5050
5099
|
const hasValue = Boolean(
|
|
5051
|
-
typeof c.value === "string" && c.value.trim() !== "" || Array.isArray(c.values) && c.values.length > 0 || attrValue !== "" || attrValues !== "" || c.hasAttribute &&
|
|
5100
|
+
typeof c.value === "string" && c.value.trim() !== "" || Array.isArray(c.values) && c.values.length > 0 || attrValue !== "" || attrValues !== "" || c.hasAttribute && c.hasAttribute("start")
|
|
5052
5101
|
);
|
|
5053
5102
|
const focused = this.isFocusedInside();
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
this.removeAttribute("active");
|
|
5060
|
-
this.removeAttribute("focus");
|
|
5061
|
-
}
|
|
5103
|
+
const highlighted = focused || isOpen;
|
|
5104
|
+
if (hasValue || highlighted) this.setAttribute("active", "");
|
|
5105
|
+
else this.removeAttribute("active");
|
|
5106
|
+
if (highlighted) this.setAttribute("focus", "");
|
|
5107
|
+
else this.removeAttribute("focus");
|
|
5062
5108
|
}
|
|
5063
5109
|
/**
|
|
5064
5110
|
* variant="in" + ícone à esquerda dentro do campo (fx-input icon):
|
|
@@ -5136,6 +5182,10 @@ _FxFloatlabel.styles = css`
|
|
|
5136
5182
|
font-family: var(--fx-font-family);
|
|
5137
5183
|
font-size: var(--fx-font-size);
|
|
5138
5184
|
vertical-align: middle;
|
|
5185
|
+
/* Cor da label em UM único lugar. active (valor OU foco OU
|
|
5186
|
+
dropdown) só posiciona; focus (foco OU dropdown) só destaca —
|
|
5187
|
+
assim a label acompanha a borda, que só fica primária em foco. */
|
|
5188
|
+
--_flabel-color: var(--fx-text-muted, #94a3b8);
|
|
5139
5189
|
}
|
|
5140
5190
|
/* Full width: o host estica até o pai; o controle interno com
|
|
5141
5191
|
atributo full (ou largura herdada) acompanha. */
|
|
@@ -5167,7 +5217,7 @@ _FxFloatlabel.styles = css`
|
|
|
5167
5217
|
transform: translateY(-50%);
|
|
5168
5218
|
font-size: calc(var(--fx-font-size, 14px) - 3px);
|
|
5169
5219
|
font-weight: 600;
|
|
5170
|
-
color: var(--
|
|
5220
|
+
color: var(--_flabel-color);
|
|
5171
5221
|
background-color: var(--fx-surface-background, #fff);
|
|
5172
5222
|
padding: 0 4px;
|
|
5173
5223
|
line-height: 1;
|
|
@@ -5185,8 +5235,11 @@ _FxFloatlabel.styles = css`
|
|
|
5185
5235
|
color var(--fx-motion-duration-normal, 180ms)
|
|
5186
5236
|
var(--fx-motion-easing, ease-in-out);
|
|
5187
5237
|
}
|
|
5188
|
-
|
|
5189
|
-
|
|
5238
|
+
/* Destacada = foco (ou dropdown aberto). NÃO usar [active]: ele
|
|
5239
|
+
também é verdadeiro com valor e sem foco — era o que deixava a
|
|
5240
|
+
label primária com a borda neutra. */
|
|
5241
|
+
:host([focus]) {
|
|
5242
|
+
--_flabel-color: var(--fx-color-primary, #4f46e5);
|
|
5190
5243
|
}
|
|
5191
5244
|
|
|
5192
5245
|
/* ---- variant="in": label como placeholder dentro, sobe ao focar/valor ---- */
|
|
@@ -5205,7 +5258,8 @@ _FxFloatlabel.styles = css`
|
|
|
5205
5258
|
font-weight: 600;
|
|
5206
5259
|
background-color: var(--fx-surface-background, #fff);
|
|
5207
5260
|
padding: 0 5px;
|
|
5208
|
-
color:
|
|
5261
|
+
/* Sem color aqui: a especificidade desta regra
|
|
5262
|
+
(variant + active) venceria :host([error])/:host([focus]). */
|
|
5209
5263
|
}
|
|
5210
5264
|
|
|
5211
5265
|
/* ---- variant="in" com ícone dentro do campo (fx-input icon):
|
|
@@ -5236,16 +5290,22 @@ _FxFloatlabel.styles = css`
|
|
|
5236
5290
|
font-size: calc(var(--fx-font-size, 14px) - 3px);
|
|
5237
5291
|
font-weight: 600;
|
|
5238
5292
|
white-space: normal;
|
|
5293
|
+
/* Fora do campo, a label pode receber clique: o listener do
|
|
5294
|
+
render() foca o controle (nas variantes on/in o
|
|
5295
|
+
pointer-events: none é intencional, para não bloquear a borda). */
|
|
5296
|
+
pointer-events: auto;
|
|
5239
5297
|
}
|
|
5240
5298
|
|
|
5241
|
-
/* ---- estados de erro / sucesso ----
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5299
|
+
/* ---- estados de erro / sucesso ----
|
|
5300
|
+
Declarados DEPOIS de :host([focus]) e com a mesma especificidade:
|
|
5301
|
+
a validação vence o foco pela ordem, sem depender de acidente. */
|
|
5302
|
+
:host([error]),
|
|
5303
|
+
:host([invalid]) {
|
|
5304
|
+
--_flabel-color: var(--fx-color-danger, #dc2626);
|
|
5245
5305
|
}
|
|
5246
|
-
:host([success])
|
|
5247
|
-
:host([valid])
|
|
5248
|
-
color: var(--fx-color-success, #10b981);
|
|
5306
|
+
:host([success]),
|
|
5307
|
+
:host([valid]) {
|
|
5308
|
+
--_flabel-color: var(--fx-color-success, #10b981);
|
|
5249
5309
|
}
|
|
5250
5310
|
|
|
5251
5311
|
/* ---- mensagem de erro sob o campo (fonte menor) ---- */
|
|
@@ -5270,7 +5330,23 @@ function defineFxFloatlabel() {
|
|
|
5270
5330
|
defineFxFloatlabel();
|
|
5271
5331
|
const _FxTextarea = class _FxTextarea extends FxFormElement {
|
|
5272
5332
|
static get observedAttributes() {
|
|
5273
|
-
return [
|
|
5333
|
+
return [
|
|
5334
|
+
"size",
|
|
5335
|
+
"placeholder",
|
|
5336
|
+
"disabled",
|
|
5337
|
+
"readonly",
|
|
5338
|
+
"full",
|
|
5339
|
+
"rows",
|
|
5340
|
+
"maxlength",
|
|
5341
|
+
"error",
|
|
5342
|
+
"invalid",
|
|
5343
|
+
"success",
|
|
5344
|
+
"valid",
|
|
5345
|
+
// Autofill: vivem no campo interno (ver o JSDoc da classe).
|
|
5346
|
+
"autocomplete",
|
|
5347
|
+
"name",
|
|
5348
|
+
"id"
|
|
5349
|
+
];
|
|
5274
5350
|
}
|
|
5275
5351
|
get size() {
|
|
5276
5352
|
const s = this.getAttr("size", "md");
|
|
@@ -5305,7 +5381,12 @@ const _FxTextarea = class _FxTextarea extends FxFormElement {
|
|
|
5305
5381
|
const disabled = this.hasAttr("disabled");
|
|
5306
5382
|
const rows = this.getAttr("rows");
|
|
5307
5383
|
const maxlength = this.getAttr("maxlength");
|
|
5384
|
+
const autocomplete = this.getAttr("autocomplete", "off");
|
|
5385
|
+
const name = this.getAttr("name");
|
|
5386
|
+
const id = this.getAttr("id");
|
|
5308
5387
|
this.setTemplate(`<textarea class="field" part="textarea"
|
|
5388
|
+
${name ? `name="${esc(name)}"` : ""} ${id ? `id="${esc(id)}"` : ""}
|
|
5389
|
+
autocomplete="${esc(autocomplete)}"
|
|
5309
5390
|
${placeholder ? `placeholder="${esc(placeholder)}"` : ""}
|
|
5310
5391
|
${rows ? `rows="${esc(rows)}"` : ""}
|
|
5311
5392
|
${maxlength ? `maxlength="${esc(maxlength)}"` : ""}
|
|
@@ -7826,8 +7907,8 @@ renderToolbar_fn = function() {
|
|
|
7826
7907
|
button("removeFormat", "format_clear", "Limpar formatação")
|
|
7827
7908
|
].join("");
|
|
7828
7909
|
const color = [
|
|
7829
|
-
`<label class="tb-color" title="Cor do texto"><input type="color" data-color="foreColor" value="#111827" aria-label="Cor do texto"></label>`,
|
|
7830
|
-
`<label class="tb-color" title="Realçar texto"><input type="color" data-color="hiliteColor" value="#fef08a" aria-label="Realçar texto"></label>`
|
|
7910
|
+
`<label class="tb-color" title="Cor do texto"><input type="color" autocomplete="off" data-color="foreColor" value="#111827" aria-label="Cor do texto"></label>`,
|
|
7911
|
+
`<label class="tb-color" title="Realçar texto"><input type="color" autocomplete="off" data-color="hiliteColor" value="#fef08a" aria-label="Realçar texto"></label>`
|
|
7831
7912
|
].join("");
|
|
7832
7913
|
const alignGroup = [
|
|
7833
7914
|
button("justifyLeft", "format_align_left", "Alinhar à esquerda"),
|
|
@@ -8295,7 +8376,7 @@ fieldHtml_fn = function(field) {
|
|
|
8295
8376
|
return `<label class="field"><span>${label}</span><select data-field="${esc(field.name)}">${options}</select></label>`;
|
|
8296
8377
|
}
|
|
8297
8378
|
const type = field.type === "url" ? "url" : field.type === "number" ? "number" : "text";
|
|
8298
|
-
return `<label class="field"><span>${label}</span><input data-field="${esc(field.name)}" type="${type}" value="${esc(field.value ?? "")}" placeholder="${esc(field.placeholder ?? "")}"></label>`;
|
|
8379
|
+
return `<label class="field"><span>${label}</span><input data-field="${esc(field.name)}" type="${type}" autocomplete="off" value="${esc(field.value ?? "")}" placeholder="${esc(field.placeholder ?? "")}"></label>`;
|
|
8299
8380
|
};
|
|
8300
8381
|
submitDialog_fn = function() {
|
|
8301
8382
|
const body = this.root.querySelector(".dialog-body");
|
|
@@ -14712,7 +14793,7 @@ const _FxOrderList = class _FxOrderList extends FxElement {
|
|
|
14712
14793
|
<div class="container" part="container">
|
|
14713
14794
|
${this.filter ? `
|
|
14714
14795
|
<div class="filter-wrapper" part="filter-wrapper">
|
|
14715
|
-
<input type="text" class="filter-input" part="filter-input"
|
|
14796
|
+
<input type="text" class="filter-input" part="filter-input" autocomplete="off"
|
|
14716
14797
|
placeholder="${this.filterPlaceholder}"
|
|
14717
14798
|
value="${esc(this._filterValue)}"
|
|
14718
14799
|
aria-label="Filtrar lista" />
|
|
@@ -15404,7 +15485,7 @@ const _FxPickList = class _FxPickList extends FxElement {
|
|
|
15404
15485
|
const tgtItems = dTgt.length === 0 ? `<li class="empty-message">${this.filter ? "Nenhum resultado" : "Nenhum selecionado"}</li>` : dTgt.map((item, i) => `<li class="list-item${this._isTargetSelected(item, i) ? " selected" : ""}" data-index="${i}" data-list="target" tabindex="0">${hasSel ? '<input type="checkbox" class="checkbox"' + (this._isTargetSelected(item, i) ? " checked" : "") + " />" : ""}<span class="item-content">${this._optionTemplate ? this._optionTemplate(item) : esc(this._getItemLabel(item))}</span></li>`).join("");
|
|
15405
15486
|
const srcAllBar = showAll ? `<div class="select-all-bar" part="select-all-bar"><label><input type="checkbox" class="select-all-checkbox" data-list="source" ${this._sourceSelection.length > 0 && this._sourceSelection.length === this._source.length ? "checked" : ""} aria-label="Selecionar todos da origem" /> Selecionar Todos</label><span class="selection-count">${this._sourceSelection.length} selecionado(s)</span></div>` : "";
|
|
15406
15487
|
const tgtAllBar = showAll ? `<div class="select-all-bar" part="select-all-bar"><label><input type="checkbox" class="select-all-checkbox" data-list="target" ${this._targetSelection.length > 0 && this._targetSelection.length === this._target.length ? "checked" : ""} aria-label="Selecionar todos do destino" /> Selecionar Todos</label><span class="selection-count">${this._targetSelection.length} selecionado(s)</span></div>` : "";
|
|
15407
|
-
this.setTemplate(`<div class="container"><div class="list-container"><div class="list-label">${esc(this.sourceLabel)} (${this._source.length})</div>${this.filter ? '<div class="filter-wrapper"><input type="text" class="filter-input source-filter" placeholder="' + this.filterPlaceholder + '" value="' + esc(this._sourceFilterValue) + '" /></div>' : ""}${srcAllBar}<div class="list-wrapper"><ul class="list source-list" role="listbox" tabindex="0">${srcItems}</ul></div></div><div class="controls"><div class="control-group"><button class="control-btn" data-action="move-all-target" part="control-btn" aria-label="Mover todos para destino"><span class="control-btn-icon">»</span></button><button class="control-btn" data-action="move-target" part="control-btn" aria-label="Mover para destino"><span class="control-btn-icon">→</span></button></div><div class="control-group"><button class="control-btn" data-action="move-source" part="control-btn" aria-label="Mover para origem"><span class="control-btn-icon">←</span></button><button class="control-btn" data-action="move-all-source" part="control-btn" aria-label="Mover todos para origem"><span class="control-btn-icon">«</span></button></div></div><div class="list-container"><div class="list-label">${esc(this.targetLabel)} (${this._target.length})</div>${this.filter ? '<div class="filter-wrapper"><input type="text" class="filter-input target-filter" placeholder="' + this.filterPlaceholder + '" value="' + esc(this._targetFilterValue) + '" /></div>' : ""}${tgtAllBar}<div class="list-wrapper"><ul class="list target-list" role="listbox" tabindex="0">${tgtItems}</ul></div></div></div>`);
|
|
15488
|
+
this.setTemplate(`<div class="container"><div class="list-container"><div class="list-label">${esc(this.sourceLabel)} (${this._source.length})</div>${this.filter ? '<div class="filter-wrapper"><input type="text" autocomplete="off" class="filter-input source-filter" placeholder="' + this.filterPlaceholder + '" value="' + esc(this._sourceFilterValue) + '" /></div>' : ""}${srcAllBar}<div class="list-wrapper"><ul class="list source-list" role="listbox" tabindex="0">${srcItems}</ul></div></div><div class="controls"><div class="control-group"><button class="control-btn" data-action="move-all-target" part="control-btn" aria-label="Mover todos para destino"><span class="control-btn-icon">»</span></button><button class="control-btn" data-action="move-target" part="control-btn" aria-label="Mover para destino"><span class="control-btn-icon">→</span></button></div><div class="control-group"><button class="control-btn" data-action="move-source" part="control-btn" aria-label="Mover para origem"><span class="control-btn-icon">←</span></button><button class="control-btn" data-action="move-all-source" part="control-btn" aria-label="Mover todos para origem"><span class="control-btn-icon">«</span></button></div></div><div class="list-container"><div class="list-label">${esc(this.targetLabel)} (${this._target.length})</div>${this.filter ? '<div class="filter-wrapper"><input type="text" autocomplete="off" class="filter-input target-filter" placeholder="' + this.filterPlaceholder + '" value="' + esc(this._targetFilterValue) + '" /></div>' : ""}${tgtAllBar}<div class="list-wrapper"><ul class="list target-list" role="listbox" tabindex="0">${tgtItems}</ul></div></div></div>`);
|
|
15408
15489
|
this._attachListeners();
|
|
15409
15490
|
}
|
|
15410
15491
|
_attachListeners() {
|