iter(g78): 新增 space 间距容器组件

This commit is contained in:
HIsheR
2026-10-26 12:55:53 +08:00
parent 1de7ec3166
commit b9261fb4ab
13 changed files with 198 additions and 8 deletions
+1
View File
@@ -35,6 +35,7 @@ export { rate } from './rate.js';
export { empty } from './empty.js';
export { result } from './result.js';
export { divider } from './divider.js';
export { space } from './space.js';
export { list } from './list.js';
export { carousel } from './carousel.js';
export { tree } from './tree.js';
+19
View File
@@ -0,0 +1,19 @@
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 统一一排子元素的间距,方向 / 档位 / 对齐 / 换行可调 ***/
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'}`;
return h('div', { class: cls, style: geom }, ...children) as HTMLDivElement;
}
+13
View File
@@ -650,4 +650,17 @@ export interface MultiSelectProps {
onChange?: (values: string[]) => void; // 变更回调(传副本)
}
/*** 间距档位:令牌档位 sm/md/lg,或直接给像素数 ***/
export type SpaceSize = 'sm' | 'md' | 'lg' | number;
/*** 间距容器入参 ***/
export interface SpaceProps {
direction?: 'horizontal' | 'vertical'; // 主轴方向;缺省 horizontal
size?: SpaceSize; // 子元素间距:sm/md/lg 走令牌,数字按像素;缺省 md
align?: 'start' | 'center' | 'end' | 'baseline'; // 交叉轴对齐;缺省 center,按钮与文字混排不会高低错位
justify?: 'start' | 'center' | 'end' | 'between'; // 主轴分布;缺省 start,between 用于两端撑开
wrap?: boolean; // 空间不足是否换行;缺省 false
block?: boolean; // 是否占满父容器宽度;缺省按内容收缩
}
export type { ColumnDef, RowKey }; // 再导出常用内核类型,方便调用方
+45
View File
@@ -43,6 +43,7 @@
"rate(props):评分星标,value 信号双向绑定,hover 预览移出还原,键盘方向键调节,max 可配",
"empty(props):空状态占位,title/description 可选,action 放操作区",
"divider(props):分隔线,水平/垂直两种方向,可带居中文案标签,dashed 切虚线",
"space(props):间距容器,flex gap 统一子元素间距,direction / size / align / justify / wrap / block 可调",
"modal(props, ...children):弹窗,open 信号驱动显隐,Esc / 遮罩 / × 关闭,size 三档宽度,footer 提供底部操作区",
"drawer(props, ...children):抽屉,open 信号驱动侧滑面板,placement 左右可配、width 可调、footer 操作区,遮罩 / × / Esc 关闭",
"form(props, items):表单容器,布局 + 聚合校验,全部通过才触发 onSubmit",
@@ -1295,6 +1296,50 @@
"工具栏内用 vertical: true 的行内竖线,dashed: true 切虚线弱化分隔感"
]
},
{
"id": "space",
"title": "间距容器 Space",
"demo": "sec-space",
"props": [
{
"n": "direction",
"t": "'horizontal' | 'vertical'",
"d": "主轴方向;缺省 horizontal 横排"
},
{
"n": "size",
"t": "'sm' | 'md' | 'lg' | number",
"d": "子元素间距:三档走 --ua-space-* 令牌,数字按像素;缺省 md"
},
{
"n": "align",
"t": "'start' | 'center' | 'end' | 'baseline'",
"d": "交叉轴对齐;缺省 center,按钮与文字混排不错位"
},
{
"n": "justify",
"t": "'start' | 'center' | 'end' | 'between'",
"d": "主轴分布;缺省 start,between 两端撑开"
},
{
"n": "wrap",
"t": "boolean",
"d": "空间不足是否换行;缺省 false"
},
{
"n": "block",
"t": "boolean",
"d": "是否占满父容器宽度;缺省按内容收缩"
}
],
"example": "space({ size: 'lg' }, button({ label: '保存' }), button({ label: '取消', variant: 'ghost' })) / space({ direction: 'vertical', align: 'start' }, ...)",
"steps": [
"把一排需要统一间距的元素交给 space 托管,不再各自写 margin",
"调间距:size 传 sm/md/lg 走令牌,需要精确像素时直接给数字",
"竖排用 direction: 'vertical',配 align: 'start' 让子元素左对齐",
"工具栏两端撑开用 justify: 'between' + block: true;窄屏放不下时加 wrap"
]
},
{
"id": "pagination",
"title": "分页器 Pagination",
+12
View File
@@ -3488,3 +3488,15 @@ button.ua-step-dot:hover {
transform: none;
}
}
/* —— 间距容器 —— */
.ua-space {
display: flex;
min-width: 0;
}
.ua-space.is-vertical {
flex-direction: column;
}
.ua-space.is-block {
width: 100%;
}