Latest repo

This commit is contained in:
Marc
2025-06-02 16:42:16 +00:00
parent 53ddf1a329
commit cde5fae175
27907 changed files with 3875388 additions and 1 deletions

21
node_modules/make-event-props/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 20182023 Wojciech Maj
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

40
node_modules/make-event-props/README.md generated vendored Normal file
View File

@@ -0,0 +1,40 @@
[![npm](https://img.shields.io/npm/v/make-event-props.svg)](https://www.npmjs.com/package/make-event-props) ![downloads](https://img.shields.io/npm/dt/make-event-props.svg) [![CI](https://github.com/wojtekmaj/make-event-props/workflows/CI/badge.svg)](https://github.com/wojtekmaj/make-event-props/actions)
# Make-Event-Props
A function that, given props, returns an object of event callback props optionally curried with additional arguments.
This package allows you to pass event callback props to a rendered DOM element without the risk of applying any invalid props that could cause unwanted side effects.
## tl;dr
- Install by executing `npm install make-event-props` or `yarn add make-event-props`.
- Import by adding `import makeEventProps from 'make-event-props'`.
- Create your event props object:
```ts
const eventProps = useMemo(
() => makeEventProps(props, (eventName) => additionalArgs),
[additionalArgs],
);
```
- Use your event props:
```tsx
return <div {...eventProps} />;
```
## License
The MIT License.
## Author
<table>
<tr>
<td >
<img src="https://avatars.githubusercontent.com/u/5426427?v=4&s=128" width="64" height="64" alt="Wojciech Maj">
</td>
<td>
<a href="https://github.com/wojtekmaj">Wojciech Maj</a>
</td>
</tr>
</table>

37
node_modules/make-event-props/dist/cjs/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,37 @@
export declare const clipboardEvents: readonly ["onCopy", "onCut", "onPaste"];
export declare const compositionEvents: readonly ["onCompositionEnd", "onCompositionStart", "onCompositionUpdate"];
export declare const focusEvents: readonly ["onFocus", "onBlur"];
export declare const formEvents: readonly ["onInput", "onInvalid", "onReset", "onSubmit"];
export declare const imageEvents: readonly ["onLoad", "onError"];
export declare const keyboardEvents: readonly ["onKeyDown", "onKeyPress", "onKeyUp"];
export declare const mediaEvents: readonly ["onAbort", "onCanPlay", "onCanPlayThrough", "onDurationChange", "onEmptied", "onEncrypted", "onEnded", "onError", "onLoadedData", "onLoadedMetadata", "onLoadStart", "onPause", "onPlay", "onPlaying", "onProgress", "onRateChange", "onSeeked", "onSeeking", "onStalled", "onSuspend", "onTimeUpdate", "onVolumeChange", "onWaiting"];
export declare const mouseEvents: readonly ["onClick", "onContextMenu", "onDoubleClick", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseMove", "onMouseOut", "onMouseOver", "onMouseUp"];
export declare const dragEvents: readonly ["onDrag", "onDragEnd", "onDragEnter", "onDragExit", "onDragLeave", "onDragOver", "onDragStart", "onDrop"];
export declare const selectionEvents: readonly ["onSelect"];
export declare const touchEvents: readonly ["onTouchCancel", "onTouchEnd", "onTouchMove", "onTouchStart"];
export declare const pointerEvents: readonly ["onPointerDown", "onPointerMove", "onPointerUp", "onPointerCancel", "onGotPointerCapture", "onLostPointerCapture", "onPointerEnter", "onPointerLeave", "onPointerOver", "onPointerOut"];
export declare const uiEvents: readonly ["onScroll"];
export declare const wheelEvents: readonly ["onWheel"];
export declare const animationEvents: readonly ["onAnimationStart", "onAnimationEnd", "onAnimationIteration"];
export declare const transitionEvents: readonly ["onTransitionEnd"];
export declare const otherEvents: readonly ["onToggle"];
export declare const changeEvents: readonly ["onChange"];
export declare const allEvents: readonly ["onCopy", "onCut", "onPaste", "onCompositionEnd", "onCompositionStart", "onCompositionUpdate", "onFocus", "onBlur", "onInput", "onInvalid", "onReset", "onSubmit", "onLoad", "onError", "onKeyDown", "onKeyPress", "onKeyUp", "onAbort", "onCanPlay", "onCanPlayThrough", "onDurationChange", "onEmptied", "onEncrypted", "onEnded", "onError", "onLoadedData", "onLoadedMetadata", "onLoadStart", "onPause", "onPlay", "onPlaying", "onProgress", "onRateChange", "onSeeked", "onSeeking", "onStalled", "onSuspend", "onTimeUpdate", "onVolumeChange", "onWaiting", "onClick", "onContextMenu", "onDoubleClick", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseMove", "onMouseOut", "onMouseOver", "onMouseUp", "onDrag", "onDragEnd", "onDragEnter", "onDragExit", "onDragLeave", "onDragOver", "onDragStart", "onDrop", "onSelect", "onTouchCancel", "onTouchEnd", "onTouchMove", "onTouchStart", "onPointerDown", "onPointerMove", "onPointerUp", "onPointerCancel", "onGotPointerCapture", "onLostPointerCapture", "onPointerEnter", "onPointerLeave", "onPointerOver", "onPointerOut", "onScroll", "onWheel", "onAnimationStart", "onAnimationEnd", "onAnimationIteration", "onTransitionEnd", "onChange", "onToggle"];
type AllEvents = (typeof allEvents)[number];
type EventHandler<ArgsType> = (event: any, args: ArgsType) => void;
type EventHandlerWithoutArgs<ArgsType, OriginalEventHandler> = OriginalEventHandler extends (event: infer Event, args: ArgsType) => void ? (event: Event) => void : never;
export type EventProps<ArgsType> = {
[K in AllEvents]?: EventHandler<ArgsType>;
};
type Props<ArgsType> = Record<string, unknown> & EventProps<ArgsType>;
type EventPropsWithoutArgs<ArgsType, PropsType> = {
[K in keyof PropsType as K extends AllEvents ? K : never]: EventHandlerWithoutArgs<ArgsType, PropsType[K]>;
};
/**
* Returns an object with on-event callback props curried with provided args.
* @param {Object} props Props passed to a component.
* @param {Function=} getArgs A function that returns argument(s) on-event callbacks
* shall be curried with.
*/
export default function makeEventProps<ArgsType, PropsType extends Props<ArgsType> = Props<ArgsType>>(props: PropsType, getArgs?: (eventName: string) => ArgsType): EventPropsWithoutArgs<ArgsType, PropsType>;
export {};

120
node_modules/make-event-props/dist/cjs/index.js generated vendored Normal file
View File

@@ -0,0 +1,120 @@
"use strict";
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.allEvents = exports.changeEvents = exports.otherEvents = exports.transitionEvents = exports.animationEvents = exports.wheelEvents = exports.uiEvents = exports.pointerEvents = exports.touchEvents = exports.selectionEvents = exports.dragEvents = exports.mouseEvents = exports.mediaEvents = exports.keyboardEvents = exports.imageEvents = exports.formEvents = exports.focusEvents = exports.compositionEvents = exports.clipboardEvents = void 0;
// As defined on the list of supported events: https://reactjs.org/docs/events.html
exports.clipboardEvents = ['onCopy', 'onCut', 'onPaste'];
exports.compositionEvents = [
'onCompositionEnd',
'onCompositionStart',
'onCompositionUpdate',
];
exports.focusEvents = ['onFocus', 'onBlur'];
exports.formEvents = ['onInput', 'onInvalid', 'onReset', 'onSubmit'];
exports.imageEvents = ['onLoad', 'onError'];
exports.keyboardEvents = ['onKeyDown', 'onKeyPress', 'onKeyUp'];
exports.mediaEvents = [
'onAbort',
'onCanPlay',
'onCanPlayThrough',
'onDurationChange',
'onEmptied',
'onEncrypted',
'onEnded',
'onError',
'onLoadedData',
'onLoadedMetadata',
'onLoadStart',
'onPause',
'onPlay',
'onPlaying',
'onProgress',
'onRateChange',
'onSeeked',
'onSeeking',
'onStalled',
'onSuspend',
'onTimeUpdate',
'onVolumeChange',
'onWaiting',
];
exports.mouseEvents = [
'onClick',
'onContextMenu',
'onDoubleClick',
'onMouseDown',
'onMouseEnter',
'onMouseLeave',
'onMouseMove',
'onMouseOut',
'onMouseOver',
'onMouseUp',
];
exports.dragEvents = [
'onDrag',
'onDragEnd',
'onDragEnter',
'onDragExit',
'onDragLeave',
'onDragOver',
'onDragStart',
'onDrop',
];
exports.selectionEvents = ['onSelect'];
exports.touchEvents = ['onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart'];
exports.pointerEvents = [
'onPointerDown',
'onPointerMove',
'onPointerUp',
'onPointerCancel',
'onGotPointerCapture',
'onLostPointerCapture',
'onPointerEnter',
'onPointerLeave',
'onPointerOver',
'onPointerOut',
];
exports.uiEvents = ['onScroll'];
exports.wheelEvents = ['onWheel'];
exports.animationEvents = [
'onAnimationStart',
'onAnimationEnd',
'onAnimationIteration',
];
exports.transitionEvents = ['onTransitionEnd'];
exports.otherEvents = ['onToggle'];
exports.changeEvents = ['onChange'];
exports.allEvents = __spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], exports.clipboardEvents, true), exports.compositionEvents, true), exports.focusEvents, true), exports.formEvents, true), exports.imageEvents, true), exports.keyboardEvents, true), exports.mediaEvents, true), exports.mouseEvents, true), exports.dragEvents, true), exports.selectionEvents, true), exports.touchEvents, true), exports.pointerEvents, true), exports.uiEvents, true), exports.wheelEvents, true), exports.animationEvents, true), exports.transitionEvents, true), exports.changeEvents, true), exports.otherEvents, true);
/**
* Returns an object with on-event callback props curried with provided args.
* @param {Object} props Props passed to a component.
* @param {Function=} getArgs A function that returns argument(s) on-event callbacks
* shall be curried with.
*/
function makeEventProps(props, getArgs) {
var eventProps = {};
exports.allEvents.forEach(function (eventName) {
var eventHandler = props[eventName];
if (!eventHandler) {
return;
}
if (getArgs) {
eventProps[eventName] = (function (event) {
return eventHandler(event, getArgs(eventName));
});
}
else {
eventProps[eventName] = eventHandler;
}
});
return eventProps;
}
exports.default = makeEventProps;

