Files
UI/packages/skin/ui/src/noticeBar.ts
T
2026-10-26 23:17:28 +08:00

33 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { h, signal } from '@ui-arch/frame';
import type { NoticeBarProps } from './types.js';
// 语义色配符号:只靠颜色区分在灰度/色弱下会失效,符号是第二条线索
const ICONS: Record<string, string> = { info: 'ℹ', success: '✓', warning: '!', danger: '×' };
const EXIT_MS = 200; // 退场时长:与 alert 的关闭过渡同档,两条播报件消失手感一致
/*** 通知条:单行横条,语义色 + 可选跑马灯与关闭;关闭先淡出再隐藏并回调 ***/
export function noticeBar(props: NoticeBarProps): HTMLElement {
const variant = props.variant ?? 'info';
const open = signal(true); // 关闭状态:退场结束后置 false(隐藏而非摘节点,调用方仍持有句柄)
const close = (): void => {
el.classList.add('is-out'); // 挂退场类:淡出 + 轻微上移,先给观感再隐藏
props.onClose?.();
window.setTimeout(() => open(false), EXIT_MS); // 与 CSS 过渡时长同源,避免节点在半路消失
};
const el = h(
'div',
{
class: `ua-notice ua-notice-${variant}${props.scroll ? ' is-roll' : ''}`,
role: 'status',
title: props.text, // 滚动/裁切时仍能悬停读到完整原文
hidden: () => !open(),
},
h('span', { class: 'ua-notice-icon', 'aria-hidden': 'true' }, props.icon ?? ICONS[variant]),
h('div', { class: 'ua-notice-body' }, h('span', { class: 'ua-notice-text' }, props.text)),
props.closable === false
? null
: h('button', { type: 'button', class: 'ua-notice-close', 'aria-label': '关闭通知', onClick: close }, '×'),
);
return el;
}