feat(web): open the local settings file

This commit is contained in:
Yichen Jiang
2026-08-04 16:33:35 +08:00
parent 828cb2ae20
commit e31b7221e7
61 changed files with 939 additions and 98 deletions

View File

@@ -167,12 +167,22 @@
flex: none;
display: flex;
align-items: flex-start;
justify-content: flex-end;
justify-content: space-between;
gap: 8px;
height: 54px;
padding: 20px 14px 8px 10px;
box-sizing: border-box;
}
.actions {
min-width: 0;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
margin-left: auto;
}
/* Close button (figma .Icon_container 501:29982): 28x28, r28, 14px glyph. */
.close {
display: inline-flex;

View File

@@ -76,6 +76,7 @@ function SettingsPanel({ rows, renderSlot, activeId, onSelect, onClose }: PanelP
</nav>
<div className={css.content}>
<div className={css.header}>
<div className={css.actions}>{renderSlot('settings.action', {})}</div>
<button ref={closeButton} type="button" className={css.close} onClick={onClose}>
<IconCloseOutline16 size={14} />
<span className={css.hiddenLabel}>{renderSlot('settings.close', {})}</span>

View File

@@ -2,8 +2,8 @@
* Settings shell slot contract — the canonical home of every settings slot
* type. The shell is a pure composition face with zero copy of its own: it
* occupies the sidebar-owned `sidebar.settings` hole and declares the slots
* below; ALL text (trigger label, panel title, close aria, section content)
* arrives from registrants. A feature owns its settings surface — adding a
* below; ALL text (trigger label, panel title, header actions, close aria,
* section content) arrives from registrants. A feature owns its settings surface — adding a
* setting never means editing the shell; copy that belongs to no single
* feature (chrome, the General section) is owned by ui-settings-general.
*/
@@ -29,6 +29,12 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
* Absent contribution leaves the heading empty.
*/
'settings.header': { kind: 'single'; scope: 'root'; owner: SettingsHeaderOwnerProps }
/**
* Optional actions rendered in the content-column header before Close.
* Registrants own visibility, behavior, copy, and failure presentation;
* the shell supplies only the ordered render site.
*/
'settings.action': { kind: 'list'; scope: 'root'; owner: SettingsHeaderOwnerProps }
/**
* The close button's visually-hidden label text (the button itself —
* icon, geometry, focus — is shell chrome). Absent contribution leaves
@@ -125,6 +131,11 @@ export type SettingsRootInjected = {
export type SettingsRootComponentProps =
PropsRuntime<'sidebar.settings'>
& PropsRenderSlots<
'settings.trigger' | 'settings.header' | 'settings.close' | 'settings.section' | 'settings.onboarding'
| 'settings.trigger'
| 'settings.header'
| 'settings.action'
| 'settings.close'
| 'settings.section'
| 'settings.onboarding'
>
& InjectFace<SettingsRootInjected>

View File

@@ -103,6 +103,7 @@ export function apply(ctx: ClientContext): void {
children: {
'settings.trigger': { kind: 'single', scope: 'root' },
'settings.header': { kind: 'single', scope: 'root' },
'settings.action': { kind: 'list', scope: 'root' },
'settings.close': { kind: 'single', scope: 'root' },
'settings.section': { kind: 'list', scope: 'root' },
'settings.onboarding': { kind: 'list', scope: 'root' },