fix(form): disable scroll wheel on number inputs

This commit is contained in:
Paul Chavard 2023-03-01 11:07:52 +01:00
parent c8571f0ee4
commit 983c533eef
3 changed files with 26 additions and 11 deletions

View file

@ -6,6 +6,7 @@ export type Detail = Record<string, unknown>;
// see: https://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
const FOCUS_EVENTS = ['focus', 'blur'];
const ACTIVE_EVENTS = ['wheel'];
export class ApplicationController extends Controller {
#debounced = new Map<() => void, ReturnType<typeof debounce>>();
@ -58,12 +59,7 @@ export class ApplicationController extends Controller {
): void {
if (typeof targetOrEventName == 'string') {
invariant(typeof eventNameOrHandler != 'string', 'handler is required');
this.onTarget(
this.element,
targetOrEventName,
eventNameOrHandler,
FOCUS_EVENTS.includes(targetOrEventName)
);
this.onTarget(this.element, targetOrEventName, eventNameOrHandler);
} else {
invariant(
typeof eventNameOrHandler == 'string',
@ -84,16 +80,19 @@ export class ApplicationController extends Controller {
private onTarget<HandlerEvent extends Event = Event>(
target: EventTarget,
eventName: string,
handler: (event: HandlerEvent) => void,
capture?: boolean
handler: (event: HandlerEvent) => void
): void {
const disconnect = this.disconnect;
const callback = (event: Event): void => {
handler(event as HandlerEvent);
};
target.addEventListener(eventName, callback, capture);
const options = {
capture: FOCUS_EVENTS.includes(eventName),
passive: ACTIVE_EVENTS.includes(eventName) ? false : undefined
};
target.addEventListener(eventName, callback, options);
this.disconnect = () => {
target.removeEventListener(eventName, callback, capture);
target.removeEventListener(eventName, callback, options);
disconnect.call(this);
};
}

View file

@ -0,0 +1,16 @@
import { isInputElement } from '@coldwired/utils';
import { ApplicationController } from './application_controller';
export class NumberInputController extends ApplicationController {
connect() {
this.onGlobal('wheel', (event) => {
if (
isInputElement(event.target) &&
event.target.type == 'number' &&
document.activeElement == event.target
) {
event.preventDefault();
}
});
}
}

View file

@ -35,7 +35,7 @@
= yield(:invisible_captcha_styles)
%body{ { id: content_for(:page_id), class: browser.platform.ios? ? 'ios' : nil, data: { controller: 'turbo' } }.compact }
%body{ { id: content_for(:page_id), class: browser.platform.ios? ? 'ios' : nil, data: { controller: 'turbo number-input' } }.compact }
= render partial: 'layouts/skiplinks'
.page-wrapper
- if feature_enabled?(:team_on_strike)