diff --git a/src/lib/render.ts b/src/lib/render.ts
index 4667e6e..185a649 100644
--- a/src/lib/render.ts
+++ b/src/lib/render.ts
@@ -5,33 +5,71 @@ import { validateLocalOptions } from './validate'
const toastQueue: Array<[Element, Element]> = []
-function renderToast(app: App, options: Options): void {
- // Render toast container
- const container = document.createElement('div')
- const mobileContainer = document.createElement('div')
+function formatAndMountContainer(el: Element, className: string, target: Element): void {
+ const attributes = [
+ ['role', 'status'],
+ ['aria-live', 'polite'],
+ ['aria-atomic', 'false']
+ ]
+
+ attributes.forEach((attr) => {
+ el.setAttribute(attr[0], attr[1])
+ })
+
+ el.className = className
+ target.appendChild(el)
+}
- // Set container attributes
- container.className = 'dk__toast-container'
- container.setAttribute('role', 'status')
- container.setAttribute('aria-live', 'polite')
- container.setAttribute('aria-atomic', 'false')
+function formatToastFromOptions(
+ text: string,
+ options: Options,
+ localOptions: LocalOptions,
+ duration?: number | false
+): Element {
+ const toast = document.createElement('div')
+ const left = localOptions.slotLeft
+ const right = localOptions.slot || localOptions.slotRight
+
+ // Add classes
+ toast.className = 'dk__toast'
+ if (options.class) toast.classList.add(options.class)
+ if (localOptions.class) toast.classList.add(localOptions.class)
+ if (localOptions.type) toast.classList.add(`dk__${localOptions.type}`)
+
+ // If text
+ if (text) toast.textContent = text
+ // If left slot
+ if (left) {
+ toast.innerHTML = `
${left}
` + toast.innerHTML
+ }
+ // If right slot
+ if (right) {
+ toast.innerHTML += `${right}
`
+ }
+ // If slot only
+ if (!text && (left || right)) toast.classList.add('dk__icon-only')
- mobileContainer.className = 'dk__toast-mobile-container'
- mobileContainer.setAttribute('role', 'status')
- mobileContainer.setAttribute('aria-live', 'polite')
- mobileContainer.setAttribute('aria-atomic', 'false')
+ const styles = localOptions.styles ? localOptions.styles : options.styles
+ toast.setAttribute('style', formatCssProperties(styles, duration))
- // Append
- document.body.appendChild(container)
- document.body.appendChild(mobileContainer)
+ if (localOptions.disableClick) {
+ // Prevent hover styling
+ toast.style.cursor = 'default'
+ toast.style.opacity = '1'
+ }
- function DKToast(text: string, localOptions?: LocalOptions): void {
- if (!localOptions) localOptions = {}
- const toast = document.createElement('div')
- const left = localOptions.slotLeft
- const right = localOptions.slot || localOptions.slotRight
- let clicked: boolean
+ return toast
+}
+
+function toastPlugin(app: App, options: Options): void {
+ const container = document.createElement('div')
+ const mobileContainer = document.createElement('div')
+
+ formatAndMountContainer(container, 'dk__toast-container', document.body)
+ formatAndMountContainer(mobileContainer, 'dk__toast-mobile-container', document.body)
+ function renderToast(text: string, localOptions?: LocalOptions): void {
+ if (!localOptions) localOptions = {}
if (!validateLocalOptions(text, localOptions)) return
const positions = {
@@ -39,63 +77,40 @@ function renderToast(app: App, options: Options): void {
x: localOptions.positionX || options.positionX
}
- // Render toast section
const section =
document.querySelector(`.dk__toast-${positions.y}-${positions.x}`) ||
document.createElement('div')
const toastCount = document.querySelectorAll('.dk__toast').length / 2
+ // Remove oldest toast if max limit is reached
if (options.max && toastCount >= options.max) {
toastQueue[0][0].parentElement?.removeChild(toastQueue[0][0])
toastQueue[0][1].parentElement?.removeChild(toastQueue[0][1])
toastQueue.shift()
}
+ // If section doesn't exist, format and mount
if (!section.className) {
- // Set section attributes
- section.className = `dk__toast-section dk__toast-${positions.y}-${positions.x}`
- section.setAttribute('role', 'status')
- section.setAttribute('aria-live', 'polite')
- section.setAttribute('aria-atomic', 'false')
-
- // Append
- container.appendChild(section)
- }
-
- toast.className = 'dk__toast'
- if (options.class) toast.classList.add(options.class)
- if (localOptions.class) toast.classList.add(localOptions.class)
- if (localOptions.type) toast.classList.add(`dk__${localOptions.type}`)
+ const className = `dk__toast-section dk__toast-${positions.y}-${positions.x}`
- // If text
- if (text) toast.textContent = text
- // If left slot
- if (left) {
- toast.innerHTML = `${left}
` + toast.innerHTML
+ formatAndMountContainer(section, className, container)
}
- // If right slot
- if (right) {
- toast.innerHTML += `${right}
`
- }
- // If slot only
- if (!text && (left || right)) toast.classList.add('dk__icon-only')
+ // Determine if duration is a number or false, local or global
const duration =
localOptions.duration || localOptions.duration === false
? localOptions.duration
: options.duration
- const styles = localOptions.styles ? localOptions.styles : options.styles
- toast.setAttribute('style', formatCssProperties(styles, duration))
+ const toast = formatToastFromOptions(text, options, localOptions, duration)
+ const mobileClone = toast.cloneNode(true)
- if (localOptions.disableClick) {
- toast.style.cursor = 'default'
- toast.style.opacity = '1'
- }
+ // Prevent attempting to remove toast if it's been removed by click
+ let clicked: boolean
- const mobileClone = toast.cloneNode(true)
+ function removeToastPair(e?: Event): void {
+ if (e) clicked = true
- function removeToastPair(): void {
if ([...section.children].includes(toast)) {
section.removeChild(toast)
}
@@ -104,16 +119,10 @@ function renderToast(app: App, options: Options): void {
}
}
- function clickHandler(): void {
- clicked = true
-
- removeToastPair()
- }
-
- // Remove toast on click
if (!options.disableClick && !localOptions.disableClick) {
- toast.addEventListener('click', clickHandler)
- mobileClone.addEventListener('click', clickHandler)
+ // Remove toast on click
+ toast.addEventListener('click', removeToastPair)
+ mobileClone.addEventListener('click', removeToastPair)
}
toastQueue.push([toast, mobileClone as Element])
@@ -129,8 +138,8 @@ function renderToast(app: App, options: Options): void {
}, duration)
}
- app.config.globalProperties.$toast = DKToast
- app.provide('$toast', DKToast)
+ app.config.globalProperties.$toast = renderToast
+ app.provide('$toast', renderToast)
}
-export default renderToast
+export default toastPlugin
diff --git a/src/lib/styles.ts b/src/lib/styles.ts
index f8aa92b..2d836ee 100644
--- a/src/lib/styles.ts
+++ b/src/lib/styles.ts
@@ -1,6 +1,6 @@
import type { Options } from './types'
-// Minify CSS
+/** Minify CSS */
function minify(styles: string): string {
let selector = false
let value = false
@@ -33,7 +33,7 @@ function minify(styles: string): string {
return minified
}
-// Format CSS from camelCase
+/** Format CSS from camelCase */
export function formatCssProperties(
styles?: Record,
duration?: number | false
@@ -72,7 +72,7 @@ export function formatCssProperties(
return formatted
}
-// Append minified stylesheet to document head
+/** Append minified stylesheet to document head */
export function appendStylesheet(options: Options): void {
const { duration, styles, positionY } = options
// Format style properties/values
diff --git a/src/lib/toast.ts b/src/lib/toast.ts
index 0d5d885..00150dc 100644
--- a/src/lib/toast.ts
+++ b/src/lib/toast.ts
@@ -9,12 +9,13 @@ import renderToast from './render'
*
* ---
* **Options:**
+ * @property `class` - CSS class to be added to every toast.
+ * @property `disableClick?: boolean`
* @property `duration` - Time in milliseconds before hiding the toast notification.
+ * @property `max` - Max number of toasts allowed per-section at any one time.
* @property `positionX` - 'left', 'right' or 'center'.
* @property `positionY` - 'top' or 'bottom'.
* @property `styles` - CSS key/value pairs.
- * @property `class` - CSS class to be added to every toast.
- * @property `max` - Max number of toasts allowed per-section at any one time.
*/
const toastPlugin = {
install: (app: App, options: Options): void => {
diff --git a/todo.txt b/todo.txt
index 27c24e5..d3c442d 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,4 +1,2 @@
-disable click option
check local options has priority over global options
-unit-tests
-code cleanup
\ No newline at end of file
+unit-tests
\ No newline at end of file