babel-plugin-jsx
babel-plugin-jsx copied to clipboard
Help How to use modifiers in events, such as @click.stop="fn"?
🧐 Problem Description
💻 Sample code
🚑 Other information
@core-admin ~~#533~~
update
import { withModifiers as _withModifiers, capitalize } from 'vue';
import type { Events } from 'vue';
type UnionOfProperties<T> = {
[K in keyof T]: SingleProperty<T, K>;
}[keyof T];
type EventObject = {
[key in keyof Events]: ((event: Events[key]) => void) | undefined;
};
type EventObjetWithModifiers = {
[eventName: string]: Function;
};
/**
* @see https://v3.vuejs.org/guide/migration/keycode-modifiers.html#keycode-modifiers
*
* @description
* Add modifier to function.
*
* @example
* <button
* class="btn"
* type="button"
* {...withModifiers(
* {
* onClick: () => {
* alert('Yeah, you clicked me! Only once, no more!');
* }
* },
* ['once']
* )}
* >
* You can click me only once!
* </button>
*/
export const withModifiers = (
eventObject: UnionOfProperties<EventObject>,
modifiers: string[]
): EventObjetWithModifiers => {
const isModifierTransformable = (modifier: string): boolean =>
(
[
'capture',
'once',
'passive'
] as string[]
).includes(modifier);
const isArrayEmpty = <T>(array: T[]): boolean => array.length === 0;
const transformableModifiers = modifiers.filter((modifier) =>
isModifierTransformable(modifier)
);
const nonTransformableModifiers = modifiers.filter(
(modifier) => !isModifierTransformable(modifier)
);
const inputEventName = Object.keys(eventObject)[0];
const inputEventFunction = Object.values(eventObject)[0] as Function;
const outputEventName = `${inputEventName}${transformableModifiers
.map(capitalize)
.join('')}`;
const outputEventFunction = isArrayEmpty(nonTransformableModifiers)
? inputEventFunction
: _withModifiers(inputEventFunction, [...nonTransformableModifiers]);
const eventObjetWithModifiers: EventObjetWithModifiers = {
[outputEventName]: outputEventFunction
};
return eventObjetWithModifiers;
};