sveltejs / rfcs

RFCs for changes to Svelte
274 stars 81 forks source link

Prop Directives #16

Closed lukeed closed 4 years ago

lukeed commented 4 years ago

Rendered

pngwn commented 4 years ago

Unless I'm getting confused, this is already mostly possible with a noop transition function (REPL).

The only addition we would need to make is to allow transitions to receive false or null instead of a function to disable transitions. The current noop approach incurs more cost than not trying to run the function at all, as far as I'm aware.

The same is true for other directives that use functions, you can pass them as props (REPL).

lukeed commented 4 years ago

Closing this since as @pngwn pointed out, it's actually possible 🎉

<!-- Alert.svelte -->
<script>
    export let show = true;
    // NO transition by default
    export let transition = () => {};
</script>

{#if show}
<div transition:transition role="alert">
    <button type="button" class="close" on:click={onClose}>
        <span aria-hidden="true">×</span>
    </button>
    <slot/>
</div>
{/if}

<!-- Consumer.svelte -->
<script>
    import { Alert } from 'somewhere';
    import { fly } from 'svelte/transition';
    import { quintOut } from 'svelte/easing';

    let show = false;
    const transition = x => fly(x, {
        delay: 250,
        duration: 300,
        x: 100,
        y: 500,
        opacity: 0.5,
        easing: quintOut
    });
</script>

<Alert {show} {transition}>
    <p>Custom Alert that flies in/away on visibility toggle!</p>
</Alert>

At this point, I'd squabble about the syntax to make this a bit easier, but I don't think it's reason enough to keep this open or pursue at this time.

FWIW, I think something like this would be ideal:

<!-- Alert.svelte -->
<script>
    export let show = true;
</script>

{#if show}
<!-- allow any transition, in/out, or animation directives -->
<div transition:* in:* out:* animation:*  role="alert">
    <button type="button" class="close" on:click={onClose}>
        <span aria-hidden="true">×</span>
    </button>
    <slot/>
</div>
{/if}

<!-- Consumer -->
<Alert transition:fly={{ .. settings .. }}>
    <p>Custom Alert that flies in/away on visibility toggle!</p>
</Alert>