View File

@@ -0,0 +1 @@
export {};

223
node_modules/make-event-props/dist/cjs/index.spec.js generated vendored Normal file
View File

@@ -0,0 +1,223 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
var jsx_runtime_1 = require("react/jsx-runtime");
var vitest_1 = require("vitest");
var index_js_1 = __importStar(require("./index.js"));
(0, vitest_1.describe)('makeEventProps()', function () {
var fakeEvent = {};
(0, vitest_1.it)('returns object with valid and only valid event callbacks', function () {
var props = {
onClick: vitest_1.vi.fn(),
someInvalidProp: vitest_1.vi.fn(),
};
var result = (0, index_js_1.default)(props);
(0, vitest_1.expect)(result).toMatchObject({ onClick: vitest_1.expect.any(Function) });
});
(0, vitest_1.it)('calls getArgs function on event invoke if given', function () {
var props = {
onClick: vitest_1.vi.fn(),
someInvalidProp: vitest_1.vi.fn(),
};
var getArgs = vitest_1.vi.fn();
var result = (0, index_js_1.default)(props, getArgs);
// getArgs shall not be invoked before a given event is fired
(0, vitest_1.expect)(getArgs).not.toHaveBeenCalled();
result.onClick(fakeEvent);
(0, vitest_1.expect)(getArgs).toHaveBeenCalledTimes(1);
(0, vitest_1.expect)(getArgs).toHaveBeenCalledWith('onClick');
});
(0, vitest_1.it)('properly calls callbacks given in props given no getArgs function', function () {
var props = {
onClick: vitest_1.vi.fn(),
};
var result = (0, index_js_1.default)(props);
result.onClick(fakeEvent);
(0, vitest_1.expect)(props.onClick).toHaveBeenCalledWith(fakeEvent);
});
(0, vitest_1.it)('properly calls callbacks given in props given getArgs function', function () {
var props = {
onClick: vitest_1.vi.fn(),
};
var getArgs = vitest_1.vi.fn();
var args = {};
getArgs.mockReturnValue(args);
var result = (0, index_js_1.default)(props, getArgs);
result.onClick(fakeEvent);
(0, vitest_1.expect)(props.onClick).toHaveBeenCalledWith(fakeEvent, args);
});
(0, vitest_1.it)('should not filter out valid event props', function () {
var props = {
onClick: vitest_1.vi.fn(),
};
var result = (0, index_js_1.default)(props);
// @ts-expect-no-error
result.onClick;
});
(0, vitest_1.it)('should filter out invalid event props', function () {
var props = {
someInvalidProp: vitest_1.vi.fn(),
};
var result = (0, index_js_1.default)(props);
// @ts-expect-error-next-line
result.someInvalidProp;
});
(0, vitest_1.it)('should allow valid onClick handler to be passed', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event) {
// Intentionally empty
},
};
// @ts-expect-no-error
(0, index_js_1.default)(props);
});
(0, vitest_1.it)('should not allow invalid onClick handler to be passed', function () {
var props = {
onClick: 'potato',
};
// @ts-expect-error-next-line
(0, index_js_1.default)(props);
});
(0, vitest_1.it)('should allow onClick handler with extra args to be passed if getArgs is provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-no-error
(0, index_js_1.default)(props, function () { return 'hello'; });
});
(0, vitest_1.it)('should not allow onClick handler with extra args to be passed if getArgs is not provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-error-next-line
(0, index_js_1.default)(props);
});
(0, vitest_1.it)('should not allow onClick handler with extra args to be passed if getArgs is provided but returns different type', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-error-next-line
(0, index_js_1.default)(props, function () { return 5; });
});
(0, vitest_1.it)('should allow div onClick handler to be passed to div', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event) {
// Intentionally empty
},
};
var result = (0, index_js_1.default)(props);
// @ts-expect-no-error
(0, jsx_runtime_1.jsx)("div", { onClick: result.onClick });
});
(0, vitest_1.it)('should not allow div onClick handler to be passed to button', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event) {
// Intentionally empty
},
};
var result = (0, index_js_1.default)(props);
// @ts-expect-error-next-line
(0, jsx_runtime_1.jsx)("button", { onClick: result.onClick });
});
(0, vitest_1.it)('should allow div onClick handler with extra args to be passed to div if getArgs is provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
var result = (0, index_js_1.default)(props, function () { return 'hello'; });
// @ts-expect-no-error
(0, jsx_runtime_1.jsx)("div", { onClick: result.onClick });
});
(0, vitest_1.it)('should not allow div onClick handler with extra args to be passed to button if getArgs is provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
var result = (0, index_js_1.default)(props, function () { return 'hello'; });
// @ts-expect-error-next-line
(0, jsx_runtime_1.jsx)("button", { onClick: result.onClick });
});
(0, vitest_1.it)('should allow onClick handler with valid extra args to be passed with args explicitly typed', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-no-error
(0, index_js_1.default)(props, function () { return 'hello'; });
});
(0, vitest_1.it)('should not allow onClick handler with invalid extra args to be passed with args explicitly typed', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-error-next-line
(0, index_js_1.default)(props, function () { return 'hello'; });
});
(0, vitest_1.it)('should allow getArgs returning valid type to be passed with args explicitly typed', function () {
var props = {};
// @ts-expect-no-error
(0, index_js_1.default)(props, function () { return 'hello'; });
});
(0, vitest_1.it)('should not allow getArgs returning invalid type to be passed with args explicitly typed', function () {
var props = {};
// @ts-expect-error-next-line
(0, index_js_1.default)(props, function () { return 5; });
});
});
(0, vitest_1.describe)('allEvents', function () {
(0, vitest_1.it)('should contain all events', function () {
var sortedAllEvents = new Set(__spreadArray([], index_js_1.allEvents, true).sort());
(0, vitest_1.expect)(sortedAllEvents).toMatchSnapshot();
});
});

