style(plugin-inventory): align install/toggle controls with the design system

The install input matched the catalog search field, and the install button plus
the enable/disable toggles now use the shared Button primitive (primary /
outline sm), replacing unstyled native buttons. The install hint clarifies that
registry installs require a published npm package.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Pine
2026-08-14 23:01:57 +08:00
parent aaa434afbd
commit c90beb5289
3 changed files with 26 additions and 14 deletions
@@ -57,12 +57,14 @@
pointer-events: none; pointer-events: none;
} }
.search input { /* The catalog search and the install field share the same field geometry. */
.search input,
.installInput {
width: 100%; width: 100%;
height: 36px; height: 36px;
border: 1px solid var(--dsw-alias-border-l2); border: 1px solid var(--dsw-alias-border-l2);
border-radius: 8px; border-radius: 8px;
padding: 0 34px 0 36px; padding: 0 12px;
outline: none; outline: none;
background: var(--dsw-alias-bg-layer-1); background: var(--dsw-alias-bg-layer-1);
color: var(--dsw-alias-label-primary); color: var(--dsw-alias-label-primary);
@@ -70,11 +72,18 @@
font-size: 13px; font-size: 13px;
} }
.search input::placeholder { /* The search field reserves leading space for its absolutely-placed icon. */
.search input {
padding: 0 34px 0 36px;
}
.search input::placeholder,
.installInput::placeholder {
color: var(--dsw-alias-label-tertiary); color: var(--dsw-alias-label-tertiary);
} }
.search input:focus-visible { .search input:focus-visible,
.installInput:focus-visible {
border-color: var(--dsw-alias-state-business-primary); border-color: var(--dsw-alias-state-business-primary);
box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 18%, transparent);
} }
@@ -1,6 +1,7 @@
import { useEffect, useId, useMemo, useState, type ReactNode } from 'react' import { useEffect, useId, useMemo, useState, type ReactNode } from 'react'
import type { InstallResult, InstallSpec, PluginInventorySnapshot } from '@deepseek-ai/dsh-api-remotes/client' import type { InstallResult, InstallSpec, PluginInventorySnapshot } from '@deepseek-ai/dsh-api-remotes/client'
import { import {
Button,
IconChevronDownOutline14, IconChevronDownOutline14,
IconSearchOutline16, IconSearchOutline16,
} from '@deepseek-ai/dsh-client-ui-primitives' } from '@deepseek-ai/dsh-client-ui-primitives'
@@ -197,27 +198,29 @@ export function PluginInventorySettingsTab({
) : null} ) : null}
</dl> </dl>
{!entry.enabled ? ( {!entry.enabled ? (
<button <Button
className={css.toggle} className={css.toggle}
type="button" variant="outline"
size="sm"
disabled={busy === entry.entryId} disabled={busy === entry.entryId}
aria-busy={busy === entry.entryId || undefined} aria-busy={busy === entry.entryId || undefined}
onClick={() => { toggle(entry.entryId, true) }} onClick={() => { toggle(entry.entryId, true) }}
> >
{busy === entry.entryId ? t('toggling') : t('enable')} {busy === entry.entryId ? t('toggling') : t('enable')}
</button> </Button>
) : entry.protected ? ( ) : entry.protected ? (
<p className={css.required}>{t('required')}</p> <p className={css.required}>{t('required')}</p>
) : ( ) : (
<button <Button
className={css.toggle} className={css.toggle}
type="button" variant="outline"
size="sm"
disabled={busy === entry.entryId} disabled={busy === entry.entryId}
aria-busy={busy === entry.entryId || undefined} aria-busy={busy === entry.entryId || undefined}
onClick={() => { toggle(entry.entryId, false) }} onClick={() => { toggle(entry.entryId, false) }}
> >
{busy === entry.entryId ? t('toggling') : t('disable')} {busy === entry.entryId ? t('toggling') : t('disable')}
</button> </Button>
)} )}
</div> </div>
) : null} ) : null}
@@ -248,14 +251,14 @@ export function PluginInventorySettingsTab({
onChange={(event) => { setSpec(event.currentTarget.value) }} onChange={(event) => { setSpec(event.currentTarget.value) }}
onKeyDown={(event) => { if (event.key === 'Enter') installRegistry() }} onKeyDown={(event) => { if (event.key === 'Enter') installRegistry() }}
/> />
<button <Button
type="button"
className={css.installAction} className={css.installAction}
variant="primary"
disabled={installBusy || spec.trim().length === 0} disabled={installBusy || spec.trim().length === 0}
onClick={installRegistry} onClick={installRegistry}
> >
{installBusy ? t('installing') : t('install')} {installBusy ? t('installing') : t('install')}
</button> </Button>
</div> </div>
{installNote !== null {installNote !== null
? <p className={installNote.kind === 'error' ? css.installError : css.installRestart} role="status">{installNote.text}</p> ? <p className={installNote.kind === 'error' ? css.installError : css.installRestart} role="status">{installNote.text}</p>
@@ -25,7 +25,7 @@ export const zh = {
toggling: '切换中…', toggling: '切换中…',
required: '应用必需插件,不可切换', required: '应用必需插件,不可切换',
installPlugin: '安装插件', installPlugin: '安装插件',
installSpec: '输入插件包名,如 @scope/plugin', installSpec: '输入插件包名,目前只支持已发布npm的包;如 @scope/plugin',
install: '安装', install: '安装',
installing: '安装中…', installing: '安装中…',
restartRequired: '已安装,重启后生效', restartRequired: '已安装,重启后生效',