iter(g24): 新增 list 列表组件(含空状态回落与可点击条目)
This commit is contained in:
@@ -548,6 +548,14 @@
|
||||
"acceptance": "tabs 聚焦时 Home 跳首个可用页签、End 跳末个可用页签并激活;方向键行为不变;npm run check 全绿",
|
||||
"status": "done",
|
||||
"notes": "自补:既有组件可用性细节;Home/End 直达首末启用页签,方向键环形逻辑不变"
|
||||
},
|
||||
{
|
||||
"id": "g24",
|
||||
"title": "新增 list 列表组件",
|
||||
"motivation": "皮肤包缺通用列表容器,审批/消息/搜索结果等场景只能手写 div 拼装,样式与令牌脱节",
|
||||
"acceptance": "list({ items, header, footer, bordered, emptyText, onItemClick }) 渲染条目 avatar/title/description/extra;空数组回落 empty;组件数 38→39 三处计数同步;npm run check 全绿",
|
||||
"status": "open",
|
||||
"notes": "自补:组件补充"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+49
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "ui-arch-registry-index/0.1",
|
||||
"generatedAt": "2026-10-26T03:31:05.626Z",
|
||||
"generatedAt": "2026-10-26T03:33:14.774Z",
|
||||
"repoRoot": ".",
|
||||
"packages": [
|
||||
{
|
||||
@@ -181,7 +181,8 @@
|
||||
"timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点",
|
||||
"segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用",
|
||||
"descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列",
|
||||
"statistic(props):统计数值,标题 + 大号数字 + 前后缀 + 环比趋势,value 变化时 rAF 滚动过渡(400ms easeOutCubic),减弱动效偏好下直落终值"
|
||||
"statistic(props):统计数值,标题 + 大号数字 + 前后缀 + 环比趋势,value 变化时 rAF 滚动过渡(400ms easeOutCubic),减弱动效偏好下直落终值",
|
||||
"list(props):列表,header/footer 外壳 + 条目 avatar/title/description/extra,onItemClick 让条目可点击,items 为空回落空状态"
|
||||
],
|
||||
"keyTypes": [
|
||||
"ButtonProps",
|
||||
@@ -1762,6 +1763,52 @@
|
||||
"多条指标并排时用 descriptions 或 flex 容器排列,本组件不自带网格",
|
||||
"用户开启「减弱动效」时组件直接落终值,无需调用方判断"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "list",
|
||||
"title": "列表 List",
|
||||
"demo": "sec-list",
|
||||
"props": [
|
||||
{
|
||||
"n": "items",
|
||||
"t": "ListItem[]",
|
||||
"r": 1,
|
||||
"d": "条目列表,每项 { title, description?, avatar?, extra? }"
|
||||
},
|
||||
{
|
||||
"n": "header",
|
||||
"t": "string",
|
||||
"d": "列表头标题;缺省不渲染"
|
||||
},
|
||||
{
|
||||
"n": "footer",
|
||||
"t": "string",
|
||||
"d": "列表尾说明;缺省不渲染"
|
||||
},
|
||||
{
|
||||
"n": "bordered",
|
||||
"t": "boolean",
|
||||
"d": "是否带外边框与分隔线;缺省 false"
|
||||
},
|
||||
{
|
||||
"n": "emptyText",
|
||||
"t": "string",
|
||||
"d": "无数据占位文案;缺省「暂无数据」"
|
||||
},
|
||||
{
|
||||
"n": "onItemClick",
|
||||
"t": "(item: ListItem, index: number) => void",
|
||||
"k": 1,
|
||||
"d": "条目点击回调;提供后条目可点击并带 hover 反馈"
|
||||
}
|
||||
],
|
||||
"example": "list({ header: '待办', bordered: true, items: [{ title: '报销单 RB-2048', description: '等待复核', avatar: avatar({ name: '王' }) }], onItemClick: (item) => console.log(item.title) })",
|
||||
"steps": [
|
||||
"准备 items 数组,每项至少给 title,description 作次要说明",
|
||||
"avatar 传头像组件(如 avatar({ name }))、extra 传右侧附加(如 tag(...)),不传该侧不留位",
|
||||
"需要点击时传 onItemClick(item, index),条目自动加 hover 底色;bordered: true 给外边框与分隔线",
|
||||
"items 为空数组时自动渲染 empty 占位,文案可用 emptyText 覆盖"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -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):38 个 DOM 组件(表单 / 反馈 / 浮层 / 导航 / 表格),样式只消费令牌
|
||||
- `packages/skin/ui`(@ui-arch/ui):39 个 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/ # 38 个组件 + ui.css
|
||||
│ │ └── ui/ # 39 个组件 + ui.css
|
||||
│ ├── design/ # 资产层(可发布)
|
||||
│ │ └── tokens/ # --ua-* 设计令牌
|
||||
│ └── tools/ # 工程层(private,不发布)
|
||||
|
||||
@@ -11,10 +11,10 @@ npm run demo # 打开演示:apps/demo/dist/demo.html
|
||||
npm run docs # 生成人类文档站 apps/docs/index.html + Agent 全量文档 llms-full.txt
|
||||
```
|
||||
|
||||
## 组件(共 38 个)
|
||||
## 组件(共 39 个)
|
||||
|
||||
<!-- ua:components -->
|
||||
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 · statistic · 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 · list · menu · modal · pagination · popover · progress · radioGroup · rate · segmented · select · skeleton · slider · spinner · statistic · stepper · switchButton · tabs · tag · textField · textarea · timeline · toast · tooltip
|
||||
<!-- /ua:components -->
|
||||
|
||||
分组:表单(button / textField / inputNumber / textarea / checkbox / switchButton / select / radioGroup / slider / rate / segmented / form / formItem)、反馈(alert / toast / spinner / progress / skeleton / badge / empty / statistic)、浮层(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/table-core` | @ui-arch/table-core:headless 表格(filter → sort → paginate 派生管线) |
|
||||
| `packages/skin/ui` | @ui-arch/ui:38 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
||||
| `packages/skin/ui` | @ui-arch/ui:39 个 DOM 组件 + ui.css(只消费 `--ua-*` 令牌) |
|
||||
| `packages/design/tokens` | @ui-arch/tokens:设计令牌(暗色只换值不换名) |
|
||||
| `packages/tools/cli` | @ui-arch/cli:`ua` 命令行与 stdio MCP server |
|
||||
| `apps/demo` | 交互演示(esbuild 打包成单文件) |
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
form,
|
||||
formItem,
|
||||
inputNumber,
|
||||
list,
|
||||
menu,
|
||||
modal,
|
||||
pagination,
|
||||
@@ -171,6 +172,7 @@ const tableLoading = signal(false);
|
||||
|
||||
// —— 菜单选中结果:演示 onSelect 回调 ——
|
||||
const menuPick = signal('');
|
||||
const listPick = signal(''); // 列表点击选中的条目标题
|
||||
|
||||
// —— 禁用态演示:开关信号同时绑定 switch 的 checked 与 checkbox 的 disabled ——
|
||||
const locked = signal(true);
|
||||
@@ -566,6 +568,32 @@ const content = h(
|
||||
pending: !flowDone(),
|
||||
}),
|
||||
),
|
||||
section(
|
||||
'sec-list',
|
||||
'列表',
|
||||
'list:header/footer 外壳 + 条目 avatar/title/description/extra;传 onItemClick 后条目可点击并有 hover 反馈,items 为空自动回落空状态。',
|
||||
h(
|
||||
'div',
|
||||
{ class: 'row' },
|
||||
list({
|
||||
header: '审批待办(3)',
|
||||
footer: '共 3 条,点击条目查看详情',
|
||||
bordered: true,
|
||||
items: [
|
||||
{ title: '王小明 · 报销单 RB-2048', description: '差旅费 ¥1,280,等待财务复核', avatar: avatar({ name: '王' }), extra: tag({ label: '待审', variant: 'warning' }) },
|
||||
{ title: '李静 · 采购申请 CG-112', description: '显示器 2 台,预算 ¥3,600', avatar: avatar({ name: '李', variant: 'success' }), extra: tag({ label: '已通过', variant: 'success' }) },
|
||||
{ title: '张伟 · 加班调休', description: '10-24 加班 3 小时,申请调休', avatar: avatar({ name: '张', variant: 'danger' }), extra: tag({ label: '已驳回', variant: 'danger' }) },
|
||||
],
|
||||
onItemClick: (item) => listPick(item.title), // 点击回传整条数据
|
||||
}),
|
||||
h(
|
||||
'div',
|
||||
{ class: 'stack' },
|
||||
h('span', { class: 'out' }, () => (listPick() ? '已选:' + listPick() : '未点击条目')),
|
||||
list({ items: [], bordered: true, emptyText: '暂无待办事项' }),
|
||||
),
|
||||
),
|
||||
),
|
||||
section(
|
||||
'sec-menu',
|
||||
'下拉菜单',
|
||||
|
||||
+28
-1
@@ -1,6 +1,6 @@
|
||||
# @ui-arch 组件库 Agent 文档(无图形版)
|
||||
|
||||
> 自动生成于 2026-10-26T03:31:05.626Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 自动生成于 2026-10-26T03:33:14.774Z,数据源:各包 ua.manifest.json,勿手改。人类版文档站:apps/docs/index.html。
|
||||
> 组件 = 普通函数,传 props 返回 DOM;状态用 signal 双向绑定:读 signal() 写 signal(v)。
|
||||
|
||||
## 快速上手
|
||||
@@ -1005,6 +1005,32 @@ const gmv = signal(128000); statistic({ title: '本月 GMV', value: gmv, prefix:
|
||||
|
||||
现场演示:apps/docs/demo.html#sec-statistic
|
||||
|
||||
### list — 列表 List
|
||||
|
||||
参数:
|
||||
|
||||
- items(必填):ListItem[] —— 条目列表,每项 { title, description?, avatar?, extra? }
|
||||
- header:string —— 列表头标题;缺省不渲染
|
||||
- footer:string —— 列表尾说明;缺省不渲染
|
||||
- bordered:boolean —— 是否带外边框与分隔线;缺省 false
|
||||
- emptyText:string —— 无数据占位文案;缺省「暂无数据」
|
||||
- onItemClick(回调):(item: ListItem, index: number) => void —— 条目点击回调;提供后条目可点击并带 hover 反馈
|
||||
|
||||
示例:
|
||||
|
||||
```
|
||||
list({ header: '待办', bordered: true, items: [{ title: '报销单 RB-2048', description: '等待复核', avatar: avatar({ name: '王' }) }], onItemClick: (item) => console.log(item.title) })
|
||||
```
|
||||
|
||||
手把手:
|
||||
|
||||
1. 准备 items 数组,每项至少给 title,description 作次要说明
|
||||
2. avatar 传头像组件(如 avatar({ name }))、extra 传右侧附加(如 tag(...)),不传该侧不留位
|
||||
3. 需要点击时传 onItemClick(item, index),条目自动加 hover 底色;bordered: true 给外边框与分隔线
|
||||
4. items 为空数组时自动渲染 empty 占位,文案可用 emptyText 覆盖
|
||||
|
||||
现场演示:apps/docs/demo.html#sec-list
|
||||
|
||||
API 速览:
|
||||
|
||||
- button(props):按钮,variant = primary | ghost | danger,disabled 支持布尔或信号禁用
|
||||
@@ -1047,6 +1073,7 @@ API 速览:
|
||||
- segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用
|
||||
- descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列
|
||||
- statistic(props):统计数值,标题 + 大号数字 + 前后缀 + 环比趋势,value 变化时 rAF 滚动过渡(400ms easeOutCubic),减弱动效偏好下直落终值
|
||||
- list(props):列表,header/footer 外壳 + 条目 avatar/title/description/extra,onItemClick 让条目可点击,items 为空回落空状态
|
||||
|
||||
一行用法:
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
- segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用
|
||||
- descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列
|
||||
- statistic(props):统计数值,标题 + 大号数字 + 前后缀 + 环比趋势,value 变化时 rAF 滚动过渡(400ms easeOutCubic),减弱动效偏好下直落终值
|
||||
- list(props):列表,header/footer 外壳 + 条目 avatar/title/description/extra,onItemClick 让条目可点击,items 为空回落空状态
|
||||
- 用法: `const checked = signal(false); checkbox({ label: '同意', checked }); const open = signal(false); modal({ title: '确认', open }, '内容')`
|
||||
- 约定: 皮肤不持有业务状态,一律委托 headless 内核或调用方信号
|
||||
- 约定: 表单类组件统一约定:*Props.value/checked/active 为 Signal 双向绑定,onChange/onInput 为回调
|
||||
|
||||
@@ -31,6 +31,7 @@ export { stepper } from './stepper.js';
|
||||
export { rate } from './rate.js';
|
||||
export { empty } from './empty.js';
|
||||
export { divider } from './divider.js';
|
||||
export { list } from './list.js';
|
||||
export { descriptions } from './descriptions.js';
|
||||
export { statistic } from './statistic.js';
|
||||
export { timeline } from './timeline.js';
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { h } from '@ui-arch/frame';
|
||||
import type { ListProps } from './types.js';
|
||||
import { empty } from './empty.js';
|
||||
|
||||
/*** 列表:header/footer 外壳 + 逐条 items(avatar / title / description / extra),传 onItemClick 时条目可点击,无数据回落空状态 ***/
|
||||
export function list(props: ListProps): HTMLElement {
|
||||
// —— 状态集中声明 ——
|
||||
const clickable = typeof props.onItemClick === 'function'; // 仅提供回调时才加可点击样式
|
||||
const rootClass = props.bordered ? 'ua-list ua-list-bordered' : 'ua-list'; // 外边框由 bordered 决定
|
||||
const root = h('div', { class: rootClass }) as HTMLElement; // 列表根容器
|
||||
if (props.header) root.append(h('div', { class: 'ua-list-header' }, props.header));
|
||||
if (!props.items.length) {
|
||||
root.append(empty({ title: props.emptyText ?? '暂无数据' })); // 空列表复用空状态组件
|
||||
return root;
|
||||
}
|
||||
const body = h('div', { class: 'ua-list-body', role: 'list' }) as HTMLElement; // 条目容器,供读屏识别列表语义
|
||||
props.items.forEach((item, index) => {
|
||||
const row = h(
|
||||
'div',
|
||||
{ class: clickable ? 'ua-list-item ua-list-clickable' : 'ua-list-item', role: 'listitem' },
|
||||
item.avatar ? h('div', { class: 'ua-list-avatar' }, item.avatar) : null, // 左侧头像/图标,缺省不留位
|
||||
h(
|
||||
'div',
|
||||
{ class: 'ua-list-main' },
|
||||
h('div', { class: 'ua-list-title' }, item.title),
|
||||
item.description ? h('div', { class: 'ua-list-desc' }, item.description) : null,
|
||||
),
|
||||
item.extra ? h('div', { class: 'ua-list-extra' }, item.extra) : null, // 右侧附加(时间、标签)
|
||||
);
|
||||
if (clickable) row.addEventListener('click', () => props.onItemClick?.(item, index)); // 点击回传条目与下标
|
||||
body.append(row);
|
||||
});
|
||||
root.append(body);
|
||||
if (props.footer) root.append(h('div', { class: 'ua-list-footer' }, props.footer));
|
||||
return root;
|
||||
}
|
||||
@@ -402,4 +402,22 @@ export interface StatisticProps {
|
||||
trend?: 'up' | 'down'; // 环比方向:up 红 / down 绿(A 股口径);缺省不渲染
|
||||
}
|
||||
|
||||
/*** 列表条目 ***/
|
||||
export interface ListItem {
|
||||
title: string; // 主标题(必填)
|
||||
description?: string; // 次要说明;缺省不渲染
|
||||
avatar?: unknown; // 左侧头像/图标;缺省不留位
|
||||
extra?: unknown; // 右侧附加内容(时间、标签等);缺省不留位
|
||||
}
|
||||
|
||||
/*** 列表入参 ***/
|
||||
export interface ListProps {
|
||||
items: ListItem[]; // 条目列表,按序渲染
|
||||
header?: string; // 列表头标题;缺省不渲染
|
||||
footer?: string; // 列表尾说明;缺省不渲染
|
||||
bordered?: boolean; // 是否带外边框与分隔线;缺省 false
|
||||
emptyText?: string; // 无数据占位文案;缺省「暂无数据」
|
||||
onItemClick?: (item: ListItem, index: number) => void; // 条目点击回调;提供后条目可点击并带 hover 反馈
|
||||
}
|
||||
|
||||
export type { ColumnDef, RowKey }; // 再导出常用内核类型,方便调用方
|
||||
|
||||
@@ -52,7 +52,8 @@
|
||||
"timeline(props):时间线,items 按序渲染纵向事件流(标题 / 时间 / 正文 + 语义色节点),mode 控制轴线左右,pending 追加进行中节点",
|
||||
"segmented(props):分段控制器,胶囊分段 + 滑动滑块,value 信号双向绑定,←→ 环形导航,整组或单项可禁用",
|
||||
"descriptions(props):描述列表,items(label/value/span) 铺进 column 列网格,bordered 切表格形态,窄屏自动单列",
|
||||
"statistic(props):统计数值,标题 + 大号数字 + 前后缀 + 环比趋势,value 变化时 rAF 滚动过渡(400ms easeOutCubic),减弱动效偏好下直落终值"
|
||||
"statistic(props):统计数值,标题 + 大号数字 + 前后缀 + 环比趋势,value 变化时 rAF 滚动过渡(400ms easeOutCubic),减弱动效偏好下直落终值",
|
||||
"list(props):列表,header/footer 外壳 + 条目 avatar/title/description/extra,onItemClick 让条目可点击,items 为空回落空状态"
|
||||
],
|
||||
"keyTypes": [
|
||||
"ButtonProps",
|
||||
@@ -1633,6 +1634,52 @@
|
||||
"多条指标并排时用 descriptions 或 flex 容器排列,本组件不自带网格",
|
||||
"用户开启「减弱动效」时组件直接落终值,无需调用方判断"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "list",
|
||||
"title": "列表 List",
|
||||
"demo": "sec-list",
|
||||
"props": [
|
||||
{
|
||||
"n": "items",
|
||||
"t": "ListItem[]",
|
||||
"r": 1,
|
||||
"d": "条目列表,每项 { title, description?, avatar?, extra? }"
|
||||
},
|
||||
{
|
||||
"n": "header",
|
||||
"t": "string",
|
||||
"d": "列表头标题;缺省不渲染"
|
||||
},
|
||||
{
|
||||
"n": "footer",
|
||||
"t": "string",
|
||||
"d": "列表尾说明;缺省不渲染"
|
||||
},
|
||||
{
|
||||
"n": "bordered",
|
||||
"t": "boolean",
|
||||
"d": "是否带外边框与分隔线;缺省 false"
|
||||
},
|
||||
{
|
||||
"n": "emptyText",
|
||||
"t": "string",
|
||||
"d": "无数据占位文案;缺省「暂无数据」"
|
||||
},
|
||||
{
|
||||
"n": "onItemClick",
|
||||
"t": "(item: ListItem, index: number) => void",
|
||||
"k": 1,
|
||||
"d": "条目点击回调;提供后条目可点击并带 hover 反馈"
|
||||
}
|
||||
],
|
||||
"example": "list({ header: '待办', bordered: true, items: [{ title: '报销单 RB-2048', description: '等待复核', avatar: avatar({ name: '王' }) }], onItemClick: (item) => console.log(item.title) })",
|
||||
"steps": [
|
||||
"准备 items 数组,每项至少给 title,description 作次要说明",
|
||||
"avatar 传头像组件(如 avatar({ name }))、extra 传右侧附加(如 tag(...)),不传该侧不留位",
|
||||
"需要点击时传 onItemClick(item, index),条目自动加 hover 底色;bordered: true 给外边框与分隔线",
|
||||
"items 为空数组时自动渲染 empty 占位,文案可用 emptyText 覆盖"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1996,3 +1996,78 @@ button.ua-step-dot:hover {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* —— 列表 —— */
|
||||
.ua-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: var(--ua-radius-md);
|
||||
overflow: hidden;
|
||||
}
|
||||
.ua-list-bordered {
|
||||
border: 1px solid var(--ua-color-border);
|
||||
background: var(--ua-color-surface);
|
||||
}
|
||||
.ua-list-header,
|
||||
.ua-list-footer {
|
||||
padding: var(--ua-space-2) var(--ua-space-3);
|
||||
font-size: var(--ua-font-size-sm);
|
||||
color: var(--ua-color-text-muted);
|
||||
}
|
||||
.ua-list-header {
|
||||
font-weight: 600;
|
||||
color: var(--ua-color-text);
|
||||
border-bottom: 1px solid var(--ua-color-border);
|
||||
}
|
||||
.ua-list-footer {
|
||||
border-top: 1px solid var(--ua-color-border);
|
||||
}
|
||||
.ua-list-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.ua-list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--ua-space-2);
|
||||
padding: var(--ua-space-2) var(--ua-space-3);
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
.ua-list-item + .ua-list-item {
|
||||
border-top: 1px solid var(--ua-color-border);
|
||||
}
|
||||
.ua-list-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.ua-list-clickable:hover {
|
||||
background: color-mix(in srgb, var(--ua-color-accent) 8%, transparent); /* 低视觉比重的悬停底色 */
|
||||
}
|
||||
.ua-list-avatar {
|
||||
flex: none;
|
||||
display: flex;
|
||||
}
|
||||
.ua-list-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.ua-list-title {
|
||||
font-size: var(--ua-font-size-md);
|
||||
color: var(--ua-color-text);
|
||||
}
|
||||
.ua-list-desc {
|
||||
font-size: var(--ua-font-size-sm);
|
||||
color: var(--ua-color-text-muted);
|
||||
}
|
||||
.ua-list-extra {
|
||||
flex: none;
|
||||
font-size: var(--ua-font-size-sm);
|
||||
color: var(--ua-color-text-muted);
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.ua-list-item {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user