-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add examples for wc-toast using script tag
- Loading branch information
Showing
9 changed files
with
876 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>wc-toast using script</title> | ||
<script type="module" src="./src/wc-toast/index.js"></script> | ||
<style> | ||
.root { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
height: 100vh; | ||
} | ||
|
||
.cheers { | ||
border: none; | ||
padding: 0.7rem 1rem; | ||
color: white; | ||
background-color: cornflowerblue; | ||
border-radius: 4px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<wc-toast></wc-toast> | ||
<div class="root"> | ||
<button class="cheers">Cheers</button> | ||
</div> | ||
</body> | ||
<script type="module"> | ||
import { toast } from "./src/wc-toast/index.js"; | ||
|
||
document.querySelector(".cheers").addEventListener("click", () => { | ||
console.log("Cheers"); | ||
toast("Cheers!"); | ||
}); | ||
</script> | ||
<!-- Use src if you want to separate the javascript code from the html --> | ||
<!-- <script type="module" src="./index.js"></script> --> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { toast } from "./src/wc-toast/index.js"; | ||
|
||
document.querySelector(".cheers").addEventListener("click", () => { | ||
console.log("Cheers"); | ||
toast("Cheers!"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import toast from './toast.js'; | ||
import WCToast from './wc-toast.js'; | ||
import WCToastItem from './wc-toast-item.js'; | ||
import WCToastIcon from './wc-toast-icon.js'; | ||
import WCToastContent from './wc-toast-content.js'; | ||
import WCToastCloseButton from './wc-toast-close-button.js'; | ||
|
||
export { toast, WCToast, WCToastItem, WCToastContent, WCToastIcon, WCToastCloseButton }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/** | ||
* Generate an id | ||
* @returns {string} id | ||
*/ | ||
const generateId = (function () { | ||
let count = 0; | ||
return function () { | ||
return (++count).toString(); | ||
}; | ||
})(); | ||
|
||
function createToast( | ||
message, | ||
type = 'blank', | ||
options = { | ||
icon: { type: '', content: '' }, | ||
duration: '', | ||
closeable: false, | ||
theme: { type: 'light', style: { background: '', color: '', stroke: '' } } | ||
} | ||
) { | ||
const id = generateId(); | ||
const toastItem = createToastItem(id, type, options); | ||
const toastIcon = createToastIcon(type, options); | ||
const toastContent = createToastContent(message); | ||
|
||
toastItem.appendChild(toastIcon); | ||
toastItem.appendChild(toastContent); | ||
|
||
if (options.closeable) toastItem.appendChild(createToastCloseButton(toastItem)); | ||
|
||
document.querySelector('wc-toast').appendChild(toastItem); | ||
|
||
return { | ||
id, | ||
type, | ||
message, | ||
...options | ||
}; | ||
} | ||
|
||
function createToastItem(id, type, options) { | ||
const { duration, theme } = options; | ||
const toastItem = document.createElement('wc-toast-item'); | ||
const isDarkTheme = window?.matchMedia && window.matchMedia('(prefers-color-scheme: dark)'); | ||
const prefersTheme = isDarkTheme?.matches ? 'dark' : 'light'; | ||
|
||
toastItem.setAttribute('type', type); | ||
toastItem.setAttribute('duration', duration ? duration : ''); | ||
toastItem.setAttribute('data-toast-item-id', id); | ||
toastItem.setAttribute('theme', theme?.type ? theme.type : prefersTheme); | ||
|
||
if (theme?.type === 'custom' && theme?.style) { | ||
const { background, stroke, color } = theme.style; | ||
toastItem.style.setProperty('--wc-toast-background', background); | ||
toastItem.style.setProperty('--wc-toast-stroke', stroke); | ||
toastItem.style.setProperty('--wc-toast-color', color); | ||
} | ||
|
||
return toastItem; | ||
} | ||
|
||
function createToastIcon(type, options) { | ||
const { icon } = options; | ||
const toastIcon = document.createElement('wc-toast-icon'); | ||
|
||
toastIcon.setAttribute('type', icon?.type ? icon.type : type); | ||
toastIcon.setAttribute('icon', icon?.content && icon?.type === 'custom' ? icon.content : ''); | ||
if (icon?.type === 'svg') toastIcon.innerHTML = icon?.content ? icon.content : ''; | ||
|
||
return toastIcon; | ||
} | ||
|
||
function createToastContent(message) { | ||
const toastContent = document.createElement('wc-toast-content'); | ||
toastContent.setAttribute('message', message); | ||
return toastContent; | ||
} | ||
|
||
function createToastCloseButton(toastItem) { | ||
const toastCloseButton = document.createElement('wc-toast-close-button'); | ||
toastCloseButton.addEventListener('click', () => { | ||
toastItem.classList.add('dismiss-with-close-button'); | ||
}); | ||
return toastCloseButton; | ||
} | ||
|
||
/** | ||
* Create toast from type | ||
* @param {'blank' | 'success' | 'loading' | 'error' | 'custom'} type | ||
*/ | ||
function createHandler(type) { | ||
/** | ||
* @param {string} message | ||
* @param {ToastOptions} [options] | ||
* @returns {string} | ||
*/ | ||
return function (message, options) { | ||
const toast = createToast(message, type, options); | ||
return toast.id; | ||
}; | ||
} | ||
|
||
/** | ||
* Author: Timo Lins | ||
* License: MIT | ||
* Source: https://github.com/timolins/react-hot-toast/blob/main/src/core/toast.ts | ||
*/ | ||
|
||
/** | ||
* @typedef {Object} ToastOptions | ||
* @property {object} [icon] | ||
* @property {string} [icon.type] | ||
* @property {string} [icon.content] | ||
* @property {number} [duration=3500] | ||
* @property {object} [theme] | ||
* @property {'light' | 'dark' | 'custom'} [theme.type="light"] | ||
* @property {object} [theme.style] | ||
* @property {string} [theme.style.background] | ||
* @property {string} [theme.style.color] | ||
* @property {string} [theme.style.stroke] | ||
* @property {boolean} [closeable=false] | ||
*/ | ||
|
||
/** | ||
* Create blank toast | ||
* @param {string} message | ||
* @param {ToastOptions} [options] | ||
* @returns {string} | ||
*/ | ||
function toast(message, options) { | ||
return createHandler('blank')(message, options); | ||
} | ||
|
||
toast.loading = createHandler('loading'); | ||
toast.success = createHandler('success'); | ||
toast.error = createHandler('error'); | ||
|
||
/** | ||
* Dismiss toast by id | ||
* @param {string} id | ||
* @returns {void} | ||
* @example | ||
* const id = toast.loading('Loading...') | ||
* ... | ||
* toast.dismiss(id); | ||
*/ | ||
toast.dismiss = function (toastId) { | ||
const toastItems = document.querySelectorAll('wc-toast-item'); | ||
|
||
for (const toastItem of toastItems) { | ||
const dataId = toastItem.getAttribute('data-toast-item-id'); | ||
|
||
if (toastId === dataId) { | ||
toastItem.classList.add('dismiss'); | ||
} | ||
} | ||
}; | ||
|
||
/** | ||
* Automatically add loading toast, success or error toast in promise | ||
* @param {Promise} promise | ||
* @param {object} message | ||
* @param {string} message.loading | ||
* @param {string} message.success | ||
* @param {string} message.error | ||
* @param {ToastOptions} [options] | ||
* @returns {Promise} | ||
*/ | ||
toast.promise = async function ( | ||
promise, | ||
message = { loading: '', success: '', error: '' }, | ||
options | ||
) { | ||
const id = toast.loading(message.loading, { ...options }); | ||
|
||
try { | ||
const result = await promise; | ||
toast.dismiss(id); | ||
toast.success(message.success, { ...options }); | ||
return result; | ||
} catch (error) { | ||
toast.dismiss(id); | ||
toast.error(message.error, { ...options }); | ||
return error; | ||
} | ||
}; | ||
|
||
export default toast; |
56 changes: 56 additions & 0 deletions
56
examples/wc-toast-script/src/wc-toast/wc-toast-close-button.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/** | ||
* @cssprop [--wc-toast-stroke=#2a2a32] - stroke. Default is #2a2a32; | ||
* | ||
* @summary - button to dismiss toast item | ||
* | ||
* @tag wc-toast-close-button | ||
*/ | ||
export default class WCToastCloseButton extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: 'open' }); | ||
this.template = document.createElement('template'); | ||
this.template.innerHTML = WCToastCloseButton.template(); | ||
this.shadowRoot.append(this.template.content.cloneNode(true)); | ||
} | ||
|
||
static template() { | ||
return ` | ||
<style> | ||
:host { | ||
width: 20px; | ||
opacity: 1; | ||
height: 20px; | ||
border-radius: 2px; | ||
border: 1px solid #dadce0; | ||
background: var(--wc-toast-background); | ||
position: relative; | ||
cursor: pointer; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
margin-left: 5px; | ||
} | ||
svg { | ||
stroke: var(--wc-toast-stroke, #2a2a32); | ||
} | ||
</style> | ||
<svg | ||
focusable="false" | ||
xmlns="http://www.w3.org/2000/svg" | ||
viewBox="0 0 24 24" | ||
stroke="currentColor" | ||
> | ||
<path | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
stroke-width="2" | ||
d="M6 18L18 6M6 6l12 12" | ||
/> | ||
</svg> | ||
`; | ||
} | ||
} | ||
|
||
customElements.define('wc-toast-close-button', WCToastCloseButton); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/** | ||
* @attr {string} message - message to be displayed in toast item | ||
* | ||
* @slot content - add your custom content such as HTMLElement to toast item | ||
* | ||
* @cssprop [--wc-toast-content-margin='4px 10px'] - margin of toast content | ||
* @cssprop [--wc-toast-color="#000"] - color. Default is #000 | ||
* @cssprop [--wc-toast-font-family="'Roboto', 'Amiri', sans-serif"] - font-family. Default is 'Roboto', 'Amiri', sans-serif; | ||
* @cssprop [--wc-toast-font-size="16px"] - font-size. Default is 16px | ||
* | ||
* @summary - message or content to be displayed in toast item | ||
* | ||
* @tag wc-toast-content | ||
*/ | ||
export default class WCToastContent extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({ mode: 'open' }); | ||
this.template = document.createElement('template'); | ||
this.template.innerHTML = WCToastContent.template(); | ||
this.shadowRoot.append(this.template.content.cloneNode(true)); | ||
} | ||
|
||
connectedCallback() { | ||
this.message = this.getAttribute('message'); | ||
this.shadowRoot.querySelector('slot[name="content"]').innerHTML = this.message; | ||
} | ||
|
||
static template() { | ||
return ` | ||
<style> | ||
:host { | ||
display: flex; | ||
justify-content: center; | ||
flex: 1 1 auto; | ||
margin: var(--wc-toast-content-margin) !important; | ||
color: var(--wc-toast-color, #000); | ||
font-family: var(--wc-toast-font-family); | ||
font-size: var(--wc-toast-font-size); | ||
} | ||
</style> | ||
<slot name="content"></slot> | ||
`; | ||
} | ||
} | ||
|
||
customElements.define('wc-toast-content', WCToastContent); |
Oops, something went wrong.