3
node_modules/make-event-props/dist/cjs/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "commonjs"
}

37
node_modules/make-event-props/dist/esm/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,37 @@
export declare const clipboardEvents: readonly ["onCopy", "onCut", "onPaste"];
export declare const compositionEvents: readonly ["onCompositionEnd", "onCompositionStart", "onCompositionUpdate"];
export declare const focusEvents: readonly ["onFocus", "onBlur"];
export declare const formEvents: readonly ["onInput", "onInvalid", "onReset", "onSubmit"];
export declare const imageEvents: readonly ["onLoad", "onError"];
export declare const keyboardEvents: readonly ["onKeyDown", "onKeyPress", "onKeyUp"];
export declare const mediaEvents: readonly ["onAbort", "onCanPlay", "onCanPlayThrough", "onDurationChange", "onEmptied", "onEncrypted", "onEnded", "onError", "onLoadedData", "onLoadedMetadata", "onLoadStart", "onPause", "onPlay", "onPlaying", "onProgress", "onRateChange", "onSeeked", "onSeeking", "onStalled", "onSuspend", "onTimeUpdate", "onVolumeChange", "onWaiting"];
export declare const mouseEvents: readonly ["onClick", "onContextMenu", "onDoubleClick", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseMove", "onMouseOut", "onMouseOver", "onMouseUp"];
export declare const dragEvents: readonly ["onDrag", "onDragEnd", "onDragEnter", "onDragExit", "onDragLeave", "onDragOver", "onDragStart", "onDrop"];
export declare const selectionEvents: readonly ["onSelect"];
export declare const touchEvents: readonly ["onTouchCancel", "onTouchEnd", "onTouchMove", "onTouchStart"];
export declare const pointerEvents: readonly ["onPointerDown", "onPointerMove", "onPointerUp", "onPointerCancel", "onGotPointerCapture", "onLostPointerCapture", "onPointerEnter", "onPointerLeave", "onPointerOver", "onPointerOut"];
export declare const uiEvents: readonly ["onScroll"];
export declare const wheelEvents: readonly ["onWheel"];
export declare const animationEvents: readonly ["onAnimationStart", "onAnimationEnd", "onAnimationIteration"];
export declare const transitionEvents: readonly ["onTransitionEnd"];
export declare const otherEvents: readonly ["onToggle"];
export declare const changeEvents: readonly ["onChange"];
export declare const allEvents: readonly ["onCopy", "onCut", "onPaste", "onCompositionEnd", "onCompositionStart", "onCompositionUpdate", "onFocus", "onBlur", "onInput", "onInvalid", "onReset", "onSubmit", "onLoad", "onError", "onKeyDown", "onKeyPress", "onKeyUp", "onAbort", "onCanPlay", "onCanPlayThrough", "onDurationChange", "onEmptied", "onEncrypted", "onEnded", "onError", "onLoadedData", "onLoadedMetadata", "onLoadStart", "onPause", "onPlay", "onPlaying", "onProgress", "onRateChange", "onSeeked", "onSeeking", "onStalled", "onSuspend", "onTimeUpdate", "onVolumeChange", "onWaiting", "onClick", "onContextMenu", "onDoubleClick", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseMove", "onMouseOut", "onMouseOver", "onMouseUp", "onDrag", "onDragEnd", "onDragEnter", "onDragExit", "onDragLeave", "onDragOver", "onDragStart", "onDrop", "onSelect", "onTouchCancel", "onTouchEnd", "onTouchMove", "onTouchStart", "onPointerDown", "onPointerMove", "onPointerUp", "onPointerCancel", "onGotPointerCapture", "onLostPointerCapture", "onPointerEnter", "onPointerLeave", "onPointerOver", "onPointerOut", "onScroll", "onWheel", "onAnimationStart", "onAnimationEnd", "onAnimationIteration", "onTransitionEnd", "onChange", "onToggle"];
type AllEvents = (typeof allEvents)[number];
type EventHandler<ArgsType> = (event: any, args: ArgsType) => void;
type EventHandlerWithoutArgs<ArgsType, OriginalEventHandler> = OriginalEventHandler extends (event: infer Event, args: ArgsType) => void ? (event: Event) => void : never;
export type EventProps<ArgsType> = {
[K in AllEvents]?: EventHandler<ArgsType>;
};
type Props<ArgsType> = Record<string, unknown> & EventProps<ArgsType>;
type EventPropsWithoutArgs<ArgsType, PropsType> = {
[K in keyof PropsType as K extends AllEvents ? K : never]: EventHandlerWithoutArgs<ArgsType, PropsType[K]>;
};
/**
* Returns an object with on-event callback props curried with provided args.
* @param {Object} props Props passed to a component.
* @param {Function=} getArgs A function that returns argument(s) on-event callbacks
* shall be curried with.
*/
export default function makeEventProps<ArgsType, PropsType extends Props<ArgsType> = Props<ArgsType>>(props: PropsType, getArgs?: (eventName: string) => ArgsType): EventPropsWithoutArgs<ArgsType, PropsType>;
export {};

116
node_modules/make-event-props/dist/esm/index.js generated vendored Normal file
View File

@@ -0,0 +1,116 @@
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
// As defined on the list of supported events: https://reactjs.org/docs/events.html
export var clipboardEvents = ['onCopy', 'onCut', 'onPaste'];
export var compositionEvents = [
'onCompositionEnd',
'onCompositionStart',
'onCompositionUpdate',
];
export var focusEvents = ['onFocus', 'onBlur'];
export var formEvents = ['onInput', 'onInvalid', 'onReset', 'onSubmit'];
export var imageEvents = ['onLoad', 'onError'];
export var keyboardEvents = ['onKeyDown', 'onKeyPress', 'onKeyUp'];
export var mediaEvents = [
'onAbort',
'onCanPlay',
'onCanPlayThrough',
'onDurationChange',
'onEmptied',
'onEncrypted',
'onEnded',
'onError',
'onLoadedData',
'onLoadedMetadata',
'onLoadStart',
'onPause',
'onPlay',
'onPlaying',
'onProgress',
'onRateChange',
'onSeeked',
'onSeeking',
'onStalled',
'onSuspend',
'onTimeUpdate',
'onVolumeChange',
'onWaiting',
];
export var mouseEvents = [
'onClick',
'onContextMenu',
'onDoubleClick',
'onMouseDown',
'onMouseEnter',
'onMouseLeave',
'onMouseMove',
'onMouseOut',
'onMouseOver',
'onMouseUp',
];
export var dragEvents = [
'onDrag',
'onDragEnd',
'onDragEnter',
'onDragExit',
'onDragLeave',
'onDragOver',
'onDragStart',
'onDrop',
];
export var selectionEvents = ['onSelect'];
export var touchEvents = ['onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart'];
export var pointerEvents = [
'onPointerDown',
'onPointerMove',
'onPointerUp',
'onPointerCancel',
'onGotPointerCapture',
'onLostPointerCapture',
'onPointerEnter',
'onPointerLeave',
'onPointerOver',
'onPointerOut',
];
export var uiEvents = ['onScroll'];
export var wheelEvents = ['onWheel'];
export var animationEvents = [
'onAnimationStart',
'onAnimationEnd',
'onAnimationIteration',
];
export var transitionEvents = ['onTransitionEnd'];
export var otherEvents = ['onToggle'];
export var changeEvents = ['onChange'];
export var allEvents = __spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], clipboardEvents, true), compositionEvents, true), focusEvents, true), formEvents, true), imageEvents, true), keyboardEvents, true), mediaEvents, true), mouseEvents, true), dragEvents, true), selectionEvents, true), touchEvents, true), pointerEvents, true), uiEvents, true), wheelEvents, true), animationEvents, true), transitionEvents, true), changeEvents, true), otherEvents, true);
/**
* Returns an object with on-event callback props curried with provided args.
* @param {Object} props Props passed to a component.
* @param {Function=} getArgs A function that returns argument(s) on-event callbacks
* shall be curried with.
*/
export default function makeEventProps(props, getArgs) {
var eventProps = {};
allEvents.forEach(function (eventName) {
var eventHandler = props[eventName];
if (!eventHandler) {
return;
}
if (getArgs) {
eventProps[eventName] = (function (event) {
return eventHandler(event, getArgs(eventName));
});
}
else {
eventProps[eventName] = eventHandler;
}
});
return eventProps;
}

