From 96c93cc7d688c443a2f6688efb27017cfd8c97eb Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sun, 11 Jun 2023 15:13:40 +0800 Subject: [PATCH] Make delegate change event more adaptable Allow delegate change event to other elements like select and textarea. --- .../react-next/src/utils/event.ts | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/web/kitchen-sink/react-next/src/utils/event.ts b/packages/web/kitchen-sink/react-next/src/utils/event.ts index 1455596..ae03358 100644 --- a/packages/web/kitchen-sink/react-next/src/utils/event.ts +++ b/packages/web/kitchen-sink/react-next/src/utils/event.ts @@ -1,13 +1,25 @@ +const TAG_NAME_ELEMENT_CONSTRUCTOR = { + 'INPUT': window.HTMLInputElement, + 'SELECT': window.HTMLSelectElement, + 'TEXTAREA': window.HTMLTextAreaElement, +} as const; + export const delegateTriggerChangeEvent = (target: T, value?: unknown) => { - if (target.tagName === 'INPUT') { - const inputTarget = target as unknown as HTMLInputElement; - const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set; - if (nativeInputValueSetter) { - if (inputTarget.type !== 'file') { - nativeInputValueSetter.call(inputTarget, value); - } - const simulatedEvent = new Event('change', {bubbles: true}); - inputTarget.dispatchEvent(simulatedEvent); + const { [target.tagName as keyof typeof TAG_NAME_ELEMENT_CONSTRUCTOR]: elementCtor } = TAG_NAME_ELEMENT_CONSTRUCTOR; + + if (!elementCtor) { + return; + } + + const nativeInputValueSetter = Object.getOwnPropertyDescriptor(elementCtor.prototype, 'value')?.set; + if (nativeInputValueSetter) { + if ( + (target.tagName === 'INPUT' && (target as unknown as HTMLInputElement).type !== 'file') + || target.tagName !== 'INPUT' + ) { + nativeInputValueSetter.call(target, value); } + const simulatedEvent = new Event('change', { bubbles: true }); + target.dispatchEvent(simulatedEvent); } }