add preventable and reversible event helper system

This commit is contained in:
Elijah Duffy
2026-04-20 19:15:00 -07:00
parent 7e6fdc4071
commit 52cd3c6e8d
2 changed files with 64 additions and 0 deletions

View File

@@ -31,6 +31,7 @@ export { default as Label } from './Label.svelte';
export { default as Link, rewriteHref } from './Link.svelte';
export { default as PhoneInput } from './PhoneInput.svelte';
export { default as PinInput } from './PinInput.svelte';
export { type Preventable, checkPreventer, type Reversible, checkReversible } from './prevent';
export { default as RadioGroup } from './RadioGroup.svelte';
export { default as ScrollBox } from './ScrollBox.svelte';
export { default as Spinner } from './Spinner.svelte';

63
src/lib/prevent.ts Normal file
View File

@@ -0,0 +1,63 @@
/**
* A type for a function that can be prevented from executing its default behavior.
* See checkPreventer for easy usage of this type.
*/
export type Preventable<T> = (ev: T & { prevent: () => void }) => Promise<void> | void;
/**
* Calls the provided function with a preventer object, and if the preventer is not
* prevented, calls the callback function.
* @param fn The function to call with the preventer.
* @param ev The event object to pass to the function.
* @param cb The callback function to call if the preventer is not prevented.
* @returns A promise that resolves to true if the action was not prevented, or false if it was prevented.
*/
export const checkPreventer = async <T>(
fn: Preventable<T>,
ev: T,
cb?: () => void
): Promise<boolean> => {
let prevented = false;
const preventer = {
prevent: () => {
prevented = true;
}
};
await fn({ ...ev, ...preventer });
if (!prevented && cb) {
cb();
}
return !prevented;
};
/**
* A type for a function that can be reversed after executing its behavior.
* See checkReversible for easy usage of this type.
*/
export type Reversible<T> = (ev: T & { reverse: () => void }) => Promise<void> | void;
/**
* Calls the provided function with a reverser object, and if the reverser is
* reversed, calls the callback function.
* @param fn The function to call with the reverser.
* @param ev The event object to pass to the function.
* @param cb The callback function to call if the reverser is reversed.
* @returns A promise that resolves to true if the action was not reversed, or false if it was reversed.
*/
export const checkReversible = async <T>(
fn: Reversible<T>,
ev: T,
cb?: () => void
): Promise<boolean> => {
let reversed = false;
const reverser = {
reverse: () => {
reversed = true;
}
};
await fn({ ...ev, ...reverser });
if (reversed && cb) {
cb();
}
return !reversed;
};