View File

@@ -0,0 +1 @@
export {};

199
node_modules/make-event-props/dist/esm/index.spec.js generated vendored Normal file
View File

@@ -0,0 +1,199 @@
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import { jsx as _jsx } from "react/jsx-runtime";
import { describe, expect, it, vi } from 'vitest';
import React from 'react';
import makeEventProps, { allEvents } from './index.js';
describe('makeEventProps()', function () {
var fakeEvent = {};
it('returns object with valid and only valid event callbacks', function () {
var props = {
onClick: vi.fn(),
someInvalidProp: vi.fn(),
};
var result = makeEventProps(props);
expect(result).toMatchObject({ onClick: expect.any(Function) });
});
it('calls getArgs function on event invoke if given', function () {
var props = {
onClick: vi.fn(),
someInvalidProp: vi.fn(),
};
var getArgs = vi.fn();
var result = makeEventProps(props, getArgs);
// getArgs shall not be invoked before a given event is fired
expect(getArgs).not.toHaveBeenCalled();
result.onClick(fakeEvent);
expect(getArgs).toHaveBeenCalledTimes(1);
expect(getArgs).toHaveBeenCalledWith('onClick');
});
it('properly calls callbacks given in props given no getArgs function', function () {
var props = {
onClick: vi.fn(),
};
var result = makeEventProps(props);
result.onClick(fakeEvent);
expect(props.onClick).toHaveBeenCalledWith(fakeEvent);
});
it('properly calls callbacks given in props given getArgs function', function () {
var props = {
onClick: vi.fn(),
};
var getArgs = vi.fn();
var args = {};
getArgs.mockReturnValue(args);
var result = makeEventProps(props, getArgs);
result.onClick(fakeEvent);
expect(props.onClick).toHaveBeenCalledWith(fakeEvent, args);
});
it('should not filter out valid event props', function () {
var props = {
onClick: vi.fn(),
};
var result = makeEventProps(props);
// @ts-expect-no-error
result.onClick;
});
it('should filter out invalid event props', function () {
var props = {
someInvalidProp: vi.fn(),
};
var result = makeEventProps(props);
// @ts-expect-error-next-line
result.someInvalidProp;
});
it('should allow valid onClick handler to be passed', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event) {
// Intentionally empty
},
};
// @ts-expect-no-error
makeEventProps(props);
});
it('should not allow invalid onClick handler to be passed', function () {
var props = {
onClick: 'potato',
};
// @ts-expect-error-next-line
makeEventProps(props);
});
it('should allow onClick handler with extra args to be passed if getArgs is provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-no-error
makeEventProps(props, function () { return 'hello'; });
});
it('should not allow onClick handler with extra args to be passed if getArgs is not provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-error-next-line
makeEventProps(props);
});
it('should not allow onClick handler with extra args to be passed if getArgs is provided but returns different type', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-error-next-line
makeEventProps(props, function () { return 5; });
});
it('should allow div onClick handler to be passed to div', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event) {
// Intentionally empty
},
};
var result = makeEventProps(props);
// @ts-expect-no-error
_jsx("div", { onClick: result.onClick });
});
it('should not allow div onClick handler to be passed to button', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event) {
// Intentionally empty
},
};
var result = makeEventProps(props);
// @ts-expect-error-next-line
_jsx("button", { onClick: result.onClick });
});
it('should allow div onClick handler with extra args to be passed to div if getArgs is provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
var result = makeEventProps(props, function () { return 'hello'; });
// @ts-expect-no-error
_jsx("div", { onClick: result.onClick });
});
it('should not allow div onClick handler with extra args to be passed to button if getArgs is provided', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
var result = makeEventProps(props, function () { return 'hello'; });
// @ts-expect-error-next-line
_jsx("button", { onClick: result.onClick });
});
it('should allow onClick handler with valid extra args to be passed with args explicitly typed', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-no-error
makeEventProps(props, function () { return 'hello'; });
});
it('should not allow onClick handler with invalid extra args to be passed with args explicitly typed', function () {
var props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: function (event, args) {
// Intentionally empty
},
};
// @ts-expect-error-next-line
makeEventProps(props, function () { return 'hello'; });
});
it('should allow getArgs returning valid type to be passed with args explicitly typed', function () {
var props = {};
// @ts-expect-no-error
makeEventProps(props, function () { return 'hello'; });
});
it('should not allow getArgs returning invalid type to be passed with args explicitly typed', function () {
var props = {};
// @ts-expect-error-next-line
makeEventProps(props, function () { return 5; });
});
});
describe('allEvents', function () {
it('should contain all events', function () {
var sortedAllEvents = new Set(__spreadArray([], allEvents, true).sort());
expect(sortedAllEvents).toMatchSnapshot();
});
});

