Merge remote-tracking branch 'origin/master' into dshw/pr-2423

# Conflicts:
#	packages/client/ui-sidebar/src/client/SidebarRoot.tsx
This commit is contained in:
_Kerman
2026-08-13 04:32:57 +08:00
3517 changed files with 51843 additions and 30957 deletions

View File

@@ -241,11 +241,34 @@
padding-left: 0;
}
/* Foot seat: a pure layout socket pinned under the region; the ui-settings
trigger row inside owns its own geometry (38px wide row / 36px rail
circle) and hover chrome. */
/* Footer seats: additive actions stack above Settings. Each occupant owns its
button geometry and hover chrome. */
.footArea {
flex: none;
display: flex;
flex-direction: column;
}
.settingsArea,
.footerActions {
flex: none;
min-width: 0;
width: 100%;
}
.footerActions {
display: flex;
}
.collapsed .footArea {
align-items: center;
}
.collapsed .settingsArea,
.collapsed .footerActions {
display: flex;
justify-content: center;
width: auto;
}
@media (prefers-reduced-motion: reduce) {

View File

@@ -7,8 +7,8 @@
* same top-down order) on one fade that ends with the slide. The bottom-pinned
* settings control only fades. The workspace/session browsing region between
* the New Session button and the foot is the `sidebar.workspaces` registrant's,
* and the foot is the `sidebar.settings` registrant's; the shell hands them the
* wide flag (plus an expand request callback for the browser).
* and the foot holds `sidebar.settings` plus `sidebar.footer.action`; the shell
* hands them the wide flag (plus an expand request callback for the browser).
*
* The column also owns whether the scroll regions nested in it draw a
* scrollbar at all: the shell tracks the pointer and rebinds ui-theme's
@@ -178,9 +178,14 @@ export function SidebarRoot({
})}
</div>
{/* Foot seat: ui-settings registers the trigger row + panel here. */}
{/* Footer actions stack above Settings in both sidebar widths. */}
<div className={css.footArea}>
{renderSlot('sidebar.settings', { wide })}
<div className={css.footerActions}>
{renderSlot('sidebar.footer.action', { wide })}
</div>
<div className={css.settingsArea}>
{renderSlot('sidebar.settings', { wide })}
</div>
</div>
</div>
)

View File

@@ -4,7 +4,8 @@
* owns column geometry (fold state machine, brand row, New Session);
* everything between the section header and the list bottom is the
* `sidebar.workspaces` registrant's (ui-workspace), and the foot is the
* `sidebar.settings` registrant's (ui-settings).
* `sidebar.settings` registrant's (ui-settings), followed by optional footer
* actions in `sidebar.footer.action`.
*/
import type { PropsLocale, PropsRenderSlots, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
// Type-only: pulls ui-layout's SlotMap merge (the 'sidebar' entry) into every
@@ -27,6 +28,11 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
* The sidebar passes only its column state — it holds no settings state.
*/
'sidebar.settings': { kind: 'single'; scope: 'root'; owner: SidebarSettingsOwnerProps }
/**
* Optional actions beside Settings at the sidebar foot. Declared by this
* package's 'sidebar' entry; each action receives only the column state.
*/
'sidebar.footer.action': { kind: 'list'; scope: 'root'; owner: SidebarFooterActionOwnerProps }
}
}
@@ -50,6 +56,12 @@ export interface SidebarSettingsOwnerProps {
wide: boolean
}
/** Owner share of an action rendered beside Settings at the sidebar foot. */
export interface SidebarFooterActionOwnerProps {
/** Whether the sidebar renders wide content (false = 56px rail). */
wide: boolean
}
/**
* Registrant-private injected share (arrives via the register inject
* factory). The shell keeps only its own controls: starting a Session from
@@ -72,5 +84,6 @@ export type SidebarRootInjected = {
* seat. No store is registered.
*/
export type SidebarRootComponentProps =
PropsRuntime<'sidebar'> & PropsRenderSlots<'sidebar.workspaces' | 'sidebar.settings'>
PropsRuntime<'sidebar'>
& PropsRenderSlots<'sidebar.workspaces' | 'sidebar.settings' | 'sidebar.footer.action'>
& SidebarRootInjected & PropsLocale<'sidebar'>

View File

@@ -6,7 +6,10 @@ import type { SidebarRootInjected } from './contract/slots.ts'
import { SidebarRoot } from './SidebarRoot.tsx'
import { en, zh, type SidebarKey } from './locales.ts'
export type { SidebarRootComponentProps, SidebarRootInjected, SidebarSectionOwnerProps, SidebarSettingsOwnerProps } from './contract/slots.ts'
export type {
SidebarFooterActionOwnerProps, SidebarRootComponentProps, SidebarRootInjected,
SidebarSectionOwnerProps, SidebarSettingsOwnerProps,
} from './contract/slots.ts'
export type { SidebarKey } from './locales.ts'
declare module '@deepseek-ai/dsh-client-ui-slots' {
@@ -44,6 +47,7 @@ export function apply(ctx: ClientContext): void {
children: {
'sidebar.workspaces': { kind: 'single', scope: 'root' },
'sidebar.settings': { kind: 'single', scope: 'root' },
'sidebar.footer.action': { kind: 'list', scope: 'root' },
},
inject: injectProps,
}, SidebarRoot),