rework error alerts

This commit is contained in:
2024-06-28 20:35:18 -04:00
parent 504c0b4156
commit acc5c71bfa
13 changed files with 135 additions and 112 deletions

View File

@ -7,11 +7,34 @@
export let slideDuration = 150;
let animationClass = "";
export function shake() {
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>
@ -51,15 +74,17 @@
</style>
<div in: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></slot>
</span>
{#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 $$slots.buttons}
<div>
<slot name="buttons"></slot>
</div>
{/if}
</div>
{/if}

View File

@ -23,9 +23,9 @@
<input
type={show ? 'text' : 'password'}
{value} {placeholder} {autofocus}
on:input={e => value = e.target.value}
on:input on:change on:focus on:blur
class="input input-bordered flex-grow join-item placeholder:text-gray-500 {classes}"
on:input={e => value = e.target.value}
/>
<button

View File

@ -1,13 +1,12 @@
<script>
import { slide } from 'svelte/transition';
import ErrorAlert from '../ErrorAlert.svelte';
export let title;
</script>
<div>
<div class="flex flex-wrap justify-between gap-y-4">
<div class="flex flex-wrap justify-between gap-4">
<h3 class="text-lg font-bold shrink-0">{title}</h3>
{#if $$slots.input}
<slot name="input"></slot>