65
node_modules/make-event-props/package.json generated vendored Normal file
View File

@@ -0,0 +1,65 @@
{
"name": "make-event-props",
"version": "1.6.2",
"description": "Returns an object with on-event callback props curried with provided args.",
"type": "module",
"sideEffects": false,
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"source": "./src/index.ts",
"types": "./dist/cjs/index.d.ts",
"exports": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js"
},
"scripts": {
"build": "yarn build-esm && yarn build-cjs && yarn build-cjs-package",
"build-esm": "tsc --project tsconfig.build.json --outDir dist/esm",
"build-cjs": "tsc --project tsconfig.build.json --outDir dist/cjs --module commonjs --verbatimModuleSyntax false",
"build-cjs-package": "echo '{\n \"type\": \"commonjs\"\n}' > dist/cjs/package.json",
"clean": "rimraf dist",
"lint": "eslint .",
"prepack": "yarn clean && yarn build",
"prettier": "prettier --check . --cache",
"test": "yarn lint && yarn tsc && yarn prettier && yarn unit",
"tsc": "tsc --noEmit",
"unit": "vitest"
},
"keywords": [
"react",
"event",
"event props"
],
"author": {
"name": "Wojciech Maj",
"email": "kontakt@wojtekmaj.pl"
},
"license": "MIT",
"devDependencies": {
"@types/react": "*",
"eslint": "^8.26.0",
"eslint-config-wojtekmaj": "^0.9.0",
"husky": "^8.0.0",
"lint-staged": "^14.0.0",
"prettier": "^3.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rimraf": "^3.0.0",
"typescript": "^5.0.0",
"vitest": "^0.34.0"
},
"publishConfig": {
"access": "public",
"provenance": true
},
"files": [
"dist",
"src"
],
"repository": {
"type": "git",
"url": "https://github.com/wojtekmaj/make-event-props.git"
},
"funding": "https://github.com/wojtekmaj/make-event-props?sponsor=1",
"packageManager": "yarn@3.1.0"
}

