Files
UI/packages/skin/ui/src/link.ts
T
2026-10-26 15:28:20 +08:00

26 lines
1.3 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 } from '@ui-arch/frame';
import type { LinkProps } from './types.js';
/*** 链接:站内跳转与站外跳转统一入口;external 自动补 ↗ 与 rel,disabled 去掉 href 并拦点击 ***/
export function link(props: LinkProps): HTMLElement {
const external = Boolean(props.external) || props.target === '_blank'; // 新窗口一律按站外处理
const cls = ['ua-link', props.muted ? 'is-muted' : '', props.disabled ? 'is-disabled' : '', external ? 'is-external' : '']
.filter(Boolean).join(' ');
const a = h('a', {
class: cls,
href: props.disabled ? null : props.href, // 禁用态去掉 href:键盘也不再当链接用
target: external ? '_blank' : props.target ?? null,
rel: external ? 'noopener noreferrer' : null, // 新窗口必须断开 opener,防目标页反向操控
'aria-disabled': props.disabled ? 'true' : null,
onclick: (e: Event) => {
if (props.disabled) {
e.preventDefault(); // 保留可聚焦但不可跳转
return;
}
props.onClick?.(e);
},
}, props.label, external ? h('span', { class: 'ua-link-icon', 'aria-hidden': 'true' }, '↗') : null);
if (external) a.append(h('span', { class: 'ua-visually-hidden' }, '(在新窗口打开)')); // 读屏需知道开了新窗
return a;
}