Snack Bar
Deliver a quick and brief message to the user.
<div class="o-snack o-flow"
x-data="{
notifications: [],
add(e) {
this.notifications.push({
id: e.timeStamp,
type: e.detail.type,
content: e.detail.content,
duration: e.detail.duration,
})
},
remove(notification) {
this.notifications = this.notifications.filter(i => i.id !== notification.id)
},
}"
@snack.window="add($event)"
role="status"
aria-live="polite"
>
<!-- Notification --->
<template x-for="notification in notifications" :key="notification.id">
<aside class="c-message"
:class="{ 'c-message--positive': notification.type === 'success', 'c-message--negative': notification.type === 'error' }"
x-data="{
show: false,
init() {
this.$nextTick(() => this.show = true)
setTimeout(() => this.transitionOut(), this.notification.duration)
},
transitionOut() {
this.show = false
setTimeout(() => this.remove(this.notification), 500)
}
}"
x-show="show"
x-transition.duration.500ms
>
<div class="c-message__wrapper">
<!-- Icons -->
<svg class="c-message__icon c-icon | u-tc-primary u-mt-xxs" viewbox="0 0 16 16" aria-hidden="true"
x-show="notification.type === 'info'"
>
<path fill="none" fill-rule="evenodd" stroke-width="1.5" d="M7.993 15a7 7 0 1 1 .014-14 7 7 0 0 1-.014 14Z"/>
<path d="M10 12H7V9H6V7h3v3h1v2ZM9 6H7V4h2v2Z"/>
</svg>
<svg class="c-message__icon c-icon" viewbox="0 0 16 16" aria-hidden="true"
x-show="notification.type === 'success'"
>
<path d="M8.104 0A8 8 0 0 1 8 16a8.009 8.009 0 0 1-8-8v-.16A8 8 0 0 1 8.104 0Zm3.966 4.803a.9.9 0 0 0-1.267.127l-3.87 4.73-1.797-1.796a.9.9 0 1 0-1.272 1.272l2.5 2.5a.9.9 0 0 0 1.333-.066l4.5-5.5a.9.9 0 0 0-.127-1.267Z"/>
</svg>
<svg class="c-message__icon c-icon" viewbox="0 0 16 16" aria-hidden="true"
x-show="notification.type === 'error'"
>
<path fill-rule="nonzero" d="M8.003 0a8 8 0 1 1-.006 16 8 8 0 0 1 .006-16ZM8 10a1 1 0 1 0 0 2 1 1 0 0 0 0-2Zm0-6a1 1 0 0 0-1 1v3a1 1 0 1 0 2 0V5a1 1 0 0 0-1-1Z"/>
</svg>
<!-- Text -->
<div class="c-message__body | o-flow-sm">
<strong class="u-heading u-epsilon u-tc-info" x-show="notification.type === 'info'">Notice</strong>
<strong class="u-heading u-epsilon u-tc-positive" x-show="notification.type === 'success'">Success</strong>
<strong class="u-heading u-epsilon u-tc-negative" x-show="notification.type === 'error'">Error</strong>
<p class="" x-text="notification.content"></p>
</div>
<!-- Close -->
<button class="c-message__close" type="button" aria-label="Close Message"
@click="transitionOut()"
>
<svg class="c-icon" viewbox="0 0 16 16" aria-hidden="aria-hidden">
<path stroke-linecap="round" stroke-width="1.5" d="m4 4 8 8m-8 0 8-8"/>
</svg>
</button>
</div>
</aside>
</template>
</div>
<form class="o-flow"
x-data="{
content: 'Something happened!',
type: 'info',
duration: '9000'
}"
x-on:submit.prevent="$dispatch('snack', { content, type, duration })"
>
<label class="c-label | u-w-100%" for="message">
<span class="c-label__text">Message:</span>
<span class="c-label__input">
<input class="c-input c-input--text | u-w-20" id="message" x-model="content" type="text">
</span>
</label>
<label class="c-label | u-w-100%" for="type">
<span class="c-label__text">Type:</span>
<span class="c-label__input">
<select class="c-input c-input--select | u-w-20" id="type" x-model="type">
<option value="info">Info</option>
<option value="success">Success</option>
<option value="error">Error</option>
</select>
</span>
</label>
<label class="c-label | u-w-100%" for="duration">
<span class="c-label__text">Duration:</span>
<span class="c-label__input">
<input class="c-input c-input--text | u-w-20" id="duration" x-model="duration" type="number">
</span>
</label>
<button class="c-btn">Dispatch Snack</button>
</form>