@wrrdev/fenix-ui 1.1.13 → 1.1.15
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 +6 -5
- package/dist/components/autocomplete/autocomplete.d.ts +11 -5
- package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/components/autocomplete/autocomplete.js +18 -2
- package/dist/components/autocomplete/autocomplete.js.map +1 -1
- package/dist/components/button/button.d.ts +15 -0
- package/dist/components/button/button.d.ts.map +1 -1
- package/dist/components/button/button.js +20 -1
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/checkbox/checkbox.d.ts +20 -4
- package/dist/components/checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox/checkbox.js +39 -2
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/datepicker/datepicker.d.ts +16 -2
- package/dist/components/datepicker/datepicker.d.ts.map +1 -1
- package/dist/components/datepicker/datepicker.js +46 -2
- package/dist/components/datepicker/datepicker.js.map +1 -1
- package/dist/components/editor/commands.d.ts +27 -0
- package/dist/components/editor/commands.d.ts.map +1 -0
- package/dist/components/editor/commands.js +235 -0
- package/dist/components/editor/commands.js.map +1 -0
- package/dist/components/editor/editor.d.ts +83 -0
- package/dist/components/editor/editor.d.ts.map +1 -0
- package/dist/components/editor/editor.js +1951 -0
- package/dist/components/editor/editor.js.map +1 -0
- package/dist/components/editor/index.d.ts +12 -0
- package/dist/components/editor/index.d.ts.map +1 -0
- package/dist/components/editor/index.js +7 -0
- package/dist/components/editor/index.js.map +1 -0
- package/dist/components/editor/normalize-html.d.ts +33 -0
- package/dist/components/editor/normalize-html.d.ts.map +1 -0
- package/dist/components/editor/normalize-html.js +316 -0
- package/dist/components/editor/normalize-html.js.map +1 -0
- package/dist/components/editor/sanitize-html.d.ts +37 -0
- package/dist/components/editor/sanitize-html.d.ts.map +1 -0
- package/dist/components/editor/sanitize-html.js +247 -0
- package/dist/components/editor/sanitize-html.js.map +1 -0
- package/dist/components/editor/schema.d.ts +36 -0
- package/dist/components/editor/schema.d.ts.map +1 -0
- package/dist/components/editor/schema.js +232 -0
- package/dist/components/editor/schema.js.map +1 -0
- package/dist/components/editor/selection.d.ts +22 -0
- package/dist/components/editor/selection.d.ts.map +1 -0
- package/dist/components/editor/selection.js +97 -0
- package/dist/components/editor/selection.js.map +1 -0
- package/dist/components/editor/styles.d.ts +10 -0
- package/dist/components/editor/styles.d.ts.map +1 -0
- package/dist/components/editor/styles.js +446 -0
- package/dist/components/editor/styles.js.map +1 -0
- package/dist/components/editor/table-utils.d.ts +33 -0
- package/dist/components/editor/table-utils.d.ts.map +1 -0
- package/dist/components/editor/table-utils.js +150 -0
- package/dist/components/editor/table-utils.js.map +1 -0
- package/dist/components/fileupload/fileupload.d.ts +10 -2
- package/dist/components/fileupload/fileupload.d.ts.map +1 -1
- package/dist/components/fileupload/fileupload.js +17 -2
- package/dist/components/fileupload/fileupload.js.map +1 -1
- package/dist/components/floatlabel/floatlabel.d.ts +9 -3
- package/dist/components/floatlabel/floatlabel.d.ts.map +1 -1
- package/dist/components/floatlabel/floatlabel.js +22 -7
- package/dist/components/floatlabel/floatlabel.js.map +1 -1
- package/dist/components/input/input.d.ts +18 -7
- package/dist/components/input/input.d.ts.map +1 -1
- package/dist/components/input/input.js +33 -3
- package/dist/components/input/input.js.map +1 -1
- package/dist/components/knob/knob.d.ts +7 -3
- package/dist/components/knob/knob.d.ts.map +1 -1
- package/dist/components/knob/knob.js +4 -2
- package/dist/components/knob/knob.js.map +1 -1
- package/dist/components/multiselect/multiselect.d.ts +13 -3
- package/dist/components/multiselect/multiselect.d.ts.map +1 -1
- package/dist/components/multiselect/multiselect.js +27 -2
- package/dist/components/multiselect/multiselect.js.map +1 -1
- package/dist/components/radio/radio.d.ts +27 -4
- package/dist/components/radio/radio.d.ts.map +1 -1
- package/dist/components/radio/radio.js +67 -8
- package/dist/components/radio/radio.js.map +1 -1
- package/dist/components/rating/rating.d.ts +8 -4
- package/dist/components/rating/rating.d.ts.map +1 -1
- package/dist/components/rating/rating.js +5 -2
- package/dist/components/rating/rating.js.map +1 -1
- package/dist/components/select/select.d.ts +9 -3
- package/dist/components/select/select.d.ts.map +1 -1
- package/dist/components/select/select.js +11 -2
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/slider/slider.d.ts +12 -6
- package/dist/components/slider/slider.d.ts.map +1 -1
- package/dist/components/slider/slider.js +10 -2
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/switch/switch.d.ts +20 -4
- package/dist/components/switch/switch.d.ts.map +1 -1
- package/dist/components/switch/switch.js +40 -2
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/textarea/textarea.d.ts +12 -5
- package/dist/components/textarea/textarea.d.ts.map +1 -1
- package/dist/components/textarea/textarea.js +12 -2
- package/dist/components/textarea/textarea.js.map +1 -1
- package/dist/components/toast/toast.d.ts +27 -15
- package/dist/components/toast/toast.d.ts.map +1 -1
- package/dist/components/toast/toast.js +205 -32
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toggle-button-group/toggle-button-group.d.ts +13 -5
- package/dist/components/toggle-button-group/toggle-button-group.d.ts.map +1 -1
- package/dist/components/toggle-button-group/toggle-button-group.js +19 -2
- package/dist/components/toggle-button-group/toggle-button-group.js.map +1 -1
- package/dist/core/base.d.ts +7 -0
- package/dist/core/base.d.ts.map +1 -1
- package/dist/core/base.js +4 -1
- package/dist/core/base.js.map +1 -1
- package/dist/core/form-element.d.ts +81 -0
- package/dist/core/form-element.d.ts.map +1 -0
- package/dist/core/form-element.js +129 -0
- package/dist/core/form-element.js.map +1 -0
- package/dist/core/jsx.d.ts +25 -1
- package/dist/core/jsx.d.ts.map +1 -1
- package/dist/core/jsx.js.map +1 -1
- package/dist/core/presets.d.ts +8 -3
- package/dist/core/presets.d.ts.map +1 -1
- package/dist/core/presets.js +6 -17
- package/dist/core/presets.js.map +1 -1
- package/dist/core/types.d.ts +4 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/vue.d.ts +3 -1
- package/dist/core/vue.d.ts.map +1 -1
- package/dist/core/vue.js.map +1 -1
- package/dist/docs/app.d.ts.map +1 -1
- package/dist/docs/componentes/autocomplete.doc.d.ts.map +1 -1
- package/dist/docs/componentes/checkbox.doc.d.ts.map +1 -1
- package/dist/docs/componentes/datepicker.doc.d.ts.map +1 -1
- package/dist/docs/componentes/editor.doc.d.ts +6 -0
- package/dist/docs/componentes/editor.doc.d.ts.map +1 -0
- package/dist/docs/componentes/fileupload.doc.d.ts.map +1 -1
- 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/knob.doc.d.ts.map +1 -1
- package/dist/docs/componentes/multiselect.doc.d.ts.map +1 -1
- package/dist/docs/componentes/rating.doc.d.ts.map +1 -1
- package/dist/docs/componentes/select.doc.d.ts.map +1 -1
- package/dist/docs/componentes/slider.doc.d.ts.map +1 -1
- package/dist/docs/componentes/switch.doc.d.ts.map +1 -1
- package/dist/docs/componentes/textarea.doc.d.ts.map +1 -1
- package/dist/docs/componentes/toast.doc.d.ts.map +1 -1
- package/dist/docs/componentes/toggle-button-group.doc.d.ts.map +1 -1
- package/dist/docs/frameworks.d.ts +75 -0
- package/dist/docs/frameworks.d.ts.map +1 -0
- package/dist/docs/ui/code.d.ts +4 -0
- package/dist/docs/ui/code.d.ts.map +1 -1
- package/dist/fenix-ui.umd.min.js +786 -254
- package/dist/fenix-ui2.esm.js.map +1 -1
- package/dist/fenix-ui4.esm.js +4396 -172
- package/dist/fenix-ui4.esm.js.map +1 -1
- package/dist/fenix-ui5.esm.js +1 -0
- package/dist/fenix-ui5.esm.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- 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 +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.js","sources":["../../../src/components/slider/slider.ts"],"sourcesContent":["import { FxElement } from '../../core/base';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\n\n/**\n * <fx-slider> — Controle deslizante para seleção de valor numérico em um intervalo.\n *\n * Atributos: min, max, step, value, size (sm|md|lg), disabled, show-value,\n * label (rótulo acima do trilho).\n * Eventos (composed): `input` (durante o arraste) e `change` (ao soltar) —\n * ambos com `detail: { value: number }`.\n */\nexport class FxSlider 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 --_track-h: 6px;\n --_thumb: 18px;\n }\n :host([size='sm']) { --_track-h: 4px; --_thumb: 14px; }\n :host([size='lg']) { --_track-h: 8px; --_thumb: 22px; }\n :host([disabled]) { opacity: 0.55; pointer-events: none; }\n\n .label {\n font-size: calc(var(--fx-font-size) - 2px);\n color: var(--fx-text-muted);\n margin-bottom: var(--fx-space-xs);\n display: flex;\n justify-content: space-between;\n gap: var(--fx-space-md);\n align-items: center;\n }\n .track-wrap {\n position: relative;\n display: flex;\n align-items: center;\n height: var(--_thumb);\n cursor: pointer;\n touch-action: none;\n }\n .track {\n width: 100%;\n height: var(--_track-h);\n border-radius: var(--fx-radius-full);\n background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.08));\n overflow: hidden;\n }\n .fill {\n height: 100%;\n background: var(--fx-color-primary);\n border-radius: var(--fx-radius-full);\n }\n .thumb {\n position: absolute;\n top: 50%;\n width: var(--_thumb);\n height: var(--_thumb);\n border-radius: var(--fx-radius-full);\n background: var(--fx-surface-background);\n border: 2px solid var(--fx-color-primary);\n box-shadow: var(--fx-shadow-sm);\n transform: translate(-50%, -50%);\n transition: box-shadow var(--fx-motion-duration-fast) var(--fx-motion-easing);\n box-sizing: border-box;\n }\n .track-wrap:hover .thumb,\n .track-wrap.dragging .thumb { box-shadow: var(--fx-effect-focus-ring, none); }\n .track-wrap:focus-visible { outline: none; }\n .track-wrap:focus-visible .thumb {\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n .value {\n position: absolute;\n bottom: calc(100% + 6px);\n transform: translateX(-50%);\n background: var(--fx-text-default, #1e293b);\n color: var(--fx-surface-background, #fff);\n font-size: calc(var(--fx-font-size) - 3px);\n font-weight: 600;\n padding: 2px var(--fx-space-xs);\n border-radius: var(--fx-radius-sm);\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity var(--fx-motion-duration-fast) var(--fx-motion-easing);\n }\n .track-wrap:hover .value,\n .track-wrap.dragging .value,\n .track-wrap:focus-visible .value { opacity: 1; }\n `;\n\n static override get observedAttributes(): string[] {\n return ['min', 'max', 'step', 'size', 'disabled', 'show-value', 'label'];\n }\n\n get min(): number { return this._num('min', 0); }\n get max(): number { return this._num('max', 100); }\n get step(): number { return this._num('step', 1); }\n\n get value(): number {\n return this._clamp(this._num('value', this.min));\n }\n set value(v: number) {\n const snapped = this._snap(v);\n this.setAttribute('value', String(snapped));\n // atualiza visual sem re-render (preserva estado de drag/foco)\n if (this.isConnected) this._syncVisual();\n }\n\n private _num(attr: string, fallback: number): number {\n const raw = this.getAttribute(attr);\n if (raw === null || raw === '') return fallback;\n const n = Number(raw);\n return Number.isFinite(n) ? n : fallback;\n }\n\n private _clamp(v: number): number {\n return Math.min(this.max, Math.max(this.min, v));\n }\n\n /** Arredonda para o múltiplo de `step` mais próximo dentro do intervalo. */\n private _snap(v: number): number {\n const step = this.step || 1;\n const snapped = Math.round((this._clamp(v) - this.min) / step) * step + this.min;\n return Number(this._clamp(snapped).toFixed(10));\n }\n\n /** Percentual (0-100) do valor atual dentro do intervalo. */\n private _pct(): number {\n const span = this.max - this.min;\n return span <= 0 ? 0 : ((this.value - this.min) / span) * 100;\n }\n\n protected override render(): void {\n const pct = this._pct();\n const label = this.getAttr('label');\n const showValue = this.hasAttr('show-value');\n\n this.setTemplate(`\n ${label ? `<div class=\"label\" part=\"label\"><span>${label}</span>${showValue ? `<span>${this.value}</span>` : ''}</div>` : ''}\n <div class=\"track-wrap\" part=\"track\" tabindex=\"0\" role=\"slider\"\n aria-valuemin=\"${this.min}\" aria-valuemax=\"${this.max}\" aria-valuenow=\"${this.value}\"\n aria-label=\"${label || 'Slider'}\" ${this.hasAttr('disabled') ? 'aria-disabled=\"true\"' : ''}>\n <div class=\"track\"><div class=\"fill\" part=\"fill\" style=\"width: ${pct}%\"></div></div>\n <div class=\"thumb\" part=\"thumb\" style=\"left: ${pct}%\"></div>\n ${showValue ? `<span class=\"value\" style=\"left: ${pct}%\">${this.value}</span>` : ''}\n </div>\n `);\n\n this._bindPointer();\n this._bindKeyboard();\n }\n\n private _dragging = false;\n private _onMove?: (e: PointerEvent) => void;\n private _onUp?: (e: PointerEvent) => void;\n\n protected override disconnectedCallback(): void {\n super.disconnectedCallback();\n // Limpa listeners de janela se o elemento for removido durante um drag.\n if (this._dragging) {\n this._dragging = false;\n if (this._onMove) window.removeEventListener('pointermove', this._onMove);\n if (this._onUp) window.removeEventListener('pointerup', this._onUp);\n }\n }\n\n private _wrap(): HTMLElement | null {\n return this.root.querySelector<HTMLElement>('.track-wrap');\n }\n\n private _bindPointer(): void {\n const wrap = this._wrap();\n if (!wrap) return;\n\n const valueFromEvent = (e: PointerEvent): number => {\n const rect = wrap.getBoundingClientRect();\n const ratio = rect.width <= 0 ? 0 : (e.clientX - rect.left) / rect.width;\n return this.min + ratio * (this.max - this.min);\n };\n\n const move = (e: PointerEvent): void => {\n if (!this._dragging) return;\n this.value = valueFromEvent(e);\n this._syncVisual();\n this.dispatchEvent(\n new CustomEvent('input', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n };\n this._onMove = move;\n const up = (e: PointerEvent): void => {\n if (!this._dragging) return;\n this._dragging = false;\n wrap.classList.remove('dragging');\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n this.value = valueFromEvent(e);\n this._syncVisual();\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n };\n this._onUp = up;\n\n wrap.addEventListener('pointerdown', (e) => {\n if (this.hasAttr('disabled')) return;\n this._dragging = true;\n wrap.classList.add('dragging');\n wrap.focus();\n this.value = valueFromEvent(e);\n this._syncVisual();\n this.dispatchEvent(\n new CustomEvent('input', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n });\n }\n\n private _bindKeyboard(): void {\n const wrap = this._wrap();\n if (!wrap) return;\n wrap.addEventListener('keydown', (e) => {\n if (this.hasAttr('disabled')) return;\n const ev = e as KeyboardEvent;\n const big = (this.max - this.min) / 10;\n let next: number | null = null;\n switch (ev.key) {\n case 'ArrowRight': case 'ArrowUp': next = this.value + this.step; break;\n case 'ArrowLeft': case 'ArrowDown': next = this.value - this.step; break;\n case 'PageUp': next = this.value + big; break;\n case 'PageDown': next = this.value - big; break;\n case 'Home': next = this.min; break;\n case 'End': next = this.max; break;\n default: return;\n }\n ev.preventDefault();\n this.value = next;\n this._syncVisual();\n this.dispatchEvent(\n new CustomEvent('input', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n });\n }\n\n /** Atualiza fill/thumb/tooltip/aria sem re-renderizar o template (evita perder o drag). */\n private _syncVisual(): void {\n const pct = this._pct();\n const wrap = this._wrap();\n if (!wrap) return;\n const fill = wrap.querySelector<HTMLElement>('.fill');\n const thumb = wrap.querySelector<HTMLElement>('.thumb');\n const tip = wrap.querySelector<HTMLElement>('.value');\n if (fill) fill.style.width = `${pct}%`;\n if (thumb) thumb.style.left = `${pct}%`;\n if (tip) {\n tip.style.left = `${pct}%`;\n tip.textContent = String(this.value);\n }\n wrap.setAttribute('aria-valuenow', String(this.value));\n const labelPct = this.root.querySelector<HTMLElement>('.label span:last-child');\n if (labelPct) labelPct.textContent = String(this.value);\n }\n}\n\nexport function defineFxSlider(): typeof FxSlider {\n return defineElement('fx-slider', FxSlider);\n}\n\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slider.js","sources":["../../../src/components/slider/slider.ts"],"sourcesContent":["import { FxFormElement } from '../../core/form-element';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\n\n/**\n * <fx-slider> — Controle deslizante para seleção de valor numérico em um intervalo.\n *\n * Form-Associated Custom Element: dentro de um <form> entra no FormData\n * (via atributo `name`) e recebe reset/disable do form.\n *\n * Atributos: min, max, step, value, name, size (sm|md|lg), disabled,\n * show-value, label (rótulo acima do trilho).\n * Eventos (composed): `input` (durante o arraste) e `change` (ao soltar),\n * ambos com `detail: { value: number }`; `change`/solta também emitem\n * `valueChange` ([(value)] do Angular) e o `input` aciona o v-model do Vue.\n */\nexport class FxSlider extends FxFormElement {\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 --_track-h: 6px;\n --_thumb: 18px;\n }\n :host([size='sm']) { --_track-h: 4px; --_thumb: 14px; }\n :host([size='lg']) { --_track-h: 8px; --_thumb: 22px; }\n :host([disabled]) { opacity: 0.55; pointer-events: none; }\n\n .label {\n font-size: calc(var(--fx-font-size) - 2px);\n color: var(--fx-text-muted);\n margin-bottom: var(--fx-space-xs);\n display: flex;\n justify-content: space-between;\n gap: var(--fx-space-md);\n align-items: center;\n }\n .track-wrap {\n position: relative;\n display: flex;\n align-items: center;\n height: var(--_thumb);\n cursor: pointer;\n touch-action: none;\n }\n .track {\n width: 100%;\n height: var(--_track-h);\n border-radius: var(--fx-radius-full);\n background: var(--fx-surface-surface-hover, rgba(0, 0, 0, 0.08));\n overflow: hidden;\n }\n .fill {\n height: 100%;\n background: var(--fx-color-primary);\n border-radius: var(--fx-radius-full);\n }\n .thumb {\n position: absolute;\n top: 50%;\n width: var(--_thumb);\n height: var(--_thumb);\n border-radius: var(--fx-radius-full);\n background: var(--fx-surface-background);\n border: 2px solid var(--fx-color-primary);\n box-shadow: var(--fx-shadow-sm);\n transform: translate(-50%, -50%);\n transition: box-shadow var(--fx-motion-duration-fast) var(--fx-motion-easing);\n box-sizing: border-box;\n }\n .track-wrap:hover .thumb,\n .track-wrap.dragging .thumb { box-shadow: var(--fx-effect-focus-ring, none); }\n .track-wrap:focus-visible { outline: none; }\n .track-wrap:focus-visible .thumb {\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n .value {\n position: absolute;\n bottom: calc(100% + 6px);\n transform: translateX(-50%);\n background: var(--fx-text-default, #1e293b);\n color: var(--fx-surface-background, #fff);\n font-size: calc(var(--fx-font-size) - 3px);\n font-weight: 600;\n padding: 2px var(--fx-space-xs);\n border-radius: var(--fx-radius-sm);\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity var(--fx-motion-duration-fast) var(--fx-motion-easing);\n }\n .track-wrap:hover .value,\n .track-wrap.dragging .value,\n .track-wrap:focus-visible .value { opacity: 1; }\n `;\n\n static override get observedAttributes(): string[] {\n return ['min', 'max', 'step', 'size', 'disabled', 'show-value', 'label'];\n }\n\n get min(): number { return this._num('min', 0); }\n get max(): number { return this._num('max', 100); }\n get step(): number { return this._num('step', 1); }\n\n get value(): number {\n return this._clamp(this._num('value', this.min));\n }\n set value(v: number) {\n const snapped = this._snap(v);\n this.setAttribute('value', String(snapped));\n // atualiza visual sem re-render (preserva estado de drag/foco)\n if (this.isConnected) this._syncVisual();\n // `value` não é observado: publica no form aqui (setFormValue não re-renderiza).\n this.updateFormValue();\n }\n\n private _num(attr: string, fallback: number): number {\n const raw = this.getAttribute(attr);\n if (raw === null || raw === '') return fallback;\n const n = Number(raw);\n return Number.isFinite(n) ? n : fallback;\n }\n\n private _clamp(v: number): number {\n return Math.min(this.max, Math.max(this.min, v));\n }\n\n /** Arredonda para o múltiplo de `step` mais próximo dentro do intervalo. */\n private _snap(v: number): number {\n const step = this.step || 1;\n const snapped = Math.round((this._clamp(v) - this.min) / step) * step + this.min;\n return Number(this._clamp(snapped).toFixed(10));\n }\n\n /** Percentual (0-100) do valor atual dentro do intervalo. */\n private _pct(): number {\n const span = this.max - this.min;\n return span <= 0 ? 0 : ((this.value - this.min) / span) * 100;\n }\n\n protected override render(): void {\n const pct = this._pct();\n const label = this.getAttr('label');\n const showValue = this.hasAttr('show-value');\n\n this.setTemplate(`\n ${label ? `<div class=\"label\" part=\"label\"><span>${label}</span>${showValue ? `<span>${this.value}</span>` : ''}</div>` : ''}\n <div class=\"track-wrap\" part=\"track\" tabindex=\"0\" role=\"slider\"\n aria-valuemin=\"${this.min}\" aria-valuemax=\"${this.max}\" aria-valuenow=\"${this.value}\"\n aria-label=\"${label || 'Slider'}\" ${this.hasAttr('disabled') ? 'aria-disabled=\"true\"' : ''}>\n <div class=\"track\"><div class=\"fill\" part=\"fill\" style=\"width: ${pct}%\"></div></div>\n <div class=\"thumb\" part=\"thumb\" style=\"left: ${pct}%\"></div>\n ${showValue ? `<span class=\"value\" style=\"left: ${pct}%\">${this.value}</span>` : ''}\n </div>\n `);\n\n this._bindPointer();\n this._bindKeyboard();\n }\n\n private _dragging = false;\n private _onMove?: (e: PointerEvent) => void;\n private _onUp?: (e: PointerEvent) => void;\n\n protected override disconnectedCallback(): void {\n super.disconnectedCallback();\n // Limpa listeners de janela se o elemento for removido durante um drag.\n if (this._dragging) {\n this._dragging = false;\n if (this._onMove) window.removeEventListener('pointermove', this._onMove);\n if (this._onUp) window.removeEventListener('pointerup', this._onUp);\n }\n }\n\n private _wrap(): HTMLElement | null {\n return this.root.querySelector<HTMLElement>('.track-wrap');\n }\n\n private _bindPointer(): void {\n const wrap = this._wrap();\n if (!wrap) return;\n\n const valueFromEvent = (e: PointerEvent): number => {\n const rect = wrap.getBoundingClientRect();\n const ratio = rect.width <= 0 ? 0 : (e.clientX - rect.left) / rect.width;\n return this.min + ratio * (this.max - this.min);\n };\n\n const move = (e: PointerEvent): void => {\n if (!this._dragging) return;\n this.value = valueFromEvent(e);\n this._syncVisual();\n this.dispatchEvent(\n new CustomEvent('input', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n };\n this._onMove = move;\n const up = (e: PointerEvent): void => {\n if (!this._dragging) return;\n this._dragging = false;\n wrap.classList.remove('dragging');\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n this.value = valueFromEvent(e);\n this._syncVisual();\n // input (v-model do Vue) + valueChange ([(value)] do Angular) no soltar.\n this.emitValueEvents();\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n };\n this._onUp = up;\n\n wrap.addEventListener('pointerdown', (e) => {\n if (this.hasAttr('disabled')) return;\n this._dragging = true;\n wrap.classList.add('dragging');\n wrap.focus();\n this.value = valueFromEvent(e);\n this._syncVisual();\n this.dispatchEvent(\n new CustomEvent('input', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n });\n }\n\n private _bindKeyboard(): void {\n const wrap = this._wrap();\n if (!wrap) return;\n wrap.addEventListener('keydown', (e) => {\n if (this.hasAttr('disabled')) return;\n const ev = e as KeyboardEvent;\n const big = (this.max - this.min) / 10;\n let next: number | null = null;\n switch (ev.key) {\n case 'ArrowRight': case 'ArrowUp': next = this.value + this.step; break;\n case 'ArrowLeft': case 'ArrowDown': next = this.value - this.step; break;\n case 'PageUp': next = this.value + big; break;\n case 'PageDown': next = this.value - big; break;\n case 'Home': next = this.min; break;\n case 'End': next = this.max; break;\n default: return;\n }\n ev.preventDefault();\n this.value = next;\n this._syncVisual();\n this.emitValueEvents();\n this.dispatchEvent(\n new CustomEvent('input', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n this.dispatchEvent(\n new CustomEvent('change', { bubbles: true, composed: true, detail: { value: this.value } }),\n );\n });\n }\n\n /** Atualiza fill/thumb/tooltip/aria sem re-renderizar o template (evita perder o drag). */\n private _syncVisual(): void {\n const pct = this._pct();\n const wrap = this._wrap();\n if (!wrap) return;\n const fill = wrap.querySelector<HTMLElement>('.fill');\n const thumb = wrap.querySelector<HTMLElement>('.thumb');\n const tip = wrap.querySelector<HTMLElement>('.value');\n if (fill) fill.style.width = `${pct}%`;\n if (thumb) thumb.style.left = `${pct}%`;\n if (tip) {\n tip.style.left = `${pct}%`;\n tip.textContent = String(this.value);\n }\n wrap.setAttribute('aria-valuenow', String(this.value));\n const labelPct = this.root.querySelector<HTMLElement>('.label span:last-child');\n if (labelPct) labelPct.textContent = String(this.value);\n }\n\n /** form.reset(): restaura o valor inicial e o visual sem re-render. */\n override formResetCallback(): void {\n super.formResetCallback();\n this._syncVisual();\n }\n}\n\nexport function defineFxSlider(): typeof FxSlider {\n return defineElement('fx-slider', FxSlider);\n}\n\n"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FxFormElement } from '../../core/form-element';
|
|
2
2
|
/**
|
|
3
3
|
* <fx-switch> — Interruptor ligado/desligado (role="switch").
|
|
4
4
|
*
|
|
5
|
+
* Form-Associated Custom Element: dentro de um <form> entra no FormData
|
|
6
|
+
* (via atributo `name`) com `value` (ou 'on') quando ligado — desligado
|
|
7
|
+
* não envia nada, igual ao checkbox. Recebe reset/disable do form.
|
|
8
|
+
*
|
|
5
9
|
* O texto do slot (light DOM) é o rótulo clicável.
|
|
6
|
-
* Atributos: checked, disabled, size (sm|md|lg).
|
|
7
|
-
*
|
|
10
|
+
* Atributos: checked, disabled, value, name, size (sm|md|lg).
|
|
11
|
+
* Eventos: `change` e `checkedChange` (composed, detail: { checked, value }) —
|
|
12
|
+
* `checkedChange` é o two-way binding do Angular [(checked)].
|
|
8
13
|
*/
|
|
9
|
-
export declare class FxSwitch extends
|
|
14
|
+
export declare class FxSwitch extends FxFormElement {
|
|
10
15
|
static styles: string;
|
|
11
16
|
static get observedAttributes(): string[];
|
|
12
17
|
/** Tamanho da trilha. Padrão: `'md'`. */
|
|
@@ -16,7 +21,18 @@ export declare class FxSwitch extends FxElement {
|
|
|
16
21
|
set checked(value: boolean);
|
|
17
22
|
get disabled(): boolean;
|
|
18
23
|
set disabled(value: boolean);
|
|
24
|
+
/** getter/setter `value` → espelho do atributo `value` (compat com v-model / [(value)]). */
|
|
25
|
+
get value(): string;
|
|
26
|
+
set value(v: string);
|
|
27
|
+
/** No FormData: `value` (ou 'on') quando ligado; null (não envia) quando não. */
|
|
28
|
+
protected getFormValue(): string | FormData | null;
|
|
19
29
|
protected render(): void;
|
|
30
|
+
/** Estado marcado inicial (para form.reset() restaurar). */
|
|
31
|
+
private _initialChecked;
|
|
32
|
+
private _initialCheckedCaptured;
|
|
33
|
+
protected connectedCallback(): void;
|
|
34
|
+
/** form.reset(): restaura o estado inicial (desligado por padrão). */
|
|
35
|
+
formResetCallback(): void;
|
|
20
36
|
}
|
|
21
37
|
export declare function defineFxSwitch(): typeof FxSwitch;
|
|
22
38
|
//# sourceMappingURL=switch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/switch/switch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/switch/switch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAIxD;;;;;;;;;;;GAWG;AACH,qBAAa,QAAS,SAAQ,aAAa;IACzC,OAAgB,MAAM,SAsDpB;IAEF,WAAoB,kBAAkB,IAAI,MAAM,EAAE,CAEjD;IAED,yCAAyC;IACzC,IAAI,IAAI,IAAI,MAAM,CAGjB;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAErB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAEzB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED,4FAA4F;IAC5F,IAAI,KAAK,IAAI,MAAM,CAAkC;IACrD,IAAI,KAAK,CAAC,CAAC,EAAE,MAAM,EAAoC;IAEvD,iFAAiF;cAC9D,YAAY,IAAI,MAAM,GAAG,QAAQ,GAAG,IAAI;cAIxC,MAAM,IAAI,IAAI;IAoCjC,4DAA4D;IAC5D,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,uBAAuB,CAAS;cAErB,iBAAiB,IAAI,IAAI;IAQ5C,sEAAsE;IAC7D,iBAAiB,IAAI,IAAI;CAMnC;AAED,wBAAgB,cAAc,IAAI,OAAO,QAAQ,CAEhD"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FxFormElement } from "../../core/form-element.js";
|
|
2
2
|
import { css } from "../../core/css.js";
|
|
3
3
|
import { defineElement } from "../../core/define.js";
|
|
4
|
-
const _FxSwitch = class _FxSwitch extends
|
|
4
|
+
const _FxSwitch = class _FxSwitch extends FxFormElement {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this._initialChecked = false;
|
|
8
|
+
this._initialCheckedCaptured = false;
|
|
9
|
+
}
|
|
5
10
|
static get observedAttributes() {
|
|
6
11
|
return ["checked", "disabled", "size"];
|
|
7
12
|
}
|
|
@@ -25,6 +30,17 @@ const _FxSwitch = class _FxSwitch extends FxElement {
|
|
|
25
30
|
set disabled(value) {
|
|
26
31
|
this.toggleAttr("disabled", Boolean(value));
|
|
27
32
|
}
|
|
33
|
+
/** getter/setter `value` → espelho do atributo `value` (compat com v-model / [(value)]). */
|
|
34
|
+
get value() {
|
|
35
|
+
return this.getAttr("value");
|
|
36
|
+
}
|
|
37
|
+
set value(v) {
|
|
38
|
+
this.setAttribute("value", v);
|
|
39
|
+
}
|
|
40
|
+
/** No FormData: `value` (ou 'on') quando ligado; null (não envia) quando não. */
|
|
41
|
+
getFormValue() {
|
|
42
|
+
return this.checked ? this.getAttr("value") || "on" : null;
|
|
43
|
+
}
|
|
28
44
|
render() {
|
|
29
45
|
this.setTemplate(`
|
|
30
46
|
<button class="switch" part="switch" type="button" role="switch"
|
|
@@ -46,7 +62,29 @@ const _FxSwitch = class _FxSwitch extends FxElement {
|
|
|
46
62
|
detail: { checked: this.checked }
|
|
47
63
|
})
|
|
48
64
|
);
|
|
65
|
+
this.dispatchEvent(
|
|
66
|
+
new CustomEvent("checkedChange", {
|
|
67
|
+
bubbles: true,
|
|
68
|
+
composed: true,
|
|
69
|
+
detail: { checked: this.checked, value: this.getAttr("value") }
|
|
70
|
+
})
|
|
71
|
+
);
|
|
49
72
|
});
|
|
73
|
+
this.updateFormValue();
|
|
74
|
+
}
|
|
75
|
+
connectedCallback() {
|
|
76
|
+
if (!this._initialCheckedCaptured) {
|
|
77
|
+
this._initialCheckedCaptured = true;
|
|
78
|
+
this._initialChecked = this.checked;
|
|
79
|
+
}
|
|
80
|
+
super.connectedCallback();
|
|
81
|
+
}
|
|
82
|
+
/** form.reset(): restaura o estado inicial (desligado por padrão). */
|
|
83
|
+
formResetCallback() {
|
|
84
|
+
this.checked = this._initialChecked;
|
|
85
|
+
const btn = this.root.querySelector(".switch");
|
|
86
|
+
if (btn) btn.setAttribute("aria-checked", String(this.checked));
|
|
87
|
+
this.updateFormValue();
|
|
50
88
|
}
|
|
51
89
|
};
|
|
52
90
|
_FxSwitch.styles = css`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.js","sources":["../../../src/components/switch/switch.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"switch.js","sources":["../../../src/components/switch/switch.ts"],"sourcesContent":["import { FxFormElement } from '../../core/form-element';\nimport { css } from '../../core/css';\nimport { defineElement } from '../../core/define';\n\n/**\n * <fx-switch> — Interruptor ligado/desligado (role=\"switch\").\n *\n * Form-Associated Custom Element: dentro de um <form> entra no FormData\n * (via atributo `name`) com `value` (ou 'on') quando ligado — desligado\n * não envia nada, igual ao checkbox. Recebe reset/disable do form.\n *\n * O texto do slot (light DOM) é o rótulo clicável.\n * Atributos: checked, disabled, value, name, size (sm|md|lg).\n * Eventos: `change` e `checkedChange` (composed, detail: { checked, value }) —\n * `checkedChange` é o two-way binding do Angular [(checked)].\n */\nexport class FxSwitch extends FxFormElement {\n static override styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n font-family: var(--fx-font-family);\n font-size: var(--fx-font-size);\n }\n .switch {\n display: inline-flex;\n align-items: center;\n gap: var(--fx-space-sm);\n cursor: pointer;\n user-select: none;\n background: none;\n border: none;\n padding: 0;\n color: var(--fx-text-default);\n font: inherit;\n }\n .track {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: var(--fx-radius-full);\n background: var(--fx-border-default);\n flex-shrink: 0;\n transition: background-color var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n .thumb {\n position: absolute;\n top: 3px;\n left: 3px;\n width: 16px;\n height: 16px;\n border-radius: var(--fx-radius-full);\n background: #fff;\n box-shadow: var(--fx-shadow-sm);\n transition: transform var(--fx-motion-duration-normal) var(--fx-motion-easing);\n }\n :host([checked]) .track { background: var(--fx-color-primary); }\n :host([checked]) .thumb { transform: translateX(18px); }\n .switch:focus-visible .track {\n outline: none;\n box-shadow: var(--fx-effect-focus-ring, none);\n }\n .label { display: inline-flex; align-items: center; }\n :host([disabled]) .switch { opacity: 0.55; cursor: not-allowed; pointer-events: none; }\n /* Escala: sm 32×18 · md 40×22 (padrão) · lg 48×26 */\n :host([size='sm']) .track { width: 32px; height: 18px; }\n :host([size='sm']) .thumb { top: 2px; left: 2px; width: 14px; height: 14px; }\n :host([size='sm'][checked]) .thumb { transform: translateX(14px); }\n :host([size='lg']) .track { width: 48px; height: 26px; }\n :host([size='lg']) .thumb { top: 4px; left: 4px; width: 18px; height: 18px; }\n :host([size='lg'][checked]) .thumb { transform: translateX(22px); }\n `;\n\n static override get observedAttributes(): string[] {\n return ['checked', 'disabled', 'size'];\n }\n\n /** Tamanho da trilha. 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 checked(): boolean {\n return this.hasAttr('checked');\n }\n set checked(value: boolean) {\n this.toggleAttr('checked', Boolean(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 /** getter/setter `value` → espelho do atributo `value` (compat com v-model / [(value)]). */\n get value(): string { return this.getAttr('value'); }\n set value(v: string) { this.setAttribute('value', v); }\n\n /** No FormData: `value` (ou 'on') quando ligado; null (não envia) quando não. */\n protected override getFormValue(): string | FormData | null {\n return this.checked ? (this.getAttr('value') || 'on') : null;\n }\n\n protected override render(): void {\n this.setTemplate(`\n <button class=\"switch\" part=\"switch\" type=\"button\" role=\"switch\"\n aria-checked=\"${this.checked}\" ${this.hasAttr('disabled') ? 'disabled' : ''}>\n <span class=\"track\" part=\"track\"><span class=\"thumb\" part=\"thumb\"></span></span>\n <span class=\"label\" part=\"label\"><slot></slot></span>\n </button>\n `);\n\n const btn = this.root.querySelector<HTMLButtonElement>('.switch');\n if (!btn) return;\n btn.addEventListener('click', () => {\n if (this.hasAttr('disabled')) return;\n this.checked = !this.checked;\n btn.setAttribute('aria-checked', String(this.checked));\n this.dispatchEvent(\n new CustomEvent('change', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked },\n }),\n );\n // Two-way binding do Angular: [(checked)] = [checked] + (checkedChange).\n this.dispatchEvent(\n new CustomEvent('checkedChange', {\n bubbles: true,\n composed: true,\n detail: { checked: this.checked, value: this.getAttr('value') },\n }),\n );\n });\n\n // Publica name/value no form (ElementInternals) a cada render.\n this.updateFormValue();\n }\n\n /** Estado marcado inicial (para form.reset() restaurar). */\n private _initialChecked = false;\n private _initialCheckedCaptured = false;\n\n protected override connectedCallback(): void {\n if (!this._initialCheckedCaptured) {\n this._initialCheckedCaptured = true;\n this._initialChecked = this.checked;\n }\n super.connectedCallback();\n }\n\n /** form.reset(): restaura o estado inicial (desligado por padrão). */\n override formResetCallback(): void {\n this.checked = this._initialChecked;\n const btn = this.root.querySelector<HTMLButtonElement>('.switch');\n if (btn) btn.setAttribute('aria-checked', String(this.checked));\n this.updateFormValue();\n }\n}\n\nexport function defineFxSwitch(): typeof FxSwitch {\n return defineElement('fx-switch', FxSwitch);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FxFormElement } from '../../core/form-element';
|
|
2
2
|
/**
|
|
3
3
|
* <fx-textarea> — Área de texto multilinha estilizada com os tokens do tema.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Form-Associated Custom Element: dentro de um <form> entra no FormData
|
|
6
|
+
* (via atributo `name`), recebe reset/disable do form e é alvo de
|
|
7
|
+
* `<label for>`/`autofocus`. Enter continua sendo quebra de linha.
|
|
8
|
+
*
|
|
9
|
+
* Atributos: value, name, size (sm|md|lg), placeholder, disabled, readonly,
|
|
10
|
+
* rows, maxlength, autofocus.
|
|
11
|
+
* Eventos: `input`, `change` e `valueChange` (composed, detail: { value }) —
|
|
12
|
+
* `input` aciona o v-model do Vue e `valueChange` o [(value)] do Angular.
|
|
8
13
|
*/
|
|
9
|
-
export declare class FxTextarea extends
|
|
14
|
+
export declare class FxTextarea extends FxFormElement {
|
|
10
15
|
static styles: string;
|
|
11
16
|
static get observedAttributes(): string[];
|
|
12
17
|
get size(): string;
|
|
@@ -14,6 +19,8 @@ export declare class FxTextarea extends FxElement {
|
|
|
14
19
|
get value(): string;
|
|
15
20
|
set value(value: string);
|
|
16
21
|
protected render(): void;
|
|
22
|
+
/** Empurra o atributo `value` para o campo interno sem re-renderizar. */
|
|
23
|
+
protected syncInternalControl(): void;
|
|
17
24
|
}
|
|
18
25
|
export declare function defineFxTextarea(): typeof FxTextarea;
|
|
19
26
|
//# sourceMappingURL=textarea.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../../src/components/textarea/textarea.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../../src/components/textarea/textarea.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAKxD;;;;;;;;;;;GAWG;AACH,qBAAa,UAAW,SAAQ,aAAa;IAC3C,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,EAMtB;cAEkB,MAAM,IAAI,IAAI;IAoCjC,yEAAyE;cACtD,mBAAmB,IAAI,IAAI;CAK/C;AAED,wBAAgB,gBAAgB,IAAI,OAAO,UAAU,CAEpD"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FxFormElement } from "../../core/form-element.js";
|
|
2
2
|
import { css } from "../../core/css.js";
|
|
3
3
|
import { defineElement } from "../../core/define.js";
|
|
4
4
|
import { esc } from "../../core/sanitize.js";
|
|
5
|
-
const _FxTextarea = class _FxTextarea extends
|
|
5
|
+
const _FxTextarea = class _FxTextarea extends FxFormElement {
|
|
6
6
|
static get observedAttributes() {
|
|
7
7
|
return ["size", "placeholder", "disabled", "readonly", "rows", "maxlength", "error", "invalid", "success", "valid"];
|
|
8
8
|
}
|
|
@@ -18,6 +18,8 @@ const _FxTextarea = class _FxTextarea extends FxElement {
|
|
|
18
18
|
}
|
|
19
19
|
set value(value) {
|
|
20
20
|
this.setAttribute("value", value);
|
|
21
|
+
this.syncInternalControl();
|
|
22
|
+
this.updateFormValue();
|
|
21
23
|
}
|
|
22
24
|
render() {
|
|
23
25
|
const placeholder = this.getAttr("placeholder");
|
|
@@ -37,6 +39,7 @@ const _FxTextarea = class _FxTextarea extends FxElement {
|
|
|
37
39
|
if (readonly) field.setAttribute("readonly", "");
|
|
38
40
|
const emit = (event) => {
|
|
39
41
|
this.value = field.value;
|
|
42
|
+
this.emitValueEvents();
|
|
40
43
|
this.dispatchEvent(
|
|
41
44
|
new CustomEvent(event, { bubbles: true, composed: true, detail: { value: field.value } })
|
|
42
45
|
);
|
|
@@ -49,6 +52,13 @@ const _FxTextarea = class _FxTextarea extends FxElement {
|
|
|
49
52
|
e.stopPropagation();
|
|
50
53
|
emit("change");
|
|
51
54
|
});
|
|
55
|
+
this.updateFormValue();
|
|
56
|
+
}
|
|
57
|
+
/** Empurra o atributo `value` para o campo interno sem re-renderizar. */
|
|
58
|
+
syncInternalControl() {
|
|
59
|
+
const field = this.root.querySelector(".field");
|
|
60
|
+
const value = this.getAttr("value");
|
|
61
|
+
if (field && field.value !== value) field.value = value;
|
|
52
62
|
}
|
|
53
63
|
};
|
|
54
64
|
_FxTextarea.styles = css`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textarea.js","sources":["../../../src/components/textarea/textarea.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"textarea.js","sources":["../../../src/components/textarea/textarea.ts"],"sourcesContent":["import { FxFormElement } from '../../core/form-element';\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 * Form-Associated Custom Element: dentro de um <form> entra no FormData\n * (via atributo `name`), recebe reset/disable do form e é alvo de\n * `<label for>`/`autofocus`. Enter continua sendo quebra de linha.\n *\n * Atributos: value, name, size (sm|md|lg), placeholder, disabled, readonly,\n * rows, maxlength, autofocus.\n * Eventos: `input`, `change` e `valueChange` (composed, detail: { value }) —\n * `input` aciona o v-model do Vue e `valueChange` o [(value)] do Angular.\n */\nexport class FxTextarea extends FxFormElement {\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) {\n this.setAttribute('value', value);\n // `value` NÃO é observado (re-render perderia o foco): o campo interno é\n // sincronizado aqui, sem re-render, preservando foco/cursor.\n this.syncInternalControl();\n this.updateFormValue();\n }\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 // input (v-model do Vue) + valueChange ([(value)] do Angular).\n this.emitValueEvents();\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 // Publica name/value no form (ElementInternals) a cada render.\n this.updateFormValue();\n }\n\n /** Empurra o atributo `value` para o campo interno sem re-renderizar. */\n protected override syncInternalControl(): void {\n const field = this.root.querySelector<HTMLTextAreaElement>('.field');\n const value = this.getAttr('value');\n if (field && field.value !== value) field.value = value;\n }\n}\n\nexport function defineFxTextarea(): typeof FxTextarea {\n return defineElement('fx-textarea', FxTextarea);\n}\n"],"names":[],"mappings":";;;;AAiBO,MAAM,cAAN,MAAM,oBAAmB,cAAc;AAAA,EAgE5C,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;AACvB,SAAK,aAAa,SAAS,KAAK;AAGhC,SAAK,oBAAA;AACL,SAAK,gBAAA;AAAA,EACP;AAAA,EAEmB,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;AAEnB,WAAK,gBAAA;AACL,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;AAGhF,SAAK,gBAAA;AAAA,EACP;AAAA;AAAA,EAGmB,sBAA4B;AAC7C,UAAM,QAAQ,KAAK,KAAK,cAAmC,QAAQ;AACnE,UAAM,QAAQ,KAAK,QAAQ,OAAO;AAClC,QAAI,SAAS,MAAM,UAAU,aAAa,QAAQ;AAAA,EACpD;AACF;AA5HE,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;AA+HA,SAAS,mBAAsC;AACpD,SAAO,cAAc,eAAe,UAAU;AAChD;"}
|
|
@@ -10,24 +10,24 @@
|
|
|
10
10
|
*/
|
|
11
11
|
declare const POSITIONS: readonly ["top-left", "top-center", "top-right", "bottom-left", "bottom-center", "bottom-right"];
|
|
12
12
|
export type ToastPosition = (typeof POSITIONS)[number];
|
|
13
|
-
type ToastKind =
|
|
13
|
+
type ToastKind = "success" | "error" | "info" | "warning";
|
|
14
14
|
export declare class FxToast extends HTMLElement {
|
|
15
15
|
#private;
|
|
16
16
|
static get observedAttributes(): string[];
|
|
17
17
|
/**
|
|
18
18
|
* Exibe a barra de contagem regressiva na base do card.
|
|
19
19
|
*
|
|
20
|
-
* A barra esvazia
|
|
21
|
-
*
|
|
22
|
-
* omitida — não há tempo restante a representar.
|
|
20
|
+
* A barra esvazia durante exatamente `duration` e usa a cor do `kind`.
|
|
21
|
+
* Com `duration="0"` (toast fixo) a barra é omitida — não há tempo restante.
|
|
23
22
|
*
|
|
24
23
|
* - `'always'` (ou atributo vazio): barra sempre correndo.
|
|
25
|
-
* - `'hover'`: a barra só corre enquanto o cursor estiver sobre o toast;
|
|
26
|
-
* ao sair, a animação pausa, então dá tempo de ler a mensagem.
|
|
27
24
|
* - `'paused'`: barra visível, porém parada.
|
|
25
|
+
* - `'hover'`: **compatibilidade** — equivale a `'always'`. O hover agora
|
|
26
|
+
* pausa a contagem (timer + barra) em qualquer modo, então a barra "só
|
|
27
|
+
* correr sob o cursor" deixou de fazer sentido.
|
|
28
28
|
*/
|
|
29
|
-
get progress():
|
|
30
|
-
set progress(value:
|
|
29
|
+
get progress(): "always" | "hover" | "paused" | undefined;
|
|
30
|
+
set progress(value: "always" | "hover" | "paused" | undefined);
|
|
31
31
|
/**
|
|
32
32
|
* Lado a partir do qual a barra esvazia.
|
|
33
33
|
*
|
|
@@ -39,14 +39,26 @@ export declare class FxToast extends HTMLElement {
|
|
|
39
39
|
* Só tem efeito junto com `progress`; qualquer valor fora da lista cai em
|
|
40
40
|
* `'left'`.
|
|
41
41
|
*/
|
|
42
|
-
get progressOrigin():
|
|
43
|
-
set progressOrigin(value:
|
|
42
|
+
get progressOrigin(): "left" | "right";
|
|
43
|
+
set progressOrigin(value: "left" | "right");
|
|
44
44
|
/** Duração efetiva em ms (0 = fixo). Mesma regra usada no timer. */
|
|
45
45
|
private get safeDuration();
|
|
46
46
|
/** Esquema de cores forçado do card: 'light' | 'dark' | undefined (segue o tema). */
|
|
47
|
-
get mode():
|
|
48
|
-
set mode(value:
|
|
47
|
+
get mode(): "light" | "dark" | undefined;
|
|
48
|
+
set mode(value: "light" | "dark" | undefined);
|
|
49
49
|
private timer;
|
|
50
|
+
/** Tempo restante (ms) quando a contagem está pausada no hover/foco. */
|
|
51
|
+
private remaining;
|
|
52
|
+
/** Instante em que o timer atual começou (para descontar o tempo decorrido). */
|
|
53
|
+
private startedAt;
|
|
54
|
+
/** Cursor sobre o toast: não retoma a contagem no focusout. */
|
|
55
|
+
private hovering;
|
|
56
|
+
/** Já saiu do DOM — impede retomar a contagem. */
|
|
57
|
+
private disposed;
|
|
58
|
+
/** Existe contagem regressiva (duration > 0) — toasts fixos nunca retomam. */
|
|
59
|
+
private counting;
|
|
60
|
+
/** Listeners de pausa/retomada registrados uma única vez. */
|
|
61
|
+
private wired;
|
|
50
62
|
constructor();
|
|
51
63
|
connectedCallback(): void;
|
|
52
64
|
/**
|
|
@@ -73,15 +85,15 @@ export interface ToastOptions {
|
|
|
73
85
|
* sobre o toast; `'paused'` exibe a barra cheia, porém imóvel.
|
|
74
86
|
* Sem efeito com `duration: 0` (não há tempo restante a representar).
|
|
75
87
|
*/
|
|
76
|
-
progress?:
|
|
88
|
+
progress?: "always" | "hover" | "paused";
|
|
77
89
|
/**
|
|
78
90
|
* Lado a partir do qual a barra esvazia. `'left'` (padrão) deixa a barra
|
|
79
91
|
* ancorada à esquerda; `'right'` a ancora à direita (espelhado).
|
|
80
92
|
* Só tem efeito junto com `progress`.
|
|
81
93
|
*/
|
|
82
|
-
progressOrigin?:
|
|
94
|
+
progressOrigin?: "left" | "right";
|
|
83
95
|
/** Força o esquema de cores do card, independentemente do tema global. */
|
|
84
|
-
mode?:
|
|
96
|
+
mode?: "light" | "dark";
|
|
85
97
|
}
|
|
86
98
|
declare class ToastApi {
|
|
87
99
|
private seq;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/components/toast/toast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,QAAA,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/components/toast/toast.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,QAAA,MAAM,SAAS,kGAOL,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AACvD,KAAK,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AA4K1D,qBAAa,OAAQ,SAAQ,WAAW;;IACtC,MAAM,KAAK,kBAAkB,aAW5B;IAED;;;;;;;;;;;OAWG;IACH,IAAI,QAAQ,IAAI,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAIxD;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,EAG5D;IAED;;;;;;;;;;OAUG;IACH,IAAI,cAAc,IAAI,MAAM,GAAG,OAAO,CAErC;IACD,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,EAEzC;IAED,oEAAoE;IACpE,OAAO,KAAK,YAAY,GAIvB;IAED,qFAAqF;IACrF,IAAI,IAAI,IAAI,OAAO,GAAG,MAAM,GAAG,SAAS,CAGvC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,EAG3C;IAED,OAAO,CAAC,KAAK,CAA8C;IAC3D,wEAAwE;IACxE,OAAO,CAAC,SAAS,CAAK;IACtB,gFAAgF;IAChF,OAAO,CAAC,SAAS,CAAK;IACtB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAS;IACzB,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAS;IACzB,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAS;IACzB,6DAA6D;IAC7D,OAAO,CAAC,KAAK,CAAS;;IAOtB,iBAAiB;IAiEjB;;;;;;;OAOG;IACH,oBAAoB;IASpB,wBAAwB,CAAC,IAAI,EAAE,MAAM;IAoErC,OAAO;CA2FR;AAgCD,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IACzC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACzB;AAED,cAAM,QAAQ;IACZ,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,GAAG,CAA8B;IAEzC,IAAI,CACF,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE,MAAM,GAAG,YAAY,EACrC,IAAI,CAAC,EAAE,YAAY,GAClB,MAAM;IAkCT,KAAK,CAAC,EAAE,EAAE,MAAM;IAKhB,OAAO,GAAI,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,YAAY,YAClB;IAChC,KAAK,GAAI,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,YAAY,YAClB;IAC9B,IAAI,GAAI,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,YAAY,YAClB;IAC7B,OAAO,GAAI,GAAG,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,YAAY,YAClB;CACjC;AAED,eAAO,MAAM,UAAU,UAAiB,CAAC;AAIzC,wBAAgB,aAAa,SAG5B"}
|