Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 69x 69x 69x 2x 2x 69x 2x 2x 2x 2x 1x 2x 1x 1x 1x 1x 1x 1x 29x | import React, {useState, type ReactNode} from 'react';
import {Button, InputText} from '../../primereact/index.js';
export interface IPathSegment {
key: string;
label: string;
}
/**
* PathBar — the commander navigation bar: navigation buttons (back/forward/up/
* refresh) on the left, a combined breadcrumb / "jump to path" widget that
* fills the remaining space, and an optional search box — Windows-Explorer
* style.
*
* The crumb/jump widget renders the breadcrumb; clicking a crumb navigates,
* while clicking the empty space switches it into an editable "jump to path"
* input (Enter navigates, Esc/Blur exits back to breadcrumbs).
*/
export function PathBar({
segments,
onNavigate,
onJump,
nav,
search,
}: {
segments: IPathSegment[];
onNavigate?: (index: number) => void;
onJump?: (path: string) => void;
/** Navigation buttons rendered at the far left (back/forward/up/refresh). */
nav?: ReactNode;
/** Search input rendered at the far right. */
search?: ReactNode;
}) {
const [editing, setEditing] = useState(false);
const [jump, setJump] = useState('');
const startJump = () => {
setJump('');
setEditing(true);
};
return (
<div
className="blong-commander-path-bar"
style={{
display: 'flex',
alignItems: 'center',
gap: '0.25rem',
padding: '0.2rem 0.4rem',
borderBottom: '1px solid var(--surface-border)',
minHeight: '2.1rem',
}}
>
{nav}
<div
className="blong-commander-crumb-jump"
title="Click a crumb to navigate · click empty space to jump to path"
onClick={e => {
Iif (editing) return;
const target = e.target as HTMLElement;
// Clicks on breadcrumb buttons navigate via their own onClick.
Iif (target.closest('.p-button')) return;
startJump();
}}
style={{
flex: 1,
minWidth: 0,
display: 'flex',
alignItems: 'center',
overflow: 'hidden',
whiteSpace: 'nowrap',
cursor: editing ? 'text' : 'default',
}}
>
{editing ? (
<InputText
autoFocus
value={jump}
onChange={e => setJump(e.target.value)}
onKeyDown={e => {
if (e.key === 'Enter') {
onJump?.(jump.trim());
setJump('');
setEditing(false);
} else Eif (e.key === 'Escape') {
setJump('');
setEditing(false);
}
}}
onBlur={() => {
setJump('');
setEditing(false);
}}
placeholder="Jump to path…"
style={{width: '100%', fontSize: '0.8rem', padding: '0.2rem 0.4rem'}}
/>
) : (
<>
{segments.map((segment, index) => (
<React.Fragment key={segment.key}>
{index > 0 && (
<span style={{color: 'var(--text-color-secondary)', margin: '0 0.1rem'}}>/</span>
)}
<Button
label={segment.label}
className="p-button-text p-button-sm"
style={{padding: '0.1rem 0.35rem'}}
onClick={() => onNavigate?.(index)}
/>
</React.Fragment>
))}
{segments.length === 0 && (
<span style={{color: 'var(--text-color-secondary)', fontSize: '0.8rem'}}>
Home · click here to jump…
</span>
)}
</>
)}
</div>
{search}
</div>
);
}
|