Merge remote-tracking branch 'origin/master' into mergebot/pr1389

# Conflicts:
#	packages/client/ui-workspace/src/client/WorkspaceBrowser.module.css
This commit is contained in:
imccyu
2026-08-04 16:06:38 +08:00
574 changed files with 8022 additions and 29830 deletions

View File

@@ -7,10 +7,11 @@
mid-slide. */
.root {
--dsh-sidebar-inline-padding: 12px;
display: flex;
flex-direction: column;
height: 100%;
padding: 6px 12px;
padding: 6px var(--dsh-sidebar-inline-padding);
box-sizing: border-box;
background: var(--dsw-specific-sidebar-fill);
color: var(--dsw-alias-label-primary);
@@ -199,16 +200,22 @@
max-width: 0;
}
/* Region seat: always mounted so the foot never moves; the browser inside
handles its own wide/rail content. */
/* Region seat: always mounted so the foot never moves. Its trailing margin
cancels the wide shell inset so the nested scrollbar can sit at the sidebar
edge; the browser restores that inset inside its own rows. */
.regionArea {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
margin-right: calc(-1 * var(--dsh-sidebar-inline-padding));
overflow: hidden;
}
.collapsed .regionArea {
margin-right: 0;
}
/* Foot seat: a pure layout socket pinned under the region; the ui-settings
trigger row inside owns its own geometry (49px wide row / 36px rail
circle) and hover chrome. */

View File

@@ -0,0 +1,38 @@
/** Sidebar shell inset contract shared with the nested workspace browser. */
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest'
const css = readFileSync(fileURLToPath(new URL('../src/client/SidebarRoot.module.css', import.meta.url)), 'utf8')
/**
* Declarations of one exact selector, keyed by property.
* @param selector - exact selector text.
* @returns the normalized declarations, or undefined when absent.
*/
function declarations(selector: string): Map<string, string> | undefined {
const withoutComments = css.replace(/\/\*[\s\S]*?\*\//g, ' ')
for (const [, selectorList = '', body = ''] of withoutComments.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
if (!selectorList.split(',').map(value => value.trim()).includes(selector)) continue
const found = new Map<string, string>()
for (const part of body.split(';')) {
const colon = part.indexOf(':')
if (colon === -1) continue
found.set(part.slice(0, colon).trim(), part.slice(colon + 1).trim().replace(/\s+/g, ' '))
}
return found
}
return undefined
}
describe('SidebarRoot.module.css inset', () => {
it('shares and cancels the wide shell trailing padding structurally', () => {
const root = declarations('.root')
expect(root?.get('--dsh-sidebar-inline-padding')).toBe('12px')
expect(root?.get('padding')).toBe('6px var(--dsh-sidebar-inline-padding)')
expect(declarations('.regionArea')?.get('margin-right')).toBe(
'calc(-1 * var(--dsh-sidebar-inline-padding))',
)
expect(declarations('.collapsed .regionArea')?.get('margin-right')).toBe('0')
})
})