ankurrsinghal / svelte-legos

A framework for Svelte Utilities 💡 Current status: 87 utilities.
https://svelte-legos.surge.sh
MIT License
794 stars 27 forks source link

rfc: Introduce 'handlers' and 'transitions' modules #51

Open sbyware opened 1 year ago

sbyware commented 1 year ago

Hi! Came across this package recently and loved the idea. I have a bunch of actions/stores/transitions etc for Svelte I've written over the years and I think this is the perfect place for them!

So, what's the proposal?

I propose we add a new handlers and transitions module(s) to the codebase. For example, we can provide easy and intuitive handlers for common use cases, such as keyboard shortcuts!

Here is an example I've written for a shortcutHandler function:

import type { EventHandler } from "../lib/shared/utils/types";

export type KeyboardShortcut = {
    key: string;
    ctrl?: boolean;
    alt?: boolean;
    description?: string;
    shift?: boolean;
    condition?: boolean;
    fn: () => void;
}

export const shortcutHandler: EventHandler<KeyboardEvent, KeyboardShortcut[]> = (event, shortcuts) => {
    shortcuts.forEach((shortcut) => {
        if (
            event.key === shortcut.key &&
            event.ctrlKey === shortcut.ctrl &&
            event.altKey === shortcut.alt &&
            event.shiftKey === shortcut.shift &&
            (shortcut.condition === undefined || shortcut.condition)
        ) {
            shortcut.fn();
        }
    });
}

and we can consume it like so:

<script lang="ts">
    import { shortcutHandler, type KeyboardShortcut } from '.';

    const SHORTCUTS = [
        {
            key: 'a',
            description: 'Add a new item',
            fn: () => alert('Add a new item'),
        },
        {
            key: 'k',
            description: 'Show dialog',
            ctrl: true,
            fn: () => alert('Show dialog'),
        },
        {
            key: 's',
            description: 'Save',
            ctrl: true,
            fn: () => alert('Save'),
        }
    ] satisfies KeyboardShortcut[];
</script>

<svelte:window on:keydown={(e) => shortcutHandler(e, SHORTCUTS)} />

Same thing applies for transitions, for example - here is a "growShrinkTransition":


interface GrowShrinkParams extends TransitionParams {opacity: boolean;}

export const growShrink = (node: Element, params: GrowShrinkParams): TransitionConfig => {
    return {
        delay: params.delay || 0,
        duration: params.duration || 400,
        easing: params.easing || sineInOut,
        css: (t, u) => `
            ${params.opacity ? `opacity: ${t};` : ""}
            width: ${t};
        `
    };
};

and so on.

Let me know what everybody thinks! I also have some ideas for refactoring the frontend (for example, we really should be loading the stores, actions etc in the layout's load function instead of subsequently loading them again in a sub-page's load function and only using the loaded directories files to get the length of the total utilities etc)

sbyware commented 1 year ago

Also, maybe we could lean into the lego terminology a bit more for the structure of the codebase? Each 'module' (actions, stores etc) could be called boxes (like a box of lego!) and each box has several pieces. Just an idea haha.