iter(g78): 新增 space 间距容器组件
This commit is contained in:
@@ -980,6 +980,14 @@
|
||||
"acceptance": "npm run changelog 重新生成(226 提交),changelog:check 不再报漂移;npm run check 全绿",
|
||||
"status": "done",
|
||||
"notes": "自补:发版前刷新步骤,按 g64 约定的方式执行"
|
||||
},
|
||||
{
|
||||
"id": "g78",
|
||||
"title": "新增 space 间距容器组件",
|
||||
"motivation": "库里 56 个组件都在各自实现里写 margin/gap,「一排按钮统一间距」「工具栏两端撑开」这类布局诉求没有承载物,演示页与业务方只能重复拼 style",
|
||||
"acceptance": "新增 space(props, ...children):direction / size(sm|md|lg 走令牌,数字按像素)/ align / justify / wrap / block;manifest 参数表 + 手把手步骤 + api.exports 登记;demo 有 sec-space 区块真实调用;README 计数与分组同步;npm run check 全绿",
|
||||
"status": "open",
|
||||
"notes": "自补:布局基础件缺失;间距一律走 --ua-space-* 令牌,几何用内联 style 不进皮肤样式表"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+46
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "ui-arch-registry-index/0.1",
|
||||
"generatedAt": "2026-10-26T04:40:12.953Z",
|
||||
"generatedAt": "2026-10-26T04:55:25.133Z",
|
||||
"repoRoot": ".",
|
||||
"packages": [
|
||||
{
|
||||
@@ -172,6 +172,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",
|
||||
@@ -1424,6 +1425,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",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
- `packages/core/table-core`(@ui-arch/table-core):Headless 表格逻辑内核
|
||||
- `packages/core/frame`(@ui-arch/frame):signal + hyperscript 微框架
|
||||
- `packages/skin/ui`(@ui-arch/ui):56 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
||||
- `packages/skin/ui`(@ui-arch/ui):57 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
||||
- `packages/design/tokens`(@ui-arch/tokens):设计令牌
|
||||
- `packages/tools/cli`(@ui-arch/cli):`ua` 命令行 + MCP 注册表服务(private)
|
||||
- `apps/demo`(@ui-arch/demo):交互演示,产物 apps/demo/dist/demo.html
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ ui-arch-mvp/
|
||||
│ │ ├── table-core/ # 表格状态内核
|
||||
│ │ └── frame/ # 信号 + hyperscript 微框架
|
||||
│ ├── skin/ # 皮肤层(DOM 组件,可发布)
|
||||
│ │ └── ui/ # 56 个组件 + ui.css
|
||||
│ │ └── ui/ # 57 个组件 + ui.css
|
||||
│ ├── design/ # 资产层(可发布)
|
||||
│ │ └── tokens/ # --ua-* 设计令牌
|
||||
│ └── tools/ # 工程层(private,不发布)
|
||||
|
||||
@@ -12,13 +12,13 @@ npm run docs # 生成人类文档站 apps/docs/index.html + Agent 全
|
||||
npm run changelog # 依据 git 提交史重写 CHANGELOG.md(发版前跑;changelog:check 可查漂移)
|
||||
```
|
||||
|
||||
## 组件(共 56 个)
|
||||
## 组件(共 57 个)
|
||||
|
||||
<!-- ua:components -->
|
||||
accordion · affix · alert · autoComplete · avatar · backTop · badge · breadcrumb · button · carousel · card · cascader · checkbox · checkboxGroup · colorPicker · dataTable · datePicker · descriptions · divider · drawer · empty · form · image · inputNumber · list · menu · modal · multiSelect · notification · pagination · popover · progress · radioGroup · rate · result · segmented · select · skeleton · slider · spinner · splitter · statistic · stepper · switchButton · tabs · tag · textField · textarea · timeline · toast · tooltip · tour · transfer · tree · upload · watermark
|
||||
accordion · affix · alert · autoComplete · avatar · backTop · badge · breadcrumb · button · carousel · card · cascader · checkbox · checkboxGroup · colorPicker · dataTable · datePicker · descriptions · divider · drawer · empty · form · image · inputNumber · list · menu · modal · multiSelect · notification · pagination · popover · progress · radioGroup · rate · result · segmented · select · skeleton · slider · space · spinner · splitter · statistic · stepper · switchButton · tabs · tag · textField · textarea · timeline · toast · tooltip · tour · transfer · tree · upload · watermark
|
||||
<!-- /ua:components -->
|
||||
|
||||
分组:表单(button / textField / inputNumber / textarea / checkbox / checkboxGroup / colorPicker / switchButton / select / multiSelect / radioGroup / slider / rate / autoComplete / datePicker / segmented / upload / form + formItem / transfer / cascader)、反馈(alert / toast / notification / result / spinner / progress / skeleton / badge / empty / statistic)、浮层(tooltip / popover / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper / tree)、数据展示(dataTable / descriptions / card / list / timeline / tag / avatar / image / carousel)、其他(divider / splitter / backTop / affix / tour / watermark)。
|
||||
分组:表单(button / textField / inputNumber / textarea / checkbox / checkboxGroup / colorPicker / switchButton / select / multiSelect / radioGroup / slider / rate / autoComplete / datePicker / segmented / upload / form + formItem / transfer / cascader)、反馈(alert / toast / notification / result / spinner / progress / skeleton / badge / empty / statistic)、浮层(tooltip / popover / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper / tree)、数据展示(dataTable / descriptions / card / list / timeline / tag / avatar / image / carousel)、其他(space / divider / splitter / backTop / affix / tour / watermark)。
|
||||
|
||||
## 可访问性约定
|
||||
|
||||
@@ -32,7 +32,7 @@ accordion · affix · alert · autoComplete · avatar · backTop · badge · bre
|
||||
|---|---|
|
||||
| `packages/core/frame` | @ui-arch/frame:signal / computed / effect + hyperscript(无虚拟 DOM) |
|
||||
| `packages/core/table-core` | @ui-arch/table-core:headless 表格(filter → sort → paginate 派生管线) |
|
||||
| `packages/skin/ui` | @ui-arch/ui:56 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
||||
| `packages/skin/ui` | @ui-arch/ui:57 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
||||
| `packages/design/tokens` | @ui-arch/tokens:设计令牌(暗色只换值不换名) |
|
||||
| `packages/tools/cli` | @ui-arch/cli:`ua` 命令行与 stdio MCP server |
|
||||
| `apps/demo` | 交互演示(esbuild 打包成单文件) |
|
||||
|
||||
@@ -54,6 +54,7 @@ import {
|
||||
skeleton,
|
||||
splitter,
|
||||
slider,
|
||||
space,
|
||||
spinner,
|
||||
stepper,
|
||||
statistic,
|
||||
@@ -524,6 +525,24 @@ const content = h(
|
||||
button({ label: '导出', variant: 'ghost' }),
|
||||
),
|
||||
),
|
||||
section(
|
||||
'sec-space',
|
||||
'间距容器',
|
||||
'space:用 flex gap 托管一排子元素的间距(不再各自写 margin),size 三档走令牌或直接给像素,direction 切竖排,justify + block 让工具栏两端撑开。',
|
||||
space(
|
||||
{ justify: 'between', block: true },
|
||||
h('span', { class: 'out' }, '左侧标题'),
|
||||
space({ size: 'sm' }, button({ label: '取消', variant: 'ghost' }), button({ label: '保存' })),
|
||||
),
|
||||
space(
|
||||
{ size: 'lg', wrap: true },
|
||||
badge({ label: '默认' }),
|
||||
badge({ label: '成功', variant: 'success' }),
|
||||
badge({ label: '警告', variant: 'warning' }),
|
||||
tag({ label: '#A1024', variant: 'info' }),
|
||||
),
|
||||
space({ direction: 'vertical', align: 'start', size: 6 }, h('span', { class: 'out' }, '竖排第一行'), h('span', { class: 'out' }, '竖排第二行(6px 精确间距)')),
|
||||
),
|
||||
section(
|
||||
'sec-statistic',
|
||||
'统计数值',
|
||||
|
||||
+28
-1
@@ -1,6 +1,6 @@
|
||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||
|
||||
> 自动生成于 2026-10-26T04:40:12.953Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 自动生成于 2026-10-26T04:55:25.133Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||
|
||||
## 快速上手
|
||||
@@ -776,6 +776,32 @@ divider({ label: '更多信息' }) / divider({ vertical: true })
|
||||
|
||||
现场演示:apps/docs/demo.html#sec-divider
|
||||
|
||||
### space — 间距容器 Space
|
||||
|
||||
参数:
|
||||
|
||||
- direction:'horizontal' | 'vertical' —— 主轴方向;缺省 horizontal 横排
|
||||
- size:'sm' | 'md' | 'lg' | number —— 子元素间距:三档走 --ua-space-* 令牌,数字按像素;缺省 md
|
||||
- align:'start' | 'center' | 'end' | 'baseline' —— 交叉轴对齐;缺省 center,按钮与文字混排不错位
|
||||
- justify:'start' | 'center' | 'end' | 'between' —— 主轴分布;缺省 start,between 两端撑开
|
||||
- wrap:boolean —— 空间不足是否换行;缺省 false
|
||||
- block:boolean —— 是否占满父容器宽度;缺省按内容收缩
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
space({ size: 'lg' }, button({ label: '保存' }), button({ label: '取消', variant: 'ghost' })) / space({ direction: 'vertical', align: 'start' }, ...)
|
||||
```
|
||||
|
||||
手把手:
|
||||
|
||||
1. 把一排需要统一间距的元素交给 space 托管,不再各自写 margin
|
||||
2. 调间距:size 传 sm/md/lg 走令牌,需要精确像素时直接给数字
|
||||
3. 竖排用 direction: 'vertical',配 align: 'start' 让子元素左对齐
|
||||
4. 工具栏两端撑开用 justify: 'between' + block: true;窄屏放不下时加 wrap
|
||||
|
||||
现场演示:apps/docs/demo.html#sec-space
|
||||
|
||||
### pagination — 分页器 Pagination
|
||||
|
||||
参数:
|
||||
@@ -1551,6 +1577,7 @@ API 速览:
|
||||
- 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
|
||||
|
||||
@@ -77,6 +77,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
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 }; // 再导出常用内核类型,方便调用方
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user