View File

@@ -0,0 +1,86 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`allEvents > should contain all events 1`] = `
Set {
"onAbort",
"onAnimationEnd",
"onAnimationIteration",
"onAnimationStart",
"onBlur",
"onCanPlay",
"onCanPlayThrough",
"onChange",
"onClick",
"onCompositionEnd",
"onCompositionStart",
"onCompositionUpdate",
"onContextMenu",
"onCopy",
"onCut",
"onDoubleClick",
"onDrag",
"onDragEnd",
"onDragEnter",
"onDragExit",
"onDragLeave",
"onDragOver",
"onDragStart",
"onDrop",
"onDurationChange",
"onEmptied",
"onEncrypted",
"onEnded",
"onError",
"onFocus",
"onGotPointerCapture",
"onInput",
"onInvalid",
"onKeyDown",
"onKeyPress",
"onKeyUp",
"onLoad",
"onLoadStart",
"onLoadedData",
"onLoadedMetadata",
"onLostPointerCapture",
"onMouseDown",
"onMouseEnter",
"onMouseLeave",
"onMouseMove",
"onMouseOut",
"onMouseOver",
"onMouseUp",
"onPaste",
"onPause",
"onPlay",
"onPlaying",
"onPointerCancel",
"onPointerDown",
"onPointerEnter",
"onPointerLeave",
"onPointerMove",
"onPointerOut",
"onPointerOver",
"onPointerUp",
"onProgress",
"onRateChange",
"onReset",
"onScroll",
"onSeeked",
"onSeeking",
"onSelect",
"onStalled",
"onSubmit",
"onSuspend",
"onTimeUpdate",
"onToggle",
"onTouchCancel",
"onTouchEnd",
"onTouchMove",
"onTouchStart",
"onTransitionEnd",
"onVolumeChange",
"onWaiting",
"onWheel",
}
`;

