Merge pull request #8716 from tchak/feat-number-input

fix(form): disable scroll wheel on number inputs
This commit is contained in:
Paul Chavard 2023-03-01 10:31:38 +00:00 committed by GitHub
commit ef970dbfe5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
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 // see: https://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
const FOCUS_EVENTS = ['focus', 'blur']; const FOCUS_EVENTS = ['focus', 'blur'];
const ACTIVE_EVENTS = ['wheel'];
export class ApplicationController extends Controller { export class ApplicationController extends Controller {
#debounced = new Map<() => void, ReturnType<typeof debounce>>(); #debounced = new Map<() => void, ReturnType<typeof debounce>>();
@ -58,12 +59,7 @@ export class ApplicationController extends Controller {
): void { ): void {
if (typeof targetOrEventName == 'string') { if (typeof targetOrEventName == 'string') {
invariant(typeof eventNameOrHandler != 'string', 'handler is required'); invariant(typeof eventNameOrHandler != 'string', 'handler is required');
this.onTarget( this.onTarget(this.element, targetOrEventName, eventNameOrHandler);
this.element,
targetOrEventName,
eventNameOrHandler,
FOCUS_EVENTS.includes(targetOrEventName)
);
} else { } else {
invariant( invariant(
typeof eventNameOrHandler == 'string', typeof eventNameOrHandler == 'string',
@ -84,16 +80,19 @@ export class ApplicationController extends Controller {
private onTarget<HandlerEvent extends Event = Event>( private onTarget<HandlerEvent extends Event = Event>(
target: EventTarget, target: EventTarget,
eventName: string, eventName: string,
handler: (event: HandlerEvent) => void, handler: (event: HandlerEvent) => void
capture?: boolean
): void { ): void {
const disconnect = this.disconnect; const disconnect = this.disconnect;
const callback = (event: Event): void => { const callback = (event: Event): void => {
handler(event as HandlerEvent); 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 = () => { this.disconnect = () => {
target.removeEventListener(eventName, callback, capture); target.removeEventListener(eventName, callback, options);
disconnect.call(this); 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) = 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' = render partial: 'layouts/skiplinks'
.page-wrapper .page-wrapper
- if feature_enabled?(:team_on_strike) - if feature_enabled?(:team_on_strike)