import { effect, h, signal } from '@ui-arch/frame'; import type { ButtonProps } from './types.js'; /*** 按钮:variant 控制视觉强度,disabled / loading 支持布尔或信号动态同步(loading 转圈并禁点),onClick 为点击回调 ***/ export function button(props: ButtonProps): HTMLElement { const loading = typeof props.loading === 'function' ? props.loading : signal(!!props.loading); // 归一成信号:布尔也走同一响应式路径 const spin = h('span', { class: 'ua-spinner ua-btn-spin', 'aria-hidden': 'true' }); // 转圈指示:CSS 默认 display:none,加载态才显形 const el = h( 'button', { class: `ua-btn ua-btn-${props.variant ?? 'primary'}${props.size && props.size !== 'md' ? ` is-${props.size}` : ''}`, type: props.type ?? 'button', disabled: () => (typeof props.disabled === 'function' ? props.disabled() : !!props.disabled) || loading(), // 禁点口径:显式禁用或加载中 'aria-busy': () => (loading() ? 'true' : null), // 读屏播报忙碌态(null 移除属性) onClick: props.onClick, }, // 缺省 button:表单内不隐式提交 spin, props.label, ); effect(() => el.classList.toggle('is-loading', loading())); // 加载态只切类名,不整棵重渲染(保住焦点与子节点) return el; }