fix(host): keep the child pane reachable on narrow viewports; surface truncated levels
The Miller row now scrolls horizontally with the child pane pinned into view when its preview lands, so descent stays reachable when the dialog is narrower than two fixed panes. The dialog also says when a visible level was cut at the backend's complete-result bound (817's maxEntries) instead of letting the tail of a huge directory go silently missing.
This commit is contained in:
@@ -43,12 +43,16 @@
|
||||
* so the edit zone to the right never leaves the bar. */
|
||||
/* The Miller columns keep their own row so a status/error line below never
|
||||
* competes with the fixed column widths for horizontal space. */
|
||||
/* A narrow viewport shrinks the dialog below two fixed panes; the row
|
||||
* scrolls horizontally (the effect pins the child pane into view) so
|
||||
* descent never hides behind the Modal's clipping. */
|
||||
.millerRow {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
gap: 20px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.crumbTrail {
|
||||
|
||||
@@ -252,6 +252,15 @@ export function DirectoryBrowser({ open, listDirectory, createDirectory, onOpen,
|
||||
const trail = crumbTrailRef.current
|
||||
if (trail !== null) trail.scrollLeft = trail.scrollWidth
|
||||
}, [crumbTail])
|
||||
// On viewports too narrow for both fixed panes the Miller row scrolls;
|
||||
// whenever a child preview lands, pin it into view the way the crumb tail
|
||||
// pins — otherwise descent is unreachable on a phone-width window.
|
||||
const millerRowRef = useRef<HTMLDivElement | null>(null)
|
||||
const childPath = child?.path
|
||||
useEffect(() => {
|
||||
const row = millerRowRef.current
|
||||
if (row !== null && childPath !== undefined) row.scrollLeft = row.scrollWidth
|
||||
}, [childPath])
|
||||
|
||||
if (!open) return null
|
||||
const twoPane = selected !== null
|
||||
@@ -362,7 +371,7 @@ export function DirectoryBrowser({ open, listDirectory, createDirectory, onOpen,
|
||||
</div>
|
||||
</div>
|
||||
<div className={css.content}>
|
||||
<div className={css.millerRow}>
|
||||
<div className={css.millerRow} ref={millerRowRef}>
|
||||
{parent !== null && (
|
||||
<LevelColumn
|
||||
entries={parent.entries}
|
||||
@@ -384,6 +393,11 @@ export function DirectoryBrowser({ open, listDirectory, createDirectory, onOpen,
|
||||
)}
|
||||
</div>
|
||||
{loading && <div className={css.status} role="status">{t('browser.loading')}</div>}
|
||||
{/* The backend bounds a level at its complete-result limit; say so
|
||||
* whenever a visible pane was cut instead of letting the tail of a
|
||||
* huge directory go silently missing. */}
|
||||
{(parent?.truncated === true || child?.truncated === true) && !loading
|
||||
&& <div className={css.status} role="status">{t('browser.truncated')}</div>}
|
||||
{error !== null && <div className={css.error} role="alert">{error}</div>}
|
||||
</div>
|
||||
<div className={css.footerBar}>
|
||||
|
||||
@@ -41,6 +41,7 @@ export function apply(ctx: ClientContext): void {
|
||||
'browser.open': '打开',
|
||||
'browser.editPath': '编辑路径',
|
||||
'browser.loading': '加载中…',
|
||||
'browser.truncated': '文件夹过多,仅显示开头部分。',
|
||||
}),
|
||||
ctx.locale.register(LOCALE_NS, 'en', {
|
||||
'browser.title': 'Select Workspace Directory',
|
||||
@@ -54,6 +55,7 @@ export function apply(ctx: ClientContext): void {
|
||||
'browser.open': 'Open',
|
||||
'browser.editPath': 'Edit path',
|
||||
'browser.loading': 'Loading…',
|
||||
'browser.truncated': 'Too many folders to list; only the beginning is shown.',
|
||||
}),
|
||||
]
|
||||
return () => { for (const dispose of disposers) dispose() }
|
||||
|
||||
Reference in New Issue
Block a user