240
node_modules/make-event-props/src/index.spec.tsx generated vendored Normal file
View File

@@ -0,0 +1,240 @@
import { describe, expect, it, vi } from 'vitest';
import React from 'react';
import makeEventProps, { allEvents } from './index.js';
describe('makeEventProps()', () => {
const fakeEvent = {};
it('returns object with valid and only valid event callbacks', () => {
const props = {
onClick: vi.fn(),
someInvalidProp: vi.fn(),
};
const result = makeEventProps(props);
expect(result).toMatchObject({ onClick: expect.any(Function) });
});
it('calls getArgs function on event invoke if given', () => {
const props = {
onClick: vi.fn(),
someInvalidProp: vi.fn(),
};
const getArgs = vi.fn();
const result = makeEventProps(props, getArgs);
// getArgs shall not be invoked before a given event is fired
expect(getArgs).not.toHaveBeenCalled();
result.onClick(fakeEvent);
expect(getArgs).toHaveBeenCalledTimes(1);
expect(getArgs).toHaveBeenCalledWith('onClick');
});
it('properly calls callbacks given in props given no getArgs function', () => {
const props = {
onClick: vi.fn(),
};
const result = makeEventProps(props);
result.onClick(fakeEvent);
expect(props.onClick).toHaveBeenCalledWith(fakeEvent);
});
it('properly calls callbacks given in props given getArgs function', () => {
const props = {
onClick: vi.fn(),
};
const getArgs = vi.fn();
const args = {};
getArgs.mockReturnValue(args);
const result = makeEventProps(props, getArgs);
result.onClick(fakeEvent);
expect(props.onClick).toHaveBeenCalledWith(fakeEvent, args);
});
it('should not filter out valid event props', () => {
const props = {
onClick: vi.fn(),
};
const result = makeEventProps(props);
// @ts-expect-no-error
result.onClick;
});
it('should filter out invalid event props', () => {
const props = {
someInvalidProp: vi.fn(),
};
const result = makeEventProps(props);
// @ts-expect-error-next-line
result.someInvalidProp;
});
it('should allow valid onClick handler to be passed', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent) => {
// Intentionally empty
},
};
// @ts-expect-no-error
makeEventProps(props);
});
it('should not allow invalid onClick handler to be passed', () => {
const props = {
onClick: 'potato',
};
// @ts-expect-error-next-line
makeEventProps(props);
});
it('should allow onClick handler with extra args to be passed if getArgs is provided', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent, args: string) => {
// Intentionally empty
},
};
// @ts-expect-no-error
makeEventProps(props, () => 'hello');
});
it('should not allow onClick handler with extra args to be passed if getArgs is not provided', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent, args: string) => {
// Intentionally empty
},
};
// @ts-expect-error-next-line
makeEventProps(props);
});
it('should not allow onClick handler with extra args to be passed if getArgs is provided but returns different type', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent, args: string) => {
// Intentionally empty
},
};
// @ts-expect-error-next-line
makeEventProps(props, () => 5);
});
it('should allow div onClick handler to be passed to div', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent<HTMLDivElement>) => {
// Intentionally empty
},
};
const result = makeEventProps(props);
// @ts-expect-no-error
<div onClick={result.onClick} />;
});
it('should not allow div onClick handler to be passed to button', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent<HTMLDivElement>) => {
// Intentionally empty
},
};
const result = makeEventProps(props);
// @ts-expect-error-next-line
<button onClick={result.onClick} />;
});
it('should allow div onClick handler with extra args to be passed to div if getArgs is provided', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent<HTMLDivElement>, args: string) => {
// Intentionally empty
},
};
const result = makeEventProps(props, () => 'hello');
// @ts-expect-no-error
<div onClick={result.onClick} />;
});
it('should not allow div onClick handler with extra args to be passed to button if getArgs is provided', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent<HTMLDivElement>, args: string) => {
// Intentionally empty
},
};
const result = makeEventProps(props, () => 'hello');
// @ts-expect-error-next-line
<button onClick={result.onClick} />;
});
it('should allow onClick handler with valid extra args to be passed with args explicitly typed', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent<HTMLDivElement>, args: string) => {
// Intentionally empty
},
};
// @ts-expect-no-error
makeEventProps<string>(props, () => 'hello');
});
it('should not allow onClick handler with invalid extra args to be passed with args explicitly typed', () => {
const props = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (event: React.MouseEvent<HTMLDivElement>, args: number) => {
// Intentionally empty
},
};
// @ts-expect-error-next-line
makeEventProps<string>(props, () => 'hello');
});
it('should allow getArgs returning valid type to be passed with args explicitly typed', () => {
const props = {};
// @ts-expect-no-error
makeEventProps<string>(props, () => 'hello');
});
it('should not allow getArgs returning invalid type to be passed with args explicitly typed', () => {
const props = {};
// @ts-expect-error-next-line
makeEventProps<string>(props, () => 5);
});
});
describe('allEvents', () => {
it('should contain all events', () => {
const sortedAllEvents = new Set([...allEvents].sort());
expect(sortedAllEvents).toMatchSnapshot();
});
});

