iter(g09): 新增 descriptions 描述列表组件
This commit is contained in:
+51
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "ui-arch-registry-index/0.1",
|
"$schema": "ui-arch-registry-index/0.1",
|
||||||
"generatedAt": "2026-10-26T02:20:07.266Z",
|
"generatedAt": "2026-10-26T02:22:42.729Z",
|
||||||
"repoRoot": ".",
|
"repoRoot": ".",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
@@ -178,7 +178,8 @@
|
|||||||
"dataTable(props):数据表格,粘性表头 / 行选择(全选三态)/ 排序 / 筛选 / 分页 / 空状态;loading 为真时数据行换骨架行且筛选/翻页禁用,内核为 table-core",
|
"dataTable(props):数据表格,粘性表头 / 行选择(全选三态)/ 排序 / 筛选 / 分页 / 空状态;loading 为真时数据行换骨架行且筛选/翻页禁用,内核为 table-core",
|
||||||
"image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽",
|
"image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽",
|
||||||
"timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点",
|
"timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点",
|
||||||
"segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用"
|
"segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用",
|
||||||
|
"descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列"
|
||||||
],
|
],
|
||||||
"keyTypes": [
|
"keyTypes": [
|
||||||
"ButtonProps",
|
"ButtonProps",
|
||||||
@@ -218,7 +219,9 @@
|
|||||||
"AvatarProps",
|
"AvatarProps",
|
||||||
"TimelineItem",
|
"TimelineItem",
|
||||||
"TimelineProps",
|
"TimelineProps",
|
||||||
"SegmentedProps"
|
"SegmentedProps",
|
||||||
|
"DescriptionItem",
|
||||||
|
"DescriptionsProps"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"usage": "const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')",
|
"usage": "const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')",
|
||||||
@@ -1663,6 +1666,51 @@
|
|||||||
"滑块几何由组件测量按钮位置得到,不要在外部改按钮宽度 / 内边距,否则需自行重渲染",
|
"滑块几何由组件测量按钮位置得到,不要在外部改按钮宽度 / 内边距,否则需自行重渲染",
|
||||||
"需要带图标或更复杂布局的分段,改用 radioGroup + 自定义样式"
|
"需要带图标或更复杂布局的分段,改用 radioGroup + 自定义样式"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "descriptions",
|
||||||
|
"title": "描述列表 Descriptions",
|
||||||
|
"demo": "sec-descriptions",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"n": "items",
|
||||||
|
"t": "DescriptionItem[]",
|
||||||
|
"r": 1,
|
||||||
|
"d": "描述项列表:每项含 label(字段名)、value(字符串 / DOM / 响应式函数)、span(跨列数)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "column",
|
||||||
|
"t": "1 | 2 | 3 | 4",
|
||||||
|
"d": "桌面列数;缺省 3,窄屏(≤640px)由样式表降为单列",
|
||||||
|
"df": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "bordered",
|
||||||
|
"t": "boolean",
|
||||||
|
"d": "表格形态(带分隔线与字段名底纹);缺省 false 纯网格",
|
||||||
|
"df": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "size",
|
||||||
|
"t": "'sm' | 'md'",
|
||||||
|
"d": "尺寸档位;缺省 md",
|
||||||
|
"df": "md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "title",
|
||||||
|
"t": "string",
|
||||||
|
"d": "分组标题;缺省不渲染标题行"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": "descriptions({ title: '订单信息', column: 2, bordered: true, items: [{ label: '订单号', value: 'RB-2048' }, { label: '金额', value: '¥1,280.00' }, { label: '备注', value: '加急', span: 2 }] })",
|
||||||
|
"steps": [
|
||||||
|
"详情页 / 抽屉里展示只读字段用它,不要用 form(form 承载输入与校验)",
|
||||||
|
"column 按信息密度定:字段多且短用 3-4 列,字段长(地址、备注)用 2 列并配 span 占整行",
|
||||||
|
"value 支持任意 DOM:放 tag、badge、button 都可以;要给值做响应式更新就传函数 () => 内容",
|
||||||
|
"bordered: true 是表格形态(适合打印与密集信息),纯网格形态更轻,适合卡片内嵌",
|
||||||
|
"窄屏自动降为单列,无需在调用方写媒体查询",
|
||||||
|
"纯展示组件,无状态无回调:值变了由调用方重新渲染或传函数式 value"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
- `packages/core/table-core`(@ui-arch/table-core):Headless 表格逻辑内核
|
- `packages/core/table-core`(@ui-arch/table-core):Headless 表格逻辑内核
|
||||||
- `packages/core/frame`(@ui-arch/frame):signal + hyperscript 微框架
|
- `packages/core/frame`(@ui-arch/frame):signal + hyperscript 微框架
|
||||||
- `packages/skin/ui`(@ui-arch/ui):36 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
- `packages/skin/ui`(@ui-arch/ui):37 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
||||||
- `packages/design/tokens`(@ui-arch/tokens):设计令牌
|
- `packages/design/tokens`(@ui-arch/tokens):设计令牌
|
||||||
- `packages/tools/cli`(@ui-arch/cli):`ua` 命令行 + MCP 注册表服务(private)
|
- `packages/tools/cli`(@ui-arch/cli):`ua` 命令行 + MCP 注册表服务(private)
|
||||||
- `apps/demo`(@ui-arch/demo):交互演示,产物 apps/demo/dist/demo.html
|
- `apps/demo`(@ui-arch/demo):交互演示,产物 apps/demo/dist/demo.html
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ ui-arch-mvp/
|
|||||||
│ │ ├── table-core/ # 表格状态内核
|
│ │ ├── table-core/ # 表格状态内核
|
||||||
│ │ └── frame/ # 信号 + hyperscript 微框架
|
│ │ └── frame/ # 信号 + hyperscript 微框架
|
||||||
│ ├── skin/ # 皮肤层(DOM 组件,可发布)
|
│ ├── skin/ # 皮肤层(DOM 组件,可发布)
|
||||||
│ │ └── ui/ # 36 个组件 + ui.css
|
│ │ └── ui/ # 37 个组件 + ui.css
|
||||||
│ ├── design/ # 资产层(可发布)
|
│ ├── design/ # 资产层(可发布)
|
||||||
│ │ └── tokens/ # --ua-* 设计令牌
|
│ │ └── tokens/ # --ua-* 设计令牌
|
||||||
│ └── tools/ # 工程层(private,不发布)
|
│ └── tools/ # 工程层(private,不发布)
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ npm run demo # 打开演示:apps/demo/dist/demo.html
|
|||||||
npm run docs # 生成人类文档站 apps/docs/index.html + Agent 全量文档 llms-full.txt
|
npm run docs # 生成人类文档站 apps/docs/index.html + Agent 全量文档 llms-full.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## 组件(共 36 个)
|
## 组件(共 37 个)
|
||||||
|
|
||||||
<!-- ua:components -->
|
<!-- ua:components -->
|
||||||
accordion · alert · avatar · badge · breadcrumb · button · card · checkbox · dataTable · divider · drawer · empty · form · image · inputNumber · menu · modal · pagination · popover · progress · radioGroup · rate · segmented · select · skeleton · slider · spinner · stepper · switchButton · tabs · tag · textField · textarea · timeline · toast · tooltip
|
accordion · alert · avatar · badge · breadcrumb · button · card · checkbox · dataTable · descriptions · divider · drawer · empty · form · image · inputNumber · menu · modal · pagination · popover · progress · radioGroup · rate · segmented · select · skeleton · slider · spinner · stepper · switchButton · tabs · tag · textField · textarea · timeline · toast · tooltip
|
||||||
<!-- /ua:components -->
|
<!-- /ua:components -->
|
||||||
|
|
||||||
分组:表单(button / textField / inputNumber / textarea / checkbox / switchButton / select / radioGroup / slider / rate / segmented / form / formItem)、反馈(alert / toast / spinner / progress / skeleton / badge / empty)、浮层(tooltip / popover / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper)、数据(dataTable / tag / avatar / card)、其他(divider / timeline)。
|
分组:表单(button / textField / inputNumber / textarea / checkbox / switchButton / select / radioGroup / slider / rate / segmented / form / formItem)、反馈(alert / toast / spinner / progress / skeleton / badge / empty)、浮层(tooltip / popover / modal / drawer / menu)、导航(tabs / breadcrumb / pagination / accordion / stepper)、数据(dataTable / descriptions / tag / avatar / card)、其他(divider / timeline)。
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ accordion · alert · avatar · badge · breadcrumb · button · card · checkbo
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `packages/core/frame` | @ui-arch/frame:signal / computed / effect + hyperscript(无虚拟 DOM) |
|
| `packages/core/frame` | @ui-arch/frame:signal / computed / effect + hyperscript(无虚拟 DOM) |
|
||||||
| `packages/core/table-core` | @ui-arch/table-core:headless 表格(filter → sort → paginate 派生管线) |
|
| `packages/core/table-core` | @ui-arch/table-core:headless 表格(filter → sort → paginate 派生管线) |
|
||||||
| `packages/skin/ui` | @ui-arch/ui:36 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
| `packages/skin/ui` | @ui-arch/ui:37 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
||||||
| `packages/design/tokens` | @ui-arch/tokens:设计令牌(暗色只换值不换名) |
|
| `packages/design/tokens` | @ui-arch/tokens:设计令牌(暗色只换值不换名) |
|
||||||
| `packages/tools/cli` | @ui-arch/cli:`ua` 命令行与 stdio MCP server |
|
| `packages/tools/cli` | @ui-arch/cli:`ua` 命令行与 stdio MCP server |
|
||||||
| `apps/demo` | 交互演示(esbuild 打包成单文件) |
|
| `apps/demo` | 交互演示(esbuild 打包成单文件) |
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
card,
|
card,
|
||||||
checkbox,
|
checkbox,
|
||||||
dataTable,
|
dataTable,
|
||||||
|
descriptions,
|
||||||
divider,
|
divider,
|
||||||
drawer,
|
drawer,
|
||||||
empty,
|
empty,
|
||||||
@@ -448,6 +449,34 @@ const content = h(
|
|||||||
button({ label: '导出', variant: 'ghost' }),
|
button({ label: '导出', variant: 'ghost' }),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
section(
|
||||||
|
'sec-descriptions',
|
||||||
|
'描述列表',
|
||||||
|
'descriptions:label : value 网格,column 定列数(窄屏自动单列);bordered 切表格形态,span 让长字段占整行。',
|
||||||
|
descriptions({
|
||||||
|
title: '订单信息(纯网格 · 3 列)',
|
||||||
|
column: 3,
|
||||||
|
items: [
|
||||||
|
{ label: '订单号', value: 'RB-2048' },
|
||||||
|
{ label: '下单人', value: '王小明' },
|
||||||
|
{ label: '金额', value: '¥1,280.00' },
|
||||||
|
{ label: '状态', value: tag({ label: '待复核', variant: 'warning' }) },
|
||||||
|
{ label: '备注', value: '需要开专用发票,抬头与税号见附件。', span: 2 },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
divider({ dashed: true }),
|
||||||
|
descriptions({
|
||||||
|
title: '物流信息(表格形态 · 2 列)',
|
||||||
|
column: 2,
|
||||||
|
bordered: true,
|
||||||
|
size: 'sm',
|
||||||
|
items: [
|
||||||
|
{ label: '承运商', value: '顺丰速运' },
|
||||||
|
{ label: '运单号', value: 'SF1234567890' },
|
||||||
|
{ label: '收件地址', value: '浙江省杭州市余杭区文一西路 969 号', span: 2 },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
),
|
||||||
section(
|
section(
|
||||||
'sec-segmented',
|
'sec-segmented',
|
||||||
'分段控制器',
|
'分段控制器',
|
||||||
|
|||||||
+29
-1
@@ -1,6 +1,6 @@
|
|||||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||||
|
|
||||||
> 自动生成于 2026-10-26T02:20:07.266Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
> 自动生成于 2026-10-26T02:22:42.729Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||||
|
|
||||||
## 快速上手
|
## 快速上手
|
||||||
@@ -950,6 +950,33 @@ segmented({ options: [{ value: 'day', label: '日' }, { value: 'week', label: '
|
|||||||
|
|
||||||
现场演示:apps/docs/demo.html#sec-segmented
|
现场演示:apps/docs/demo.html#sec-segmented
|
||||||
|
|
||||||
|
### descriptions — 描述列表 Descriptions
|
||||||
|
|
||||||
|
参数:
|
||||||
|
|
||||||
|
- items(必填):DescriptionItem[] —— 描述项列表:每项含 label(字段名)、value(字符串 / DOM / 响应式函数)、span(跨列数)
|
||||||
|
- column(默认 3):1 | 2 | 3 | 4 —— 桌面列数;缺省 3,窄屏(≤640px)由样式表降为单列
|
||||||
|
- bordered(默认 false):boolean —— 表格形态(带分隔线与字段名底纹);缺省 false 纯网格
|
||||||
|
- size(默认 md):'sm' | 'md' —— 尺寸档位;缺省 md
|
||||||
|
- title:string —— 分组标题;缺省不渲染标题行
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
descriptions({ title: '订单信息', column: 2, bordered: true, items: [{ label: '订单号', value: 'RB-2048' }, { label: '金额', value: '¥1,280.00' }, { label: '备注', value: '加急', span: 2 }] })
|
||||||
|
```
|
||||||
|
|
||||||
|
手把手:
|
||||||
|
|
||||||
|
1. 详情页 / 抽屉里展示只读字段用它,不要用 form(form 承载输入与校验)
|
||||||
|
2. column 按信息密度定:字段多且短用 3-4 列,字段长(地址、备注)用 2 列并配 span 占整行
|
||||||
|
3. value 支持任意 DOM:放 tag、badge、button 都可以;要给值做响应式更新就传函数 () => 内容
|
||||||
|
4. bordered: true 是表格形态(适合打印与密集信息),纯网格形态更轻,适合卡片内嵌
|
||||||
|
5. 窄屏自动降为单列,无需在调用方写媒体查询
|
||||||
|
6. 纯展示组件,无状态无回调:值变了由调用方重新渲染或传函数式 value
|
||||||
|
|
||||||
|
现场演示:apps/docs/demo.html#sec-descriptions
|
||||||
|
|
||||||
API 速览:
|
API 速览:
|
||||||
|
|
||||||
- button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用
|
- button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用
|
||||||
@@ -989,6 +1016,7 @@ API 速览:
|
|||||||
- image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽
|
- image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽
|
||||||
- timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点
|
- timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点
|
||||||
- segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用
|
- segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用
|
||||||
|
- descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列
|
||||||
|
|
||||||
一行用法:
|
一行用法:
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
- image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽
|
- image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽
|
||||||
- timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点
|
- timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点
|
||||||
- segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用
|
- segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用
|
||||||
|
- descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列
|
||||||
- 用法: `const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')`
|
- 用法: `const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')`
|
||||||
- 约定: 皮肤不持有业务状态,一律委托 headless 内核或调用方信号
|
- 约定: 皮肤不持有业务状态,一律委托 headless 内核或调用方信号
|
||||||
- 约定: 表单类组件统一约定:*Props.value/checked/active 为 Signal 双向绑定,onChange/onInput 为回调
|
- 约定: 表单类组件统一约定:*Props.value/checked/active 为 Signal 双向绑定,onChange/onInput 为回调
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { h } from '@ui-arch/frame';
|
||||||
|
import type { DescriptionItem, DescriptionsProps } from './types.js';
|
||||||
|
|
||||||
|
/*** 单个描述项:字段名 + 字段值,span 控制跨列(超出列数时按整行处理) ***/
|
||||||
|
function cell(item: DescriptionItem, column: number): HTMLElement {
|
||||||
|
const cellEl = h('div', { class: 'ua-desc-item' },
|
||||||
|
h('div', { class: 'ua-desc-label' }, item.label),
|
||||||
|
h('div', { class: 'ua-desc-value' }, item.value));
|
||||||
|
cellEl.style.gridColumn = `span ${Math.min(item.span ?? 1, column)}`; // 跨列不越界
|
||||||
|
return cellEl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** 描述列表:label:value 两栏网格,column 定桌面列数,窄屏由样式表降到单列;bordered 走表格形态 ***/
|
||||||
|
export function descriptions(props: DescriptionsProps): HTMLElement {
|
||||||
|
const column = props.column ?? 3;
|
||||||
|
const grid = h('div', { class: `ua-desc ua-desc-${props.size ?? 'md'}${props.bordered ? ' is-bordered' : ''}` },
|
||||||
|
...props.items.map((item) => cell(item, column)));
|
||||||
|
grid.style.setProperty('--ua-desc-col', String(column)); // 列数交给 CSS 变量,媒体查询可在窄屏覆盖
|
||||||
|
if (!props.title) return grid;
|
||||||
|
return h('div', { class: 'ua-desc-wrap' }, h('div', { class: 'ua-desc-title' }, props.title), grid);
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ export { stepper } from './stepper.js';
|
|||||||
export { rate } from './rate.js';
|
export { rate } from './rate.js';
|
||||||
export { empty } from './empty.js';
|
export { empty } from './empty.js';
|
||||||
export { divider } from './divider.js';
|
export { divider } from './divider.js';
|
||||||
|
export { descriptions } from './descriptions.js';
|
||||||
export { timeline } from './timeline.js';
|
export { timeline } from './timeline.js';
|
||||||
export { modal } from './modal.js';
|
export { modal } from './modal.js';
|
||||||
export { drawer } from './drawer.js';
|
export { drawer } from './drawer.js';
|
||||||
|
|||||||
@@ -372,4 +372,20 @@ export interface TimelineProps {
|
|||||||
pending?: boolean; // 末尾追加「进行中」虚线节点,表示流程未结束;缺省 false
|
pending?: boolean; // 末尾追加「进行中」虚线节点,表示流程未结束;缺省 false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** 描述项:详情页的「字段名 : 字段值」一行 ***/
|
||||||
|
export interface DescriptionItem {
|
||||||
|
label: string; // 字段名(左栏)
|
||||||
|
value: unknown; // 字段值(右栏):字符串 / DOM 节点 / 响应式函数
|
||||||
|
span?: number; // 占列数;缺省 1,超过 column 时按整行占满
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** 描述列表入参 ***/
|
||||||
|
export interface DescriptionsProps {
|
||||||
|
items: DescriptionItem[]; // 描述项列表,按序铺进网格
|
||||||
|
column?: 1 | 2 | 3 | 4; // 桌面列数;缺省 3(窄屏自动降为单列)
|
||||||
|
bordered?: boolean; // 表格形态(带分隔线与底纹);缺省 false(纯网格)
|
||||||
|
size?: 'sm' | 'md'; // 尺寸档位;缺省 md
|
||||||
|
title?: string; // 分组标题;缺省不渲染
|
||||||
|
}
|
||||||
|
|
||||||
export type { ColumnDef, RowKey }; // 再导出常用内核类型,方便调用方
|
export type { ColumnDef, RowKey }; // 再导出常用内核类型,方便调用方
|
||||||
|
|||||||
@@ -49,7 +49,8 @@
|
|||||||
"dataTable(props):数据表格,粘性表头 / 行选择(全选三态)/ 排序 / 筛选 / 分页 / 空状态;loading 为真时数据行换骨架行且筛选/翻页禁用,内核为 table-core",
|
"dataTable(props):数据表格,粘性表头 / 行选择(全选三态)/ 排序 / 筛选 / 分页 / 空状态;loading 为真时数据行换骨架行且筛选/翻页禁用,内核为 table-core",
|
||||||
"image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽",
|
"image(props):图片,缩略图点击 / 回车开遮罩大图预览(Esc 或点击遮罩关闭),width 控制缩略宽",
|
||||||
"timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点",
|
"timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点",
|
||||||
"segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用"
|
"segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用",
|
||||||
|
"descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列"
|
||||||
],
|
],
|
||||||
"keyTypes": [
|
"keyTypes": [
|
||||||
"ButtonProps",
|
"ButtonProps",
|
||||||
@@ -89,7 +90,9 @@
|
|||||||
"AvatarProps",
|
"AvatarProps",
|
||||||
"TimelineItem",
|
"TimelineItem",
|
||||||
"TimelineProps",
|
"TimelineProps",
|
||||||
"SegmentedProps"
|
"SegmentedProps",
|
||||||
|
"DescriptionItem",
|
||||||
|
"DescriptionsProps"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"usage": "const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')",
|
"usage": "const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')",
|
||||||
@@ -1534,6 +1537,51 @@
|
|||||||
"滑块几何由组件测量按钮位置得到,不要在外部改按钮宽度 / 内边距,否则需自行重渲染",
|
"滑块几何由组件测量按钮位置得到,不要在外部改按钮宽度 / 内边距,否则需自行重渲染",
|
||||||
"需要带图标或更复杂布局的分段,改用 radioGroup + 自定义样式"
|
"需要带图标或更复杂布局的分段,改用 radioGroup + 自定义样式"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "descriptions",
|
||||||
|
"title": "描述列表 Descriptions",
|
||||||
|
"demo": "sec-descriptions",
|
||||||
|
"props": [
|
||||||
|
{
|
||||||
|
"n": "items",
|
||||||
|
"t": "DescriptionItem[]",
|
||||||
|
"r": 1,
|
||||||
|
"d": "描述项列表:每项含 label(字段名)、value(字符串 / DOM / 响应式函数)、span(跨列数)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "column",
|
||||||
|
"t": "1 | 2 | 3 | 4",
|
||||||
|
"d": "桌面列数;缺省 3,窄屏(≤640px)由样式表降为单列",
|
||||||
|
"df": "3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "bordered",
|
||||||
|
"t": "boolean",
|
||||||
|
"d": "表格形态(带分隔线与字段名底纹);缺省 false 纯网格",
|
||||||
|
"df": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "size",
|
||||||
|
"t": "'sm' | 'md'",
|
||||||
|
"d": "尺寸档位;缺省 md",
|
||||||
|
"df": "md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"n": "title",
|
||||||
|
"t": "string",
|
||||||
|
"d": "分组标题;缺省不渲染标题行"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"example": "descriptions({ title: '订单信息', column: 2, bordered: true, items: [{ label: '订单号', value: 'RB-2048' }, { label: '金额', value: '¥1,280.00' }, { label: '备注', value: '加急', span: 2 }] })",
|
||||||
|
"steps": [
|
||||||
|
"详情页 / 抽屉里展示只读字段用它,不要用 form(form 承载输入与校验)",
|
||||||
|
"column 按信息密度定:字段多且短用 3-4 列,字段长(地址、备注)用 2 列并配 span 占整行",
|
||||||
|
"value 支持任意 DOM:放 tag、badge、button 都可以;要给值做响应式更新就传函数 () => 内容",
|
||||||
|
"bordered: true 是表格形态(适合打印与密集信息),纯网格形态更轻,适合卡片内嵌",
|
||||||
|
"窄屏自动降为单列,无需在调用方写媒体查询",
|
||||||
|
"纯展示组件,无状态无回调:值变了由调用方重新渲染或传函数式 value"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1816,3 +1816,67 @@ button.ua-step-dot:hover {
|
|||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* —— 描述列表:label : value 网格,列数走 --ua-desc-col,窄屏自动单列 —— */
|
||||||
|
.ua-desc {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(var(--ua-desc-col, 3), minmax(0, 1fr));
|
||||||
|
gap: var(--ua-space-2) var(--ua-space-3);
|
||||||
|
}
|
||||||
|
.ua-desc-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--ua-space-2);
|
||||||
|
}
|
||||||
|
.ua-desc-title {
|
||||||
|
color: var(--ua-color-text);
|
||||||
|
font-size: var(--ua-font-size-md);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.ua-desc-item {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--ua-space-2);
|
||||||
|
min-width: 0;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
.ua-desc-label {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: var(--ua-color-text-muted);
|
||||||
|
font-size: var(--ua-font-size-md);
|
||||||
|
}
|
||||||
|
.ua-desc-value {
|
||||||
|
min-width: 0;
|
||||||
|
color: var(--ua-color-text);
|
||||||
|
font-size: var(--ua-font-size-md);
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
.ua-desc-sm .ua-desc-label,
|
||||||
|
.ua-desc-sm .ua-desc-value {
|
||||||
|
font-size: var(--ua-font-size-sm);
|
||||||
|
}
|
||||||
|
.ua-desc.is-bordered {
|
||||||
|
gap: 0;
|
||||||
|
border: 1px solid var(--ua-color-border);
|
||||||
|
border-radius: var(--ua-radius-md);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.ua-desc.is-bordered .ua-desc-item {
|
||||||
|
padding: 0;
|
||||||
|
border-right: 1px solid var(--ua-color-border);
|
||||||
|
border-bottom: 1px solid var(--ua-color-border);
|
||||||
|
}
|
||||||
|
.ua-desc.is-bordered .ua-desc-label {
|
||||||
|
padding: 6px 10px;
|
||||||
|
background: color-mix(in srgb, var(--ua-color-text) 4%, transparent);
|
||||||
|
border-right: 1px solid var(--ua-color-border);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.ua-desc.is-bordered .ua-desc-value {
|
||||||
|
padding: 6px 10px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.ua-desc {
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user