24 lines
1.8 KiB
TypeScript
24 lines
1.8 KiB
TypeScript
import { h } from '@ui-arch/frame';
|
|
import type { SpaceProps, SpaceSize } from './types.js';
|
|
|
|
// 间距档位 → 令牌(数字档位不入表,直接拼像素)
|
|
const GAP: Record<Exclude<SpaceSize, number>, string> = { sm: 'var(--ua-space-2)', md: 'var(--ua-space-3)', lg: 'var(--ua-space-4)' };
|
|
// 交叉轴对齐 → flex align-items 取值
|
|
const ALIGN: Record<string, string> = { start: 'flex-start', center: 'center', end: 'flex-end', baseline: 'baseline' };
|
|
// 主轴分布 → flex justify-content 取值
|
|
const JUSTIFY: Record<string, string> = { start: 'flex-start', center: 'center', end: 'flex-end', between: 'space-between' };
|
|
|
|
/*** 间距容器:用 flex gap 统一一排子元素的间距,方向 / 档位 / 对齐 / 换行可调;split 在子元素之间插分隔符 ***/
|
|
export function space(props: SpaceProps, ...children: unknown[]): HTMLDivElement {
|
|
const size = props.size ?? 'md'; // 缺省中档,与多数组件内边距对齐
|
|
const gap = typeof size === 'number' ? `${size}px` : GAP[size]; // 数字档位按像素透传
|
|
const cls = ['ua-space', props.direction === 'vertical' ? 'is-vertical' : '', props.block ? 'is-block' : ''].filter(Boolean).join(' ');
|
|
// 内联只放几何(间距/对齐/换行),颜色与描边一律留给令牌驱动的类名
|
|
const geom = `gap:${gap};align-items:${ALIGN[props.align ?? 'center']};justify-content:${JUSTIFY[props.justify ?? 'start']};flex-wrap:${props.wrap ? 'wrap' : 'nowrap'}`;
|
|
// 分隔符:仅 2 个以上子元素时插入,aria-hidden 让读屏跳过装饰符号
|
|
const nodes = props.split && children.length > 1
|
|
? children.flatMap((child, i) => (i === 0 ? [child] : [h('span', { class: 'ua-space-split', 'aria-hidden': 'true' }, props.split), child]))
|
|
: children;
|
|
return h('div', { class: cls, style: geom }, ...nodes) as HTMLDivElement;
|
|
}
|