167
node_modules/make-event-props/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,167 @@
// As defined on the list of supported events: https://reactjs.org/docs/events.html
export const clipboardEvents = ['onCopy', 'onCut', 'onPaste'] as const;
export const compositionEvents = [
'onCompositionEnd',
'onCompositionStart',
'onCompositionUpdate',
] as const;
export const focusEvents = ['onFocus', 'onBlur'] as const;
export const formEvents = ['onInput', 'onInvalid', 'onReset', 'onSubmit'] as const;
export const imageEvents = ['onLoad', 'onError'] as const;
export const keyboardEvents = ['onKeyDown', 'onKeyPress', 'onKeyUp'] as const;
export const mediaEvents = [
'onAbort',
'onCanPlay',
'onCanPlayThrough',
'onDurationChange',
'onEmptied',
'onEncrypted',
'onEnded',
'onError',
'onLoadedData',
'onLoadedMetadata',
'onLoadStart',
'onPause',
'onPlay',
'onPlaying',
'onProgress',
'onRateChange',
'onSeeked',
'onSeeking',
'onStalled',
'onSuspend',
'onTimeUpdate',
'onVolumeChange',
'onWaiting',
] as const;
export const mouseEvents = [
'onClick',
'onContextMenu',
'onDoubleClick',
'onMouseDown',
'onMouseEnter',
'onMouseLeave',
'onMouseMove',
'onMouseOut',
'onMouseOver',
'onMouseUp',
] as const;
export const dragEvents = [
'onDrag',
'onDragEnd',
'onDragEnter',
'onDragExit',
'onDragLeave',
'onDragOver',
'onDragStart',
'onDrop',
] as const;
export const selectionEvents = ['onSelect'] as const;
export const touchEvents = ['onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart'] as const;
export const pointerEvents = [
'onPointerDown',
'onPointerMove',
'onPointerUp',
'onPointerCancel',
'onGotPointerCapture',
'onLostPointerCapture',
'onPointerEnter',
'onPointerLeave',
'onPointerOver',
'onPointerOut',
] as const;
export const uiEvents = ['onScroll'] as const;
export const wheelEvents = ['onWheel'] as const;
export const animationEvents = [
'onAnimationStart',
'onAnimationEnd',
'onAnimationIteration',
] as const;
export const transitionEvents = ['onTransitionEnd'] as const;
export const otherEvents = ['onToggle'] as const;
export const changeEvents = ['onChange'] as const;
export const allEvents = [
...clipboardEvents,
...compositionEvents,
...focusEvents,
...formEvents,
...imageEvents,
...keyboardEvents,
...mediaEvents,
...mouseEvents,
...dragEvents,
...selectionEvents,
...touchEvents,
...pointerEvents,
...uiEvents,
...wheelEvents,
...animationEvents,
...transitionEvents,
...changeEvents,
...otherEvents,
] as const;
type AllEvents = (typeof allEvents)[number];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type EventHandler<ArgsType> = (event: any, args: ArgsType) => void;
// Creates inferred type for event handler without args.
type EventHandlerWithoutArgs<ArgsType, OriginalEventHandler> = OriginalEventHandler extends (
event: infer Event,
args: ArgsType,
) => void
? (event: Event) => void
: never;
export type EventProps<ArgsType> = {
[K in AllEvents]?: EventHandler<ArgsType>;
};
type Props<ArgsType> = Record<string, unknown> & EventProps<ArgsType>;
type EventPropsWithoutArgs<ArgsType, PropsType> = {
[K in keyof PropsType as K extends AllEvents ? K : never]: EventHandlerWithoutArgs<
ArgsType,
PropsType[K]
>;
};
/**
* Returns an object with on-event callback props curried with provided args.
* @param {Object} props Props passed to a component.
* @param {Function=} getArgs A function that returns argument(s) on-event callbacks
* shall be curried with.
*/
export default function makeEventProps<
ArgsType,
PropsType extends Props<ArgsType> = Props<ArgsType>,
>(
props: PropsType,
getArgs?: (eventName: string) => ArgsType,
): EventPropsWithoutArgs<ArgsType, PropsType> {
const eventProps: EventPropsWithoutArgs<ArgsType, PropsType> = {} as EventPropsWithoutArgs<
ArgsType,
PropsType
>;
allEvents.forEach((eventName) => {
type EventHandlerType = EventPropsWithoutArgs<ArgsType, PropsType>[typeof eventName];
const eventHandler = props[eventName];
if (!eventHandler) {
return;
}
if (getArgs) {
eventProps[eventName] = ((event) =>
eventHandler(event, getArgs(eventName))) as EventHandlerType;
} else {
eventProps[eventName] = eventHandler as EventHandlerType;
}
});
return eventProps;
}