From e6b4a8408561fc00a7ed54939f2725ea70922d32 Mon Sep 17 00:00:00 2001 From: HIsheR Date: Mon, 26 Oct 2026 11:33:27 +0800 Subject: [PATCH] =?UTF-8?q?iter(g24):=20=E6=96=B0=E5=A2=9E=20list=20?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E7=BB=84=E4=BB=B6=EF=BC=88=E5=90=AB=E7=A9=BA?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=9B=9E=E8=90=BD=E4=B8=8E=E5=8F=AF=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E6=9D=A1=E7=9B=AE=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ua/backlog.json | 8 ++++ .ua/index.json | 51 ++++++++++++++++++++- AGENTS.md | 2 +- ARCHITECTURE.md | 2 +- README.md | 6 +-- apps/demo/main.ts | 28 ++++++++++++ llms-full.txt | 29 +++++++++++- llms.txt | 1 + packages/skin/ui/src/index.ts | 1 + packages/skin/ui/src/list.ts | 36 +++++++++++++++ packages/skin/ui/src/types.ts | 18 ++++++++ packages/skin/ui/ua.manifest.json | 49 +++++++++++++++++++- packages/skin/ui/ui.css | 75 +++++++++++++++++++++++++++++++ 13 files changed, 297 insertions(+), 9 deletions(-) create mode 100644 packages/skin/ui/src/list.ts diff --git a/.ua/backlog.json b/.ua/backlog.json index 9dbdab3..8fefd63 100644 --- a/.ua/backlog.json +++ b/.ua/backlog.json @@ -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": "自补:组件补充" } ] } diff --git a/.ua/index.json b/.ua/index.json index 2e26980..ac73237 100644 --- a/.ua/index.json +++ b/.ua/index.json @@ -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 覆盖" + ] } ] }, diff --git a/AGENTS.md b/AGENTS.md index e88dc02..3db0a07 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 4b4b893..9ba9a3c 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -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,不发布) diff --git a/README.md b/README.md index 4a91ef7..9658dc6 100644 --- a/README.md +++ b/README.md @@ -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 个) -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 分组:表单(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 打包成单文件) | diff --git a/apps/demo/main.ts b/apps/demo/main.ts index 5fc6c8e..42b7ac8 100644 --- a/apps/demo/main.ts +++ b/apps/demo/main.ts @@ -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', '下拉菜单', diff --git a/llms-full.txt b/llms-full.txt index cef9cb3..23ff5c9 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -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 为空回落空状态 一行用法: diff --git a/llms.txt b/llms.txt index 5d086fe..b3badc6 100644 --- a/llms.txt +++ b/llms.txt @@ -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 为回调 diff --git a/packages/skin/ui/src/index.ts b/packages/skin/ui/src/index.ts index 59ddb77..28aeb93 100644 --- a/packages/skin/ui/src/index.ts +++ b/packages/skin/ui/src/index.ts @@ -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'; diff --git a/packages/skin/ui/src/list.ts b/packages/skin/ui/src/list.ts new file mode 100644 index 0000000..7e896eb --- /dev/null +++ b/packages/skin/ui/src/list.ts @@ -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; +} diff --git a/packages/skin/ui/src/types.ts b/packages/skin/ui/src/types.ts index 2966d93..f1e6129 100644 --- a/packages/skin/ui/src/types.ts +++ b/packages/skin/ui/src/types.ts @@ -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 }; // 再导出常用内核类型,方便调用方 diff --git a/packages/skin/ui/ua.manifest.json b/packages/skin/ui/ua.manifest.json index 733fce2..67a7555 100644 --- a/packages/skin/ui/ua.manifest.json +++ b/packages/skin/ui/ua.manifest.json @@ -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 覆盖" + ] } ] } diff --git a/packages/skin/ui/ui.css b/packages/skin/ui/ui.css index ffd4d56..4aa87ad 100644 --- a/packages/skin/ui/ui.css +++ b/packages/skin/ui/ui.css @@ -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; + } +}