♻️ refactor(client): 浏览器半拆成 src 模块,client.js 改由构建产出
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* The light popup stack: the frame-wide overlay entry this package owns.
|
||||
*
|
||||
* @module @dsh-plugin/session-notify/client/ui/ToastLayer
|
||||
*/
|
||||
|
||||
import * as React from 'react'
|
||||
import { KindIcon, CloseIcon } from './icons.js'
|
||||
import { seatTranslator, useOwnStore } from './hooks.js'
|
||||
import { CSS } from './styles.js'
|
||||
|
||||
const h = React.createElement
|
||||
|
||||
export function ToastLayer(props) {
|
||||
const snapshot = useOwnStore(props.store)
|
||||
const toasts = snapshot.toasts
|
||||
const tr = seatTranslator(props, props.fallbackT)
|
||||
React.useEffect(() => {
|
||||
if (toasts.length === 0) return undefined
|
||||
const onKeyDown = (event) => {
|
||||
if (event.key !== 'Escape' || event.defaultPrevented) return
|
||||
const top = toasts[0]
|
||||
if (top === undefined) return
|
||||
event.preventDefault()
|
||||
props.dismiss(top.id)
|
||||
}
|
||||
document.addEventListener('keydown', onKeyDown)
|
||||
return () => {
|
||||
document.removeEventListener('keydown', onKeyDown)
|
||||
}
|
||||
}, [toasts, props])
|
||||
if (toasts.length === 0) return null
|
||||
return h(React.Fragment, null,
|
||||
h('style', null, CSS),
|
||||
h('div', { className: 'dsn-stack', role: 'region', 'aria-live': 'polite' },
|
||||
toasts.map((toast) => h('div', {
|
||||
key: toast.id,
|
||||
className: 'dsn-toast',
|
||||
role: toast.kind === 'completion' ? 'status' : 'alert',
|
||||
onMouseEnter: () => props.hold(toast.id),
|
||||
onMouseLeave: () => props.arm(toast.id),
|
||||
},
|
||||
h('span', { className: `dsn-toast-icon is-${toast.kind}` }, h(KindIcon, { kind: toast.kind, size: 16 })),
|
||||
h('div', { className: 'dsn-toast-text' },
|
||||
h('div', { className: 'dsn-toast-title' }, toast.title),
|
||||
h('div', { className: 'dsn-toast-desc' }, toast.body)),
|
||||
h('div', { className: 'dsn-toast-actions' },
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dsn-toast-action',
|
||||
onClick: () => {
|
||||
props.dismiss(toast.id)
|
||||
props.open(toast.sessionId)
|
||||
},
|
||||
}, tr('toast.view')),
|
||||
h('button', {
|
||||
type: 'button',
|
||||
className: 'dsn-toast-close',
|
||||
'aria-label': tr('toast.dismiss'),
|
||||
onClick: () => props.dismiss(toast.id),
|
||||
}, h(CloseIcon, { size: 14 })))))))
|
||||
}
|
||||
Reference in New Issue
Block a user