Skip to content

Commit

Permalink
feat: Add visible timer to individual alerts
Browse files Browse the repository at this point in the history
  • Loading branch information
Mitcheljager committed Aug 19, 2023
1 parent 4ff03f6 commit 46a4a79
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 10 deletions.
18 changes: 18 additions & 0 deletions app/assets/stylesheets/elements/_alert.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
}

.alert {
position: relative;
display: flex;
align-items: center;
gap: 1em;
Expand All @@ -28,6 +29,7 @@
border-radius: $border-radius;
background: $green;
box-shadow: 0 10px 10px rgba($black, .5);
overflow: hidden;
color: $pure-white;
font-size: 14px;
text-decoration: none;
Expand Down Expand Up @@ -63,3 +65,19 @@
background: darken($orange, 8%);
}
}

@keyframes deplete-timer {
to {
width: 0%;
}
}

.alert__timer {
position: absolute;
bottom: 0;
left: 0;
height: 0.15rem;
width: 100%;
background: rgba($pure-white, 0.75);
animation: deplete-timer var(--timer) forwards linear;
}
27 changes: 27 additions & 0 deletions app/javascript/src/components/Alert.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script>
import { onMount, onDestroy, createEventDispatcher } from "svelte"
export let text = ""
export let type = ""
export let key = ""
const timer = 5000
const dispatch = createEventDispatcher()
let timeout
onMount(() => setTimeout(close, timer))
onDestroy(() => { if (timeout) clearTimeout(timeout) })
function close() {
dispatch("close", key)
}
</script>

<div class="alert {type} static">
<p class="m-0">{text}</p>

<button class="button p-0 pl-1/16 pr-1/16 text-pure-white" on:click={close}>✕</button>

<div class="alert__timer" style="--timer: {timer}ms" />
</div>
15 changes: 5 additions & 10 deletions app/javascript/src/components/Alerts.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script>
import Alert from "./Alert.svelte"
import { slide } from "svelte/transition"
// When alerts are passed from rails they are passed as a string
// that is an array of arrays shaped like [[type, text], [type, text]]
export let initialAlerts = ""
const timeout = 3000
let alerts = []
$: if (initialAlerts) JSON.parse(initialAlerts)?.forEach(([type, text]) => add({ text, type: `alert--${ type }` }))
Expand All @@ -15,21 +14,17 @@
alerts = [...alerts, { ...alert, key: Math.random() }]
}
function close(index) {
alerts = alerts.filter((_, i) => i !== index)
function close(key) {
alerts = alerts.filter((a) => a.key !== key)
}
</script>
<svelte:window on:alert={({ detail }) => add(detail)} />
<div class="alerts">
{#each alerts as { text, type, key }, i (key)}
{#each alerts as { text, type, key } (key)}
<div transition:slide={{ duration: 200 }}>
<div class="alert {type} static">
<p class="m-0">{text}</p>
<button class="button p-0 pl-1/16 pr-1/16 text-pure-white" on:click={() => close(i)}></button>
</div>
<Alert {text} {type} {key} on:close={({ detail }) => close(detail)} />
</div>
{/each}
</div>

0 comments on commit 46a4a79

Please sign in to comment.