mirror of
https://github.com/php-flasher/php-flasher.git
synced 2026-03-31 15:07:47 +01:00
refactor(themes): create shared utilities and design tokens
This refactoring improves code quality and reduces duplication: ## New Files - `themes/shared/icons.ts` - Centralized SVG icons (getIcon, getCloseIcon) - `themes/shared/accessibility.ts` - A11y helpers (getA11yString, getCloseButtonA11y) - `themes/shared/constants.ts` - Standard class names and default titles ## Design Tokens Added (index.scss) - Spacing scale: --fl-spacing-xs through --fl-spacing-2xl - Typography scale: --fl-font-size-xs through --fl-font-size-xl - Close button sizes: --fl-close-sm, --fl-close-md, --fl-close-lg - Border radius: --fl-radius-sm through --fl-radius-full - Shadow tokens: --fl-shadow-sm through --fl-shadow-lg - Animation: --fl-duration-*, --fl-easing-*, --fl-slide-* ## Mixins Updated - Added `close-button-sized($size)` with sm/md/lg support - Added `close-button-circular($size)` variant - Added `close-button-text` for text-style buttons - Updated existing mixins to use design tokens ## All 17 Themes Refactored Each theme now uses shared utilities instead of duplicating code: - Icon code: 20+ lines → 1 function call - Accessibility: 3 lines → 1 function call - Class names: via CLASS_NAMES constants Backwards compatible - no breaking changes.
This commit is contained in:
@@ -1,63 +1,37 @@
|
|||||||
import './amazon.scss'
|
import './amazon.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getTypeIcon, getCloseIcon } from '../shared/icons'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES, DEFAULT_TITLES } from '../shared/constants'
|
||||||
|
|
||||||
|
const AMAZON_TITLES: Record<string, string> = {
|
||||||
|
success: 'Success!',
|
||||||
|
error: 'Problem',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
}
|
||||||
|
|
||||||
export const amazonTheme = {
|
export const amazonTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
const alertTitle = AMAZON_TITLES[type] || DEFAULT_TITLES[type] || 'Alert'
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
const getAlertIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'error':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'warning':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'info':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const getAlertTitle = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success': return 'Success!'
|
|
||||||
case 'error': return 'Problem'
|
|
||||||
case 'warning': return 'Warning'
|
|
||||||
case 'info': return 'Information'
|
|
||||||
default: return 'Alert'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-amazon fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('amazon')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-amazon-alert">
|
<div class="fl-amazon-alert">
|
||||||
<div class="fl-alert-content">
|
<div class="fl-alert-content">
|
||||||
<div class="fl-icon-container">
|
<div class="fl-icon-container">
|
||||||
${getAlertIcon()}
|
${getTypeIcon(type, { size: 'lg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
<div class="fl-alert-title">${getAlertTitle()}</div>
|
<div class="fl-alert-title">${alertTitle}</div>
|
||||||
<div class="fl-alert-message">${message}</div>
|
<div class="fl-alert-message">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-alert-actions">
|
<div class="fl-alert-actions">
|
||||||
<button class="fl-close" aria-label="Close notification">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<svg viewBox="0 0 24 24" width="16" height="16">
|
${getCloseIcon()}
|
||||||
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,25 +1,23 @@
|
|||||||
import './amber.scss'
|
import './amber.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const amberTheme = {
|
export const amberTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-amber fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('amber')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
import './aurora.scss'
|
import './aurora.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const auroraTheme = {
|
export const auroraTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-aurora fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('aurora')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
import './crystal.scss'
|
import './crystal.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const crystalTheme = {
|
export const crystalTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-crystal fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('crystal')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<p class="fl-message">${message}</p>
|
<p class="${CLASS_NAMES.message}">${message}</p>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
import './emerald.scss'
|
import './emerald.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const emeraldTheme = {
|
export const emeraldTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-emerald fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('emerald')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import './facebook.scss'
|
import './facebook.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getCloseIcon } from '../shared/icons'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
|
function getTimeString(): string {
|
||||||
|
const now = new Date()
|
||||||
|
return now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })
|
||||||
|
}
|
||||||
|
|
||||||
export const facebookTheme = {
|
export const facebookTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
const now = new Date()
|
|
||||||
const timeString = now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })
|
|
||||||
|
|
||||||
const getNotificationIcon = () => {
|
const getNotificationIcon = () => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'success':
|
case 'success':
|
||||||
@@ -43,25 +44,23 @@ export const facebookTheme = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-facebook fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('facebook')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-fb-notification">
|
<div class="fl-fb-notification">
|
||||||
<div class="fl-icon-container">
|
<div class="fl-icon-container">
|
||||||
${getNotificationIcon()}
|
${getNotificationIcon()}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">
|
<div class="${CLASS_NAMES.message}">
|
||||||
${message}
|
${message}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-meta">
|
<div class="fl-meta">
|
||||||
<span class="fl-time">${timeString}</span>
|
<span class="fl-time">${getTimeString()}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<div class="fl-button-icon">
|
<div class="fl-button-icon">
|
||||||
<svg viewBox="0 0 24 24" width="20" height="20">
|
${getCloseIcon({ size: 'md' })}
|
||||||
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,28 +1,26 @@
|
|||||||
import './flasher.scss'
|
import './flasher.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES, getTitle } from '../shared/constants'
|
||||||
|
|
||||||
export const flasherTheme = {
|
export const flasherTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, title, message } = envelope
|
const { type, title, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
const displayTitle = getTitle(title, type)
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
const displayTitle = title || type.charAt(0).toUpperCase() + type.slice(1)
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-flasher fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('flasher')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div>
|
<div>
|
||||||
<strong class="fl-title">${displayTitle}</strong>
|
<strong class="${CLASS_NAMES.title}">${displayTitle}</strong>
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="fl-progress-bar">
|
<span class="${CLASS_NAMES.progressBar}">
|
||||||
<span class="fl-progress"></span>
|
<span class="${CLASS_NAMES.progress}"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,60 +1,35 @@
|
|||||||
import './google.scss'
|
import './google.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getTypeIcon } from '../shared/icons'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES, DEFAULT_TEXT } from '../shared/constants'
|
||||||
|
|
||||||
export const googleTheme = {
|
export const googleTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message, title } = envelope
|
const { type, message, title } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
const titleSection = title ? `<div class="${CLASS_NAMES.title}">${title}</div>` : ''
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
const actionText = 'DISMISS'
|
|
||||||
|
|
||||||
const getIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'error':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'warning':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'info':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const titleSection = title ? `<div class="fl-title">${title}</div>` : ''
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-google fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('google')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-md-card">
|
<div class="fl-md-card">
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon-wrapper">
|
<div class="${CLASS_NAMES.iconWrapper}">
|
||||||
${getIcon()}
|
${getTypeIcon(type, { size: 'lg', className: 'fl-icon-svg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
${titleSection}
|
${titleSection}
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-action-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-action-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
${actionText}
|
${DEFAULT_TEXT.dismissButton}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
@use "sass:meta";
|
@use "sass:meta";
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
// Colors
|
||||||
--fl-success: #10b981;
|
--fl-success: #10b981;
|
||||||
--fl-info: #3b82f6;
|
--fl-info: #3b82f6;
|
||||||
--fl-warning: #f59e0b;
|
--fl-warning: #f59e0b;
|
||||||
@@ -19,12 +20,56 @@
|
|||||||
--fl-text-light: rgb(75, 85, 99);
|
--fl-text-light: rgb(75, 85, 99);
|
||||||
--fl-text-dark: var(--fl-white);
|
--fl-text-dark: var(--fl-white);
|
||||||
|
|
||||||
|
// Typography
|
||||||
--fl-font: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
--fl-font: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
|
--fl-font-size-xs: 0.75rem;
|
||||||
|
--fl-font-size-sm: 0.875rem;
|
||||||
|
--fl-font-size-base: 1rem;
|
||||||
|
--fl-font-size-lg: 1.125rem;
|
||||||
|
--fl-font-size-xl: 1.25rem;
|
||||||
|
|
||||||
|
// Spacing scale (rem for consistency)
|
||||||
|
--fl-spacing-xs: 0.25rem;
|
||||||
|
--fl-spacing-sm: 0.5rem;
|
||||||
|
--fl-spacing-md: 0.75rem;
|
||||||
|
--fl-spacing-lg: 1rem;
|
||||||
|
--fl-spacing-xl: 1.5rem;
|
||||||
|
--fl-spacing-2xl: 2rem;
|
||||||
|
|
||||||
|
// Close button sizes
|
||||||
|
--fl-close-sm: 1.125rem;
|
||||||
|
--fl-close-md: 1.5rem;
|
||||||
|
--fl-close-lg: 1.875rem;
|
||||||
|
|
||||||
|
// Border radius
|
||||||
--fl-border-radius: 4px;
|
--fl-border-radius: 4px;
|
||||||
|
--fl-radius-sm: 0.25rem;
|
||||||
|
--fl-radius-md: 0.5rem;
|
||||||
|
--fl-radius-lg: 0.75rem;
|
||||||
|
--fl-radius-xl: 1rem;
|
||||||
|
--fl-radius-full: 9999px;
|
||||||
|
|
||||||
|
// Shadows
|
||||||
--fl-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
--fl-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
--fl-shadow-dark: 0 4px 12px rgba(0, 0, 0, 0.35);
|
--fl-shadow-dark: 0 4px 12px rgba(0, 0, 0, 0.35);
|
||||||
--fl-transition: 0.4s cubic-bezier(0.23, 1, 0.32, 1);
|
--fl-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||||
|
--fl-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||||
|
--fl-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
// Animation
|
||||||
|
--fl-transition: 0.4s cubic-bezier(0.23, 1, 0.32, 1);
|
||||||
|
--fl-duration-fast: 0.15s;
|
||||||
|
--fl-duration-base: 0.3s;
|
||||||
|
--fl-duration-slow: 0.5s;
|
||||||
|
--fl-easing-spring: cubic-bezier(0.23, 1, 0.32, 1);
|
||||||
|
--fl-easing-material: cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
|
||||||
|
// Animation distances
|
||||||
|
--fl-slide-sm: 8px;
|
||||||
|
--fl-slide-md: 12px;
|
||||||
|
--fl-slide-lg: 20px;
|
||||||
|
|
||||||
|
// Legacy aliases (for backwards compatibility)
|
||||||
--background-color: var(--fl-bg-light);
|
--background-color: var(--fl-bg-light);
|
||||||
--text-color: var(--fl-text-light);
|
--text-color: var(--fl-text-light);
|
||||||
--dark-background-color: var(--fl-bg-dark);
|
--dark-background-color: var(--fl-bg-dark);
|
||||||
|
|||||||
@@ -1,59 +1,38 @@
|
|||||||
import './ios.scss'
|
import './ios.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getTypeIcon } from '../shared/icons'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
|
const APP_NAME = 'PHPFlasher'
|
||||||
|
|
||||||
|
function getTimeString(): string {
|
||||||
|
const now = new Date()
|
||||||
|
return now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })
|
||||||
|
}
|
||||||
|
|
||||||
export const iosTheme = {
|
export const iosTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message, title } = envelope
|
const { type, message, title } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
const displayTitle = title || APP_NAME
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
const appName = 'PHPFlasher'
|
|
||||||
|
|
||||||
const now = new Date()
|
|
||||||
const timeString = now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })
|
|
||||||
|
|
||||||
const getIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'error':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'warning':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
|
|
||||||
</svg>`
|
|
||||||
case 'info':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const displayTitle = title || appName
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-ios fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('ios')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-ios-notification">
|
<div class="fl-ios-notification">
|
||||||
<div class="fl-header">
|
<div class="fl-header">
|
||||||
<div class="fl-app-icon">
|
<div class="fl-app-icon">
|
||||||
${getIcon()}
|
${getTypeIcon(type, { size: 'md', className: 'fl-icon-svg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-app-info">
|
<div class="fl-app-info">
|
||||||
<div class="fl-app-name">${displayTitle}</div>
|
<div class="fl-app-name">${displayTitle}</div>
|
||||||
<div class="fl-time">${timeString}</div>
|
<div class="fl-time">${getTimeString()}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
import './jade.scss'
|
import './jade.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const jadeTheme = {
|
export const jadeTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-jade fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('jade')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,32 +1,28 @@
|
|||||||
import './material.scss'
|
import './material.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES, DEFAULT_TEXT } from '../shared/constants'
|
||||||
|
|
||||||
export const materialTheme = {
|
export const materialTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
const actionText = 'DISMISS'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-material fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('material')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-md-card">
|
<div class="fl-md-card">
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-action-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-action-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
${actionText}
|
${DEFAULT_TEXT.dismissButton}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
import './minimal.scss'
|
import './minimal.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const minimalTheme = {
|
export const minimalTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-minimal fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('minimal')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,26 +8,122 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Legacy close button mixin (for backwards compatibility)
|
||||||
@mixin close-button {
|
@mixin close-button {
|
||||||
.fl-close {
|
.fl-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0.75rem;
|
right: var(--fl-spacing-md, 0.75rem);
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 1.25rem;
|
font-size: var(--fl-font-size-xl, 1.25rem);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
padding: 0.25rem;
|
padding: var(--fl-spacing-xs, 0.25rem);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
transition: opacity 0.2s ease;
|
transition: opacity var(--fl-duration-fast, 0.15s) ease;
|
||||||
color: currentColor;
|
color: currentColor;
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
|
|
||||||
&:hover, &:focus {
|
&:hover, &:focus {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: 2px solid currentColor;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameterized close button with size variants
|
||||||
|
@mixin close-button-sized($size: 'md', $position: 'absolute') {
|
||||||
|
.fl-close {
|
||||||
|
@if $position == 'absolute' {
|
||||||
|
position: absolute;
|
||||||
|
right: var(--fl-spacing-md, 0.75rem);
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
} @else {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
color: currentColor;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: opacity var(--fl-duration-fast, 0.15s) ease,
|
||||||
|
transform var(--fl-duration-fast, 0.15s) ease;
|
||||||
|
touch-action: manipulation;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
@if $size == 'sm' {
|
||||||
|
width: var(--fl-close-sm, 1.125rem);
|
||||||
|
height: var(--fl-close-sm, 1.125rem);
|
||||||
|
font-size: var(--fl-font-size-base, 1rem);
|
||||||
|
} @else if $size == 'lg' {
|
||||||
|
width: var(--fl-close-lg, 1.875rem);
|
||||||
|
height: var(--fl-close-lg, 1.875rem);
|
||||||
|
font-size: var(--fl-font-size-xl, 1.25rem);
|
||||||
|
} @else {
|
||||||
|
width: var(--fl-close-md, 1.5rem);
|
||||||
|
height: var(--fl-close-md, 1.5rem);
|
||||||
|
font-size: var(--fl-font-size-lg, 1.125rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: 2px solid currentColor;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Circular close button variant
|
||||||
|
@mixin close-button-circular($size: 'md') {
|
||||||
|
@include close-button-sized($size, 'relative');
|
||||||
|
|
||||||
|
.fl-close {
|
||||||
|
border-radius: var(--fl-radius-full, 9999px);
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text-style close button (e.g., "DISMISS")
|
||||||
|
@mixin close-button-text {
|
||||||
|
.fl-close {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: var(--fl-font-size-sm, 0.875rem);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
padding: var(--fl-spacing-sm, 0.5rem) var(--fl-spacing-md, 0.75rem);
|
||||||
|
cursor: pointer;
|
||||||
|
color: currentColor;
|
||||||
|
border-radius: var(--fl-radius-sm, 0.25rem);
|
||||||
|
transition: background-color var(--fl-duration-fast, 0.15s) ease;
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: 2px solid currentColor;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +135,7 @@
|
|||||||
|
|
||||||
.fl-close {
|
.fl-close {
|
||||||
right: auto;
|
right: auto;
|
||||||
left: 0.75rem;
|
left: var(--fl-spacing-md, 0.75rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
import './neon.scss'
|
import './neon.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const neonTheme = {
|
export const neonTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-neon fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('neon')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,24 +1,22 @@
|
|||||||
import './onyx.scss'
|
import './onyx.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const onyxTheme = {
|
export const onyxTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-onyx fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('onyx')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,28 +1,26 @@
|
|||||||
import './ruby.scss'
|
import './ruby.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const rubyTheme = {
|
export const rubyTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-ruby fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('ruby')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-shine"></div>
|
<div class="fl-shine"></div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon-circle">
|
<div class="fl-icon-circle">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
import './sapphire.scss'
|
import './sapphire.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getA11yString } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
export const sapphireTheme = {
|
export const sapphireTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-sapphire fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('sapphire')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`
|
</div>`
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
export type NotificationType = 'success' | 'info' | 'warning' | 'error'
|
||||||
|
|
||||||
|
export interface A11yAttributes {
|
||||||
|
role: 'alert' | 'status'
|
||||||
|
ariaLive: 'assertive' | 'polite'
|
||||||
|
ariaAtomic: 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getA11yAttributes(type: NotificationType | string): A11yAttributes {
|
||||||
|
const isAlert = type === 'error' || type === 'warning'
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getA11yString(type: NotificationType | string): string {
|
||||||
|
const attrs = getA11yAttributes(type)
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCloseButtonA11y(type: NotificationType | string): string {
|
||||||
|
return `aria-label="Close ${type} message"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
export const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
|
||||||
|
type: (type: string) => `fl-${type}`,
|
||||||
|
theme: (name: string) => `fl-${name}`,
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export const DEFAULT_TITLES: Record<string, string> = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_TEXT = {
|
||||||
|
dismissButton: 'DISMISS',
|
||||||
|
closeLabel: (type: string) => `Close ${type} message`,
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export function capitalizeType(type: string): string {
|
||||||
|
return type.charAt(0).toUpperCase() + type.slice(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTitle(title: string | undefined, type: string): string {
|
||||||
|
return title || DEFAULT_TITLES[type] || capitalizeType(type)
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
export type IconType = 'success' | 'info' | 'warning' | 'error' | 'close'
|
||||||
|
export type IconSize = 'sm' | 'md' | 'lg' | number
|
||||||
|
|
||||||
|
export interface IconConfig {
|
||||||
|
size?: IconSize
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const sizeMap: Record<string, number> = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconPaths: Record<IconType, string> = {
|
||||||
|
success:
|
||||||
|
'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning:
|
||||||
|
'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getIcon(type: IconType, config: IconConfig = {}): string {
|
||||||
|
const { size = 'md', className = '' } = config
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size]
|
||||||
|
const path = iconPaths[type]
|
||||||
|
|
||||||
|
if (!path) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const classAttr = className ? ` class="${className}"` : ''
|
||||||
|
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCloseIcon(config: IconConfig = {}): string {
|
||||||
|
return getIcon('close', { size: 'sm', ...config })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTypeIcon(
|
||||||
|
type: string,
|
||||||
|
config: IconConfig = {}
|
||||||
|
): string {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config)
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export { getIcon, getCloseIcon, getTypeIcon } from './icons'
|
||||||
|
export type { IconType, IconSize, IconConfig } from './icons'
|
||||||
|
|
||||||
|
export { getA11yAttributes, getA11yString, getCloseButtonA11y } from './accessibility'
|
||||||
|
export type { NotificationType, A11yAttributes } from './accessibility'
|
||||||
|
|
||||||
|
export {
|
||||||
|
CLASS_NAMES,
|
||||||
|
DEFAULT_TITLES,
|
||||||
|
DEFAULT_TEXT,
|
||||||
|
capitalizeType,
|
||||||
|
getTitle,
|
||||||
|
} from './constants'
|
||||||
@@ -1,42 +1,34 @@
|
|||||||
import './slack.scss'
|
import './slack.scss'
|
||||||
import type { Envelope } from '../../types'
|
import type { Envelope } from '../../types'
|
||||||
|
import { getCloseIcon } from '../shared/icons'
|
||||||
|
import { getA11yString, getCloseButtonA11y } from '../shared/accessibility'
|
||||||
|
import { CLASS_NAMES } from '../shared/constants'
|
||||||
|
|
||||||
|
const TYPE_ICONS: Record<string, string> = {
|
||||||
|
success: '✓',
|
||||||
|
error: '✕',
|
||||||
|
warning: '!',
|
||||||
|
info: 'i',
|
||||||
|
}
|
||||||
|
|
||||||
export const slackTheme = {
|
export const slackTheme = {
|
||||||
render: (envelope: Envelope): string => {
|
render: (envelope: Envelope): string => {
|
||||||
const { type, message } = envelope
|
const { type, message } = envelope
|
||||||
|
|
||||||
const isAlert = type === 'error' || type === 'warning'
|
const iconChar = TYPE_ICONS[type] || ''
|
||||||
const role = isAlert ? 'alert' : 'status'
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite'
|
|
||||||
|
|
||||||
const getTypeIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<div class="fl-type-icon fl-success-icon">✓</div>`
|
|
||||||
case 'error':
|
|
||||||
return `<div class="fl-type-icon fl-error-icon">✕</div>`
|
|
||||||
case 'warning':
|
|
||||||
return `<div class="fl-type-icon fl-warning-icon">!</div>`
|
|
||||||
case 'info':
|
|
||||||
return `<div class="fl-type-icon fl-info-icon">i</div>`
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-slack fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('slack')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-slack-message">
|
<div class="fl-slack-message">
|
||||||
<div class="fl-avatar">
|
<div class="fl-avatar">
|
||||||
${getTypeIcon()}
|
<div class="fl-type-icon fl-${type}-icon">${iconChar}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-message-content">
|
<div class="fl-message-content">
|
||||||
<div class="fl-message-text">${message}</div>
|
<div class="fl-message-text">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-close" aria-label="Close ${type} message">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<svg viewBox="0 0 20 20" width="16" height="16">
|
${getCloseIcon()}
|
||||||
<path fill="currentColor" d="M10 8.586L6.707 5.293a1 1 0 00-1.414 1.414L8.586 10l-3.293 3.293a1 1 0 101.414 1.414L10 11.414l3.293 3.293a1 1 0 001.414-1.414L11.414 10l3.293-3.293a1 1 0 00-1.414-1.414L10 8.586z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+57
-12
@@ -598,25 +598,70 @@ class Flasher extends AbstractPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
function capitalizeType(type) {
|
||||||
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
||||||
|
}
|
||||||
|
function getTitle(title, type) {
|
||||||
|
return title || DEFAULT_TITLES[type] || capitalizeType(type);
|
||||||
|
}
|
||||||
|
|
||||||
const flasherTheme = {
|
const flasherTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, title, message } = envelope;
|
const { type, title, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const displayTitle = getTitle(title, type);
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const displayTitle = title || type.charAt(0).toUpperCase() + type.slice(1);
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-flasher fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('flasher')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div>
|
<div>
|
||||||
<strong class="fl-title">${displayTitle}</strong>
|
<strong class="${CLASS_NAMES.title}">${displayTitle}</strong>
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="fl-progress-bar">
|
<span class="${CLASS_NAMES.progressBar}">
|
||||||
<span class="fl-progress"></span>
|
<span class="${CLASS_NAMES.progress}"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
+57
-12
@@ -604,25 +604,70 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
function capitalizeType(type) {
|
||||||
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
||||||
|
}
|
||||||
|
function getTitle(title, type) {
|
||||||
|
return title || DEFAULT_TITLES[type] || capitalizeType(type);
|
||||||
|
}
|
||||||
|
|
||||||
const flasherTheme = {
|
const flasherTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, title, message } = envelope;
|
const { type, title, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const displayTitle = getTitle(title, type);
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const displayTitle = title || type.charAt(0).toUpperCase() + type.slice(1);
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-flasher fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('flasher')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div>
|
<div>
|
||||||
<strong class="fl-title">${displayTitle}</strong>
|
<strong class="${CLASS_NAMES.title}">${displayTitle}</strong>
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="fl-progress-bar">
|
<span class="${CLASS_NAMES.progressBar}">
|
||||||
<span class="fl-progress"></span>
|
<span class="${CLASS_NAMES.progress}"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+86
-40
@@ -5,59 +5,105 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
|
||||||
|
const AMAZON_TITLES = {
|
||||||
|
success: 'Success!',
|
||||||
|
error: 'Problem',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
const amazonTheme = {
|
const amazonTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const alertTitle = AMAZON_TITLES[type] || DEFAULT_TITLES[type] || 'Alert';
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const getAlertIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'error':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'info':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
const getAlertTitle = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success': return 'Success!';
|
|
||||||
case 'error': return 'Problem';
|
|
||||||
case 'warning': return 'Warning';
|
|
||||||
case 'info': return 'Information';
|
|
||||||
default: return 'Alert';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-amazon fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('amazon')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-amazon-alert">
|
<div class="fl-amazon-alert">
|
||||||
<div class="fl-alert-content">
|
<div class="fl-alert-content">
|
||||||
<div class="fl-icon-container">
|
<div class="fl-icon-container">
|
||||||
${getAlertIcon()}
|
${getTypeIcon(type, { size: 'lg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
<div class="fl-alert-title">${getAlertTitle()}</div>
|
<div class="fl-alert-title">${alertTitle}</div>
|
||||||
<div class="fl-alert-message">${message}</div>
|
<div class="fl-alert-message">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-alert-actions">
|
<div class="fl-alert-actions">
|
||||||
<button class="fl-close" aria-label="Close notification">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<svg viewBox="0 0 24 24" width="16" height="16">
|
${getCloseIcon()}
|
||||||
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+86
-40
@@ -9,59 +9,105 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
|
||||||
|
const AMAZON_TITLES = {
|
||||||
|
success: 'Success!',
|
||||||
|
error: 'Problem',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
const amazonTheme = {
|
const amazonTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const alertTitle = AMAZON_TITLES[type] || DEFAULT_TITLES[type] || 'Alert';
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const getAlertIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'error':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'info':
|
|
||||||
return `<svg viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
const getAlertTitle = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success': return 'Success!';
|
|
||||||
case 'error': return 'Problem';
|
|
||||||
case 'warning': return 'Warning';
|
|
||||||
case 'info': return 'Information';
|
|
||||||
default: return 'Alert';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-amazon fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('amazon')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-amazon-alert">
|
<div class="fl-amazon-alert">
|
||||||
<div class="fl-alert-content">
|
<div class="fl-alert-content">
|
||||||
<div class="fl-icon-container">
|
<div class="fl-icon-container">
|
||||||
${getAlertIcon()}
|
${getTypeIcon(type, { size: 'lg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
<div class="fl-alert-title">${getAlertTitle()}</div>
|
<div class="fl-alert-title">${alertTitle}</div>
|
||||||
<div class="fl-alert-message">${message}</div>
|
<div class="fl-alert-message">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-alert-actions">
|
<div class="fl-alert-actions">
|
||||||
<button class="fl-close" aria-label="Close notification">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<svg viewBox="0 0 24 24" width="16" height="16">
|
${getCloseIcon()}
|
||||||
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("amazon",{render:e=>{const{type:n,message:t}=e,r="error"===n||"warning"===n;return`\n <div class="fl-amazon fl-${n}" role="${r?"alert":"status"}" aria-live="${r?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-amazon-alert">\n <div class="fl-alert-content">\n <div class="fl-icon-container">\n ${(()=>{switch(n){case"success":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>\n </svg>';case"warning":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>\n </svg>';case"info":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-text-content">\n <div class="fl-alert-title">${(()=>{switch(n){case"success":return"Success!";case"error":return"Problem";case"warning":return"Warning";case"info":return"Information";default:return"Alert"}})()}</div>\n <div class="fl-alert-message">${t}</div>\n </div>\n </div>\n <div class="fl-alert-actions">\n <button class="fl-close" aria-label="Close notification">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>\n </svg>\n </button>\n </div>\n </div>\n </div>`}})}));
|
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).flasher)}(this,(function(n){"use strict";const e={sm:16,md:20,lg:24},s={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function r(n,r={}){const{size:i="md",className:t=""}=r,a="number"==typeof i?i:e[i],o=s[n];if(!o)return"";return`<svg${t?` class="${t}"`:""} viewBox="0 0 24 24" width="${a}" height="${a}" aria-hidden="true"><path fill="currentColor" d="${o}"/></svg>`}const i="fl-close",t=n=>`fl-${n}`,a=n=>`fl-${n}`,o={success:"Success",error:"Error",warning:"Warning",info:"Information"},l={success:"Success!",error:"Problem",warning:"Warning",info:"Information"},c={render:n=>{const{type:e,message:s}=n,c=l[e]||o[e]||"Alert";return`\n <div class="${a("amazon")} ${t(e)}" ${function(n){const e=function(n){const e="error"===n||"warning"===n;return{role:e?"alert":"status",ariaLive:e?"assertive":"polite",ariaAtomic:"true"}}(n);return`role="${e.role}" aria-live="${e.ariaLive}" aria-atomic="${e.ariaAtomic}"`}(e)}>\n <div class="fl-amazon-alert">\n <div class="fl-alert-content">\n <div class="fl-icon-container">\n ${function(n,e={}){return"success"===n||"error"===n||"warning"===n||"info"===n?r(n,e):""}(e,{size:"lg"})}\n </div>\n <div class="fl-text-content">\n <div class="fl-alert-title">${c}</div>\n <div class="fl-alert-message">${s}</div>\n </div>\n </div>\n <div class="fl-alert-actions">\n <button class="${i}" ${function(n){return`aria-label="Close ${n} message"`}(e)}>\n ${function(n={}){return r("close",Object.assign({size:"sm"},n))}()}\n </button>\n </div>\n </div>\n </div>`}};n.addTheme("amazon",c)}));
|
||||||
|
|||||||
+44
-11
@@ -5,23 +5,56 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const amberTheme = {
|
const amberTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-amber fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('amber')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+44
-11
@@ -9,23 +9,56 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const amberTheme = {
|
const amberTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-amber fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('amber')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("amber",{render:e=>{const{type:s,message:i}=e,l="error"===s||"warning"===s;return`\n <div class="fl-amber fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-icon"></div>\n <div class="fl-text">\n <div class="fl-message">${i}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s="fl-content",i="fl-message",n="fl-text",a="fl-icon",r="fl-close",t="fl-progress-bar",l="fl-progress",o=e=>`fl-${e}`,f=e=>`fl-${e}`,c={render:e=>{const{type:c,message:d}=e;return`\n <div class="${f("amber")} ${o(c)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(c)}>\n <div class="${s}">\n <div class="${a}"></div>\n <div class="${n}">\n <div class="${i}">${d}</div>\n </div>\n <button class="${r}" ${function(e){return`aria-label="Close ${e} message"`}(c)}>×</button>\n </div>\n <div class="${t}">\n <div class="${l}"></div>\n </div>\n </div>`}};e.addTheme("amber",c)}));
|
||||||
|
|||||||
+42
-9
@@ -5,20 +5,53 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const auroraTheme = {
|
const auroraTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-aurora fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('aurora')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+42
-9
@@ -9,20 +9,53 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const auroraTheme = {
|
const auroraTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-aurora fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('aurora')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("aurora",{render:e=>{const{type:s,message:a}=e,r="error"===s||"warning"===s;return`\n <div class="fl-aurora fl-${s}" role="${r?"alert":"status"}" aria-live="${r?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],r):r((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const r="fl-content",s="fl-message",a="fl-close",n="fl-progress-bar",i="fl-progress",t=e=>`fl-${e}`,o=e=>`fl-${e}`,l={render:e=>{const{type:l,message:f}=e;return`\n <div class="${o("aurora")} ${t(l)}" ${function(e){const r=function(e){const r="error"===e||"warning"===e;return{role:r?"alert":"status",ariaLive:r?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${r.role}" aria-live="${r.ariaLive}" aria-atomic="${r.ariaAtomic}"`}(l)}>\n <div class="${r}">\n <div class="${s}">${f}</div>\n <button class="${a}" ${function(e){return`aria-label="Close ${e} message"`}(l)}>×</button>\n </div>\n <div class="${n}">\n <div class="${i}"></div>\n </div>\n </div>`}};e.addTheme("aurora",l)}));
|
||||||
|
|||||||
+43
-10
@@ -5,22 +5,55 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const crystalTheme = {
|
const crystalTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-crystal fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('crystal')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<p class="fl-message">${message}</p>
|
<p class="${CLASS_NAMES.message}">${message}</p>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+43
-10
@@ -9,22 +9,55 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const crystalTheme = {
|
const crystalTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-crystal fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('crystal')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<p class="fl-message">${message}</p>
|
<p class="${CLASS_NAMES.message}">${message}</p>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("crystal",{render:e=>{const{type:s,message:l}=e,a="error"===s||"warning"===s;return`\n <div class="fl-crystal fl-${s}" role="${a?"alert":"status"}" aria-live="${a?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-text">\n <p class="fl-message">${l}</p>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s="fl-content",n="fl-message",r="fl-text",t="fl-close",a="fl-progress-bar",i="fl-progress",l=e=>`fl-${e}`,o=e=>`fl-${e}`,f={render:e=>{const{type:f,message:c}=e;return`\n <div class="${o("crystal")} ${l(f)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(f)}>\n <div class="${s}">\n <div class="${r}">\n <p class="${n}">${c}</p>\n </div>\n <button class="${t}" ${function(e){return`aria-label="Close ${e} message"`}(f)}>×</button>\n </div>\n <div class="${a}">\n <div class="${i}"></div>\n </div>\n </div>`}};e.addTheme("crystal",f)}));
|
||||||
|
|||||||
+40
-7
@@ -5,17 +5,50 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const emeraldTheme = {
|
const emeraldTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-emerald fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('emerald')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+40
-7
@@ -9,17 +9,50 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const emeraldTheme = {
|
const emeraldTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-emerald fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('emerald')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("emerald",{render:e=>{const{type:s,message:a}=e,l="error"===s||"warning"===s;return`\n <div class="fl-emerald fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",t="fl-message",a="fl-close",i=e=>`fl-${e}`,r=e=>`fl-${e}`,s={render:e=>{const{type:s,message:l}=e;return`\n <div class="${r("emerald")} ${i(s)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(s)}>\n <div class="${n}">\n <div class="${t}">${l}</div>\n <button class="${a}" ${function(e){return`aria-label="Close ${e} message"`}(s)}>×</button>\n </div>\n </div>`}};e.addTheme("emerald",s)}));
|
||||||
|
|||||||
+70
-14
@@ -5,14 +5,72 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
function getTimeString() {
|
||||||
|
const now = new Date();
|
||||||
|
return now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
||||||
|
}
|
||||||
const facebookTheme = {
|
const facebookTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const now = new Date();
|
|
||||||
const timeString = now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
|
||||||
const getNotificationIcon = () => {
|
const getNotificationIcon = () => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'success':
|
case 'success':
|
||||||
@@ -43,25 +101,23 @@ const facebookTheme = {
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
return `
|
return `
|
||||||
<div class="fl-facebook fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('facebook')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-fb-notification">
|
<div class="fl-fb-notification">
|
||||||
<div class="fl-icon-container">
|
<div class="fl-icon-container">
|
||||||
${getNotificationIcon()}
|
${getNotificationIcon()}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">
|
<div class="${CLASS_NAMES.message}">
|
||||||
${message}
|
${message}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-meta">
|
<div class="fl-meta">
|
||||||
<span class="fl-time">${timeString}</span>
|
<span class="fl-time">${getTimeString()}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<div class="fl-button-icon">
|
<div class="fl-button-icon">
|
||||||
<svg viewBox="0 0 24 24" width="20" height="20">
|
${getCloseIcon({ size: 'md' })}
|
||||||
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+70
-14
@@ -9,14 +9,72 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
function getTimeString() {
|
||||||
|
const now = new Date();
|
||||||
|
return now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
||||||
|
}
|
||||||
const facebookTheme = {
|
const facebookTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const now = new Date();
|
|
||||||
const timeString = now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
|
||||||
const getNotificationIcon = () => {
|
const getNotificationIcon = () => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'success':
|
case 'success':
|
||||||
@@ -47,25 +105,23 @@
|
|||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
return `
|
return `
|
||||||
<div class="fl-facebook fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('facebook')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-fb-notification">
|
<div class="fl-fb-notification">
|
||||||
<div class="fl-icon-container">
|
<div class="fl-icon-container">
|
||||||
${getNotificationIcon()}
|
${getNotificationIcon()}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">
|
<div class="${CLASS_NAMES.message}">
|
||||||
${message}
|
${message}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-meta">
|
<div class="fl-meta">
|
||||||
<span class="fl-time">${timeString}</span>
|
<span class="fl-time">${getTimeString()}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<div class="fl-button-icon">
|
<div class="fl-button-icon">
|
||||||
<svg viewBox="0 0 24 24" width="20" height="20">
|
${getCloseIcon({ size: 'md' })}
|
||||||
<path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(n,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):i((n="undefined"!=typeof globalThis?globalThis:n||self).flasher)}(this,(function(n){"use strict";const i={render:n=>{const{type:i,message:e}=n,s="error"===i||"warning"===i,t=s?"alert":"status",l=s?"assertive":"polite",o=(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"});return`\n <div class="fl-facebook fl-${i}" role="${t}" aria-live="${l}" aria-atomic="true">\n <div class="fl-fb-notification">\n <div class="fl-icon-container">\n ${(()=>{switch(i){case"success":return'<div class="fl-fb-icon fl-fb-icon-success">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z"/>\n </svg>\n </div>';case"error":return'<div class="fl-fb-icon fl-fb-icon-error">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.5c-.69 0-1.25.56-1.25 1.25S11.31 13 12 13s1.25-.56 1.25-1.25S12.69 10.5 12 10.5zM12 9c.552 0 1-.448 1-1V7c0-.552-.448-1-1-1s-1 .448-1 1v1c0 .552.448 1 1 1z"/>\n </svg>\n </div>';case"warning":return'<div class="fl-fb-icon fl-fb-icon-warning">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.409 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72192 12.7772 2.84815 12.865 3.00017ZM11 16.0002V18.0002H13V16.0002H11ZM11 8.00017V14.0002H13V8.00017H11Z"/>\n </svg>\n </div>';case"info":return'<div class="fl-fb-icon fl-fb-icon-info">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v-2h-2v2zm0-4h2V7h-2v4z"/>\n </svg>\n </div>'}return""})()}\n </div>\n <div class="fl-content">\n <div class="fl-message">\n ${e}\n </div>\n <div class="fl-meta">\n <span class="fl-time">${o}</span>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-button fl-close" aria-label="Close ${i} message">\n <div class="fl-button-icon">\n <svg viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>\n </svg>\n </div>\n </button>\n </div>\n </div>\n </div>`}};n.addTheme("facebook",i)}));
|
!function(n,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):i((n="undefined"!=typeof globalThis?globalThis:n||self).flasher)}(this,(function(n){"use strict";const i={sm:16,md:20,lg:24},e={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function s(n={}){return function(n,s={}){const{size:t="md",className:o=""}=s,r="number"==typeof t?t:i[t];return`<svg${o?` class="${o}"`:""} viewBox="0 0 24 24" width="${r}" height="${r}" aria-hidden="true"><path fill="currentColor" d="${e[n]}"/></svg>`}("close",Object.assign({size:"sm"},n))}const t="fl-content",o="fl-message",r="fl-actions",l="fl-close",c=n=>`fl-${n}`,a=n=>`fl-${n}`;const f={render:n=>{const{type:i,message:e}=n;return`\n <div class="${a("facebook")} ${c(i)}" ${function(n){const i=function(n){const i="error"===n||"warning"===n;return{role:i?"alert":"status",ariaLive:i?"assertive":"polite",ariaAtomic:"true"}}(n);return`role="${i.role}" aria-live="${i.ariaLive}" aria-atomic="${i.ariaAtomic}"`}(i)}>\n <div class="fl-fb-notification">\n <div class="fl-icon-container">\n ${(()=>{switch(i){case"success":return'<div class="fl-fb-icon fl-fb-icon-success">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z"/>\n </svg>\n </div>';case"error":return'<div class="fl-fb-icon fl-fb-icon-error">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.5c-.69 0-1.25.56-1.25 1.25S11.31 13 12 13s1.25-.56 1.25-1.25S12.69 10.5 12 10.5zM12 9c.552 0 1-.448 1-1V7c0-.552-.448-1-1-1s-1 .448-1 1v1c0 .552.448 1 1 1z"/>\n </svg>\n </div>';case"warning":return'<div class="fl-fb-icon fl-fb-icon-warning">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.409 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72192 12.7772 2.84815 12.865 3.00017ZM11 16.0002V18.0002H13V16.0002H11ZM11 8.00017V14.0002H13V8.00017H11Z"/>\n </svg>\n </div>';case"info":return'<div class="fl-fb-icon fl-fb-icon-info">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v-2h-2v2zm0-4h2V7h-2v4z"/>\n </svg>\n </div>'}return""})()}\n </div>\n <div class="${t}">\n <div class="${o}">\n ${e}\n </div>\n <div class="fl-meta">\n <span class="fl-time">${(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}</span>\n </div>\n </div>\n <div class="${r}">\n <button class="fl-button ${l}" ${function(n){return`aria-label="Close ${n} message"`}(i)}>\n <div class="fl-button-icon">\n ${s({size:"md"})}\n </div>\n </button>\n </div>\n </div>\n </div>`}};n.addTheme("facebook",f)}));
|
||||||
|
|||||||
+57
-12
@@ -5,25 +5,70 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
function capitalizeType(type) {
|
||||||
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
||||||
|
}
|
||||||
|
function getTitle(title, type) {
|
||||||
|
return title || DEFAULT_TITLES[type] || capitalizeType(type);
|
||||||
|
}
|
||||||
|
|
||||||
const flasherTheme = {
|
const flasherTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, title, message } = envelope;
|
const { type, title, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const displayTitle = getTitle(title, type);
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const displayTitle = title || type.charAt(0).toUpperCase() + type.slice(1);
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-flasher fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('flasher')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div>
|
<div>
|
||||||
<strong class="fl-title">${displayTitle}</strong>
|
<strong class="${CLASS_NAMES.title}">${displayTitle}</strong>
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="fl-progress-bar">
|
<span class="${CLASS_NAMES.progressBar}">
|
||||||
<span class="fl-progress"></span>
|
<span class="${CLASS_NAMES.progress}"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+57
-12
@@ -9,25 +9,70 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
function capitalizeType(type) {
|
||||||
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
||||||
|
}
|
||||||
|
function getTitle(title, type) {
|
||||||
|
return title || DEFAULT_TITLES[type] || capitalizeType(type);
|
||||||
|
}
|
||||||
|
|
||||||
const flasherTheme = {
|
const flasherTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, title, message } = envelope;
|
const { type, title, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const displayTitle = getTitle(title, type);
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const displayTitle = title || type.charAt(0).toUpperCase() + type.slice(1);
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-flasher fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('flasher')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
<div>
|
<div>
|
||||||
<strong class="fl-title">${displayTitle}</strong>
|
<strong class="${CLASS_NAMES.title}">${displayTitle}</strong>
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<span class="fl-progress-bar">
|
<span class="${CLASS_NAMES.progressBar}">
|
||||||
<span class="fl-progress"></span>
|
<span class="${CLASS_NAMES.progress}"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("flasher",{render:e=>{const{type:s,title:n,message:a}=e,l="error"===s||"warning"===s,t=l?"alert":"status",r=l?"assertive":"polite",i=n||s.charAt(0).toUpperCase()+s.slice(1);return`\n <div class="fl-flasher fl-${s}" role="${t}" aria-live="${r}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-icon"></div>\n <div>\n <strong class="fl-title">${i}</strong>\n <span class="fl-message">${a}</span>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <span class="fl-progress-bar">\n <span class="fl-progress"></span>\n </span>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",s="fl-message",r="fl-title",a="fl-icon",t="fl-close",i="fl-progress-bar",o="fl-progress",l=e=>`fl-${e}`,f=e=>`fl-${e}`,c={success:"Success",error:"Error",warning:"Warning",info:"Information"};const u={render:e=>{const{type:u,title:d,message:$}=e,p=function(e,n){return e||c[n]||function(e){return e.charAt(0).toUpperCase()+e.slice(1)}(n)}(d,u);return`\n <div class="${f("flasher")} ${l(u)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(u)}>\n <div class="${n}">\n <div class="${a}"></div>\n <div>\n <strong class="${r}">${p}</strong>\n <span class="${s}">${$}</span>\n </div>\n <button class="${t}" ${function(e){return`aria-label="Close ${e} message"`}(u)}>×</button>\n </div>\n <span class="${i}">\n <span class="${o}"></span>\n </span>\n </div>`}};e.addTheme("flasher",u)}));
|
||||||
|
|||||||
+78
-36
@@ -5,55 +5,97 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TEXT = {
|
||||||
|
dismissButton: 'DISMISS'};
|
||||||
|
|
||||||
const googleTheme = {
|
const googleTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message, title } = envelope;
|
const { type, message, title } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const titleSection = title ? `<div class="${CLASS_NAMES.title}">${title}</div>` : '';
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const actionText = 'DISMISS';
|
|
||||||
const getIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'error':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'info':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
const titleSection = title ? `<div class="fl-title">${title}</div>` : '';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-google fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('google')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-md-card">
|
<div class="fl-md-card">
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon-wrapper">
|
<div class="${CLASS_NAMES.iconWrapper}">
|
||||||
${getIcon()}
|
${getTypeIcon(type, { size: 'lg', className: 'fl-icon-svg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
${titleSection}
|
${titleSection}
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-action-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-action-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
${actionText}
|
${DEFAULT_TEXT.dismissButton}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+78
-36
@@ -9,55 +9,97 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TEXT = {
|
||||||
|
dismissButton: 'DISMISS'};
|
||||||
|
|
||||||
const googleTheme = {
|
const googleTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message, title } = envelope;
|
const { type, message, title } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const titleSection = title ? `<div class="${CLASS_NAMES.title}">${title}</div>` : '';
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const actionText = 'DISMISS';
|
|
||||||
const getIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'error':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'info':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
const titleSection = title ? `<div class="fl-title">${title}</div>` : '';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-google fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('google')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-md-card">
|
<div class="fl-md-card">
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon-wrapper">
|
<div class="${CLASS_NAMES.iconWrapper}">
|
||||||
${getIcon()}
|
${getTypeIcon(type, { size: 'lg', className: 'fl-icon-svg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
${titleSection}
|
${titleSection}
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-action-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-action-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
${actionText}
|
${DEFAULT_TEXT.dismissButton}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(s,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],e):e((s="undefined"!=typeof globalThis?globalThis:s||self).flasher)}(this,(function(s){"use strict";s.addTheme("google",{render:s=>{const{type:e,message:n,title:l}=s,i="error"===e||"warning"===e,t=l?`<div class="fl-title">${l}</div>`:"";return`\n <div class="fl-google fl-${e}" role="${i?"alert":"status"}" aria-live="${i?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-md-card">\n <div class="fl-content">\n <div class="fl-icon-wrapper">\n ${(()=>{switch(e){case"success":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/>\n </svg>';case"warning":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z"/>\n </svg>';case"info":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-text-content">\n ${t}\n <div class="fl-message">${n}</div>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-action-button fl-close" aria-label="Close ${e} message">\n DISMISS\n </button>\n </div>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n={sm:16,md:20,lg:24},s={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function i(e,i={}){return"success"===e||"error"===e||"warning"===e||"info"===e?function(e,i={}){const{size:t="md",className:l=""}=i,r="number"==typeof t?t:n[t],a=s[e];return a?`<svg${l?` class="${l}"`:""} viewBox="0 0 24 24" width="${r}" height="${r}" aria-hidden="true"><path fill="currentColor" d="${a}"/></svg>`:""}(e,i):""}const t="fl-content",l="fl-message",r="fl-title",a="fl-icon-wrapper",o="fl-actions",c="fl-close",f="fl-progress-bar",d="fl-progress",v=e=>`fl-${e}`,u=e=>`fl-${e}`,$="DISMISS",h={render:e=>{const{type:n,message:s,title:h}=e,m=h?`<div class="${r}">${h}</div>`:"";return`\n <div class="${u("google")} ${v(n)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(n)}>\n <div class="fl-md-card">\n <div class="${t}">\n <div class="${a}">\n ${i(n,{size:"lg",className:"fl-icon-svg"})}\n </div>\n <div class="fl-text-content">\n ${m}\n <div class="${l}">${s}</div>\n </div>\n </div>\n <div class="${o}">\n <button class="fl-action-button ${c}" ${function(e){return`aria-label="Close ${e} message"`}(n)}>\n ${$}\n </button>\n </div>\n </div>\n <div class="${f}">\n <div class="${d}"></div>\n </div>\n </div>`}};e.addTheme("google",h)}));
|
||||||
|
|||||||
+77
-34
@@ -5,53 +5,96 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const APP_NAME = 'PHPFlasher';
|
||||||
|
function getTimeString() {
|
||||||
|
const now = new Date();
|
||||||
|
return now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
||||||
|
}
|
||||||
const iosTheme = {
|
const iosTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message, title } = envelope;
|
const { type, message, title } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const displayTitle = title || APP_NAME;
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const appName = 'PHPFlasher';
|
|
||||||
const now = new Date();
|
|
||||||
const timeString = now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
|
||||||
const getIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'error':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'info':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
const displayTitle = title || appName;
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-ios fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('ios')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-ios-notification">
|
<div class="fl-ios-notification">
|
||||||
<div class="fl-header">
|
<div class="fl-header">
|
||||||
<div class="fl-app-icon">
|
<div class="fl-app-icon">
|
||||||
${getIcon()}
|
${getTypeIcon(type, { size: 'md', className: 'fl-icon-svg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-app-info">
|
<div class="fl-app-info">
|
||||||
<div class="fl-app-name">${displayTitle}</div>
|
<div class="fl-app-name">${displayTitle}</div>
|
||||||
<div class="fl-time">${timeString}</div>
|
<div class="fl-time">${getTimeString()}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+77
-34
@@ -9,53 +9,96 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const APP_NAME = 'PHPFlasher';
|
||||||
|
function getTimeString() {
|
||||||
|
const now = new Date();
|
||||||
|
return now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
||||||
|
}
|
||||||
const iosTheme = {
|
const iosTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message, title } = envelope;
|
const { type, message, title } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const displayTitle = title || APP_NAME;
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const appName = 'PHPFlasher';
|
|
||||||
const now = new Date();
|
|
||||||
const timeString = now.toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' });
|
|
||||||
const getIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'error':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
|
|
||||||
</svg>`;
|
|
||||||
case 'info':
|
|
||||||
return `<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">
|
|
||||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
||||||
</svg>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
const displayTitle = title || appName;
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-ios fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('ios')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-ios-notification">
|
<div class="fl-ios-notification">
|
||||||
<div class="fl-header">
|
<div class="fl-header">
|
||||||
<div class="fl-app-icon">
|
<div class="fl-app-icon">
|
||||||
${getIcon()}
|
${getTypeIcon(type, { size: 'md', className: 'fl-icon-svg' })}
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-app-info">
|
<div class="fl-app-info">
|
||||||
<div class="fl-app-name">${displayTitle}</div>
|
<div class="fl-app-name">${displayTitle}</div>
|
||||||
<div class="fl-time">${timeString}</div>
|
<div class="fl-time">${getTimeString()}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s={render:e=>{const{type:s,message:i,title:n}=e,l="error"===s||"warning"===s,t=l?"alert":"status",a=l?"assertive":"polite",r=(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"}),o=n||"PHPFlasher";return`\n <div class="fl-ios fl-${s}" role="${t}" aria-live="${a}" aria-atomic="true">\n <div class="fl-ios-notification">\n <div class="fl-header">\n <div class="fl-app-icon">\n ${(()=>{switch(s){case"success":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>\n </svg>';case"warning":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>\n </svg>';case"info":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-app-info">\n <div class="fl-app-name">${o}</div>\n <div class="fl-time">${r}</div>\n </div>\n </div>\n <div class="fl-content">\n <div class="fl-message">${i}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n </div>`}};e.addTheme("ios",s)}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n={sm:16,md:20,lg:24},i={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function s(e,s={}){return"success"===e||"error"===e||"warning"===e||"info"===e?function(e,s={}){const{size:a="md",className:t=""}=s,r="number"==typeof a?a:n[a],l=i[e];return l?`<svg${t?` class="${t}"`:""} viewBox="0 0 24 24" width="${r}" height="${r}" aria-hidden="true"><path fill="currentColor" d="${l}"/></svg>`:""}(e,s):""}const a="fl-content",t="fl-message",r="fl-close",l=e=>`fl-${e}`,o=e=>`fl-${e}`;const c={render:e=>{const{type:n,message:i,title:c}=e,d=c||"PHPFlasher";return`\n <div class="${o("ios")} ${l(n)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(n)}>\n <div class="fl-ios-notification">\n <div class="fl-header">\n <div class="fl-app-icon">\n ${s(n,{size:"md",className:"fl-icon-svg"})}\n </div>\n <div class="fl-app-info">\n <div class="fl-app-name">${d}</div>\n <div class="fl-time">${(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}</div>\n </div>\n </div>\n <div class="${a}">\n <div class="${t}">${i}</div>\n </div>\n <button class="${r}" ${function(e){return`aria-label="Close ${e} message"`}(n)}>\n <span aria-hidden="true">×</span>\n </button>\n </div>\n </div>`}};e.addTheme("ios",c)}));
|
||||||
|
|||||||
+42
-9
@@ -5,20 +5,53 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const jadeTheme = {
|
const jadeTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-jade fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('jade')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+42
-9
@@ -9,20 +9,53 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const jadeTheme = {
|
const jadeTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-jade fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('jade')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("jade",{render:e=>{const{type:s,message:a}=e,l="error"===s||"warning"===s;return`\n <div class="fl-jade fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s="fl-content",n="fl-message",i="fl-close",a="fl-progress-bar",r="fl-progress",t=e=>`fl-${e}`,l=e=>`fl-${e}`,o={render:e=>{const{type:o,message:f}=e;return`\n <div class="${l("jade")} ${t(o)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(o)}>\n <div class="${s}">\n <div class="${n}">${f}</div>\n <button class="${i}" ${function(e){return`aria-label="Close ${e} message"`}(o)}>×</button>\n </div>\n <div class="${a}">\n <div class="${r}"></div>\n </div>\n </div>`}};e.addTheme("jade",o)}));
|
||||||
|
|||||||
+46
-12
@@ -5,29 +5,63 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TEXT = {
|
||||||
|
dismissButton: 'DISMISS'};
|
||||||
|
|
||||||
const materialTheme = {
|
const materialTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const actionText = 'DISMISS';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-material fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('material')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-md-card">
|
<div class="fl-md-card">
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-action-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-action-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
${actionText}
|
${DEFAULT_TEXT.dismissButton}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+46
-12
@@ -9,29 +9,63 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TEXT = {
|
||||||
|
dismissButton: 'DISMISS'};
|
||||||
|
|
||||||
const materialTheme = {
|
const materialTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const actionText = 'DISMISS';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-material fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('material')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-md-card">
|
<div class="fl-md-card">
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text-content">
|
<div class="fl-text-content">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-action-button fl-close" aria-label="Close ${type} message">
|
<button class="fl-action-button ${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
${actionText}
|
${DEFAULT_TEXT.dismissButton}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("material",{render:e=>{const{type:s,message:n}=e,a="error"===s||"warning"===s;return`\n <div class="fl-material fl-${s}" role="${a?"alert":"status"}" aria-live="${a?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-md-card">\n <div class="fl-content">\n <div class="fl-text-content">\n <div class="fl-message">${n}</div>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-action-button fl-close" aria-label="Close ${s} message">\n DISMISS\n </button>\n </div>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",i="fl-message",s="fl-actions",a="fl-close",t="fl-progress-bar",r="fl-progress",l=e=>`fl-${e}`,o=e=>`fl-${e}`,f="DISMISS",c={render:e=>{const{type:c,message:d}=e;return`\n <div class="${o("material")} ${l(c)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(c)}>\n <div class="fl-md-card">\n <div class="${n}">\n <div class="fl-text-content">\n <div class="${i}">${d}</div>\n </div>\n </div>\n <div class="${s}">\n <button class="fl-action-button ${a}" ${function(e){return`aria-label="Close ${e} message"`}(c)}>\n ${f}\n </button>\n </div>\n </div>\n <div class="${t}">\n <div class="${r}"></div>\n </div>\n </div>`}};e.addTheme("material",c)}));
|
||||||
|
|||||||
+42
-9
@@ -5,20 +5,53 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const minimalTheme = {
|
const minimalTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-minimal fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('minimal')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+42
-9
@@ -9,20 +9,53 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const minimalTheme = {
|
const minimalTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-minimal fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('minimal')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("minimal",{render:e=>{const{type:s,message:i}=e,l="error"===s||"warning"===s;return`\n <div class="fl-minimal fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${i}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const i="fl-content",n="fl-message",s="fl-close",a="fl-progress-bar",r="fl-progress",t=e=>`fl-${e}`,l=e=>`fl-${e}`,o={render:e=>{const{type:o,message:f}=e;return`\n <div class="${l("minimal")} ${t(o)}" ${function(e){const i=function(e){const i="error"===e||"warning"===e;return{role:i?"alert":"status",ariaLive:i?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${i.role}" aria-live="${i.ariaLive}" aria-atomic="${i.ariaAtomic}"`}(o)}>\n <div class="${i}">\n <div class="${n}">${f}</div>\n <button class="${s}" ${function(e){return`aria-label="Close ${e} message"`}(o)}>×</button>\n </div>\n <div class="${a}">\n <div class="${r}"></div>\n </div>\n </div>`}};e.addTheme("minimal",o)}));
|
||||||
|
|||||||
+42
-9
@@ -5,20 +5,53 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const neonTheme = {
|
const neonTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-neon fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('neon')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+42
-9
@@ -9,20 +9,53 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const neonTheme = {
|
const neonTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-neon fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('neon')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("neon",{render:e=>{const{type:s,message:n}=e,l="error"===s||"warning"===s;return`\n <div class="fl-neon fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${n}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",s="fl-message",i="fl-close",r="fl-progress-bar",a="fl-progress",t=e=>`fl-${e}`,o=e=>`fl-${e}`,l={render:e=>{const{type:l,message:f}=e;return`\n <div class="${o("neon")} ${t(l)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(l)}>\n <div class="${n}">\n <div class="${s}">${f}</div>\n <button class="${i}" ${function(e){return`aria-label="Close ${e} message"`}(l)}>×</button>\n </div>\n <div class="${r}">\n <div class="${a}"></div>\n </div>\n </div>`}};e.addTheme("neon",l)}));
|
||||||
|
|||||||
+43
-10
@@ -5,22 +5,55 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const onyxTheme = {
|
const onyxTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-onyx fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('onyx')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+43
-10
@@ -9,22 +9,55 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const onyxTheme = {
|
const onyxTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-onyx fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('onyx')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("onyx",{render:e=>{const{type:s,message:n}=e,l="error"===s||"warning"===s;return`\n <div class="fl-onyx fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-text">\n <div class="fl-message">${n}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",s="fl-message",i="fl-text",r="fl-close",t="fl-progress-bar",a="fl-progress",l=e=>`fl-${e}`,o=e=>`fl-${e}`,f={render:e=>{const{type:f,message:c}=e;return`\n <div class="${o("onyx")} ${l(f)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(f)}>\n <div class="${n}">\n <div class="${i}">\n <div class="${s}">${c}</div>\n </div>\n <button class="${r}" ${function(e){return`aria-label="Close ${e} message"`}(f)}>×</button>\n </div>\n <div class="${t}">\n <div class="${a}"></div>\n </div>\n </div>`}};e.addTheme("onyx",f)}));
|
||||||
|
|||||||
+44
-11
@@ -5,26 +5,59 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const rubyTheme = {
|
const rubyTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-ruby fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('ruby')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-shine"></div>
|
<div class="fl-shine"></div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon-circle">
|
<div class="fl-icon-circle">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+44
-11
@@ -9,26 +9,59 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const rubyTheme = {
|
const rubyTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-ruby fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('ruby')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-shine"></div>
|
<div class="fl-shine"></div>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<div class="fl-icon-circle">
|
<div class="fl-icon-circle">
|
||||||
<div class="fl-icon"></div>
|
<div class="${CLASS_NAMES.icon}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-text">
|
<div class="${CLASS_NAMES.text}">
|
||||||
<div class="fl-message">${message}</div>
|
<div class="${CLASS_NAMES.message}">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="fl-close" aria-label="Close ${type} message">×</button>
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("ruby",{render:e=>{const{type:s,message:i}=e,l="error"===s||"warning"===s;return`\n <div class="fl-ruby fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-shine"></div>\n <div class="fl-content">\n <div class="fl-icon-circle">\n <div class="fl-icon"></div>\n </div>\n <div class="fl-text">\n <div class="fl-message">${i}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):i((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const i="fl-content",s="fl-message",n="fl-text",r="fl-icon",a="fl-close",l="fl-progress-bar",t="fl-progress",o=e=>`fl-${e}`,f=e=>`fl-${e}`,c={render:e=>{const{type:c,message:d}=e;return`\n <div class="${f("ruby")} ${o(c)}" ${function(e){const i=function(e){const i="error"===e||"warning"===e;return{role:i?"alert":"status",ariaLive:i?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${i.role}" aria-live="${i.ariaLive}" aria-atomic="${i.ariaAtomic}"`}(c)}>\n <div class="fl-shine"></div>\n <div class="${i}">\n <div class="fl-icon-circle">\n <div class="${r}"></div>\n </div>\n <div class="${n}">\n <div class="${s}">${d}</div>\n </div>\n <button class="${a}" ${function(e){return`aria-label="Close ${e} message"`}(c)}>×</button>\n </div>\n <div class="${l}">\n <div class="${t}"></div>\n </div>\n </div>`}};e.addTheme("ruby",c)}));
|
||||||
|
|||||||
+38
-8
@@ -5,19 +5,49 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const sapphireTheme = {
|
const sapphireTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-sapphire fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('sapphire')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
+38
-8
@@ -9,19 +9,49 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
const sapphireTheme = {
|
const sapphireTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-sapphire fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('sapphire')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-content">
|
<div class="${CLASS_NAMES.content}">
|
||||||
<span class="fl-message">${message}</span>
|
<span class="${CLASS_NAMES.message}">${message}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-progress-bar">
|
<div class="${CLASS_NAMES.progressBar}">
|
||||||
<div class="fl-progress"></div>
|
<div class="${CLASS_NAMES.progress}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("sapphire",{render:e=>{const{type:s,message:a}=e,i="error"===s||"warning"===s;return`\n <div class="fl-sapphire fl-${s}" role="${i?"alert":"status"}" aria-live="${i?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <span class="fl-message">${a}</span>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s="fl-content",i="fl-message",r="fl-progress-bar",n="fl-progress",a=e=>`fl-${e}`,t=e=>`fl-${e}`,o={render:e=>{const{type:o,message:l}=e;return`\n <div class="${t("sapphire")} ${a(o)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(o)}>\n <div class="${s}">\n <span class="${i}">${l}</span>\n </div>\n <div class="${r}">\n <div class="${n}"></div>\n </div>\n </div>`}};e.addTheme("sapphire",o)}));
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export type NotificationType = 'success' | 'info' | 'warning' | 'error';
|
||||||
|
export interface A11yAttributes {
|
||||||
|
role: 'alert' | 'status';
|
||||||
|
ariaLive: 'assertive' | 'polite';
|
||||||
|
ariaAtomic: 'true';
|
||||||
|
}
|
||||||
|
export declare function getA11yAttributes(type: NotificationType | string): A11yAttributes;
|
||||||
|
export declare function getA11yString(type: NotificationType | string): string;
|
||||||
|
export declare function getCloseButtonA11y(type: NotificationType | string): string;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
export declare const CLASS_NAMES: {
|
||||||
|
readonly container: "fl-container";
|
||||||
|
readonly wrapper: "fl-wrapper";
|
||||||
|
readonly content: "fl-content";
|
||||||
|
readonly message: "fl-message";
|
||||||
|
readonly title: "fl-title";
|
||||||
|
readonly text: "fl-text";
|
||||||
|
readonly icon: "fl-icon";
|
||||||
|
readonly iconWrapper: "fl-icon-wrapper";
|
||||||
|
readonly actions: "fl-actions";
|
||||||
|
readonly close: "fl-close";
|
||||||
|
readonly progressBar: "fl-progress-bar";
|
||||||
|
readonly progress: "fl-progress";
|
||||||
|
readonly show: "fl-show";
|
||||||
|
readonly sticky: "fl-sticky";
|
||||||
|
readonly rtl: "fl-rtl";
|
||||||
|
readonly type: (type: string) => string;
|
||||||
|
readonly theme: (name: string) => string;
|
||||||
|
};
|
||||||
|
export declare const DEFAULT_TITLES: Record<string, string>;
|
||||||
|
export declare const DEFAULT_TEXT: {
|
||||||
|
readonly dismissButton: "DISMISS";
|
||||||
|
readonly closeLabel: (type: string) => string;
|
||||||
|
};
|
||||||
|
export declare function capitalizeType(type: string): string;
|
||||||
|
export declare function getTitle(title: string | undefined, type: string): string;
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export type IconType = 'success' | 'info' | 'warning' | 'error' | 'close';
|
||||||
|
export type IconSize = 'sm' | 'md' | 'lg' | number;
|
||||||
|
export interface IconConfig {
|
||||||
|
size?: IconSize;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
export declare function getIcon(type: IconType, config?: IconConfig): string;
|
||||||
|
export declare function getCloseIcon(config?: IconConfig): string;
|
||||||
|
export declare function getTypeIcon(type: string, config?: IconConfig): string;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export { getIcon, getCloseIcon, getTypeIcon } from './icons';
|
||||||
|
export type { IconType, IconSize, IconConfig } from './icons';
|
||||||
|
export { getA11yAttributes, getA11yString, getCloseButtonA11y } from './accessibility';
|
||||||
|
export type { NotificationType, A11yAttributes } from './accessibility';
|
||||||
|
export { CLASS_NAMES, DEFAULT_TITLES, DEFAULT_TEXT, capitalizeType, getTitle, } from './constants';
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* @package PHPFlasher
|
||||||
|
* @author Younes ENNAJI
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
const DEFAULT_TEXT = {
|
||||||
|
dismissButton: 'DISMISS',
|
||||||
|
closeLabel: (type) => `Close ${type} message`,
|
||||||
|
};
|
||||||
|
function capitalizeType(type) {
|
||||||
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
||||||
|
}
|
||||||
|
function getTitle(title, type) {
|
||||||
|
return title || DEFAULT_TITLES[type] || capitalizeType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { CLASS_NAMES, DEFAULT_TEXT, DEFAULT_TITLES, capitalizeType, getA11yAttributes, getA11yString, getCloseButtonA11y, getCloseIcon, getIcon, getTitle, getTypeIcon };
|
||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* @package PHPFlasher
|
||||||
|
* @author Younes ENNAJI
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||||
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.theme = global.theme || {}, global.theme.shared = {})));
|
||||||
|
})(this, (function (exports) { 'use strict';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
if (!path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
function getTypeIcon(type, config = {}) {
|
||||||
|
if (type === 'success' || type === 'error' || type === 'warning' || type === 'info') {
|
||||||
|
return getIcon(type, config);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
const DEFAULT_TITLES = {
|
||||||
|
success: 'Success',
|
||||||
|
error: 'Error',
|
||||||
|
warning: 'Warning',
|
||||||
|
info: 'Information',
|
||||||
|
};
|
||||||
|
const DEFAULT_TEXT = {
|
||||||
|
dismissButton: 'DISMISS',
|
||||||
|
closeLabel: (type) => `Close ${type} message`,
|
||||||
|
};
|
||||||
|
function capitalizeType(type) {
|
||||||
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
||||||
|
}
|
||||||
|
function getTitle(title, type) {
|
||||||
|
return title || DEFAULT_TITLES[type] || capitalizeType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.CLASS_NAMES = CLASS_NAMES;
|
||||||
|
exports.DEFAULT_TEXT = DEFAULT_TEXT;
|
||||||
|
exports.DEFAULT_TITLES = DEFAULT_TITLES;
|
||||||
|
exports.capitalizeType = capitalizeType;
|
||||||
|
exports.getA11yAttributes = getA11yAttributes;
|
||||||
|
exports.getA11yString = getA11yString;
|
||||||
|
exports.getCloseButtonA11y = getCloseButtonA11y;
|
||||||
|
exports.getCloseIcon = getCloseIcon;
|
||||||
|
exports.getIcon = getIcon;
|
||||||
|
exports.getTitle = getTitle;
|
||||||
|
exports.getTypeIcon = getTypeIcon;
|
||||||
|
|
||||||
|
}));
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).theme=e.theme||{},e.theme.shared={}))}(this,(function(e){"use strict";const t={sm:16,md:20,lg:24},r={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function n(e,n={}){const{size:s="md",className:o=""}=n,i="number"==typeof s?s:t[s],l=r[e];if(!l)return"";return`<svg${o?` class="${o}"`:""} viewBox="0 0 24 24" width="${i}" height="${i}" aria-hidden="true"><path fill="currentColor" d="${l}"/></svg>`}function s(e){const t="error"===e||"warning"===e;return{role:t?"alert":"status",ariaLive:t?"assertive":"polite",ariaAtomic:"true"}}const o={success:"Success",error:"Error",warning:"Warning",info:"Information"};function i(e){return e.charAt(0).toUpperCase()+e.slice(1)}e.CLASS_NAMES={container:"fl-container",wrapper:"fl-wrapper",content:"fl-content",message:"fl-message",title:"fl-title",text:"fl-text",icon:"fl-icon",iconWrapper:"fl-icon-wrapper",actions:"fl-actions",close:"fl-close",progressBar:"fl-progress-bar",progress:"fl-progress",show:"fl-show",sticky:"fl-sticky",rtl:"fl-rtl",type:e=>`fl-${e}`,theme:e=>`fl-${e}`},e.DEFAULT_TEXT={dismissButton:"DISMISS",closeLabel:e=>`Close ${e} message`},e.DEFAULT_TITLES=o,e.capitalizeType=i,e.getA11yAttributes=s,e.getA11yString=function(e){const t=s(e);return`role="${t.role}" aria-live="${t.ariaLive}" aria-atomic="${t.ariaAtomic}"`},e.getCloseButtonA11y=function(e){return`aria-label="Close ${e} message"`},e.getCloseIcon=function(e={}){return n("close",Object.assign({size:"sm"},e))},e.getIcon=n,e.getTitle=function(e,t){return e||o[t]||i(t)},e.getTypeIcon=function(e,t={}){return"success"===e||"error"===e||"warning"===e||"info"===e?n(e,t):""}}));
|
||||||
+71
-23
@@ -5,39 +5,87 @@
|
|||||||
*/
|
*/
|
||||||
import flasher from '@flasher/flasher';
|
import flasher from '@flasher/flasher';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const TYPE_ICONS = {
|
||||||
|
success: '✓',
|
||||||
|
error: '✕',
|
||||||
|
warning: '!',
|
||||||
|
info: 'i',
|
||||||
|
};
|
||||||
const slackTheme = {
|
const slackTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const iconChar = TYPE_ICONS[type] || '';
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const getTypeIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<div class="fl-type-icon fl-success-icon">✓</div>`;
|
|
||||||
case 'error':
|
|
||||||
return `<div class="fl-type-icon fl-error-icon">✕</div>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<div class="fl-type-icon fl-warning-icon">!</div>`;
|
|
||||||
case 'info':
|
|
||||||
return `<div class="fl-type-icon fl-info-icon">i</div>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-slack fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('slack')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-slack-message">
|
<div class="fl-slack-message">
|
||||||
<div class="fl-avatar">
|
<div class="fl-avatar">
|
||||||
${getTypeIcon()}
|
<div class="fl-type-icon fl-${type}-icon">${iconChar}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-message-content">
|
<div class="fl-message-content">
|
||||||
<div class="fl-message-text">${message}</div>
|
<div class="fl-message-text">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-close" aria-label="Close ${type} message">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<svg viewBox="0 0 20 20" width="16" height="16">
|
${getCloseIcon()}
|
||||||
<path fill="currentColor" d="M10 8.586L6.707 5.293a1 1 0 00-1.414 1.414L8.586 10l-3.293 3.293a1 1 0 101.414 1.414L10 11.414l3.293 3.293a1 1 0 001.414-1.414L11.414 10l3.293-3.293a1 1 0 00-1.414-1.414L10 8.586z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+71
-23
@@ -9,39 +9,87 @@
|
|||||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.flasher));
|
||||||
})(this, (function (flasher) { 'use strict';
|
})(this, (function (flasher) { 'use strict';
|
||||||
|
|
||||||
|
const sizeMap = {
|
||||||
|
sm: 16,
|
||||||
|
md: 20,
|
||||||
|
lg: 24,
|
||||||
|
};
|
||||||
|
const iconPaths = {
|
||||||
|
success: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z',
|
||||||
|
error: 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z',
|
||||||
|
warning: 'M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z',
|
||||||
|
info: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z',
|
||||||
|
close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
|
||||||
|
};
|
||||||
|
function getIcon(type, config = {}) {
|
||||||
|
const { size = 'md', className = '' } = config;
|
||||||
|
const dimension = typeof size === 'number' ? size : sizeMap[size];
|
||||||
|
const path = iconPaths[type];
|
||||||
|
const classAttr = className ? ` class="${className}"` : '';
|
||||||
|
return `<svg${classAttr} viewBox="0 0 24 24" width="${dimension}" height="${dimension}" aria-hidden="true"><path fill="currentColor" d="${path}"/></svg>`;
|
||||||
|
}
|
||||||
|
function getCloseIcon(config = {}) {
|
||||||
|
return getIcon('close', Object.assign({ size: 'sm' }, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getA11yAttributes(type) {
|
||||||
|
const isAlert = type === 'error' || type === 'warning';
|
||||||
|
return {
|
||||||
|
role: isAlert ? 'alert' : 'status',
|
||||||
|
ariaLive: isAlert ? 'assertive' : 'polite',
|
||||||
|
ariaAtomic: 'true',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getA11yString(type) {
|
||||||
|
const attrs = getA11yAttributes(type);
|
||||||
|
return `role="${attrs.role}" aria-live="${attrs.ariaLive}" aria-atomic="${attrs.ariaAtomic}"`;
|
||||||
|
}
|
||||||
|
function getCloseButtonA11y(type) {
|
||||||
|
return `aria-label="Close ${type} message"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLASS_NAMES = {
|
||||||
|
container: 'fl-container',
|
||||||
|
wrapper: 'fl-wrapper',
|
||||||
|
content: 'fl-content',
|
||||||
|
message: 'fl-message',
|
||||||
|
title: 'fl-title',
|
||||||
|
text: 'fl-text',
|
||||||
|
icon: 'fl-icon',
|
||||||
|
iconWrapper: 'fl-icon-wrapper',
|
||||||
|
actions: 'fl-actions',
|
||||||
|
close: 'fl-close',
|
||||||
|
progressBar: 'fl-progress-bar',
|
||||||
|
progress: 'fl-progress',
|
||||||
|
show: 'fl-show',
|
||||||
|
sticky: 'fl-sticky',
|
||||||
|
rtl: 'fl-rtl',
|
||||||
|
type: (type) => `fl-${type}`,
|
||||||
|
theme: (name) => `fl-${name}`,
|
||||||
|
};
|
||||||
|
|
||||||
|
const TYPE_ICONS = {
|
||||||
|
success: '✓',
|
||||||
|
error: '✕',
|
||||||
|
warning: '!',
|
||||||
|
info: 'i',
|
||||||
|
};
|
||||||
const slackTheme = {
|
const slackTheme = {
|
||||||
render: (envelope) => {
|
render: (envelope) => {
|
||||||
const { type, message } = envelope;
|
const { type, message } = envelope;
|
||||||
const isAlert = type === 'error' || type === 'warning';
|
const iconChar = TYPE_ICONS[type] || '';
|
||||||
const role = isAlert ? 'alert' : 'status';
|
|
||||||
const ariaLive = isAlert ? 'assertive' : 'polite';
|
|
||||||
const getTypeIcon = () => {
|
|
||||||
switch (type) {
|
|
||||||
case 'success':
|
|
||||||
return `<div class="fl-type-icon fl-success-icon">✓</div>`;
|
|
||||||
case 'error':
|
|
||||||
return `<div class="fl-type-icon fl-error-icon">✕</div>`;
|
|
||||||
case 'warning':
|
|
||||||
return `<div class="fl-type-icon fl-warning-icon">!</div>`;
|
|
||||||
case 'info':
|
|
||||||
return `<div class="fl-type-icon fl-info-icon">i</div>`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
return `
|
return `
|
||||||
<div class="fl-slack fl-${type}" role="${role}" aria-live="${ariaLive}" aria-atomic="true">
|
<div class="${CLASS_NAMES.theme('slack')} ${CLASS_NAMES.type(type)}" ${getA11yString(type)}>
|
||||||
<div class="fl-slack-message">
|
<div class="fl-slack-message">
|
||||||
<div class="fl-avatar">
|
<div class="fl-avatar">
|
||||||
${getTypeIcon()}
|
<div class="fl-type-icon fl-${type}-icon">${iconChar}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-message-content">
|
<div class="fl-message-content">
|
||||||
<div class="fl-message-text">${message}</div>
|
<div class="fl-message-text">${message}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fl-actions">
|
<div class="${CLASS_NAMES.actions}">
|
||||||
<button class="fl-close" aria-label="Close ${type} message">
|
<button class="${CLASS_NAMES.close}" ${getCloseButtonA11y(type)}>
|
||||||
<svg viewBox="0 0 20 20" width="16" height="16">
|
${getCloseIcon()}
|
||||||
<path fill="currentColor" d="M10 8.586L6.707 5.293a1 1 0 00-1.414 1.414L8.586 10l-3.293 3.293a1 1 0 101.414 1.414L10 11.414l3.293 3.293a1 1 0 001.414-1.414L11.414 10l3.293-3.293a1 1 0 00-1.414-1.414L10 8.586z"/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("slack",{render:e=>{const{type:s,message:i}=e,n="error"===s||"warning"===s;return`\n <div class="fl-slack fl-${s}" role="${n?"alert":"status"}" aria-live="${n?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-slack-message">\n <div class="fl-avatar">\n ${(()=>{switch(s){case"success":return'<div class="fl-type-icon fl-success-icon">✓</div>';case"error":return'<div class="fl-type-icon fl-error-icon">✕</div>';case"warning":return'<div class="fl-type-icon fl-warning-icon">!</div>';case"info":return'<div class="fl-type-icon fl-info-icon">i</div>'}return""})()}\n </div>\n <div class="fl-message-content">\n <div class="fl-message-text">${i}</div>\n </div>\n <div class="fl-actions">\n <button class="fl-close" aria-label="Close ${s} message">\n <svg viewBox="0 0 20 20" width="16" height="16">\n <path fill="currentColor" d="M10 8.586L6.707 5.293a1 1 0 00-1.414 1.414L8.586 10l-3.293 3.293a1 1 0 101.414 1.414L10 11.414l3.293 3.293a1 1 0 001.414-1.414L11.414 10l3.293-3.293a1 1 0 00-1.414-1.414L10 8.586z"/>\n </svg>\n </button>\n </div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s={sm:16,md:20,lg:24},n={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function i(e={}){return function(e,i={}){const{size:a="md",className:t=""}=i,r="number"==typeof a?a:s[a];return`<svg${t?` class="${t}"`:""} viewBox="0 0 24 24" width="${r}" height="${r}" aria-hidden="true"><path fill="currentColor" d="${n[e]}"/></svg>`}("close",Object.assign({size:"sm"},e))}const a="fl-actions",t="fl-close",r=e=>`fl-${e}`,l=e=>`fl-${e}`,o={success:"✓",error:"✕",warning:"!",info:"i"},c={render:e=>{const{type:s,message:n}=e,c=o[s]||"";return`\n <div class="${l("slack")} ${r(s)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(s)}>\n <div class="fl-slack-message">\n <div class="fl-avatar">\n <div class="fl-type-icon fl-${s}-icon">${c}</div>\n </div>\n <div class="fl-message-content">\n <div class="fl-message-text">${n}</div>\n </div>\n <div class="${a}">\n <button class="${t}" ${function(e){return`aria-label="Close ${e} message"`}(s)}>\n ${i()}\n </button>\n </div>\n </div>\n </div>`}};e.addTheme("slack",c)}));
|
||||||
|
|||||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("amazon",{render:e=>{const{type:n,message:t}=e,r="error"===n||"warning"===n;return`\n <div class="fl-amazon fl-${n}" role="${r?"alert":"status"}" aria-live="${r?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-amazon-alert">\n <div class="fl-alert-content">\n <div class="fl-icon-container">\n ${(()=>{switch(n){case"success":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>\n </svg>';case"warning":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>\n </svg>';case"info":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-text-content">\n <div class="fl-alert-title">${(()=>{switch(n){case"success":return"Success!";case"error":return"Problem";case"warning":return"Warning";case"info":return"Information";default:return"Alert"}})()}</div>\n <div class="fl-alert-message">${t}</div>\n </div>\n </div>\n <div class="fl-alert-actions">\n <button class="fl-close" aria-label="Close notification">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>\n </svg>\n </button>\n </div>\n </div>\n </div>`}})}));
|
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).flasher)}(this,(function(n){"use strict";const e={sm:16,md:20,lg:24},s={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function r(n,r={}){const{size:i="md",className:t=""}=r,a="number"==typeof i?i:e[i],o=s[n];if(!o)return"";return`<svg${t?` class="${t}"`:""} viewBox="0 0 24 24" width="${a}" height="${a}" aria-hidden="true"><path fill="currentColor" d="${o}"/></svg>`}const i="fl-close",t=n=>`fl-${n}`,a=n=>`fl-${n}`,o={success:"Success",error:"Error",warning:"Warning",info:"Information"},l={success:"Success!",error:"Problem",warning:"Warning",info:"Information"},c={render:n=>{const{type:e,message:s}=n,c=l[e]||o[e]||"Alert";return`\n <div class="${a("amazon")} ${t(e)}" ${function(n){const e=function(n){const e="error"===n||"warning"===n;return{role:e?"alert":"status",ariaLive:e?"assertive":"polite",ariaAtomic:"true"}}(n);return`role="${e.role}" aria-live="${e.ariaLive}" aria-atomic="${e.ariaAtomic}"`}(e)}>\n <div class="fl-amazon-alert">\n <div class="fl-alert-content">\n <div class="fl-icon-container">\n ${function(n,e={}){return"success"===n||"error"===n||"warning"===n||"info"===n?r(n,e):""}(e,{size:"lg"})}\n </div>\n <div class="fl-text-content">\n <div class="fl-alert-title">${c}</div>\n <div class="fl-alert-message">${s}</div>\n </div>\n </div>\n <div class="fl-alert-actions">\n <button class="${i}" ${function(n){return`aria-label="Close ${n} message"`}(e)}>\n ${function(n={}){return r("close",Object.assign({size:"sm"},n))}()}\n </button>\n </div>\n </div>\n </div>`}};n.addTheme("amazon",c)}));
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("amber",{render:e=>{const{type:s,message:i}=e,l="error"===s||"warning"===s;return`\n <div class="fl-amber fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-icon"></div>\n <div class="fl-text">\n <div class="fl-message">${i}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s="fl-content",i="fl-message",n="fl-text",a="fl-icon",r="fl-close",t="fl-progress-bar",l="fl-progress",o=e=>`fl-${e}`,f=e=>`fl-${e}`,c={render:e=>{const{type:c,message:d}=e;return`\n <div class="${f("amber")} ${o(c)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(c)}>\n <div class="${s}">\n <div class="${a}"></div>\n <div class="${n}">\n <div class="${i}">${d}</div>\n </div>\n <button class="${r}" ${function(e){return`aria-label="Close ${e} message"`}(c)}>×</button>\n </div>\n <div class="${t}">\n <div class="${l}"></div>\n </div>\n </div>`}};e.addTheme("amber",c)}));
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("aurora",{render:e=>{const{type:s,message:a}=e,r="error"===s||"warning"===s;return`\n <div class="fl-aurora fl-${s}" role="${r?"alert":"status"}" aria-live="${r?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],r):r((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const r="fl-content",s="fl-message",a="fl-close",n="fl-progress-bar",i="fl-progress",t=e=>`fl-${e}`,o=e=>`fl-${e}`,l={render:e=>{const{type:l,message:f}=e;return`\n <div class="${o("aurora")} ${t(l)}" ${function(e){const r=function(e){const r="error"===e||"warning"===e;return{role:r?"alert":"status",ariaLive:r?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${r.role}" aria-live="${r.ariaLive}" aria-atomic="${r.ariaAtomic}"`}(l)}>\n <div class="${r}">\n <div class="${s}">${f}</div>\n <button class="${a}" ${function(e){return`aria-label="Close ${e} message"`}(l)}>×</button>\n </div>\n <div class="${n}">\n <div class="${i}"></div>\n </div>\n </div>`}};e.addTheme("aurora",l)}));
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("crystal",{render:e=>{const{type:s,message:l}=e,a="error"===s||"warning"===s;return`\n <div class="fl-crystal fl-${s}" role="${a?"alert":"status"}" aria-live="${a?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-text">\n <p class="fl-message">${l}</p>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s="fl-content",n="fl-message",r="fl-text",t="fl-close",a="fl-progress-bar",i="fl-progress",l=e=>`fl-${e}`,o=e=>`fl-${e}`,f={render:e=>{const{type:f,message:c}=e;return`\n <div class="${o("crystal")} ${l(f)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(f)}>\n <div class="${s}">\n <div class="${r}">\n <p class="${n}">${c}</p>\n </div>\n <button class="${t}" ${function(e){return`aria-label="Close ${e} message"`}(f)}>×</button>\n </div>\n <div class="${a}">\n <div class="${i}"></div>\n </div>\n </div>`}};e.addTheme("crystal",f)}));
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("emerald",{render:e=>{const{type:s,message:a}=e,l="error"===s||"warning"===s;return`\n <div class="fl-emerald fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",t="fl-message",a="fl-close",i=e=>`fl-${e}`,r=e=>`fl-${e}`,s={render:e=>{const{type:s,message:l}=e;return`\n <div class="${r("emerald")} ${i(s)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(s)}>\n <div class="${n}">\n <div class="${t}">${l}</div>\n <button class="${a}" ${function(e){return`aria-label="Close ${e} message"`}(s)}>×</button>\n </div>\n </div>`}};e.addTheme("emerald",s)}));
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(n,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):i((n="undefined"!=typeof globalThis?globalThis:n||self).flasher)}(this,(function(n){"use strict";const i={render:n=>{const{type:i,message:e}=n,s="error"===i||"warning"===i,t=s?"alert":"status",l=s?"assertive":"polite",o=(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"});return`\n <div class="fl-facebook fl-${i}" role="${t}" aria-live="${l}" aria-atomic="true">\n <div class="fl-fb-notification">\n <div class="fl-icon-container">\n ${(()=>{switch(i){case"success":return'<div class="fl-fb-icon fl-fb-icon-success">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z"/>\n </svg>\n </div>';case"error":return'<div class="fl-fb-icon fl-fb-icon-error">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.5c-.69 0-1.25.56-1.25 1.25S11.31 13 12 13s1.25-.56 1.25-1.25S12.69 10.5 12 10.5zM12 9c.552 0 1-.448 1-1V7c0-.552-.448-1-1-1s-1 .448-1 1v1c0 .552.448 1 1 1z"/>\n </svg>\n </div>';case"warning":return'<div class="fl-fb-icon fl-fb-icon-warning">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.409 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72192 12.7772 2.84815 12.865 3.00017ZM11 16.0002V18.0002H13V16.0002H11ZM11 8.00017V14.0002H13V8.00017H11Z"/>\n </svg>\n </div>';case"info":return'<div class="fl-fb-icon fl-fb-icon-info">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v-2h-2v2zm0-4h2V7h-2v4z"/>\n </svg>\n </div>'}return""})()}\n </div>\n <div class="fl-content">\n <div class="fl-message">\n ${e}\n </div>\n <div class="fl-meta">\n <span class="fl-time">${o}</span>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-button fl-close" aria-label="Close ${i} message">\n <div class="fl-button-icon">\n <svg viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>\n </svg>\n </div>\n </button>\n </div>\n </div>\n </div>`}};n.addTheme("facebook",i)}));
|
!function(n,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):i((n="undefined"!=typeof globalThis?globalThis:n||self).flasher)}(this,(function(n){"use strict";const i={sm:16,md:20,lg:24},e={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function s(n={}){return function(n,s={}){const{size:t="md",className:o=""}=s,r="number"==typeof t?t:i[t];return`<svg${o?` class="${o}"`:""} viewBox="0 0 24 24" width="${r}" height="${r}" aria-hidden="true"><path fill="currentColor" d="${e[n]}"/></svg>`}("close",Object.assign({size:"sm"},n))}const t="fl-content",o="fl-message",r="fl-actions",l="fl-close",c=n=>`fl-${n}`,a=n=>`fl-${n}`;const f={render:n=>{const{type:i,message:e}=n;return`\n <div class="${a("facebook")} ${c(i)}" ${function(n){const i=function(n){const i="error"===n||"warning"===n;return{role:i?"alert":"status",ariaLive:i?"assertive":"polite",ariaAtomic:"true"}}(n);return`role="${i.role}" aria-live="${i.ariaLive}" aria-atomic="${i.ariaAtomic}"`}(i)}>\n <div class="fl-fb-notification">\n <div class="fl-icon-container">\n ${(()=>{switch(i){case"success":return'<div class="fl-fb-icon fl-fb-icon-success">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z"/>\n </svg>\n </div>';case"error":return'<div class="fl-fb-icon fl-fb-icon-error">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.5c-.69 0-1.25.56-1.25 1.25S11.31 13 12 13s1.25-.56 1.25-1.25S12.69 10.5 12 10.5zM12 9c.552 0 1-.448 1-1V7c0-.552-.448-1-1-1s-1 .448-1 1v1c0 .552.448 1 1 1z"/>\n </svg>\n </div>';case"warning":return'<div class="fl-fb-icon fl-fb-icon-warning">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.409 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72192 12.7772 2.84815 12.865 3.00017ZM11 16.0002V18.0002H13V16.0002H11ZM11 8.00017V14.0002H13V8.00017H11Z"/>\n </svg>\n </div>';case"info":return'<div class="fl-fb-icon fl-fb-icon-info">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v-2h-2v2zm0-4h2V7h-2v4z"/>\n </svg>\n </div>'}return""})()}\n </div>\n <div class="${t}">\n <div class="${o}">\n ${e}\n </div>\n <div class="fl-meta">\n <span class="fl-time">${(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}</span>\n </div>\n </div>\n <div class="${r}">\n <button class="fl-button ${l}" ${function(n){return`aria-label="Close ${n} message"`}(i)}>\n <div class="fl-button-icon">\n ${s({size:"md"})}\n </div>\n </button>\n </div>\n </div>\n </div>`}};n.addTheme("facebook",f)}));
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("flasher",{render:e=>{const{type:s,title:n,message:a}=e,l="error"===s||"warning"===s,t=l?"alert":"status",r=l?"assertive":"polite",i=n||s.charAt(0).toUpperCase()+s.slice(1);return`\n <div class="fl-flasher fl-${s}" role="${t}" aria-live="${r}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-icon"></div>\n <div>\n <strong class="fl-title">${i}</strong>\n <span class="fl-message">${a}</span>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <span class="fl-progress-bar">\n <span class="fl-progress"></span>\n </span>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",s="fl-message",r="fl-title",a="fl-icon",t="fl-close",i="fl-progress-bar",o="fl-progress",l=e=>`fl-${e}`,f=e=>`fl-${e}`,c={success:"Success",error:"Error",warning:"Warning",info:"Information"};const u={render:e=>{const{type:u,title:d,message:$}=e,p=function(e,n){return e||c[n]||function(e){return e.charAt(0).toUpperCase()+e.slice(1)}(n)}(d,u);return`\n <div class="${f("flasher")} ${l(u)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(u)}>\n <div class="${n}">\n <div class="${a}"></div>\n <div>\n <strong class="${r}">${p}</strong>\n <span class="${s}">${$}</span>\n </div>\n <button class="${t}" ${function(e){return`aria-label="Close ${e} message"`}(u)}>×</button>\n </div>\n <span class="${i}">\n <span class="${o}"></span>\n </span>\n </div>`}};e.addTheme("flasher",u)}));
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(s,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],e):e((s="undefined"!=typeof globalThis?globalThis:s||self).flasher)}(this,(function(s){"use strict";s.addTheme("google",{render:s=>{const{type:e,message:n,title:l}=s,i="error"===e||"warning"===e,t=l?`<div class="fl-title">${l}</div>`:"";return`\n <div class="fl-google fl-${e}" role="${i?"alert":"status"}" aria-live="${i?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-md-card">\n <div class="fl-content">\n <div class="fl-icon-wrapper">\n ${(()=>{switch(e){case"success":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/>\n </svg>';case"warning":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z"/>\n </svg>';case"info":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-text-content">\n ${t}\n <div class="fl-message">${n}</div>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-action-button fl-close" aria-label="Close ${e} message">\n DISMISS\n </button>\n </div>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n={sm:16,md:20,lg:24},s={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function i(e,i={}){return"success"===e||"error"===e||"warning"===e||"info"===e?function(e,i={}){const{size:t="md",className:l=""}=i,r="number"==typeof t?t:n[t],a=s[e];return a?`<svg${l?` class="${l}"`:""} viewBox="0 0 24 24" width="${r}" height="${r}" aria-hidden="true"><path fill="currentColor" d="${a}"/></svg>`:""}(e,i):""}const t="fl-content",l="fl-message",r="fl-title",a="fl-icon-wrapper",o="fl-actions",c="fl-close",f="fl-progress-bar",d="fl-progress",v=e=>`fl-${e}`,u=e=>`fl-${e}`,$="DISMISS",h={render:e=>{const{type:n,message:s,title:h}=e,m=h?`<div class="${r}">${h}</div>`:"";return`\n <div class="${u("google")} ${v(n)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(n)}>\n <div class="fl-md-card">\n <div class="${t}">\n <div class="${a}">\n ${i(n,{size:"lg",className:"fl-icon-svg"})}\n </div>\n <div class="fl-text-content">\n ${m}\n <div class="${l}">${s}</div>\n </div>\n </div>\n <div class="${o}">\n <button class="fl-action-button ${c}" ${function(e){return`aria-label="Close ${e} message"`}(n)}>\n ${$}\n </button>\n </div>\n </div>\n <div class="${f}">\n <div class="${d}"></div>\n </div>\n </div>`}};e.addTheme("google",h)}));
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s={render:e=>{const{type:s,message:i,title:n}=e,l="error"===s||"warning"===s,t=l?"alert":"status",a=l?"assertive":"polite",r=(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"}),o=n||"PHPFlasher";return`\n <div class="fl-ios fl-${s}" role="${t}" aria-live="${a}" aria-atomic="true">\n <div class="fl-ios-notification">\n <div class="fl-header">\n <div class="fl-app-icon">\n ${(()=>{switch(s){case"success":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>\n </svg>';case"warning":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>\n </svg>';case"info":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-app-info">\n <div class="fl-app-name">${o}</div>\n <div class="fl-time">${r}</div>\n </div>\n </div>\n <div class="fl-content">\n <div class="fl-message">${i}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n </div>`}};e.addTheme("ios",s)}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n={sm:16,md:20,lg:24},i={success:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z",error:"M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z",warning:"M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z",info:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z",close:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"};function s(e,s={}){return"success"===e||"error"===e||"warning"===e||"info"===e?function(e,s={}){const{size:a="md",className:t=""}=s,r="number"==typeof a?a:n[a],l=i[e];return l?`<svg${t?` class="${t}"`:""} viewBox="0 0 24 24" width="${r}" height="${r}" aria-hidden="true"><path fill="currentColor" d="${l}"/></svg>`:""}(e,s):""}const a="fl-content",t="fl-message",r="fl-close",l=e=>`fl-${e}`,o=e=>`fl-${e}`;const c={render:e=>{const{type:n,message:i,title:c}=e,d=c||"PHPFlasher";return`\n <div class="${o("ios")} ${l(n)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(n)}>\n <div class="fl-ios-notification">\n <div class="fl-header">\n <div class="fl-app-icon">\n ${s(n,{size:"md",className:"fl-icon-svg"})}\n </div>\n <div class="fl-app-info">\n <div class="fl-app-name">${d}</div>\n <div class="fl-time">${(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}</div>\n </div>\n </div>\n <div class="${a}">\n <div class="${t}">${i}</div>\n </div>\n <button class="${r}" ${function(e){return`aria-label="Close ${e} message"`}(n)}>\n <span aria-hidden="true">×</span>\n </button>\n </div>\n </div>`}};e.addTheme("ios",c)}));
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("jade",{render:e=>{const{type:s,message:a}=e,l="error"===s||"warning"===s;return`\n <div class="fl-jade fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s="fl-content",n="fl-message",i="fl-close",a="fl-progress-bar",r="fl-progress",t=e=>`fl-${e}`,l=e=>`fl-${e}`,o={render:e=>{const{type:o,message:f}=e;return`\n <div class="${l("jade")} ${t(o)}" ${function(e){const s=function(e){const s="error"===e||"warning"===e;return{role:s?"alert":"status",ariaLive:s?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${s.role}" aria-live="${s.ariaLive}" aria-atomic="${s.ariaAtomic}"`}(o)}>\n <div class="${s}">\n <div class="${n}">${f}</div>\n <button class="${i}" ${function(e){return`aria-label="Close ${e} message"`}(o)}>×</button>\n </div>\n <div class="${a}">\n <div class="${r}"></div>\n </div>\n </div>`}};e.addTheme("jade",o)}));
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("material",{render:e=>{const{type:s,message:n}=e,a="error"===s||"warning"===s;return`\n <div class="fl-material fl-${s}" role="${a?"alert":"status"}" aria-live="${a?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-md-card">\n <div class="fl-content">\n <div class="fl-text-content">\n <div class="fl-message">${n}</div>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-action-button fl-close" aria-label="Close ${s} message">\n DISMISS\n </button>\n </div>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const n="fl-content",i="fl-message",s="fl-actions",a="fl-close",t="fl-progress-bar",r="fl-progress",l=e=>`fl-${e}`,o=e=>`fl-${e}`,f="DISMISS",c={render:e=>{const{type:c,message:d}=e;return`\n <div class="${o("material")} ${l(c)}" ${function(e){const n=function(e){const n="error"===e||"warning"===e;return{role:n?"alert":"status",ariaLive:n?"assertive":"polite",ariaAtomic:"true"}}(e);return`role="${n.role}" aria-live="${n.ariaLive}" aria-atomic="${n.ariaAtomic}"`}(c)}>\n <div class="fl-md-card">\n <div class="${n}">\n <div class="fl-text-content">\n <div class="${i}">${d}</div>\n </div>\n </div>\n <div class="${s}">\n <button class="fl-action-button ${a}" ${function(e){return`aria-label="Close ${e} message"`}(c)}>\n ${f}\n </button>\n </div>\n </div>\n <div class="${t}">\n <div class="${r}"></div>\n </div>\n </div>`}};e.addTheme("material",c)}));
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user