From 2614a2df93b038505fda3d505ff2b920f7cb1db2 Mon Sep 17 00:00:00 2001 From: ZiyaZhang <199893125+ZiyaZhang@users.noreply.github.com> Date: Tue, 11 Aug 2026 08:03:39 -0700 Subject: [PATCH] Refine plugin inventory card details --- .../settings-chrome/plugins.expected.md | 10 ++- packages/client/ui-plugins/README.i18n.yaml | 4 +- packages/client/ui-plugins/README.md | 2 +- packages/client/ui-plugins/README.zh.md | 2 +- .../client/PluginSettingsSection.module.css | 74 +++++++++++++++++++ .../src/client/PluginSettingsSection.tsx | 45 ++++++++++- .../client/ui-plugins/src/client/locales.ts | 18 +++-- .../ui-plugins/tests/components.spec.tsx | 19 ++++- 8 files changed, 153 insertions(+), 21 deletions(-) diff --git a/apps/web/tests/snapshots/settings-chrome/plugins.expected.md b/apps/web/tests/snapshots/settings-chrome/plugins.expected.md index e3b2e9ee54..9e8362a942 100644 --- a/apps/web/tests/snapshots/settings-chrome/plugins.expected.md +++ b/apps/web/tests/snapshots/settings-chrome/plugins.expected.md @@ -1,4 +1,6 @@ -- listitem "ui-settings, 存活, 已启用": - - strong: ui-settings - - img "存活" - - text: 已启用 +- listitem: + - button "ui-settings, 已挂载, 已启用": + - strong: ui-settings + - img "已挂载" + - text: 已启用 + - img diff --git a/packages/client/ui-plugins/README.i18n.yaml b/packages/client/ui-plugins/README.i18n.yaml index ce5113cde1..62085c3d6b 100644 --- a/packages/client/ui-plugins/README.i18n.yaml +++ b/packages/client/ui-plugins/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-plugins/README.md -README.md: c3236935b2a568c6996fcac8469f061a813cd95c -README.zh.md: 77810bccf95a55761518f89909fddd99818f686a +README.md: bb487d5e2cbd34406d83867997ede4d70b190d70 +README.zh.md: 48a11911509ea260aa9727d55c0b4df6efbfb1c9 diff --git a/packages/client/ui-plugins/README.md b/packages/client/ui-plugins/README.md index c3236935b2..bb487d5e2c 100644 --- a/packages/client/ui-plugins/README.md +++ b/packages/client/ui-plugins/README.md @@ -4,7 +4,7 @@ English | [中文](README.zh.md) Read-only Plugins section for Web Settings. The browser plugin registers one localized `settings.section` contribution with id `plugin-inventory`, after Models, and lets the Settings shell supply its ordinary fallback icon. It performs no Remote read during plugin activation; mounting the section lazily calls `ctx.remote.pluginInventory.list()` through [`api-remotes`](../../api/remotes/README.md). -The page renders a searchable two-column catalog of compact cards. Each card uses the local Loader id as its title, a colored root-Fiber status dot, and a small effective-enablement tag. Loading, empty, no-match, and generic failure states stay local to the mounted component, and a failed read can be retried without exposing transport details. The registration uses `ctx.slots.inject()`, so it follows late Settings declaration, redeclaration, locale changes, and teardown without owning another global store. +The page renders a searchable two-column catalog of compact disclosure cards. Each collapsed card uses the local Loader id as its title, a colored root-Fiber status dot, and a small effective-enablement tag. Expanding one card reveals its Loader-tree entry value without a redundant field label, followed by the effective configuration and Cordis status. Loading, empty, no-match, and generic failure states stay local to the mounted component, and a failed read can be retried without exposing transport details. The registration uses `ctx.slots.inject()`, so it follows late Settings declaration, redeclaration, locale changes, and teardown without owning another global store. ## Model Experience diff --git a/packages/client/ui-plugins/README.zh.md b/packages/client/ui-plugins/README.zh.md index 77810bccf9..48a1191150 100644 --- a/packages/client/ui-plugins/README.zh.md +++ b/packages/client/ui-plugins/README.zh.md @@ -4,7 +4,7 @@ Web 设置中的只读“插件”分区。浏览器插件在“模型”之后注册一个 id 为 `plugin-inventory` 的本地化 `settings.section` 贡献,并由 Settings shell 提供常规的回退图标。插件激活期间不会读取 Remote;挂载该分区时,组件才通过 [`api-remotes`](../../api/remotes/README.md) 懒调用 `ctx.remote.pluginInventory.list()`。 -页面以可搜索的双列紧凑卡片展示清单。每张卡片使用 Loader 本地 id 作为标题,以彩色圆点表示根 Fiber 状态,以小标签表示有效启停状态。加载、空结果、无匹配结果与通用失败状态只属于已挂载组件;读取失败后可以重试,且不会暴露传输细节。注册使用 `ctx.slots.inject()`,因此能跟随 Settings 的延迟声明、重新声明、本地化变化与 teardown,而不拥有另一份全局 store。 +页面以可搜索的双列紧凑折叠卡片展示清单。每张收起的卡片使用 Loader 本地 id 作为标题,以彩色圆点表示根 Fiber 状态,以小标签表示有效启停状态。展开卡片后会直接展示 Loader 树条目值,不附加重复的字段标题,并列出有效配置状态与 Cordis 状态。加载、空结果、无匹配结果与通用失败状态只属于已挂载组件;读取失败后可以重试,且不会暴露传输细节。注册使用 `ctx.slots.inject()`,因此能跟随 Settings 的延迟声明、重新声明、本地化变化与 teardown,而不拥有另一份全局 store。 ## 模型体验 diff --git a/packages/client/ui-plugins/src/client/PluginSettingsSection.module.css b/packages/client/ui-plugins/src/client/PluginSettingsSection.module.css index c2cf16cf16..9429b60bb5 100644 --- a/packages/client/ui-plugins/src/client/PluginSettingsSection.module.css +++ b/packages/client/ui-plugins/src/client/PluginSettingsSection.module.css @@ -124,11 +124,18 @@ background: var(--dsw-alias-bg-layer-3); } +.card[data-open='true'] { + border-color: var(--dsw-alias-border-l1); + box-shadow: var(--dsw-shadow-lv1); +} + .cardContent { + box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 12px; + width: 100%; min-height: 52px; border: 0; padding: 12px 14px; @@ -136,6 +143,17 @@ color: inherit; font: inherit; text-align: left; + cursor: pointer; +} + +.cardContent:hover, +.card[data-open='true'] > .cardContent { + background: var(--dsw-alias-interactive-bg-hover); +} + +.cardContent:focus-visible { + outline: 2px solid var(--dsw-alias-state-business-primary); + outline-offset: -2px; } .cardTitle { @@ -195,6 +213,56 @@ color: var(--dsw-alias-state-success-primary); } +.chevron { + flex: none; + color: var(--dsw-alias-label-tertiary); +} + +.card[data-open='true'] .chevron { + transform: rotate(180deg); +} + +.cardDetails { + border-top: 1px solid var(--dsw-alias-border-l2); + padding: 10px 14px 12px; + background: var(--dsw-alias-bg-module-platform); +} + +.entryValue { + display: block; + overflow-wrap: anywhere; + color: var(--dsw-alias-label-primary); + font-family: var(--ds-font-family-code); + font-size: 12px; + line-height: 18px; +} + +.details { + display: grid; + grid-template-columns: 76px minmax(0, 1fr); + gap: 6px 10px; + margin: 8px 0 0; +} + +.details div { + display: contents; +} + +.details dt { + color: var(--dsw-alias-label-tertiary); + font-size: 11px; + line-height: 17px; +} + +.details dd { + min-width: 0; + margin: 0; + overflow-wrap: anywhere; + color: var(--dsw-alias-label-secondary); + font-size: 12px; + line-height: 17px; +} + .visuallyHidden { position: absolute; width: 1px; @@ -205,6 +273,12 @@ white-space: nowrap; } +@media (prefers-reduced-motion: no-preference) { + .chevron { + transition: transform 140ms var(--ds-ease-in-out); + } +} + @media (max-width: 680px) { .cards { grid-template-columns: minmax(0, 1fr); diff --git a/packages/client/ui-plugins/src/client/PluginSettingsSection.tsx b/packages/client/ui-plugins/src/client/PluginSettingsSection.tsx index 2d33ac2e8b..fc04e9b12a 100644 --- a/packages/client/ui-plugins/src/client/PluginSettingsSection.tsx +++ b/packages/client/ui-plugins/src/client/PluginSettingsSection.tsx @@ -1,6 +1,9 @@ import { useEffect, useId, useMemo, useState, type ReactNode } from 'react' import type { ClientRemote } from '@deepseek-ai/dsh-api-remotes/client' -import { IconSearchOutline16 } from '@deepseek-ai/dsh-client-ui-primitives' +import { + IconChevronDownOutline14, + IconSearchOutline16, +} from '@deepseek-ai/dsh-client-ui-primitives' import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots' import type { PluginsKey } from './locales.ts' import css from './PluginSettingsSection.module.css' @@ -54,6 +57,7 @@ export function PluginSettingsSection({ list, t }: PluginSettingsSectionProps): const titleId = useId() const [request, setRequest] = useState(0) const [query, setQuery] = useState('') + const [expanded, setExpanded] = useState(null) const [state, setState] = useState({ status: 'loading' }) useEffect(() => { @@ -73,6 +77,12 @@ export function PluginSettingsSection({ list, t }: PluginSettingsSectionProps): [normalizedQuery, state], ) + useEffect(() => { + if (expanded !== null && !filteredEntries.some(entry => entry.entryId === expanded)) { + setExpanded(null) + } + }, [expanded, filteredEntries]) + const retry = (): void => { setState({ status: 'loading' }) setRequest(value => value + 1) @@ -115,14 +125,25 @@ export function PluginSettingsSection({ list, t }: PluginSettingsSectionProps):