iter(g67): tag 支持 checkable 筛选片,选中态与 aria-pressed 同步
This commit is contained in:
@@ -1,15 +1,28 @@
|
||||
import { h } from '@ui-arch/frame';
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { TagProps } from './types.js';
|
||||
|
||||
/*** 标签:语义色小胶囊,可选 × 关闭;与 badge 的分工是 tag 可交互(带关闭回调) ***/
|
||||
/*** 标签:语义色小胶囊;checkable 时作筛选片(aria-pressed + 信号双向绑定),否则可选 × 关闭 ***/
|
||||
export function tag(props: TagProps): HTMLElement {
|
||||
const label = h('span', { class: 'ua-tag-label' }, props.label);
|
||||
if (!props.closable) {
|
||||
return h('span', { class: `ua-tag ua-tag-${props.variant ?? 'default'}` }, label); // 纯展示形态
|
||||
const base = `ua-tag ua-tag-${props.variant ?? 'default'}`; // 语义色共用
|
||||
if (props.checkable) {
|
||||
const on = props.checked ?? signal(false); // 未受控时内部自持,行为与受控一致
|
||||
const btn = h('button', { type: 'button', class: `${base} is-checkable`, 'aria-pressed': String(on()) }, label) as HTMLButtonElement;
|
||||
btn.addEventListener('click', () => {
|
||||
on(!on()); // 用户点击写回信号
|
||||
props.onChange?.(on());
|
||||
});
|
||||
effect(() => {
|
||||
const value = on();
|
||||
btn.setAttribute('aria-pressed', String(value)); // 读屏与视觉同源
|
||||
btn.classList.toggle('is-checked', value);
|
||||
});
|
||||
return btn;
|
||||
}
|
||||
if (!props.closable) return h('span', { class: base }, label); // 纯展示形态
|
||||
return h(
|
||||
'span',
|
||||
{ class: `ua-tag is-closable ua-tag-${props.variant ?? 'default'}` },
|
||||
{ class: `${base} is-closable` },
|
||||
label,
|
||||
h('button', { type: 'button', class: 'ua-tag-close', 'aria-label': `移除 ${props.label}`, onClick: () => props.onClose?.() }, '×'),
|
||||
);
|
||||
|
||||
@@ -254,6 +254,9 @@ export interface TagProps {
|
||||
variant?: 'default' | 'success' | 'warning' | 'danger' | 'info'; // 语义色;缺省 default
|
||||
closable?: boolean; // 显示 × 关闭按钮;缺省 false
|
||||
onClose?: () => void; // 关闭回调(调用方自行从数据源移除该项)
|
||||
checkable?: boolean; // 可选中(当筛选片用);与 closable 互斥,同时传时以 checkable 为准
|
||||
checked?: Signal<boolean>; // 选中态信号,双向绑定;不传则组件内部自持
|
||||
onChange?: (checked: boolean) => void; // 选中态变化回调(点一下即回调新值)
|
||||
}
|
||||
|
||||
/*** 图片入参 ***/
|
||||
|
||||
Reference in New Issue
Block a user