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

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;
}