<script>
    import { onMount } from 'svelte';
    import { slide } from 'svelte/transition';

    let extraClasses = "";
    export {extraClasses as class};
    export let slideDuration = 150;
    let animationClass = "";

    let error = null;

    function shake() {
        animationClass = 'shake';
        window.setTimeout(() => animationClass = "", 400);
    }

    export async function run(fallible) {
        try {
            const ret = await Promise.resolve(fallible());
            error = null;
            return ret;
        }
        catch (e) {
            if (error) shake();
            error = e;
            // re-throw so it can be caught by the caller if necessary
            throw e;
        }
    }

    // this is a method rather than a prop so that we can re-shake every time
    // the error occurs, even if the error message doesn't change
    export function setError(e) {
        if (error) shake();
        error = e;
    }

</script>


<style>
    /* animation from https://svelte.dev/repl/e606c27c864045e5a9700691a7417f99?version=3.58.0 */
    @keyframes shake {
        0% {
            transform: translateX(0px);
        }
        20% {
            transform: translateX(10px);
        }
        40% {
            transform: translateX(-10px);
        }
        60% {
            transform: translateX(5px);
        }
        80% {
            transform: translateX(-5px);
        }
        90% {
            transform: translateX(2px);
        }
        95% {
            transform: translateX(-2px);
        }
        100% {
            transform: translateX(0px);
        }
    }
    .shake {
        animation-name: shake;
        animation-play-state: running;
        animation-duration: 0.4s;
    }
</style>


{#if error}
    <div transition:slide="{{duration: slideDuration}}" class="alert alert-error shadow-lg {animationClass} {extraClasses}">
        <svg xmlns="http://www.w3.org/2000/svg" class="stroke-current flex-shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
        <span>
            <slot {error}>{error.msg || error}</slot>
        </span>

        {#if $$slots.buttons}
            <div>
                <slot name="buttons"></slot>
            </div>
        {/if}
    </div>
{/if}
