From df78685dc3b3277d81ebd9569a3484ca5a902f4a Mon Sep 17 00:00:00 2001 From: xiaomai Date: Wed, 6 May 2026 22:11:09 +0800 Subject: [PATCH] feat(frontend): enhance trading item search and keyboard navigation Implement weighted search scoring for trading items Add keyboard support (arrows, enter) for item selection Limit trading detail list height with independent scrolling --- DESIGN.md | 4 +- frontend/src/styles/main.css | 17 +++ frontend/src/views/PokemonDetail.vue | 189 +++++++++++++++++++++++++-- 3 files changed, 196 insertions(+), 14 deletions(-) diff --git a/DESIGN.md b/DESIGN.md index 3d8f6eb..729887c 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -603,8 +603,8 @@ Pokemon 详情页展示: - 六维使用 ProgressBar 展示,最大值按 150 计算。 - 特长 - 特长掉落物品:当该 Pokemon 拥有支持掉落物的已选特长时默认展示;已配置时展示掉落物品图标,未配置时展示空状态 -- Trading:当该 Pokemon 拥有支持 Trading 的已选特长时默认展示;分 Likes 与 Neutral 两组展示物品,Likes 表示交易价格 1.5x,Neutral 表示无加成,未配置观察时展示空状态 -- Trading 可在详情页通过 Manage Trading Modal 维护;Modal 左侧顶部为同一行搜索框和分类下拉筛选,下面提供 Likes / Neutral 默认加入目标切换;从左侧选择物品会加入当前默认目标组,右侧按 Likes / Neutral 分组展示已选物品,并可切换分组或移除;列表区域高度稳定,过滤结果减少时 Modal 不应抖动 +- Trading:当该 Pokemon 拥有支持 Trading 的已选特长时默认展示;分 Likes 与 Neutral 两组展示物品,Likes 表示交易价格 1.5x,Neutral 表示无加成,未配置观察时展示空状态;详情页双列列表高度受限,内容较多时每列内部独立滚动,避免 Section 被大量物品无限拉长 +- Trading 可在详情页通过 Manage Trading Modal 维护;Modal 左侧顶部为同一行搜索框和分类下拉筛选,下面提供 Likes / Neutral 默认加入目标切换;搜索结果优先展示名称精确匹配、名称开头匹配和单词匹配的物品,再展示名称包含、分类或用途包含的物品;搜索框支持上下键切换当前结果、左右键切换默认加入组、Enter 将当前结果加入默认目标组;从左侧选择物品会加入当前默认目标组,右侧按 Likes / Neutral 分组展示已选物品,并可切换分组或移除;列表区域高度稳定,过滤结果减少时 Modal 不应抖动 - 喜欢的环境 - 喜欢的东西 - 相关 Pokemon:与关联喜欢的东西的物品在桌面端左右并排展示;按相同喜欢的环境优先,其次按共同喜欢的东西数量从多到少排序;支持按喜欢的环境筛选,默认筛选当前 Pokemon 的喜欢的环境,也可切换到其他喜欢的环境或全部;每个筛选视图最多展示 6 个;每项左侧展示 Pokemon 图片或默认 Poké Ball 占位符,原列表项信息布局保持不变,第一行左侧展示名称,右侧展示特长和喜欢的环境,第二行展示喜欢的东西,并高亮共同喜欢的东西 diff --git a/frontend/src/styles/main.css b/frontend/src/styles/main.css index 7ced4fa..059f992 100644 --- a/frontend/src/styles/main.css +++ b/frontend/src/styles/main.css @@ -5143,6 +5143,14 @@ button:disabled, flex-wrap: wrap; } +.trading-detail-list { + max-height: 360px; + overflow: auto; + padding-right: 4px; + overscroll-behavior: contain; + scrollbar-gutter: stable; +} + .trading-manager { min-height: 640px; display: grid; @@ -5232,6 +5240,11 @@ button:disabled, background: var(--surface-soft); } +.trading-pick-row--active { + border-color: var(--pokemon-blue); + box-shadow: 0 0 0 2px rgba(42, 117, 187, .16); +} + .trading-pick-row__copy, .trading-selected-list__copy { min-width: 0; @@ -5320,6 +5333,10 @@ button:disabled, max-height: 240px; } + .trading-detail-list { + max-height: 280px; + } + .trading-preference-toggle, .trading-selected-list .plain-button--icon { grid-column: 2; diff --git a/frontend/src/views/PokemonDetail.vue b/frontend/src/views/PokemonDetail.vue index 4858c3e..d9a41c6 100644 --- a/frontend/src/views/PokemonDetail.vue +++ b/frontend/src/views/PokemonDetail.vue @@ -1,6 +1,6 @@