@wrrdev/fenix-ui 1.1.5 → 1.1.7
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 +77 -2
- package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/components/autocomplete/autocomplete.js +16 -7
- package/dist/components/autocomplete/autocomplete.js.map +1 -1
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/button.js +7 -5
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/card/card.d.ts +2 -1
- package/dist/components/card/card.d.ts.map +1 -1
- package/dist/components/card/card.js +5 -2
- package/dist/components/card/card.js.map +1 -1
- package/dist/components/datepicker/datepicker.d.ts.map +1 -1
- package/dist/components/datepicker/datepicker.js +11 -6
- package/dist/components/datepicker/datepicker.js.map +1 -1
- package/dist/components/fileupload/fileupload.d.ts +1 -1
- package/dist/components/fileupload/fileupload.d.ts.map +1 -1
- package/dist/components/fileupload/fileupload.js +10 -3
- package/dist/components/fileupload/fileupload.js.map +1 -1
- package/dist/components/icon/icon.d.ts +40 -0
- package/dist/components/icon/icon.d.ts.map +1 -0
- package/dist/components/icon/index.d.ts +8 -0
- package/dist/components/icon/index.d.ts.map +1 -0
- package/dist/components/input/input.d.ts +3 -0
- package/dist/components/input/input.d.ts.map +1 -1
- package/dist/components/input/input.js +24 -8
- package/dist/components/input/input.js.map +1 -1
- package/dist/components/knob/knob.d.ts +1 -1
- package/dist/components/knob/knob.d.ts.map +1 -1
- package/dist/components/knob/knob.js +3 -1
- package/dist/components/knob/knob.js.map +1 -1
- package/dist/components/multiselect/multiselect.d.ts.map +1 -1
- package/dist/components/multiselect/multiselect.js +17 -6
- package/dist/components/multiselect/multiselect.js.map +1 -1
- package/dist/components/orderlist/orderlist.js +2 -2
- package/dist/components/orderlist/orderlist.js.map +1 -1
- package/dist/components/picklist/picklist.js +2 -2
- package/dist/components/picklist/picklist.js.map +1 -1
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/select/select.js +18 -5
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/textarea/textarea.d.ts.map +1 -1
- package/dist/components/textarea/textarea.js +16 -5
- package/dist/components/textarea/textarea.js.map +1 -1
- package/dist/components/toggle-button-group/toggle-button-group.d.ts.map +1 -1
- package/dist/components/toggle-button-group/toggle-button-group.js +3 -1
- package/dist/components/toggle-button-group/toggle-button-group.js.map +1 -1
- package/dist/core/jsx.d.ts +233 -29
- package/dist/core/jsx.d.ts.map +1 -1
- package/dist/core/jsx.js.map +1 -1
- package/dist/core/presets.js +1 -1
- package/dist/core/presets.js.map +1 -1
- package/dist/core/react.d.ts +20 -0
- package/dist/core/react.d.ts.map +1 -0
- package/dist/core/react.js +5 -0
- package/dist/core/react.js.map +1 -0
- package/dist/core/theme.d.ts.map +1 -1
- package/dist/core/theme.js +12 -0
- package/dist/core/theme.js.map +1 -1
- package/dist/core/tokens.d.ts +4 -0
- package/dist/core/tokens.d.ts.map +1 -1
- package/dist/core/tokens.js +9 -1
- package/dist/core/tokens.js.map +1 -1
- package/dist/core/vue.d.ts +47 -2
- package/dist/core/vue.d.ts.map +1 -1
- package/dist/core/vue.js.map +1 -1
- package/dist/docs/app.d.ts +6 -0
- package/dist/docs/app.d.ts.map +1 -1
- package/dist/docs/componentes/autocomplete.doc.d.ts.map +1 -1
- package/dist/docs/componentes/card.doc.d.ts.map +1 -1
- package/dist/docs/componentes/icon.doc.d.ts +9 -0
- package/dist/docs/componentes/icon.doc.d.ts.map +1 -0
- package/dist/docs/componentes/index.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/select.doc.d.ts.map +1 -1
- package/dist/docs/componentes/textarea.doc.d.ts.map +1 -1
- package/dist/fenix-ui.esm.js +2 -2
- package/dist/fenix-ui.esm.js.map +1 -1
- package/dist/fenix-ui.umd.min.js +296 -215
- package/dist/fenix-ui2.esm.js +2 -4321
- package/dist/fenix-ui2.esm.js.map +1 -1
- package/dist/fenix-ui3.esm.js +4338 -10616
- package/dist/fenix-ui3.esm.js.map +1 -1
- package/dist/fenix-ui4.esm.js +10724 -104
- package/dist/fenix-ui4.esm.js.map +1 -1
- package/dist/fenix-ui5.esm.js +111 -0
- package/dist/fenix-ui5.esm.js.map +1 -0
- package/dist/icons/font.d.ts +26 -0
- package/dist/icons/font.d.ts.map +1 -0
- package/dist/icons/font.js +42 -0
- package/dist/icons/font.js.map +1 -0
- package/dist/icons/index.d.ts +3 -1
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/index.js +11 -13
- package/dist/icons/index.js.map +1 -1
- package/dist/icons/name-union.d.ts +11 -0
- package/dist/icons/name-union.d.ts.map +1 -0
- package/dist/icons/names.d.ts +0 -1
- package/dist/icons/names.d.ts.map +1 -1
- package/dist/icons/names.js.map +1 -1
- package/dist/icons/types.d.ts +14 -0
- package/dist/icons/types.d.ts.map +1 -0
- package/dist/plugins/auto-import.d.ts.map +1 -1
- package/dist/plugins/auto-import.js +1 -0
- package/dist/plugins/auto-import.js.map +1 -1
- package/package.json +10 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"picklist.js","sources":["../../../src/components/picklist/picklist.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\nexport interface PickListItem {\n [key: string]: unknown;\n}\n\n/**\n * <fx-picklist> - Componente para transferir itens entre duas listas.\n *\n * Permite mover itens entre uma lista de origem e uma lista de destino.\n * Suporta filtro, seleção múltipla, checkbox e templates customizados.\n *\n * Atributos: source, target, source-key, target-key, filter, filter-by,\n * filter-placeholder, dragdrop, striped, selection-mode, source-label, target-label.\n * Evento: `move-to-target` (composed, detail: { items }).\n * Evento: `move-to-source` (composed, detail: { items }).\n * Evento: `selection-change-source` (composed, detail: { selection }).\n * Evento: `selection-change-target` (composed, detail: { selection }).\n */\nexport class FxPickList extends FxElement {\n static override styles = css`\n :host {\n display: block;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n --picklist-primary: var(--fx-color-primary, #3b82f6);\n --picklist-border: var(--fx-border-default, #e2e8f0);\n --picklist-bg: var(--fx-surface-background, #ffffff);\n --picklist-bg-hover: var(--fx-surface-surface-hover, #f1f5f9);\n --picklist-text: var(--fx-text-default, #1e293b);\n --picklist-text-muted: var(--fx-text-muted, #64748b);\n --picklist-radius: var(--fx-radius-md, 8px);\n --picklist-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n --picklist-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n }\n * { box-sizing: border-box; }\n .container {\n display: flex;\n gap: var(--fx-space-sm, 8px);\n align-items: stretch;\n }\n .list-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--fx-space-sm, 8px);\n min-width: 0;\n }\n .list-label {\n font-weight: 600;\n color: var(--picklist-text);\n font-size: calc(var(--fx-font-size) - 1px);\n }\n .select-all-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--fx-space-sm, 10px) var(--fx-space-md, 14px);\n background: linear-gradient(135deg, var(--picklist-bg), var(--picklist-bg-hover));\n border: 1px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n font-size: 0.9em;\n font-weight: 500;\n }\n .select-all-bar label {\n display: flex;\n align-items: center;\n gap: var(--fx-space-sm, 10px);\n cursor: pointer;\n user-select: none;\n color: var(--picklist-text);\n }\n .select-all-bar input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n accent-color: var(--picklist-primary);\n cursor: pointer;\n }\n .selection-count {\n font-size: 0.85em;\n color: var(--picklist-primary);\n background: color-mix(in srgb, var(--picklist-primary) 12%, transparent);\n padding: 4px 12px;\n border-radius: 20px;\n font-weight: 600;\n }\n .controls {\n display: flex;\n flex-direction: column;\n gap: 4px;\n justify-content: center;\n padding: var(--fx-space-xs, 6px);\n background: var(--picklist-bg);\n border: 1px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n box-shadow: var(--picklist-shadow);\n height: fit-content;\n position: sticky;\n top: 0;\n align-self: center;\n }\n .control-group {\n display: flex;\n flex-direction: column;\n gap: 3px;\n }\n .control-group + .control-group {\n margin-top: 4px;\n padding-top: 6px;\n border-top: 1px solid var(--picklist-border);\n }\n .list-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--fx-space-sm, 8px);\n }\n .filter-wrapper {\n margin-bottom: var(--fx-space-xs, 4px);\n }\n .filter-input {\n width: 100%;\n box-sizing: border-box;\n padding: var(--fx-space-sm, 10px) var(--fx-space-md, 14px);\n padding-left: 42px;\n border: 1.5px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n font-family: inherit;\n font-size: inherit;\n color: var(--picklist-text);\n background: var(--picklist-bg) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E\") no-repeat 14px center;\n transition: var(--picklist-transition);\n }\n .filter-input:focus {\n outline: none;\n border-color: var(--picklist-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--picklist-primary) 20%, transparent);\n }\n .filter-input::placeholder {\n color: var(--picklist-text-muted);\n }\n .list {\n list-style: none;\n margin: 0;\n padding: 0;\n border: 1px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n overflow: hidden;\n box-shadow: var(--picklist-shadow);\n min-height: 200px;\n max-height: 450px;\n overflow-y: auto;\n flex: 1;\n }\n .list::-webkit-scrollbar { width: 6px; }\n .list::-webkit-scrollbar-track { background: transparent; }\n .list::-webkit-scrollbar-thumb { background: var(--picklist-border); border-radius: 3px; }\n .list::-webkit-scrollbar-thumb:hover { background: var(--picklist-text-muted); }\n :host([striped]) .list-item:nth-child(even) {\n background: var(--fx-surface-surface, #f8fafc);\n }\n .list-item {\n display: flex;\n align-items: center;\n gap: var(--fx-space-sm, 10px);\n padding: var(--fx-space-sm, 10px) var(--fx-space-md, 14px);\n background: var(--picklist-bg);\n border-bottom: 1px solid var(--picklist-border);\n cursor: pointer;\n user-select: none;\n transition: var(--picklist-transition);\n }\n .list-item:last-child { border-bottom: none; }\n .list-item:hover { background: var(--picklist-bg-hover); }\n .list-item.selected {\n background: color-mix(in srgb, var(--picklist-primary) 8%, transparent);\n border-left: 3px solid var(--picklist-primary);\n padding-left: 11px;\n }\n .list-item:focus-visible {\n outline: none;\n background: color-mix(in srgb, var(--picklist-primary) 15%, transparent);\n }\n .checkbox {\n flex-shrink: 0;\n width: 18px;\n height: 18px;\n accent-color: var(--picklist-primary);\n cursor: pointer;\n transition: var(--picklist-transition);\n }\n .checkbox:hover { transform: scale(1.1); }\n .item-content {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .empty-message {\n padding: var(--fx-space-xl, 32px);\n text-align: center;\n color: var(--picklist-text-muted);\n font-style: italic;\n }\n button.control-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 42px;\n height: 38px;\n padding: 0;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--picklist-text-muted);\n cursor: pointer;\n font-size: 16px;\n line-height: 1;\n transition: var(--picklist-transition);\n position: relative;\n }\n button.control-btn:hover:not(:disabled) {\n background: var(--picklist-bg-hover);\n color: var(--picklist-primary);\n transform: scale(1.1);\n }\n button.control-btn:active:not(:disabled) {\n transform: scale(0.92);\n background: color-mix(in srgb, var(--picklist-primary) 15%, transparent);\n }\n button.control-btn:focus-visible {\n outline: none;\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--picklist-primary) 30%, transparent);\n }\n button.control-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n transform: none;\n }\n .control-btn-icon { font-size: 18px; line-height: 1; }\n\n button.control-btn:hover::after {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n @media (max-width: 640px) {\n .container { flex-direction: column; }\n .controls {\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: center;\n position: relative;\n }\n .control-group { flex-direction: row; }\n .control-group + .control-group {\n margin-top: 0;\n margin-left: 4px;\n padding-top: 0;\n padding-left: 4px;\n border-top: none;\n border-left: 1px solid var(--picklist-border);\n }\n button.control-btn { width: 44px; height: 40px; }\n button.control-btn::after { display: none; }\n .list { max-height: 300px; min-height: 150px; }\n }\n @keyframes slideIn {\n from { opacity: 0; transform: translateX(-10px); }\n to { opacity: 1; transform: translateX(0); }\n }\n .list-item { animation: slideIn 0.2s ease-out; }\n `;\n\n static override get observedAttributes(): string[] {\n return [\n 'source',\n 'target',\n 'source-key',\n 'target-key',\n 'filter',\n 'filter-by',\n 'filter-placeholder',\n 'dragdrop',\n 'striped',\n 'selection-mode',\n 'show-select-all',\n 'source-label',\n 'target-label',\n ];\n }\n\n set source(value: PickListItem[]) {\n this._source = value;\n this._filteredSource = null;\n this.render();\n }\n get source(): PickListItem[] {\n return this._source;\n }\n private _source: PickListItem[] = [];\n private _filteredSource: PickListItem[] | null = null;\n\n set target(value: PickListItem[]) {\n this._target = value;\n this._filteredTarget = null;\n this.render();\n }\n get target(): PickListItem[] {\n return this._target;\n }\n private _target: PickListItem[] = [];\n private _filteredTarget: PickListItem[] | null = null;\n\n set sourceSelection(value: PickListItem[]) {\n this._sourceSelection = value;\n this.render();\n }\n get sourceSelection(): PickListItem[] {\n return this._sourceSelection;\n }\n private _sourceSelection: PickListItem[] = [];\n\n set targetSelection(value: PickListItem[]) {\n this._targetSelection = value;\n this.render();\n }\n get targetSelection(): PickListItem[] {\n return this._targetSelection;\n }\n private _targetSelection: PickListItem[] = [];\n\n get sourceKey(): string {\n return this.getAttr('source-key', '');\n }\n set sourceKey(v: string) {\n this.setAttribute('source-key', v);\n }\n\n get targetKey(): string {\n return this.getAttr('target-key', '');\n }\n set targetKey(v: string) {\n this.setAttribute('target-key', v);\n }\n\n get filter(): boolean {\n return this.hasAttr('filter');\n }\n set filter(v: boolean) {\n this.toggleAttr('filter', v);\n }\n\n get filterBy(): string {\n return this.getAttr('filter-by', 'label');\n }\n set filterBy(v: string) {\n this.setAttribute('filter-by', v);\n }\n\n get filterPlaceholder(): string {\n return this.getAttr('filter-placeholder', 'Buscar...');\n }\n set filterPlaceholder(v: string) {\n this.setAttribute('filter-placeholder', v);\n }\n\n get dragdrop(): boolean {\n return this.hasAttr('dragdrop');\n }\n set dragdrop(v: boolean) {\n this.toggleAttr('dragdrop', v);\n }\n\n get striped(): boolean {\n return this.hasAttr('striped');\n }\n set striped(v: boolean) {\n this.toggleAttr('striped', v);\n }\n\n get selectionMode(): string {\n const s = this.getAttr('selection-mode', '');\n return s === 'single' || s === 'multiple' ? s : '';\n }\n set selectionMode(v: string) {\n this.setAttribute('selection-mode', v);\n }\n\n get showSelectAll(): boolean {\n return this.hasAttr('show-select-all');\n }\n set showSelectAll(v: boolean) {\n this.toggleAttr('show-select-all', v);\n }\n\n get sourceLabel(): string {\n return this.getAttr('source-label', 'Disponíveis');\n }\n set sourceLabel(v: string) {\n this.setAttribute('source-label', v);\n }\n\n get targetLabel(): string {\n return this.getAttr('target-label', 'Selecionados');\n }\n set targetLabel(v: string) {\n this.setAttribute('target-label', v);\n }\n\n get sourceFilterValue(): string {\n return this._sourceFilterValue;\n }\n set sourceFilterValue(v: string) {\n this._sourceFilterValue = v;\n this._applySourceFilter();\n this._updateListDisplay();\n }\n private _sourceFilterValue = '';\n\n get targetFilterValue(): string {\n return this._targetFilterValue;\n }\n set targetFilterValue(v: string) {\n this._targetFilterValue = v;\n this._applyTargetFilter();\n this._updateListDisplay();\n }\n private _targetFilterValue = '';\n private _filterListenersAttached = false;\n\n private _optionTemplate: ((item: PickListItem) => string) | null = null;\n\n setOptionTemplate(template: (item: PickListItem) => string): void {\n this._optionTemplate = template;\n this.render();\n }\n\n protected override connectedCallback(): void {\n this._parseSourceAttribute();\n this._parseTargetAttribute();\n super.connectedCallback();\n }\n\n protected override attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (this.getAttr('source', '') !== '') {\n this._parseSourceAttribute();\n }\n if (this.getAttr('target', '') !== '') {\n this._parseTargetAttribute();\n }\n super.attributeChangedCallback(name, oldValue, newValue);\n }\n\n private _parseSourceAttribute(): void {\n const dataAttr = this.getAttr('source', '');\n if (dataAttr) {\n try {\n this._source = JSON.parse(dataAttr);\n this._filteredSource = null;\n } catch {\n this._source = [];\n }\n }\n }\n\n private _parseTargetAttribute(): void {\n const dataAttr = this.getAttr('target', '');\n if (dataAttr) {\n try {\n this._target = JSON.parse(dataAttr);\n this._filteredTarget = null;\n } catch {\n this._target = [];\n }\n }\n }\n\n private _applySourceFilter(): void {\n if (!this._sourceFilterValue) {\n this._filteredSource = null;\n return;\n }\n const filterFields = this.filterBy.split(',').map(f => f.trim());\n this._filteredSource = this._source.filter(item => {\n return filterFields.some(field => {\n const value = item[field];\n if (value == null) return false;\n return String(value).toLowerCase().includes(this._sourceFilterValue.toLowerCase());\n });\n });\n }\n\n private _applyTargetFilter(): void {\n if (!this._targetFilterValue) {\n this._filteredTarget = null;\n return;\n }\n const filterFields = this.filterBy.split(',').map(f => f.trim());\n this._filteredTarget = this._target.filter(item => {\n return filterFields.some(field => {\n const value = item[field];\n if (value == null) return false;\n return String(value).toLowerCase().includes(this._targetFilterValue.toLowerCase());\n });\n });\n }\n\n private _getDisplaySource(): PickListItem[] {\n return this._filteredSource || this._source;\n }\n\n private _getDisplayTarget(): PickListItem[] {\n return this._filteredTarget || this._target;\n }\n\n private _getItemKey(item: PickListItem, index: number, isSource: boolean): string {\n const keyField = isSource ? this.sourceKey : this.targetKey;\n if (keyField && item[keyField] != null) {\n return String(item[keyField]);\n }\n if (item['id'] != null) return String(item['id']);\n if (item['key'] != null) return String(item['key']);\n if (item['label'] != null) return String(item['label']);\n if (item['name'] != null) return String(item['name']);\n if (item['value'] != null) return String(item['value']);\n return String(index);\n }\n\n private _getItemLabel(item: PickListItem): string {\n const fields = ['label', 'name', 'title', 'text', 'value'];\n for (const field of fields) {\n if (item[field] != null) {\n return String(item[field]);\n }\n }\n return JSON.stringify(item);\n }\n\n private _isSourceSelected(item: PickListItem, index: number): boolean {\n return this._sourceSelection.some(s => this._getItemKey(s, -1, true) === this._getItemKey(item, index, true));\n }\n\n private _isTargetSelected(item: PickListItem, index: number): boolean {\n return this._targetSelection.some(s => this._getItemKey(s, -1, false) === this._getItemKey(item, index, false));\n }\n\n private _emitMoveToTarget(): void {\n this.dispatchEvent(new CustomEvent('move-to-target', {\n bubbles: true,\n composed: true,\n detail: { items: [...this._sourceSelection], source: [...this._source], target: [...this._target] },\n }));\n }\n\n private _emitMoveToSource(): void {\n this.dispatchEvent(new CustomEvent('move-to-source', {\n bubbles: true,\n composed: true,\n detail: { items: [...this._targetSelection], source: [...this._source], target: [...this._target] },\n }));\n }\n\n private _emitSelectionChangeSource(): void {\n this.dispatchEvent(new CustomEvent('selection-change-source', {\n bubbles: true,\n composed: true,\n detail: { selection: [...this._sourceSelection] },\n }));\n }\n\n private _emitSelectionChangeTarget(): void {\n this.dispatchEvent(new CustomEvent('selection-change-target', {\n bubbles: true,\n composed: true,\n detail: { selection: [...this._targetSelection] },\n }));\n }\n\n protected override render(): void {\n const dSrc = this._getDisplaySource();\n const dTgt = this._getDisplayTarget();\n const hasSel = this.selectionMode;\n const showAll = hasSel === 'multiple' && this.showSelectAll;\n const srcItems = dSrc.length === 0 ? `<li class=\"empty-message\">${this.filter ? 'Nenhum resultado' : 'Nenhum item'}</li>` : dSrc.map((item, i) => `<li class=\"list-item${this._isSourceSelected(item, i) ? ' selected' : ''}\" data-index=\"${i}\" data-list=\"source\" tabindex=\"0\">${hasSel ? '<input type=\"checkbox\" class=\"checkbox\"' + (this._isSourceSelected(item, i) ? ' checked' : '') + ' />' : ''}<span class=\"item-content\">${this._optionTemplate ? this._optionTemplate(item) : esc(this._getItemLabel(item))}</span></li>`).join('');\n 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('');\n 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>` : '';\n 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>` : '';\n\n 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>`);\n\n this._attachListeners();\n }\n\n private _attachListeners(): void {\n // Listeners delegados no root, anexados uma unica vez (sobrevivem a re-renders)\n if (!this._filterListenersAttached) {\n this._filterListenersAttached = true;\n\n this.root.addEventListener('input', (e) => {\n const t = e.target as HTMLElement;\n if (t.classList.contains('select-all-checkbox')) {\n this._handleSelectAll(t as HTMLInputElement);\n return;\n }\n if (t.classList.contains('source-filter')) {\n this.sourceFilterValue = (t as HTMLInputElement).value;\n } else if (t.classList.contains('target-filter')) {\n this.targetFilterValue = (t as HTMLInputElement).value;\n }\n });\n\n this.root.addEventListener('click', (e) => {\n const t = e.target as HTMLElement;\n const btn = t.closest('.control-btn') as HTMLButtonElement | null;\n if (btn) {\n switch (btn.dataset.action) {\n case 'move-target': this._moveToTarget(); break;\n case 'move-all-target': this._moveAllToTarget(); break;\n case 'move-source': this._moveToSource(); break;\n case 'move-all-source': this._moveAllToSource(); break;\n }\n return;\n }\n const el = t.closest('.list-item') as HTMLElement | null;\n if (!el) return;\n const isSrc = el.dataset.list === 'source';\n const idx = Number(el.dataset.index);\n const item = (isSrc ? this._getDisplaySource() : this._getDisplayTarget())[idx];\n if (isSrc) this._toggleSourceSelection(item, idx); else this._toggleTargetSelection(item, idx);\n });\n }\n this._updateControlsState();\n }\n\n private _handleSelectAll(checkbox: HTMLInputElement): void {\n const isSrc = checkbox.dataset.list === 'source';\n if (isSrc) {\n this._sourceSelection = checkbox.checked ? [...this._getDisplaySource()] : [];\n this._emitSelectionChangeSource();\n } else {\n this._targetSelection = checkbox.checked ? [...this._getDisplayTarget()] : [];\n this._emitSelectionChangeTarget();\n }\n this._updateSelectionDisplay();\n this._updateControlsState();\n }\n\n /**\n * Atualiza a selecao visual in-place (classes e checkboxes dos itens existentes),\n * sem recriar o DOM — mantendo referencias de elementos validas durante cliques.\n */\n private _updateSelectionDisplay(): void {\n const updateList = (listSel: HTMLElement | null, isSelFn: (item: PickListItem, i: number) => boolean, getData: () => PickListItem[]): void => {\n if (!listSel) return;\n listSel.querySelectorAll<HTMLElement>('.list-item').forEach(el => {\n const idx = Number(el.dataset.index);\n const selected = isSelFn(getData()[idx], idx);\n el.classList.toggle('selected', selected);\n el.setAttribute('aria-selected', String(selected));\n const cb = el.querySelector<HTMLInputElement>('.checkbox');\n if (cb) cb.checked = selected;\n });\n };\n updateList(this.root.querySelector('.source-list'), (it, i) => this._isSourceSelected(it, i), () => this._getDisplaySource());\n updateList(this.root.querySelector('.target-list'), (it, i) => this._isTargetSelected(it, i), () => this._getDisplayTarget());\n this._updateSelectAllBars();\n }\n\n /** Sincroniza as barras \"Selecionar Todos\" (checkbox + contador) sem re-render completo. */\n private _updateSelectAllBars(): void {\n if (!(this.selectionMode === 'multiple' && this.showSelectAll)) return;\n const bars = [\n { el: this.root.querySelector<HTMLInputElement>('.select-all-checkbox[data-list=\"source\"]'), total: this._source.length, sel: this._sourceSelection.length },\n { el: this.root.querySelector<HTMLInputElement>('.select-all-checkbox[data-list=\"target\"]'), total: this._target.length, sel: this._targetSelection.length },\n ];\n bars.forEach(({ el, total, sel }) => {\n if (!el) return;\n el.checked = total > 0 && sel === total;\n const count = el.closest('.select-all-bar')?.querySelector('.selection-count');\n if (count) count.textContent = `${sel} selecionado(s)`;\n });\n }\n\n private _updateControlsState(): void {\n this.root.querySelectorAll<HTMLButtonElement>('.control-btn').forEach(btn => {\n const a = btn.dataset.action;\n btn.disabled = (a === 'move-target' && this._sourceSelection.length === 0) || (a === 'move-all-target' && this._source.length === 0) || (a === 'move-source' && this._targetSelection.length === 0) || (a === 'move-all-source' && this._target.length === 0);\n });\n }\n\n private _moveToTarget(): void {\n if (!this._sourceSelection.length) return;\n const items = [...this._sourceSelection];\n this._source = this._source.filter(s => !items.some(i => this._getItemKey(i, -1, true) === this._getItemKey(s, -1, true)));\n this._target = [...this._target, ...items];\n this._sourceSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToTarget();\n }\n\n private _moveToSource(): void {\n if (!this._targetSelection.length) return;\n const items = [...this._targetSelection];\n this._target = this._target.filter(t => !items.some(i => this._getItemKey(i, -1, false) === this._getItemKey(t, -1, false)));\n this._source = [...this._source, ...items];\n this._targetSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToSource();\n }\n\n private _moveAllToTarget(): void {\n const items = [...this._source];\n this._source = [];\n this._target = [...this._target, ...items];\n this._sourceSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToTarget();\n }\n\n private _moveAllToSource(): void {\n const items = [...this._target];\n this._target = [];\n this._source = [...this._source, ...items];\n this._targetSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToSource();\n }\n\n private _toggleSourceSelection(item: PickListItem, index: number): void {\n // Sem selection-mode definido, permite selecao simples (um item por vez)\n const mode = this.selectionMode || 'single';\n const key = this._getItemKey(item, index, true);\n const idx = this._sourceSelection.findIndex(s => this._getItemKey(s, -1, true) === key);\n if (idx >= 0) {\n this._sourceSelection.splice(idx, 1);\n } else if (mode === 'multiple') {\n this._sourceSelection.push(item);\n } else {\n this._sourceSelection = [item];\n }\n this._emitSelectionChangeSource();\n this._updateSelectionDisplay();\n this._updateControlsState();\n }\n\n private _toggleTargetSelection(item: PickListItem, index: number): void {\n // Sem selection-mode definido, permite selecao simples (um item por vez)\n const mode = this.selectionMode || 'single';\n const key = this._getItemKey(item, index, false);\n const idx = this._targetSelection.findIndex(s => this._getItemKey(s, -1, false) === key);\n if (idx >= 0) {\n this._targetSelection.splice(idx, 1);\n } else if (mode === 'multiple') {\n this._targetSelection.push(item);\n } else {\n this._targetSelection = [item];\n }\n this._emitSelectionChangeTarget();\n this._updateSelectionDisplay();\n this._updateControlsState();\n }\n\n private _updateListDisplay(): void {\n const srcWrapper = this.root.querySelector('.source-list')?.parentElement;\n const tgtWrapper = this.root.querySelector('.target-list')?.parentElement;\n const srcLabel = this.root.querySelector('.list-container:first-of-type .list-label');\n const tgtLabel = this.root.querySelector('.list-container:last-of-type .list-label');\n if (!srcWrapper || !tgtWrapper) { this.render(); return; }\n const dSrc = this._getDisplaySource();\n const dTgt = this._getDisplayTarget();\n const hasSel = this.selectionMode;\n const srcItems = dSrc.length === 0 ? `<li class=\"empty-message\" part=\"empty-message\">${this.filter ? 'Nenhum resultado' : 'Nenhum item'}</li>` : dSrc.map((item, i) => `<li class=\"list-item${this._isSourceSelected(item, i) ? ' selected' : ''}\" part=\"list-item\" data-index=\"${i}\" data-list=\"source\" role=\"option\" aria-selected=\"${this._isSourceSelected(item, i)}\" tabindex=\"0\">${hasSel ? '<input type=\"checkbox\" class=\"checkbox\" part=\"checkbox\"' + (this._isSourceSelected(item, i) ? ' checked' : '') + ' />' : ''}<span class=\"item-content\" part=\"item-content\">${this._optionTemplate ? this._optionTemplate(item) : esc(this._getItemLabel(item))}</span></li>`).join('');\n const tgtItems = dTgt.length === 0 ? `<li class=\"empty-message\" part=\"empty-message\">${this.filter ? 'Nenhum resultado' : 'Nenhum selecionado'}</li>` : dTgt.map((item, i) => `<li class=\"list-item${this._isTargetSelected(item, i) ? ' selected' : ''}\" part=\"list-item\" data-index=\"${i}\" data-list=\"target\" role=\"option\" aria-selected=\"${this._isTargetSelected(item, i)}\" tabindex=\"0\">${hasSel ? '<input type=\"checkbox\" class=\"checkbox\" part=\"checkbox\"' + (this._isTargetSelected(item, i) ? ' checked' : '') + ' />' : ''}<span class=\"item-content\" part=\"item-content\">${this._optionTemplate ? this._optionTemplate(item) : esc(this._getItemLabel(item))}</span></li>`).join('');\n srcWrapper.innerHTML = `<ul class=\"list source-list\" role=\"listbox\" tabindex=\"0\">${srcItems}</ul>`;\n tgtWrapper.innerHTML = `<ul class=\"list target-list\" role=\"listbox\" tabindex=\"0\">${tgtItems}</ul>`;\n if (srcLabel) srcLabel.textContent = `${this.sourceLabel} (${this._source.length})`;\n if (tgtLabel) tgtLabel.textContent = `${this.targetLabel} (${this._target.length})`;\n this._updateSelectAllBars();\n this._attachListeners();\n }\n}\n\nexport function defineFxPickList(): typeof FxPickList {\n return defineElement('fx-picklist', FxPickList);\n}"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"picklist.js","sources":["../../../src/components/picklist/picklist.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\nexport interface PickListItem {\n [key: string]: unknown;\n}\n\n/**\n * <fx-picklist> - Componente para transferir itens entre duas listas.\n *\n * Permite mover itens entre uma lista de origem e uma lista de destino.\n * Suporta filtro, seleção múltipla, checkbox e templates customizados.\n *\n * Atributos: source, target, source-key, target-key, filter, filter-by,\n * filter-placeholder, dragdrop, striped, selection-mode, source-label, target-label.\n * Evento: `move-to-target` (composed, detail: { items }).\n * Evento: `move-to-source` (composed, detail: { items }).\n * Evento: `selection-change-source` (composed, detail: { selection }).\n * Evento: `selection-change-target` (composed, detail: { selection }).\n */\nexport class FxPickList extends FxElement {\n static override styles = css`\n :host {\n display: block;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n --picklist-primary: var(--fx-color-primary, #3b82f6);\n --picklist-border: var(--fx-border-default, #e2e8f0);\n --picklist-bg: var(--fx-surface-background, #ffffff);\n --picklist-bg-hover: var(--fx-surface-surface-hover, #f1f5f9);\n --picklist-text: var(--fx-text-default, #1e293b);\n --picklist-text-muted: var(--fx-text-muted, #64748b);\n --picklist-radius: var(--fx-radius-md, 8px);\n --picklist-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n --picklist-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n }\n * { box-sizing: border-box; }\n .container {\n display: flex;\n gap: var(--fx-space-sm, 8px);\n align-items: stretch;\n }\n .list-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--fx-space-sm, 8px);\n min-width: 0;\n }\n .list-label {\n font-weight: 600;\n color: var(--picklist-text);\n font-size: calc(var(--fx-font-size) - 1px);\n }\n .select-all-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--fx-space-sm, 10px) var(--fx-space-md, 14px);\n background: linear-gradient(135deg, var(--picklist-bg), var(--picklist-bg-hover));\n border: 1px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n font-size: 0.9em;\n font-weight: 500;\n }\n .select-all-bar label {\n display: flex;\n align-items: center;\n gap: var(--fx-space-sm, 10px);\n cursor: pointer;\n user-select: none;\n color: var(--picklist-text);\n }\n .select-all-bar input[type=\"checkbox\"] {\n width: 18px;\n height: 18px;\n accent-color: var(--picklist-primary);\n cursor: pointer;\n }\n .selection-count {\n font-size: 0.85em;\n color: var(--picklist-primary);\n background: color-mix(in srgb, var(--picklist-primary) 12%, transparent);\n padding: 4px 12px;\n border-radius: 20px;\n font-weight: 600;\n }\n .controls {\n display: flex;\n flex-direction: column;\n gap: 4px;\n justify-content: center;\n padding: var(--fx-space-xs, 6px);\n background: var(--picklist-bg);\n border: 1px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n box-shadow: var(--picklist-shadow);\n height: fit-content;\n position: sticky;\n top: 0;\n align-self: center;\n }\n .control-group {\n display: flex;\n flex-direction: column;\n gap: 3px;\n }\n .control-group + .control-group {\n margin-top: 4px;\n padding-top: 6px;\n border-top: 1px solid var(--picklist-border);\n }\n .list-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--fx-space-sm, 8px);\n }\n .filter-wrapper {\n margin-bottom: var(--fx-space-xs, 4px);\n }\n .filter-input {\n width: 100%;\n box-sizing: border-box;\n padding: var(--fx-space-sm, 10px) var(--fx-space-md, 14px);\n padding-left: 42px;\n border: 1.5px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n font-family: inherit;\n font-size: inherit;\n color: var(--picklist-text);\n background: var(--picklist-bg) url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E\") no-repeat 14px center;\n transition: var(--picklist-transition);\n }\n .filter-input:focus {\n outline: none;\n border-color: var(--picklist-primary);\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n .filter-input::placeholder {\n color: var(--picklist-text-muted);\n }\n .list {\n list-style: none;\n margin: 0;\n padding: 0;\n border: 1px solid var(--picklist-border);\n border-radius: var(--picklist-radius);\n overflow: hidden;\n box-shadow: var(--picklist-shadow);\n min-height: 200px;\n max-height: 450px;\n overflow-y: auto;\n flex: 1;\n }\n .list::-webkit-scrollbar { width: 6px; }\n .list::-webkit-scrollbar-track { background: transparent; }\n .list::-webkit-scrollbar-thumb { background: var(--picklist-border); border-radius: 3px; }\n .list::-webkit-scrollbar-thumb:hover { background: var(--picklist-text-muted); }\n :host([striped]) .list-item:nth-child(even) {\n background: var(--fx-surface-surface, #f8fafc);\n }\n .list-item {\n display: flex;\n align-items: center;\n gap: var(--fx-space-sm, 10px);\n padding: var(--fx-space-sm, 10px) var(--fx-space-md, 14px);\n background: var(--picklist-bg);\n border-bottom: 1px solid var(--picklist-border);\n cursor: pointer;\n user-select: none;\n transition: var(--picklist-transition);\n }\n .list-item:last-child { border-bottom: none; }\n .list-item:hover { background: var(--picklist-bg-hover); }\n .list-item.selected {\n background: color-mix(in srgb, var(--picklist-primary) 8%, transparent);\n border-left: 3px solid var(--picklist-primary);\n padding-left: 11px;\n }\n .list-item:focus-visible {\n outline: none;\n background: color-mix(in srgb, var(--picklist-primary) 15%, transparent);\n }\n .checkbox {\n flex-shrink: 0;\n width: 18px;\n height: 18px;\n accent-color: var(--picklist-primary);\n cursor: pointer;\n transition: var(--picklist-transition);\n }\n .checkbox:hover { transform: scale(1.1); }\n .item-content {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .empty-message {\n padding: var(--fx-space-xl, 32px);\n text-align: center;\n color: var(--picklist-text-muted);\n font-style: italic;\n }\n button.control-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 42px;\n height: 38px;\n padding: 0;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--picklist-text-muted);\n cursor: pointer;\n font-size: 16px;\n line-height: 1;\n transition: var(--picklist-transition);\n position: relative;\n }\n button.control-btn:hover:not(:disabled) {\n background: var(--picklist-bg-hover);\n color: var(--picklist-primary);\n transform: scale(1.1);\n }\n button.control-btn:active:not(:disabled) {\n transform: scale(0.92);\n background: color-mix(in srgb, var(--picklist-primary) 15%, transparent);\n }\n button.control-btn:focus-visible {\n outline: none;\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n button.control-btn:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n transform: none;\n }\n .control-btn-icon { font-size: 18px; line-height: 1; }\n\n button.control-btn:hover::after {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n @media (max-width: 640px) {\n .container { flex-direction: column; }\n .controls {\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: center;\n position: relative;\n }\n .control-group { flex-direction: row; }\n .control-group + .control-group {\n margin-top: 0;\n margin-left: 4px;\n padding-top: 0;\n padding-left: 4px;\n border-top: none;\n border-left: 1px solid var(--picklist-border);\n }\n button.control-btn { width: 44px; height: 40px; }\n button.control-btn::after { display: none; }\n .list { max-height: 300px; min-height: 150px; }\n }\n @keyframes slideIn {\n from { opacity: 0; transform: translateX(-10px); }\n to { opacity: 1; transform: translateX(0); }\n }\n .list-item { animation: slideIn 0.2s ease-out; }\n `;\n\n static override get observedAttributes(): string[] {\n return [\n 'source',\n 'target',\n 'source-key',\n 'target-key',\n 'filter',\n 'filter-by',\n 'filter-placeholder',\n 'dragdrop',\n 'striped',\n 'selection-mode',\n 'show-select-all',\n 'source-label',\n 'target-label',\n ];\n }\n\n set source(value: PickListItem[]) {\n this._source = value;\n this._filteredSource = null;\n this.render();\n }\n get source(): PickListItem[] {\n return this._source;\n }\n private _source: PickListItem[] = [];\n private _filteredSource: PickListItem[] | null = null;\n\n set target(value: PickListItem[]) {\n this._target = value;\n this._filteredTarget = null;\n this.render();\n }\n get target(): PickListItem[] {\n return this._target;\n }\n private _target: PickListItem[] = [];\n private _filteredTarget: PickListItem[] | null = null;\n\n set sourceSelection(value: PickListItem[]) {\n this._sourceSelection = value;\n this.render();\n }\n get sourceSelection(): PickListItem[] {\n return this._sourceSelection;\n }\n private _sourceSelection: PickListItem[] = [];\n\n set targetSelection(value: PickListItem[]) {\n this._targetSelection = value;\n this.render();\n }\n get targetSelection(): PickListItem[] {\n return this._targetSelection;\n }\n private _targetSelection: PickListItem[] = [];\n\n get sourceKey(): string {\n return this.getAttr('source-key', '');\n }\n set sourceKey(v: string) {\n this.setAttribute('source-key', v);\n }\n\n get targetKey(): string {\n return this.getAttr('target-key', '');\n }\n set targetKey(v: string) {\n this.setAttribute('target-key', v);\n }\n\n get filter(): boolean {\n return this.hasAttr('filter');\n }\n set filter(v: boolean) {\n this.toggleAttr('filter', v);\n }\n\n get filterBy(): string {\n return this.getAttr('filter-by', 'label');\n }\n set filterBy(v: string) {\n this.setAttribute('filter-by', v);\n }\n\n get filterPlaceholder(): string {\n return this.getAttr('filter-placeholder', 'Buscar...');\n }\n set filterPlaceholder(v: string) {\n this.setAttribute('filter-placeholder', v);\n }\n\n get dragdrop(): boolean {\n return this.hasAttr('dragdrop');\n }\n set dragdrop(v: boolean) {\n this.toggleAttr('dragdrop', v);\n }\n\n get striped(): boolean {\n return this.hasAttr('striped');\n }\n set striped(v: boolean) {\n this.toggleAttr('striped', v);\n }\n\n get selectionMode(): string {\n const s = this.getAttr('selection-mode', '');\n return s === 'single' || s === 'multiple' ? s : '';\n }\n set selectionMode(v: string) {\n this.setAttribute('selection-mode', v);\n }\n\n get showSelectAll(): boolean {\n return this.hasAttr('show-select-all');\n }\n set showSelectAll(v: boolean) {\n this.toggleAttr('show-select-all', v);\n }\n\n get sourceLabel(): string {\n return this.getAttr('source-label', 'Disponíveis');\n }\n set sourceLabel(v: string) {\n this.setAttribute('source-label', v);\n }\n\n get targetLabel(): string {\n return this.getAttr('target-label', 'Selecionados');\n }\n set targetLabel(v: string) {\n this.setAttribute('target-label', v);\n }\n\n get sourceFilterValue(): string {\n return this._sourceFilterValue;\n }\n set sourceFilterValue(v: string) {\n this._sourceFilterValue = v;\n this._applySourceFilter();\n this._updateListDisplay();\n }\n private _sourceFilterValue = '';\n\n get targetFilterValue(): string {\n return this._targetFilterValue;\n }\n set targetFilterValue(v: string) {\n this._targetFilterValue = v;\n this._applyTargetFilter();\n this._updateListDisplay();\n }\n private _targetFilterValue = '';\n private _filterListenersAttached = false;\n\n private _optionTemplate: ((item: PickListItem) => string) | null = null;\n\n setOptionTemplate(template: (item: PickListItem) => string): void {\n this._optionTemplate = template;\n this.render();\n }\n\n protected override connectedCallback(): void {\n this._parseSourceAttribute();\n this._parseTargetAttribute();\n super.connectedCallback();\n }\n\n protected override attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (this.getAttr('source', '') !== '') {\n this._parseSourceAttribute();\n }\n if (this.getAttr('target', '') !== '') {\n this._parseTargetAttribute();\n }\n super.attributeChangedCallback(name, oldValue, newValue);\n }\n\n private _parseSourceAttribute(): void {\n const dataAttr = this.getAttr('source', '');\n if (dataAttr) {\n try {\n this._source = JSON.parse(dataAttr);\n this._filteredSource = null;\n } catch {\n this._source = [];\n }\n }\n }\n\n private _parseTargetAttribute(): void {\n const dataAttr = this.getAttr('target', '');\n if (dataAttr) {\n try {\n this._target = JSON.parse(dataAttr);\n this._filteredTarget = null;\n } catch {\n this._target = [];\n }\n }\n }\n\n private _applySourceFilter(): void {\n if (!this._sourceFilterValue) {\n this._filteredSource = null;\n return;\n }\n const filterFields = this.filterBy.split(',').map(f => f.trim());\n this._filteredSource = this._source.filter(item => {\n return filterFields.some(field => {\n const value = item[field];\n if (value == null) return false;\n return String(value).toLowerCase().includes(this._sourceFilterValue.toLowerCase());\n });\n });\n }\n\n private _applyTargetFilter(): void {\n if (!this._targetFilterValue) {\n this._filteredTarget = null;\n return;\n }\n const filterFields = this.filterBy.split(',').map(f => f.trim());\n this._filteredTarget = this._target.filter(item => {\n return filterFields.some(field => {\n const value = item[field];\n if (value == null) return false;\n return String(value).toLowerCase().includes(this._targetFilterValue.toLowerCase());\n });\n });\n }\n\n private _getDisplaySource(): PickListItem[] {\n return this._filteredSource || this._source;\n }\n\n private _getDisplayTarget(): PickListItem[] {\n return this._filteredTarget || this._target;\n }\n\n private _getItemKey(item: PickListItem, index: number, isSource: boolean): string {\n const keyField = isSource ? this.sourceKey : this.targetKey;\n if (keyField && item[keyField] != null) {\n return String(item[keyField]);\n }\n if (item['id'] != null) return String(item['id']);\n if (item['key'] != null) return String(item['key']);\n if (item['label'] != null) return String(item['label']);\n if (item['name'] != null) return String(item['name']);\n if (item['value'] != null) return String(item['value']);\n return String(index);\n }\n\n private _getItemLabel(item: PickListItem): string {\n const fields = ['label', 'name', 'title', 'text', 'value'];\n for (const field of fields) {\n if (item[field] != null) {\n return String(item[field]);\n }\n }\n return JSON.stringify(item);\n }\n\n private _isSourceSelected(item: PickListItem, index: number): boolean {\n return this._sourceSelection.some(s => this._getItemKey(s, -1, true) === this._getItemKey(item, index, true));\n }\n\n private _isTargetSelected(item: PickListItem, index: number): boolean {\n return this._targetSelection.some(s => this._getItemKey(s, -1, false) === this._getItemKey(item, index, false));\n }\n\n private _emitMoveToTarget(): void {\n this.dispatchEvent(new CustomEvent('move-to-target', {\n bubbles: true,\n composed: true,\n detail: { items: [...this._sourceSelection], source: [...this._source], target: [...this._target] },\n }));\n }\n\n private _emitMoveToSource(): void {\n this.dispatchEvent(new CustomEvent('move-to-source', {\n bubbles: true,\n composed: true,\n detail: { items: [...this._targetSelection], source: [...this._source], target: [...this._target] },\n }));\n }\n\n private _emitSelectionChangeSource(): void {\n this.dispatchEvent(new CustomEvent('selection-change-source', {\n bubbles: true,\n composed: true,\n detail: { selection: [...this._sourceSelection] },\n }));\n }\n\n private _emitSelectionChangeTarget(): void {\n this.dispatchEvent(new CustomEvent('selection-change-target', {\n bubbles: true,\n composed: true,\n detail: { selection: [...this._targetSelection] },\n }));\n }\n\n protected override render(): void {\n const dSrc = this._getDisplaySource();\n const dTgt = this._getDisplayTarget();\n const hasSel = this.selectionMode;\n const showAll = hasSel === 'multiple' && this.showSelectAll;\n const srcItems = dSrc.length === 0 ? `<li class=\"empty-message\">${this.filter ? 'Nenhum resultado' : 'Nenhum item'}</li>` : dSrc.map((item, i) => `<li class=\"list-item${this._isSourceSelected(item, i) ? ' selected' : ''}\" data-index=\"${i}\" data-list=\"source\" tabindex=\"0\">${hasSel ? '<input type=\"checkbox\" class=\"checkbox\"' + (this._isSourceSelected(item, i) ? ' checked' : '') + ' />' : ''}<span class=\"item-content\">${this._optionTemplate ? this._optionTemplate(item) : esc(this._getItemLabel(item))}</span></li>`).join('');\n 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('');\n 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>` : '';\n 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>` : '';\n\n 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>`);\n\n this._attachListeners();\n }\n\n private _attachListeners(): void {\n // Listeners delegados no root, anexados uma unica vez (sobrevivem a re-renders)\n if (!this._filterListenersAttached) {\n this._filterListenersAttached = true;\n\n this.root.addEventListener('input', (e) => {\n const t = e.target as HTMLElement;\n if (t.classList.contains('select-all-checkbox')) {\n this._handleSelectAll(t as HTMLInputElement);\n return;\n }\n if (t.classList.contains('source-filter')) {\n this.sourceFilterValue = (t as HTMLInputElement).value;\n } else if (t.classList.contains('target-filter')) {\n this.targetFilterValue = (t as HTMLInputElement).value;\n }\n });\n\n this.root.addEventListener('click', (e) => {\n const t = e.target as HTMLElement;\n const btn = t.closest('.control-btn') as HTMLButtonElement | null;\n if (btn) {\n switch (btn.dataset.action) {\n case 'move-target': this._moveToTarget(); break;\n case 'move-all-target': this._moveAllToTarget(); break;\n case 'move-source': this._moveToSource(); break;\n case 'move-all-source': this._moveAllToSource(); break;\n }\n return;\n }\n const el = t.closest('.list-item') as HTMLElement | null;\n if (!el) return;\n const isSrc = el.dataset.list === 'source';\n const idx = Number(el.dataset.index);\n const item = (isSrc ? this._getDisplaySource() : this._getDisplayTarget())[idx];\n if (isSrc) this._toggleSourceSelection(item, idx); else this._toggleTargetSelection(item, idx);\n });\n }\n this._updateControlsState();\n }\n\n private _handleSelectAll(checkbox: HTMLInputElement): void {\n const isSrc = checkbox.dataset.list === 'source';\n if (isSrc) {\n this._sourceSelection = checkbox.checked ? [...this._getDisplaySource()] : [];\n this._emitSelectionChangeSource();\n } else {\n this._targetSelection = checkbox.checked ? [...this._getDisplayTarget()] : [];\n this._emitSelectionChangeTarget();\n }\n this._updateSelectionDisplay();\n this._updateControlsState();\n }\n\n /**\n * Atualiza a selecao visual in-place (classes e checkboxes dos itens existentes),\n * sem recriar o DOM — mantendo referencias de elementos validas durante cliques.\n */\n private _updateSelectionDisplay(): void {\n const updateList = (listSel: HTMLElement | null, isSelFn: (item: PickListItem, i: number) => boolean, getData: () => PickListItem[]): void => {\n if (!listSel) return;\n listSel.querySelectorAll<HTMLElement>('.list-item').forEach(el => {\n const idx = Number(el.dataset.index);\n const selected = isSelFn(getData()[idx], idx);\n el.classList.toggle('selected', selected);\n el.setAttribute('aria-selected', String(selected));\n const cb = el.querySelector<HTMLInputElement>('.checkbox');\n if (cb) cb.checked = selected;\n });\n };\n updateList(this.root.querySelector('.source-list'), (it, i) => this._isSourceSelected(it, i), () => this._getDisplaySource());\n updateList(this.root.querySelector('.target-list'), (it, i) => this._isTargetSelected(it, i), () => this._getDisplayTarget());\n this._updateSelectAllBars();\n }\n\n /** Sincroniza as barras \"Selecionar Todos\" (checkbox + contador) sem re-render completo. */\n private _updateSelectAllBars(): void {\n if (!(this.selectionMode === 'multiple' && this.showSelectAll)) return;\n const bars = [\n { el: this.root.querySelector<HTMLInputElement>('.select-all-checkbox[data-list=\"source\"]'), total: this._source.length, sel: this._sourceSelection.length },\n { el: this.root.querySelector<HTMLInputElement>('.select-all-checkbox[data-list=\"target\"]'), total: this._target.length, sel: this._targetSelection.length },\n ];\n bars.forEach(({ el, total, sel }) => {\n if (!el) return;\n el.checked = total > 0 && sel === total;\n const count = el.closest('.select-all-bar')?.querySelector('.selection-count');\n if (count) count.textContent = `${sel} selecionado(s)`;\n });\n }\n\n private _updateControlsState(): void {\n this.root.querySelectorAll<HTMLButtonElement>('.control-btn').forEach(btn => {\n const a = btn.dataset.action;\n btn.disabled = (a === 'move-target' && this._sourceSelection.length === 0) || (a === 'move-all-target' && this._source.length === 0) || (a === 'move-source' && this._targetSelection.length === 0) || (a === 'move-all-source' && this._target.length === 0);\n });\n }\n\n private _moveToTarget(): void {\n if (!this._sourceSelection.length) return;\n const items = [...this._sourceSelection];\n this._source = this._source.filter(s => !items.some(i => this._getItemKey(i, -1, true) === this._getItemKey(s, -1, true)));\n this._target = [...this._target, ...items];\n this._sourceSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToTarget();\n }\n\n private _moveToSource(): void {\n if (!this._targetSelection.length) return;\n const items = [...this._targetSelection];\n this._target = this._target.filter(t => !items.some(i => this._getItemKey(i, -1, false) === this._getItemKey(t, -1, false)));\n this._source = [...this._source, ...items];\n this._targetSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToSource();\n }\n\n private _moveAllToTarget(): void {\n const items = [...this._source];\n this._source = [];\n this._target = [...this._target, ...items];\n this._sourceSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToTarget();\n }\n\n private _moveAllToSource(): void {\n const items = [...this._target];\n this._target = [];\n this._source = [...this._source, ...items];\n this._targetSelection = [];\n this._filteredSource = null;\n this._filteredTarget = null;\n this._updateListDisplay();\n this._updateControlsState();\n this._emitMoveToSource();\n }\n\n private _toggleSourceSelection(item: PickListItem, index: number): void {\n // Sem selection-mode definido, permite selecao simples (um item por vez)\n const mode = this.selectionMode || 'single';\n const key = this._getItemKey(item, index, true);\n const idx = this._sourceSelection.findIndex(s => this._getItemKey(s, -1, true) === key);\n if (idx >= 0) {\n this._sourceSelection.splice(idx, 1);\n } else if (mode === 'multiple') {\n this._sourceSelection.push(item);\n } else {\n this._sourceSelection = [item];\n }\n this._emitSelectionChangeSource();\n this._updateSelectionDisplay();\n this._updateControlsState();\n }\n\n private _toggleTargetSelection(item: PickListItem, index: number): void {\n // Sem selection-mode definido, permite selecao simples (um item por vez)\n const mode = this.selectionMode || 'single';\n const key = this._getItemKey(item, index, false);\n const idx = this._targetSelection.findIndex(s => this._getItemKey(s, -1, false) === key);\n if (idx >= 0) {\n this._targetSelection.splice(idx, 1);\n } else if (mode === 'multiple') {\n this._targetSelection.push(item);\n } else {\n this._targetSelection = [item];\n }\n this._emitSelectionChangeTarget();\n this._updateSelectionDisplay();\n this._updateControlsState();\n }\n\n private _updateListDisplay(): void {\n const srcWrapper = this.root.querySelector('.source-list')?.parentElement;\n const tgtWrapper = this.root.querySelector('.target-list')?.parentElement;\n const srcLabel = this.root.querySelector('.list-container:first-of-type .list-label');\n const tgtLabel = this.root.querySelector('.list-container:last-of-type .list-label');\n if (!srcWrapper || !tgtWrapper) { this.render(); return; }\n const dSrc = this._getDisplaySource();\n const dTgt = this._getDisplayTarget();\n const hasSel = this.selectionMode;\n const srcItems = dSrc.length === 0 ? `<li class=\"empty-message\" part=\"empty-message\">${this.filter ? 'Nenhum resultado' : 'Nenhum item'}</li>` : dSrc.map((item, i) => `<li class=\"list-item${this._isSourceSelected(item, i) ? ' selected' : ''}\" part=\"list-item\" data-index=\"${i}\" data-list=\"source\" role=\"option\" aria-selected=\"${this._isSourceSelected(item, i)}\" tabindex=\"0\">${hasSel ? '<input type=\"checkbox\" class=\"checkbox\" part=\"checkbox\"' + (this._isSourceSelected(item, i) ? ' checked' : '') + ' />' : ''}<span class=\"item-content\" part=\"item-content\">${this._optionTemplate ? this._optionTemplate(item) : esc(this._getItemLabel(item))}</span></li>`).join('');\n const tgtItems = dTgt.length === 0 ? `<li class=\"empty-message\" part=\"empty-message\">${this.filter ? 'Nenhum resultado' : 'Nenhum selecionado'}</li>` : dTgt.map((item, i) => `<li class=\"list-item${this._isTargetSelected(item, i) ? ' selected' : ''}\" part=\"list-item\" data-index=\"${i}\" data-list=\"target\" role=\"option\" aria-selected=\"${this._isTargetSelected(item, i)}\" tabindex=\"0\">${hasSel ? '<input type=\"checkbox\" class=\"checkbox\" part=\"checkbox\"' + (this._isTargetSelected(item, i) ? ' checked' : '') + ' />' : ''}<span class=\"item-content\" part=\"item-content\">${this._optionTemplate ? this._optionTemplate(item) : esc(this._getItemLabel(item))}</span></li>`).join('');\n srcWrapper.innerHTML = `<ul class=\"list source-list\" role=\"listbox\" tabindex=\"0\">${srcItems}</ul>`;\n tgtWrapper.innerHTML = `<ul class=\"list target-list\" role=\"listbox\" tabindex=\"0\">${tgtItems}</ul>`;\n if (srcLabel) srcLabel.textContent = `${this.sourceLabel} (${this._source.length})`;\n if (tgtLabel) tgtLabel.textContent = `${this.targetLabel} (${this._target.length})`;\n this._updateSelectAllBars();\n this._attachListeners();\n }\n}\n\nexport function defineFxPickList(): typeof FxPickList {\n return defineElement('fx-picklist', FxPickList);\n}"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/select/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,QAAS,SAAQ,SAAS;IACrC,OAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/select/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,QAAS,SAAQ,SAAS;IACrC,OAAgB,MAAM,SA+JpB;IAIF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAIjD;IAED,OAAO,CAAC,QAAQ,CAAC,CAAmB;IACpC,OAAO,CAAC,WAAW,CAAC,CAAqB;IAEzC,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAGjB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAErB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAEtB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED,OAAO,KAAK,OAAO,GAKlB;cAEkB,iBAAiB,IAAI,IAAI;cAezB,oBAAoB,IAAI,IAAI;IAM/C,OAAO,CAAC,MAAM;IASd,qEAAqE;IACrE,OAAO,CAAC,gBAAgB;cAiBL,MAAM,IAAI,IAAI;CAqGlC;AAED,wBAAgB,cAAc,IAAI,OAAO,QAAQ,CAEhD"}
|
|
@@ -171,6 +171,10 @@ _FxSelect.styles = css`
|
|
|
171
171
|
font-family: var(--fx-font-family);
|
|
172
172
|
font-size: var(--fx-font-size);
|
|
173
173
|
position: relative;
|
|
174
|
+
/* Largura no HOST (padrão: conteúdo com mín. 200px). CSS externo, classes
|
|
175
|
+
e style inline no elemento definem a largura sem precisar do full. */
|
|
176
|
+
width: var(--fx-select-width, max-content);
|
|
177
|
+
min-width: var(--fx-select-min-width, 200px);
|
|
174
178
|
}
|
|
175
179
|
.trigger {
|
|
176
180
|
display: inline-flex;
|
|
@@ -179,8 +183,12 @@ _FxSelect.styles = css`
|
|
|
179
183
|
gap: var(--fx-space-sm);
|
|
180
184
|
box-sizing: border-box;
|
|
181
185
|
min-height: var(--fx-size-md);
|
|
182
|
-
|
|
186
|
+
/* Acompanha a largura definida no :host. */
|
|
187
|
+
width: 100%;
|
|
183
188
|
font: inherit;
|
|
189
|
+
/* Altura/linha determinísticas: a caixa fica no token --fx-size-*
|
|
190
|
+
(o line-height fixo impede que a herança da página estoure o min-height). */
|
|
191
|
+
line-height: var(--fx-font-line-height);
|
|
184
192
|
font-weight: var(--fx-font-weight);
|
|
185
193
|
color: var(--fx-text-default);
|
|
186
194
|
text-align: left;
|
|
@@ -200,34 +208,39 @@ _FxSelect.styles = css`
|
|
|
200
208
|
border-color: var(--fx-color-primary);
|
|
201
209
|
box-shadow: var(--fx-effect-focus-ring, none);
|
|
202
210
|
}
|
|
203
|
-
:host([size='sm'])
|
|
211
|
+
:host([size='sm']) { min-width: var(--fx-select-min-width-sm, 180px); }
|
|
212
|
+
:host([size='sm']) .trigger { min-height: var(--fx-size-sm); }
|
|
204
213
|
:host([size='lg']) .trigger { min-height: var(--fx-size-lg); font-size: calc(var(--fx-font-size) + 4px); }
|
|
205
214
|
/* Full width: o host estica até o pai e o trigger acompanha. */
|
|
206
215
|
:host([full]) { display: block; width: 100%; }
|
|
216
|
+
:host([full]) { min-width: 0; }
|
|
207
217
|
:host([full]) .trigger { width: 100%; min-width: 0; }
|
|
208
218
|
:host([full]) .panel { width: 100%; }
|
|
209
|
-
/* Validação
|
|
219
|
+
/* Validação — borda e brilho JÁ EM REPOUSO (igual ao fx-input); o
|
|
220
|
+
brilho segue --fx-effect-error-ring, que acompanha effect.focus-ring. */
|
|
210
221
|
:host([error]) .trigger,
|
|
211
222
|
:host([invalid]) .trigger {
|
|
212
223
|
border-color: var(--fx-color-danger, #dc2626);
|
|
224
|
+
box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));
|
|
213
225
|
}
|
|
214
226
|
:host([error]) .trigger:focus-visible,
|
|
215
227
|
:host([invalid]) .trigger:focus-visible,
|
|
216
228
|
:host([error][open]) .trigger,
|
|
217
229
|
:host([invalid][open]) .trigger {
|
|
218
230
|
border-color: var(--fx-color-danger, #dc2626);
|
|
219
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent);
|
|
231
|
+
box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));
|
|
220
232
|
}
|
|
221
233
|
:host([success]) .trigger,
|
|
222
234
|
:host([valid]) .trigger {
|
|
223
235
|
border-color: var(--fx-color-success, #16a34a);
|
|
236
|
+
box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));
|
|
224
237
|
}
|
|
225
238
|
:host([success]) .trigger:focus-visible,
|
|
226
239
|
:host([valid]) .trigger:focus-visible,
|
|
227
240
|
:host([success][open]) .trigger,
|
|
228
241
|
:host([valid][open]) .trigger {
|
|
229
242
|
border-color: var(--fx-color-success, #16a34a);
|
|
230
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent);
|
|
243
|
+
box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));
|
|
231
244
|
}
|
|
232
245
|
:host([disabled]) .trigger,
|
|
233
246
|
.trigger[aria-disabled='true'] { opacity: 0.55; cursor: not-allowed; background-color: var(--fx-surface-surface-hover); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sources":["../../../src/components/select/select.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-select> — Campo de seleção com dropdown customizado.\n *\n * Escreva os filhos como `<option>` nativos no light DOM; eles são\n * espelhados automaticamente (MutationObserver):\n *\n * <fx-select value=\"b\" searchable clearable>\n * <option value=\"a\">Opção A</option>\n * <option value=\"b\">Opção B</option>\n * </fx-select>\n *\n * Atributos: value, size (sm|md|lg), disabled, placeholder,\n * searchable, clearable, search-placeholder, no-results.\n * Evento: `change` (composed, detail: { value }).\n */\nexport class FxSelect extends FxElement {\n static override styles = css`\n :host {\n display: inline-block;\n vertical-align: middle;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n position: relative;\n }\n .trigger {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--fx-space-sm);\n box-sizing: border-box;\n min-height: var(--fx-size-md);\n min-width: 200px;\n font: inherit;\n font-weight: var(--fx-font-weight);\n color: var(--fx-text-default);\n text-align: left;\n background-color: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n padding: var(--fx-space-xs) var(--fx-space-md);\n cursor: pointer;\n transition:\n border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),\n box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n .trigger:hover { border-color: var(--fx-border-hover); }\n .trigger:focus-visible,\n :host([open]) .trigger {\n outline: none;\n border-color: var(--fx-color-primary);\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n :host([size='sm']) .trigger { min-width: 180px; min-height: var(--fx-size-sm); }\n :host([size='lg']) .trigger { min-height: var(--fx-size-lg); font-size: calc(var(--fx-font-size) + 4px); }\n /* Full width: o host estica até o pai e o trigger acompanha. */\n :host([full]) { display: block; width: 100%; }\n :host([full]) .trigger { width: 100%; min-width: 0; }\n :host([full]) .panel { width: 100%; }\n /* Validação */\n :host([error]) .trigger,\n :host([invalid]) .trigger {\n border-color: var(--fx-color-danger, #dc2626);\n }\n :host([error]) .trigger:focus-visible,\n :host([invalid]) .trigger:focus-visible,\n :host([error][open]) .trigger,\n :host([invalid][open]) .trigger {\n border-color: var(--fx-color-danger, #dc2626);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent);\n }\n :host([success]) .trigger,\n :host([valid]) .trigger {\n border-color: var(--fx-color-success, #16a34a);\n }\n :host([success]) .trigger:focus-visible,\n :host([valid]) .trigger:focus-visible,\n :host([success][open]) .trigger,\n :host([valid][open]) .trigger {\n border-color: var(--fx-color-success, #16a34a);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent);\n }\n :host([disabled]) .trigger,\n .trigger[aria-disabled='true'] { opacity: 0.55; cursor: not-allowed; background-color: var(--fx-surface-surface-hover); }\n /* O rótulo encolhe (ellipsis) e os ícones NUNCA saem do campo. */\n .label,\n .placeholder {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .placeholder { color: var(--fx-text-muted); }\n .actions {\n display: inline-flex;\n align-items: center;\n gap: var(--fx-space-xs, 8px);\n flex-shrink: 0;\n }\n .caret { font-size: calc(var(--fx-font-size) - 3px); color: var(--fx-text-muted); pointer-events: none; }\n\n /* Painel do dropdown */\n .panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n z-index: var(--fx-z-dropdown, 1000);\n width: max(100%, 220px);\n max-height: 260px;\n overflow-y: auto;\n display: none;\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n box-shadow: var(--fx-shadow-lg);\n }\n :host([open]) .panel { display: block; }\n .search {\n position: sticky;\n top: 0;\n width: 100%;\n box-sizing: border-box;\n font: inherit;\n color: var(--fx-text-default);\n background: var(--fx-surface-background);\n border: none;\n border-bottom: 1px solid var(--fx-border-default);\n padding: var(--fx-space-sm) var(--fx-space-md);\n outline: none;\n }\n .opt {\n display: block;\n width: 100%;\n text-align: left;\n font: inherit;\n color: var(--fx-text-default);\n background: none;\n border: none;\n padding: var(--fx-space-sm) var(--fx-space-md);\n cursor: pointer;\n }\n /* Hover e selecionado com a cor primária do tema (igual ao multiselect). */\n .opt:hover { background: color-mix(in srgb, var(--fx-color-primary) 12%, transparent); }\n .opt[aria-selected='true'] {\n background: color-mix(in srgb, var(--fx-color-primary) 18%, transparent);\n color: var(--fx-color-primary);\n font-weight: var(--fx-font-weight);\n }\n .empty { padding: var(--fx-space-sm) var(--fx-space-md); color: var(--fx-text-muted); }\n\n /* Clearable */\n .clear {\n border: none;\n background: transparent;\n color: var(--fx-text-muted);\n font-size: calc(var(--fx-font-size) + 2px);\n line-height: 1;\n cursor: pointer;\n padding: 0;\n }\n .clear:hover { color: var(--fx-color-danger); }\n .clear[hidden] { display: none; }\n `;\n\n // `value` fica FORA da observação: refleti-lo no change não pode\n // re-renderizar o template e fechar o dropdown.\n static override get observedAttributes(): string[] {\n // `invalid`/`valid` são aliases aceitos no CSS; sem observá-los o\n // setAttribute no submit não re-renderiza.\n return ['size', 'disabled', 'placeholder', 'searchable', 'clearable', 'error', 'invalid', 'success', 'valid'];\n }\n\n private observer?: MutationObserver;\n private docListener?: (e: Event) => void;\n\n /** Tamanho do campo. Padrão: `'md'`. */\n get size(): string {\n const s = this.getAttr('size', 'md');\n return s === 'sm' || s === 'lg' ? s : 'md';\n }\n set size(value: string) {\n this.setAttribute('size', value);\n }\n\n get value(): string {\n return this.getAttr('value');\n }\n set value(value: string) {\n this.setAttribute('value', value);\n }\n\n get disabled(): boolean {\n return this.hasAttr('disabled');\n }\n set disabled(value: boolean) {\n this.toggleAttr('disabled', Boolean(value));\n }\n\n private get options(): { value: string; label: string }[] {\n return [...this.querySelectorAll('option')].map((o) => ({\n value: o.getAttribute('value') ?? o.textContent?.trim() ?? '',\n label: o.textContent?.trim() ?? '',\n }));\n }\n\n protected override connectedCallback(): void {\n super.connectedCallback();\n // Espelha mudanças nas <option> do light DOM.\n this.observer = new MutationObserver(() => this.render());\n this.observer.observe(this, { childList: true, subtree: true, characterData: true });\n // Fecha o dropdown ao clicar fora.\n this.docListener = (e: Event) => {\n if (!this.hasAttr('open')) return;\n if (e.composedPath().includes(this)) return;\n this.removeAttribute('open');\n this.render();\n };\n document.addEventListener('click', this.docListener);\n }\n\n protected override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.observer?.disconnect();\n if (this.docListener) document.removeEventListener('click', this.docListener);\n }\n\n private select(value: string): void {\n this.value = value;\n this.removeAttribute('open');\n this.render();\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value } }),\n );\n }\n\n /** Navegação por teclado entre as opções do listbox (WCAG 2.1.1). */\n private _navigateOptions(e: KeyboardEvent): void {\n e.preventDefault();\n if (!this.hasAttr('open')) {\n this.toggleAttribute('open');\n this.render();\n }\n const opts = Array.from(this.root.querySelectorAll<HTMLButtonElement>('.opt'));\n if (!opts.length) return;\n const current = opts.indexOf(this.root.activeElement as HTMLButtonElement);\n let next = 0;\n if (e.key === 'ArrowDown') next = current === -1 ? 0 : Math.min(current + 1, opts.length - 1);\n else if (e.key === 'ArrowUp') next = current === -1 ? opts.length - 1 : Math.max(current - 1, 0);\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = opts.length - 1;\n opts[next]?.focus();\n }\n\n protected override render(): void {\n const prevOpen = this.hasAttr('open');\n const prevSearch = this.root.querySelector<HTMLInputElement>('.search');\n // Estado do campo de busca antes de re-renderizar (valor, foco e cursor).\n const search = prevSearch?.value ?? '';\n const searchFocused =\n prevSearch != null && this.root.activeElement === prevSearch;\n const caretPos = searchFocused ? prevSearch!.selectionStart : null;\n\n const opts = this.options;\n let current = this.getAttr('value');\n if (!current) {\n const explicit = this.querySelector('option[selected]');\n current = explicit?.getAttribute('value') ?? explicit?.textContent?.trim() ?? '';\n }\n const selectedLabel = opts.find((o) => o.value === current)?.label ?? '';\n const placeholder = this.getAttr('placeholder', 'Selecione…');\n\n const filtered = search\n ? opts.filter((o) => o.label.toLowerCase().includes(search.toLowerCase()))\n : opts;\n\n this.setTemplate(`\n <span class=\"trigger\" part=\"trigger\" role=\"button\" tabindex=\"${this.disabled ? -1 : 0}\" aria-haspopup=\"listbox\" aria-expanded=\"${prevOpen}\">\n <span class=\"${selectedLabel ? 'label' : 'placeholder'}\">${esc(selectedLabel) || esc(placeholder)}</span>\n <span class=\"actions\">\n ${this.hasAttr('clearable') && current ? '<button type=\"button\" class=\"clear\" part=\"clear\" aria-label=\"Limpar\">×</button>' : ''}\n <span class=\"caret\">▼</span>\n </span>\n </span>\n <div class=\"panel\" part=\"panel\" role=\"listbox\">\n ${this.hasAttr('searchable') ? `<input class=\"search\" part=\"search\" type=\"text\" placeholder=\"${esc(this.getAttr('search-placeholder', 'Pesquisar…'))}\">` : ''}\n ${filtered.map((o) => `\n <button type=\"button\" class=\"opt\" role=\"option\" data-value=\"${esc(o.value)}\"\n aria-selected=\"${o.value === current}\">${esc(o.label)}</button>`).join('')}\n ${filtered.length === 0 ? `<div class=\"empty\">${esc(this.getAttr('no-results', 'Nenhum resultado'))}</div>` : ''}\n </div>\n `);\n\n if (prevOpen) this.setAttribute('open', '');\n const searchInput = this.root.querySelector<HTMLInputElement>('.search');\n if (searchInput) {\n searchInput.value = search;\n searchInput.addEventListener('input', () => this.render());\n searchInput.addEventListener('click', (e) => e.stopPropagation());\n // Re-render não pode roubar o foco nem perder a posição do cursor.\n if (searchFocused) {\n searchInput.focus();\n try { searchInput.setSelectionRange(caretPos!, caretPos!); } catch { /* type=text sempre suporta */ }\n }\n }\n\n const trigger = this.root.querySelector<HTMLElement>('.trigger');\n if (!trigger) return;\n if (this.disabled) trigger.setAttribute('aria-disabled', 'true');\n\n trigger.addEventListener('click', (e) => {\n if (this.disabled) return;\n if ((e.target as HTMLElement).closest('.clear')) return;\n this.toggleAttribute('open');\n this.render();\n this.root.querySelector<HTMLInputElement>('.search')?.focus();\n });\n\n // Teclado: Enter/Espaço abrem o dropdown; setas/Home/End/Escape navegam.\n trigger.addEventListener('keydown', (e) => {\n if (this.disabled) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n trigger.click();\n return;\n }\n if (e.key === 'Escape') {\n if (this.hasAttr('open')) {\n this.removeAttribute('open');\n this.render();\n this.root.querySelector<HTMLElement>('.trigger')?.focus();\n }\n return;\n }\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Home' || e.key === 'End') {\n this._navigateOptions(e);\n }\n });\n\n // Limpar.\n this.root.querySelector('.clear')?.addEventListener('click', (e) => {\n e.stopPropagation();\n this.value = '';\n this.removeAttribute('open');\n this.render();\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value: '' } }),\n );\n });\n\n // Escolher opção.\n this.root.querySelectorAll<HTMLElement>('.opt').forEach((opt) => {\n opt.addEventListener('click', () => this.select(opt.dataset.value!));\n });\n }\n}\n\nexport function defineFxSelect(): typeof FxSelect {\n return defineElement('fx-select', FxSelect);\n}\n\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select.js","sources":["../../../src/components/select/select.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-select> — Campo de seleção com dropdown customizado.\n *\n * Escreva os filhos como `<option>` nativos no light DOM; eles são\n * espelhados automaticamente (MutationObserver):\n *\n * <fx-select value=\"b\" searchable clearable>\n * <option value=\"a\">Opção A</option>\n * <option value=\"b\">Opção B</option>\n * </fx-select>\n *\n * Atributos: value, size (sm|md|lg), disabled, placeholder,\n * searchable, clearable, search-placeholder, no-results.\n * Evento: `change` (composed, detail: { value }).\n */\nexport class FxSelect extends FxElement {\n static override styles = css`\n :host {\n display: inline-block;\n vertical-align: middle;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n position: relative;\n /* Largura no HOST (padrão: conteúdo com mín. 200px). CSS externo, classes\n e style inline no elemento definem a largura sem precisar do full. */\n width: var(--fx-select-width, max-content);\n min-width: var(--fx-select-min-width, 200px);\n }\n .trigger {\n display: inline-flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--fx-space-sm);\n box-sizing: border-box;\n min-height: var(--fx-size-md);\n /* Acompanha a largura definida no :host. */\n width: 100%;\n font: inherit;\n /* Altura/linha determinísticas: a caixa fica no token --fx-size-*\n (o line-height fixo impede que a herança da página estoure o min-height). */\n line-height: var(--fx-font-line-height);\n font-weight: var(--fx-font-weight);\n color: var(--fx-text-default);\n text-align: left;\n background-color: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n padding: var(--fx-space-xs) var(--fx-space-md);\n cursor: pointer;\n transition:\n border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),\n box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n .trigger:hover { border-color: var(--fx-border-hover); }\n .trigger:focus-visible,\n :host([open]) .trigger {\n outline: none;\n border-color: var(--fx-color-primary);\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n :host([size='sm']) { min-width: var(--fx-select-min-width-sm, 180px); }\n :host([size='sm']) .trigger { min-height: var(--fx-size-sm); }\n :host([size='lg']) .trigger { min-height: var(--fx-size-lg); font-size: calc(var(--fx-font-size) + 4px); }\n /* Full width: o host estica até o pai e o trigger acompanha. */\n :host([full]) { display: block; width: 100%; }\n :host([full]) { min-width: 0; }\n :host([full]) .trigger { width: 100%; min-width: 0; }\n :host([full]) .panel { width: 100%; }\n /* Validação — borda e brilho JÁ EM REPOUSO (igual ao fx-input); o\n brilho segue --fx-effect-error-ring, que acompanha effect.focus-ring. */\n :host([error]) .trigger,\n :host([invalid]) .trigger {\n border-color: var(--fx-color-danger, #dc2626);\n box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));\n }\n :host([error]) .trigger:focus-visible,\n :host([invalid]) .trigger:focus-visible,\n :host([error][open]) .trigger,\n :host([invalid][open]) .trigger {\n border-color: var(--fx-color-danger, #dc2626);\n box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));\n }\n :host([success]) .trigger,\n :host([valid]) .trigger {\n border-color: var(--fx-color-success, #16a34a);\n box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));\n }\n :host([success]) .trigger:focus-visible,\n :host([valid]) .trigger:focus-visible,\n :host([success][open]) .trigger,\n :host([valid][open]) .trigger {\n border-color: var(--fx-color-success, #16a34a);\n box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));\n }\n :host([disabled]) .trigger,\n .trigger[aria-disabled='true'] { opacity: 0.55; cursor: not-allowed; background-color: var(--fx-surface-surface-hover); }\n /* O rótulo encolhe (ellipsis) e os ícones NUNCA saem do campo. */\n .label,\n .placeholder {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .placeholder { color: var(--fx-text-muted); }\n .actions {\n display: inline-flex;\n align-items: center;\n gap: var(--fx-space-xs, 8px);\n flex-shrink: 0;\n }\n .caret { font-size: calc(var(--fx-font-size) - 3px); color: var(--fx-text-muted); pointer-events: none; }\n\n /* Painel do dropdown */\n .panel {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n z-index: var(--fx-z-dropdown, 1000);\n width: max(100%, 220px);\n max-height: 260px;\n overflow-y: auto;\n display: none;\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n box-shadow: var(--fx-shadow-lg);\n }\n :host([open]) .panel { display: block; }\n .search {\n position: sticky;\n top: 0;\n width: 100%;\n box-sizing: border-box;\n font: inherit;\n color: var(--fx-text-default);\n background: var(--fx-surface-background);\n border: none;\n border-bottom: 1px solid var(--fx-border-default);\n padding: var(--fx-space-sm) var(--fx-space-md);\n outline: none;\n }\n .opt {\n display: block;\n width: 100%;\n text-align: left;\n font: inherit;\n color: var(--fx-text-default);\n background: none;\n border: none;\n padding: var(--fx-space-sm) var(--fx-space-md);\n cursor: pointer;\n }\n /* Hover e selecionado com a cor primária do tema (igual ao multiselect). */\n .opt:hover { background: color-mix(in srgb, var(--fx-color-primary) 12%, transparent); }\n .opt[aria-selected='true'] {\n background: color-mix(in srgb, var(--fx-color-primary) 18%, transparent);\n color: var(--fx-color-primary);\n font-weight: var(--fx-font-weight);\n }\n .empty { padding: var(--fx-space-sm) var(--fx-space-md); color: var(--fx-text-muted); }\n\n /* Clearable */\n .clear {\n border: none;\n background: transparent;\n color: var(--fx-text-muted);\n font-size: calc(var(--fx-font-size) + 2px);\n line-height: 1;\n cursor: pointer;\n padding: 0;\n }\n .clear:hover { color: var(--fx-color-danger); }\n .clear[hidden] { display: none; }\n `;\n\n // `value` fica FORA da observação: refleti-lo no change não pode\n // re-renderizar o template e fechar o dropdown.\n static override get observedAttributes(): string[] {\n // `invalid`/`valid` são aliases aceitos no CSS; sem observá-los o\n // setAttribute no submit não re-renderiza.\n return ['size', 'disabled', 'placeholder', 'searchable', 'clearable', 'error', 'invalid', 'success', 'valid'];\n }\n\n private observer?: MutationObserver;\n private docListener?: (e: Event) => void;\n\n /** Tamanho do campo. Padrão: `'md'`. */\n get size(): string {\n const s = this.getAttr('size', 'md');\n return s === 'sm' || s === 'lg' ? s : 'md';\n }\n set size(value: string) {\n this.setAttribute('size', value);\n }\n\n get value(): string {\n return this.getAttr('value');\n }\n set value(value: string) {\n this.setAttribute('value', value);\n }\n\n get disabled(): boolean {\n return this.hasAttr('disabled');\n }\n set disabled(value: boolean) {\n this.toggleAttr('disabled', Boolean(value));\n }\n\n private get options(): { value: string; label: string }[] {\n return [...this.querySelectorAll('option')].map((o) => ({\n value: o.getAttribute('value') ?? o.textContent?.trim() ?? '',\n label: o.textContent?.trim() ?? '',\n }));\n }\n\n protected override connectedCallback(): void {\n super.connectedCallback();\n // Espelha mudanças nas <option> do light DOM.\n this.observer = new MutationObserver(() => this.render());\n this.observer.observe(this, { childList: true, subtree: true, characterData: true });\n // Fecha o dropdown ao clicar fora.\n this.docListener = (e: Event) => {\n if (!this.hasAttr('open')) return;\n if (e.composedPath().includes(this)) return;\n this.removeAttribute('open');\n this.render();\n };\n document.addEventListener('click', this.docListener);\n }\n\n protected override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.observer?.disconnect();\n if (this.docListener) document.removeEventListener('click', this.docListener);\n }\n\n private select(value: string): void {\n this.value = value;\n this.removeAttribute('open');\n this.render();\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value } }),\n );\n }\n\n /** Navegação por teclado entre as opções do listbox (WCAG 2.1.1). */\n private _navigateOptions(e: KeyboardEvent): void {\n e.preventDefault();\n if (!this.hasAttr('open')) {\n this.toggleAttribute('open');\n this.render();\n }\n const opts = Array.from(this.root.querySelectorAll<HTMLButtonElement>('.opt'));\n if (!opts.length) return;\n const current = opts.indexOf(this.root.activeElement as HTMLButtonElement);\n let next = 0;\n if (e.key === 'ArrowDown') next = current === -1 ? 0 : Math.min(current + 1, opts.length - 1);\n else if (e.key === 'ArrowUp') next = current === -1 ? opts.length - 1 : Math.max(current - 1, 0);\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = opts.length - 1;\n opts[next]?.focus();\n }\n\n protected override render(): void {\n const prevOpen = this.hasAttr('open');\n const prevSearch = this.root.querySelector<HTMLInputElement>('.search');\n // Estado do campo de busca antes de re-renderizar (valor, foco e cursor).\n const search = prevSearch?.value ?? '';\n const searchFocused =\n prevSearch != null && this.root.activeElement === prevSearch;\n const caretPos = searchFocused ? prevSearch!.selectionStart : null;\n\n const opts = this.options;\n let current = this.getAttr('value');\n if (!current) {\n const explicit = this.querySelector('option[selected]');\n current = explicit?.getAttribute('value') ?? explicit?.textContent?.trim() ?? '';\n }\n const selectedLabel = opts.find((o) => o.value === current)?.label ?? '';\n const placeholder = this.getAttr('placeholder', 'Selecione…');\n\n const filtered = search\n ? opts.filter((o) => o.label.toLowerCase().includes(search.toLowerCase()))\n : opts;\n\n this.setTemplate(`\n <span class=\"trigger\" part=\"trigger\" role=\"button\" tabindex=\"${this.disabled ? -1 : 0}\" aria-haspopup=\"listbox\" aria-expanded=\"${prevOpen}\">\n <span class=\"${selectedLabel ? 'label' : 'placeholder'}\">${esc(selectedLabel) || esc(placeholder)}</span>\n <span class=\"actions\">\n ${this.hasAttr('clearable') && current ? '<button type=\"button\" class=\"clear\" part=\"clear\" aria-label=\"Limpar\">×</button>' : ''}\n <span class=\"caret\">▼</span>\n </span>\n </span>\n <div class=\"panel\" part=\"panel\" role=\"listbox\">\n ${this.hasAttr('searchable') ? `<input class=\"search\" part=\"search\" type=\"text\" placeholder=\"${esc(this.getAttr('search-placeholder', 'Pesquisar…'))}\">` : ''}\n ${filtered.map((o) => `\n <button type=\"button\" class=\"opt\" role=\"option\" data-value=\"${esc(o.value)}\"\n aria-selected=\"${o.value === current}\">${esc(o.label)}</button>`).join('')}\n ${filtered.length === 0 ? `<div class=\"empty\">${esc(this.getAttr('no-results', 'Nenhum resultado'))}</div>` : ''}\n </div>\n `);\n\n if (prevOpen) this.setAttribute('open', '');\n const searchInput = this.root.querySelector<HTMLInputElement>('.search');\n if (searchInput) {\n searchInput.value = search;\n searchInput.addEventListener('input', () => this.render());\n searchInput.addEventListener('click', (e) => e.stopPropagation());\n // Re-render não pode roubar o foco nem perder a posição do cursor.\n if (searchFocused) {\n searchInput.focus();\n try { searchInput.setSelectionRange(caretPos!, caretPos!); } catch { /* type=text sempre suporta */ }\n }\n }\n\n const trigger = this.root.querySelector<HTMLElement>('.trigger');\n if (!trigger) return;\n if (this.disabled) trigger.setAttribute('aria-disabled', 'true');\n\n trigger.addEventListener('click', (e) => {\n if (this.disabled) return;\n if ((e.target as HTMLElement).closest('.clear')) return;\n this.toggleAttribute('open');\n this.render();\n this.root.querySelector<HTMLInputElement>('.search')?.focus();\n });\n\n // Teclado: Enter/Espaço abrem o dropdown; setas/Home/End/Escape navegam.\n trigger.addEventListener('keydown', (e) => {\n if (this.disabled) return;\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n trigger.click();\n return;\n }\n if (e.key === 'Escape') {\n if (this.hasAttr('open')) {\n this.removeAttribute('open');\n this.render();\n this.root.querySelector<HTMLElement>('.trigger')?.focus();\n }\n return;\n }\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Home' || e.key === 'End') {\n this._navigateOptions(e);\n }\n });\n\n // Limpar.\n this.root.querySelector('.clear')?.addEventListener('click', (e) => {\n e.stopPropagation();\n this.value = '';\n this.removeAttribute('open');\n this.render();\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value: '' } }),\n );\n });\n\n // Escolher opção.\n this.root.querySelectorAll<HTMLElement>('.opt').forEach((opt) => {\n opt.addEventListener('click', () => this.select(opt.dataset.value!));\n });\n }\n}\n\nexport function defineFxSelect(): typeof FxSelect {\n return defineElement('fx-select', FxSelect);\n}\n\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../../src/components/textarea/textarea.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,SAAS;IACvC,OAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../../src/components/textarea/textarea.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,SAAS;IACvC,OAAgB,MAAM,SA6DpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;IAED,IAAI,IAAI,IAAI,MAAM,CAGjB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAuC;IAE7D,IAAI,KAAK,IAAI,MAAM,CAAkC;IACrD,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAAwC;cAE5C,MAAM,IAAI,IAAI;CA8BlC;AAED,wBAAgB,gBAAgB,IAAI,OAAO,UAAU,CAEpD"}
|
|
@@ -55,19 +55,26 @@ _FxTextarea.styles = css`
|
|
|
55
55
|
:host {
|
|
56
56
|
display: inline-block;
|
|
57
57
|
vertical-align: middle;
|
|
58
|
+
/* Largura padrão no HOST: CSS externo, classes e style inline no elemento
|
|
59
|
+
vencem este default naturalmente (regras do documento > :host). */
|
|
60
|
+
width: var(--fx-textarea-width, 260px);
|
|
61
|
+
vertical-align: middle;
|
|
58
62
|
font-family: var(--fx-font-family);
|
|
59
63
|
font-size: var(--fx-font-size);
|
|
60
64
|
}
|
|
61
65
|
.field {
|
|
62
66
|
font-family: inherit;
|
|
63
67
|
font-size: inherit;
|
|
68
|
+
/* Altura determinística: a caixa fica EXATAMENTE no token --fx-size-*. */
|
|
69
|
+
line-height: var(--fx-font-line-height);
|
|
64
70
|
font-weight: var(--fx-font-weight);
|
|
65
71
|
color: var(--fx-text-default);
|
|
66
72
|
background-color: var(--fx-surface-background);
|
|
67
73
|
border: 1px solid var(--fx-border-default);
|
|
68
74
|
border-radius: var(--fx-radius-md);
|
|
69
75
|
padding: var(--fx-space-md) var(--fx-space-lg);
|
|
70
|
-
|
|
76
|
+
/* Acompanha a largura definida no :host. */
|
|
77
|
+
width: 100%;
|
|
71
78
|
min-height: calc(var(--fx-size-md) + 40px);
|
|
72
79
|
resize: vertical;
|
|
73
80
|
box-sizing: border-box;
|
|
@@ -88,16 +95,20 @@ _FxTextarea.styles = css`
|
|
|
88
95
|
cursor: not-allowed;
|
|
89
96
|
background-color: var(--fx-surface-surface-hover);
|
|
90
97
|
}
|
|
98
|
+
/* Validação: borda sempre; brilho (anel) via token que acompanha
|
|
99
|
+
effect.focus-ring — desligado ⇒ erro só com a borda vermelha. */
|
|
91
100
|
:host([error]) .field, :host([invalid]) .field {
|
|
92
101
|
border-color: var(--fx-color-danger, #dc2626);
|
|
93
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent);
|
|
102
|
+
box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));
|
|
94
103
|
}
|
|
95
104
|
:host([success]) .field, :host([valid]) .field {
|
|
96
105
|
border-color: var(--fx-color-success, #16a34a);
|
|
97
|
-
box-shadow: 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent);
|
|
106
|
+
box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));
|
|
98
107
|
}
|
|
99
|
-
:host([size='sm'])
|
|
100
|
-
:host([size='
|
|
108
|
+
:host([size='sm']) { width: var(--fx-textarea-width-sm, 220px); }
|
|
109
|
+
:host([size='sm']) .field { min-height: var(--fx-size-sm); padding: var(--fx-space-xs) var(--fx-space-md); }
|
|
110
|
+
:host([size='lg']) { width: var(--fx-textarea-width-lg, 300px); }
|
|
111
|
+
:host([size='lg']) .field { min-height: calc(var(--fx-size-lg) + 80px); }
|
|
101
112
|
/* Full width: o host estica até o pai e o campo interno acompanha. */
|
|
102
113
|
:host([full]) { display: block; width: 100%; }
|
|
103
114
|
:host([full]) .field { width: 100%; }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.js","sources":["../../../src/components/textarea/textarea.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-textarea> — Área de texto multilinha estilizada com os tokens do tema.\n *\n * Atributos: value, size (sm|md|lg), placeholder, disabled, readonly,\n * rows, maxlength.\n * Eventos: `input` e `change` (composed, detail: { value }).\n */\nexport class FxTextarea extends FxElement {\n static override styles = css`\n :host {\n display: inline-block;\n vertical-align: middle;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n }\n .field {\n font-family: inherit;\n font-size: inherit;\n font-weight: var(--fx-font-weight);\n color: var(--fx-text-default);\n background-color: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n padding: var(--fx-space-md) var(--fx-space-lg);\n width:
|
|
1
|
+
{"version":3,"file":"textarea.js","sources":["../../../src/components/textarea/textarea.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-textarea> — Área de texto multilinha estilizada com os tokens do tema.\n *\n * Atributos: value, size (sm|md|lg), placeholder, disabled, readonly,\n * rows, maxlength.\n * Eventos: `input` e `change` (composed, detail: { value }).\n */\nexport class FxTextarea extends FxElement {\n static override styles = css`\n :host {\n display: inline-block;\n vertical-align: middle;\n /* Largura padrão no HOST: CSS externo, classes e style inline no elemento\n vencem este default naturalmente (regras do documento > :host). */\n width: var(--fx-textarea-width, 260px);\n vertical-align: middle;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n }\n .field {\n font-family: inherit;\n font-size: inherit;\n /* Altura determinística: a caixa fica EXATAMENTE no token --fx-size-*. */\n line-height: var(--fx-font-line-height);\n font-weight: var(--fx-font-weight);\n color: var(--fx-text-default);\n background-color: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n padding: var(--fx-space-md) var(--fx-space-lg);\n /* Acompanha a largura definida no :host. */\n width: 100%;\n min-height: calc(var(--fx-size-md) + 40px);\n resize: vertical;\n box-sizing: border-box;\n transition:\n border-color var(--fx-motion-duration-normal) var(--fx-motion-easing),\n box-shadow var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n .field::placeholder { color: var(--fx-text-muted); opacity: 1; }\n .field:hover { border-color: var(--fx-border-hover); }\n .field:focus-visible {\n outline: none;\n border-color: var(--fx-color-primary);\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n .field:disabled,\n .field[readonly] {\n opacity: 0.55;\n cursor: not-allowed;\n background-color: var(--fx-surface-surface-hover);\n }\n /* Validação: borda sempre; brilho (anel) via token que acompanha\n effect.focus-ring — desligado ⇒ erro só com a borda vermelha. */\n :host([error]) .field, :host([invalid]) .field {\n border-color: var(--fx-color-danger, #dc2626);\n box-shadow: var(--fx-effect-error-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-danger, #dc2626) 18%, transparent));\n }\n :host([success]) .field, :host([valid]) .field {\n border-color: var(--fx-color-success, #16a34a);\n box-shadow: var(--fx-effect-success-ring, 0 0 0 3px color-mix(in srgb, var(--fx-color-success, #16a34a) 18%, transparent));\n }\n :host([size='sm']) { width: var(--fx-textarea-width-sm, 220px); }\n :host([size='sm']) .field { min-height: var(--fx-size-sm); padding: var(--fx-space-xs) var(--fx-space-md); }\n :host([size='lg']) { width: var(--fx-textarea-width-lg, 300px); }\n :host([size='lg']) .field { min-height: calc(var(--fx-size-lg) + 80px); }\n /* Full width: o host estica até o pai e o campo interno acompanha. */\n :host([full]) { display: block; width: 100%; }\n :host([full]) .field { width: 100%; }\n `;\n\n static override get observedAttributes(): string[] {\n return ['size', 'placeholder', 'disabled', 'readonly', 'rows', 'maxlength', 'error', 'invalid', 'success', 'valid'];\n }\n\n get size(): string {\n const s = this.getAttr('size', 'md');\n return s === 'sm' || s === 'lg' ? s : 'md';\n }\n set size(value: string) { this.setAttribute('size', value); }\n\n get value(): string { return this.getAttr('value'); }\n set value(value: string) { this.setAttribute('value', value); }\n\n protected override render(): void {\n const placeholder = this.getAttr('placeholder');\n const readonly = this.hasAttr('readonly');\n const disabled = this.hasAttr('disabled');\n const rows = this.getAttr('rows');\n const maxlength = this.getAttr('maxlength');\n\n this.setTemplate(`<textarea class=\"field\" part=\"textarea\"\n ${placeholder ? `placeholder=\"${esc(placeholder)}\"` : ''}\n ${rows ? `rows=\"${esc(rows)}\"` : ''}\n ${maxlength ? `maxlength=\"${esc(maxlength)}\"` : ''}\n ></textarea>`);\n\n const field = this.root.querySelector<HTMLTextAreaElement>('.field');\n if (!field) return;\n field.value = this.getAttr('value');\n if (disabled) field.setAttribute('disabled', '');\n if (readonly) field.setAttribute('readonly', '');\n\n const emit = (event: string): void => {\n this.value = field.value;\n this.dispatchEvent(\n new CustomEvent(event, { bubbles: true, composed: true, detail: { value: field.value } }),\n );\n };\n // Bloqueia o evento nativo (composed, sem detail) para que só o\n // CustomEvent com detail chegue aos consumidores.\n field.addEventListener('input', (e) => { e.stopPropagation(); emit('input'); });\n field.addEventListener('change', (e) => { e.stopPropagation(); emit('change'); });\n }\n}\n\nexport function defineFxTextarea(): typeof FxTextarea {\n return defineElement('fx-textarea', FxTextarea);\n}\n"],"names":[],"mappings":";;;;AAYO,MAAM,cAAN,MAAM,oBAAmB,UAAU;AAAA,EAgExC,WAAoB,qBAA+B;AACjD,WAAO,CAAC,QAAQ,eAAe,YAAY,YAAY,QAAQ,aAAa,SAAS,WAAW,WAAW,OAAO;AAAA,EACpH;AAAA,EAEA,IAAI,OAAe;AACjB,UAAM,IAAI,KAAK,QAAQ,QAAQ,IAAI;AACnC,WAAO,MAAM,QAAQ,MAAM,OAAO,IAAI;AAAA,EACxC;AAAA,EACA,IAAI,KAAK,OAAe;AAAE,SAAK,aAAa,QAAQ,KAAK;AAAA,EAAG;AAAA,EAE5D,IAAI,QAAgB;AAAE,WAAO,KAAK,QAAQ,OAAO;AAAA,EAAG;AAAA,EACpD,IAAI,MAAM,OAAe;AAAE,SAAK,aAAa,SAAS,KAAK;AAAA,EAAG;AAAA,EAE3C,SAAe;AAChC,UAAM,cAAc,KAAK,QAAQ,aAAa;AAC9C,UAAM,WAAW,KAAK,QAAQ,UAAU;AACxC,UAAM,WAAW,KAAK,QAAQ,UAAU;AACxC,UAAM,OAAO,KAAK,QAAQ,MAAM;AAChC,UAAM,YAAY,KAAK,QAAQ,WAAW;AAE1C,SAAK,YAAY;AAAA,QACb,cAAc,gBAAgB,IAAI,WAAW,CAAC,MAAM,EAAE;AAAA,QACtD,OAAO,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE;AAAA,QACjC,YAAY,cAAc,IAAI,SAAS,CAAC,MAAM,EAAE;AAAA,iBACvC;AAEb,UAAM,QAAQ,KAAK,KAAK,cAAmC,QAAQ;AACnE,QAAI,CAAC,MAAO;AACZ,UAAM,QAAQ,KAAK,QAAQ,OAAO;AAClC,QAAI,SAAU,OAAM,aAAa,YAAY,EAAE;AAC/C,QAAI,SAAU,OAAM,aAAa,YAAY,EAAE;AAE/C,UAAM,OAAO,CAAC,UAAwB;AACpC,WAAK,QAAQ,MAAM;AACnB,WAAK;AAAA,QACH,IAAI,YAAY,OAAO,EAAE,SAAS,MAAM,UAAU,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAA,GAAS;AAAA,MAAA;AAAA,IAE5F;AAGA,UAAM,iBAAiB,SAAS,CAAC,MAAM;AAAE,QAAE,gBAAA;AAAmB,WAAK,OAAO;AAAA,IAAG,CAAC;AAC9E,UAAM,iBAAiB,UAAU,CAAC,MAAM;AAAE,QAAE,gBAAA;AAAmB,WAAK,QAAQ;AAAA,IAAG,CAAC;AAAA,EAClF;AACF;AA1GE,YAAgB,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADpB,IAAM,aAAN;AA6GA,SAAS,mBAAsC;AACpD,SAAO,cAAc,eAAe,UAAU;AAChD;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-button-group.d.ts","sourceRoot":"","sources":["../../../src/components/toggle-button-group/toggle-button-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,OAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"toggle-button-group.d.ts","sourceRoot":"","sources":["../../../src/components/toggle-button-group/toggle-button-group.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,OAAgB,MAAM,SA6BpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;IAED,IAAI,KAAK,IAAI,MAAM,EAAE,CAGpB;IACD,IAAI,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAA8C;IAEnE,IAAI,QAAQ,IAAI,OAAO,CAAqC;IAE5D,IAAI,OAAO,IAAI,WAAW,EAAE,CAE3B;cAEkB,MAAM,IAAI,IAAI;IAqBjC,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,OAAO;CAmBhB;AAED,wBAAgB,yBAAyB,IAAI,OAAO,mBAAmB,CAEtE"}
|
|
@@ -74,6 +74,8 @@ _FxToggleButtonGroup.styles = css`
|
|
|
74
74
|
min-height: var(--fx-size-md);
|
|
75
75
|
padding: var(--fx-space-sm) var(--fx-space-lg);
|
|
76
76
|
font-weight: var(--fx-font-weight);
|
|
77
|
+
/* Altura determinística: a caixa fica EXATAMENTE no token --fx-size-*. */
|
|
78
|
+
line-height: var(--fx-font-line-height);
|
|
77
79
|
color: var(--fx-text-default);
|
|
78
80
|
background: var(--fx-surface-background);
|
|
79
81
|
border: 1px solid var(--fx-border-default);
|
|
@@ -83,7 +85,7 @@ _FxToggleButtonGroup.styles = css`
|
|
|
83
85
|
transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing), border-color var(--fx-motion-duration-fast) var(--fx-motion-easing), color var(--fx-motion-duration-fast) var(--fx-motion-easing);
|
|
84
86
|
}
|
|
85
87
|
:host([size='sm']) .option { min-height: var(--fx-size-sm); padding: var(--fx-space-xs) var(--fx-space-md); font-size: calc(var(--fx-font-size) - 2px); }
|
|
86
|
-
:host([size='lg']) .option { min-height: var(--fx-size-lg); padding: var(--fx-space-
|
|
88
|
+
:host([size='lg']) .option { min-height: var(--fx-size-lg); padding: var(--fx-space-sm) var(--fx-space-xl); font-size: calc(var(--fx-font-size) + 2px); }
|
|
87
89
|
.option:hover { border-color: var(--fx-color-primary); }
|
|
88
90
|
.option.active {
|
|
89
91
|
background: var(--fx-color-primary);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle-button-group.js","sources":["../../../src/components/toggle-button-group/toggle-button-group.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-toggle-button-group> — Grupo de botones de selección múltiple o única.\n *\n * Atributos: multiple (permite varios seleccionados), value (lista), size.\n * Slots `option`: cada botón con [slot=\"option\" value=\"...\"].\n * Evento (composed): `change` (detail: { value: string[] }).\n */\nexport class FxToggleButtonGroup extends FxElement {\n static override styles = css`\n :host { display: inline-flex; font-family: var(--fx-font-family); font-size: var(--fx-font-size); gap: var(--fx-space-xs); }\n .option {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--fx-space-xs);\n min-height: var(--fx-size-md);\n padding: var(--fx-space-sm) var(--fx-space-lg);\n font-weight: var(--fx-font-weight);\n color: var(--fx-text-default);\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n cursor: pointer;\n user-select: none;\n transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing), border-color var(--fx-motion-duration-fast) var(--fx-motion-easing), color var(--fx-motion-duration-fast) var(--fx-motion-easing);\n }\n :host([size='sm']) .option { min-height: var(--fx-size-sm); padding: var(--fx-space-xs) var(--fx-space-md); font-size: calc(var(--fx-font-size) - 2px); }\n :host([size='lg']) .option { min-height: var(--fx-size-lg); padding: var(--fx-space-
|
|
1
|
+
{"version":3,"file":"toggle-button-group.js","sources":["../../../src/components/toggle-button-group/toggle-button-group.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\nimport { esc } from '../../core/sanitize';\n\n/**\n * <fx-toggle-button-group> — Grupo de botones de selección múltiple o única.\n *\n * Atributos: multiple (permite varios seleccionados), value (lista), size.\n * Slots `option`: cada botón con [slot=\"option\" value=\"...\"].\n * Evento (composed): `change` (detail: { value: string[] }).\n */\nexport class FxToggleButtonGroup extends FxElement {\n static override styles = css`\n :host { display: inline-flex; font-family: var(--fx-font-family); font-size: var(--fx-font-size); gap: var(--fx-space-xs); }\n .option {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--fx-space-xs);\n min-height: var(--fx-size-md);\n padding: var(--fx-space-sm) var(--fx-space-lg);\n font-weight: var(--fx-font-weight);\n /* Altura determinística: a caixa fica EXATAMENTE no token --fx-size-*. */\n line-height: var(--fx-font-line-height);\n color: var(--fx-text-default);\n background: var(--fx-surface-background);\n border: 1px solid var(--fx-border-default);\n border-radius: var(--fx-radius-md);\n cursor: pointer;\n user-select: none;\n transition: background var(--fx-motion-duration-fast) var(--fx-motion-easing), border-color var(--fx-motion-duration-fast) var(--fx-motion-easing), color var(--fx-motion-duration-fast) var(--fx-motion-easing);\n }\n :host([size='sm']) .option { min-height: var(--fx-size-sm); padding: var(--fx-space-xs) var(--fx-space-md); font-size: calc(var(--fx-font-size) - 2px); }\n :host([size='lg']) .option { min-height: var(--fx-size-lg); padding: var(--fx-space-sm) var(--fx-space-xl); font-size: calc(var(--fx-font-size) + 2px); }\n .option:hover { border-color: var(--fx-color-primary); }\n .option.active {\n background: var(--fx-color-primary);\n border-color: var(--fx-color-primary);\n color: #fff;\n }\n .option.active:hover { filter: brightness(0.92); }\n `;\n\n static override get observedAttributes(): string[] {\n return ['multiple', 'size'];\n }\n\n get value(): string[] {\n const raw = this.getAttr('value');\n return raw ? raw.split(',').map((s) => s.trim()).filter(Boolean) : [];\n }\n set value(v: string[]) { this.setAttribute('value', v.join(',')); }\n\n get multiple(): boolean { return this.hasAttr('multiple'); }\n\n get options(): HTMLElement[] {\n return Array.from(this.children).filter((el) => el.matches('[slot=\"option\"]')).map((el) => el as HTMLElement);\n }\n\n protected override render(): void {\n const opts = this.options;\n const selected = this.value;\n\n const html = opts\n .map((o, i) => {\n const val = o.getAttribute('value') ?? '';\n const active = selected.includes(val);\n return `<button type=\"button\" class=\"option ${active ? 'active' : ''}\" part=\"option\" data-v=\"${esc(val)}\" aria-pressed=\"${active}\">${esc(o.textContent?.trim() || `Opción ${i + 1}`)}</button>`;\n })\n .join('');\n\n this.setTemplate(`\n <div class=\"options\" part=\"options\" role=\"group\" aria-label=\"Toggle buttons\">\n ${html}\n </div>\n `);\n\n this._bindOptions();\n }\n\n private _bindOptions(): void {\n Array.from(this.root.querySelectorAll<HTMLElement>('.option') || []).forEach((opt) => {\n opt.addEventListener('click', () => this._toggle(opt));\n opt.addEventListener('keydown', (e) => {\n const ev = e as KeyboardEvent;\n if (ev.key === 'Enter' || ev.key === ' ') {\n ev.preventDefault();\n this._toggle(opt);\n }\n });\n });\n }\n\n private _toggle(opt: HTMLElement): void {\n const val = opt.dataset.v ?? '';\n let current = this.value;\n\n if (this.multiple) {\n if (current.includes(val)) current = current.filter((v) => v !== val);\n else current.push(val);\n } else {\n current = current.includes(val) ? [] : [val];\n }\n\n this.value = current;\n this.root.querySelectorAll<HTMLElement>('.option').forEach((o) => {\n const on = current.includes(o.dataset.v ?? '');\n o.classList.toggle('active', on);\n o.setAttribute('aria-pressed', String(on));\n });\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: { value: current } }));\n }\n}\n\nexport function defineFxToggleButtonGroup(): typeof FxToggleButtonGroup {\n return defineElement('fx-toggle-button-group', FxToggleButtonGroup);\n}"],"names":[],"mappings":"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"}
|