diff --git a/src/lib/teact/teact-dom.ts b/src/lib/teact/teact-dom.ts index 4219f01c7..f47df2298 100644 --- a/src/lib/teact/teact-dom.ts +++ b/src/lib/teact/teact-dom.ts @@ -1,4 +1,4 @@ -import type { ChangeEvent } from 'react'; +import type { ChangeEvent, FocusEvent } from 'react'; import type { Signal } from '../../util/signals'; import type { @@ -53,6 +53,7 @@ const MAPPED_ATTRIBUTES: { [k: string]: string } = { spellCheck: 'spellcheck', }; const INDEX_KEY_PREFIX = '__indexKey#'; +const SELECTION_STATE_ATTRIBUTE = '__teactSelectionState'; const headsByElement = new WeakMap(); const extraClasses = new WeakMap>(); @@ -702,7 +703,7 @@ function processControlled(tag: string, props: AnyLiteral) { } const { - value, checked, onInput, onChange, + value, checked, onInput, onChange, onBlur, } = props; props.onChange = undefined; @@ -721,7 +722,7 @@ function processControlled(tag: string, props: AnyLiteral) { const selectionState: SelectionState = { selectionStart, selectionEnd, isCaretAtEnd }; - e.currentTarget.dataset.__teactSelectionState = JSON.stringify(selectionState); + e.currentTarget.dataset[SELECTION_STATE_ATTRIBUTE] = JSON.stringify(selectionState); } } @@ -729,6 +730,11 @@ function processControlled(tag: string, props: AnyLiteral) { e.currentTarget.checked = checked; } }; + props.onBlur = (e: FocusEvent) => { + delete e.currentTarget.dataset[SELECTION_STATE_ATTRIBUTE]; + + onBlur?.(e); + }; } function processUncontrolledOnMount(element: DOMElement, props: AnyLiteral) { @@ -785,7 +791,7 @@ function setAttribute(element: DOMElement, key: string, value: any, namespace?: if (inputEl.value !== value) { inputEl.value = value; - const selectionStateJson = inputEl.dataset.__teactSelectionState; + const selectionStateJson = inputEl.dataset[SELECTION_STATE_ATTRIBUTE]; if (selectionStateJson) { const { selectionStart, selectionEnd, isCaretAtEnd } = JSON.parse(selectionStateJson) as SelectionState;