feat: panel-toggle-button
This commit is contained in:
@@ -181,6 +181,25 @@
|
||||
background-color: currentColor;
|
||||
}
|
||||
|
||||
.window-titlebar-panel-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border: 1.5px solid currentColor;
|
||||
border-radius: 2px;
|
||||
display: block;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.window-titlebar-panel-pane {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 33.3333%;
|
||||
background-color: currentColor;
|
||||
}
|
||||
|
||||
.window-titlebar-action-button:hover {
|
||||
background-color: var(--vscode-toolbar-hoverBackground, rgba(90, 93, 94, 0.31));
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ type WindowControlsOverlayLike = {
|
||||
};
|
||||
|
||||
export const WindowTitleBar: React.FC = () => {
|
||||
const { sidebarVisible, toggleSidebar } = useAppStore();
|
||||
const { sidebarVisible, panelVisible, toggleSidebar, togglePanel } = useAppStore();
|
||||
const [windowTitle, setWindowTitle] = useState<string>(document.title || 'Blogging Desktop Server');
|
||||
const [openMenu, setOpenMenu] = useState<{ label: string; left: number } | null>(null);
|
||||
const [showMnemonics, setShowMnemonics] = useState<boolean>(false);
|
||||
@@ -416,6 +416,16 @@ export const WindowTitleBar: React.FC = () => {
|
||||
<span className="window-titlebar-sidebar-pane" data-shape="left-half" />
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
className="window-titlebar-action-button"
|
||||
aria-label="Toggle Panel"
|
||||
onClick={togglePanel}
|
||||
title={`${panelVisible ? 'Hide' : 'Show'} Panel (Ctrl+J)`}
|
||||
>
|
||||
<span className="window-titlebar-panel-icon" data-shape="frame-square" aria-hidden="true">
|
||||
<span className="window-titlebar-panel-pane" data-shape="bottom-half" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
{openMenu && activeMenu && (
|
||||
<div
|
||||
|
||||
@@ -8,6 +8,7 @@ describe('WindowTitleBar', () => {
|
||||
beforeEach(() => {
|
||||
useAppStore.setState({
|
||||
sidebarVisible: true,
|
||||
panelVisible: false,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -37,6 +38,42 @@ describe('WindowTitleBar', () => {
|
||||
expect(iconPane).toHaveAttribute('data-shape', 'left-half');
|
||||
});
|
||||
|
||||
it('renders a right-side panel toggle button and toggles panel visibility', () => {
|
||||
render(<WindowTitleBar />);
|
||||
|
||||
const toggleButton = screen.getByLabelText('Toggle Panel');
|
||||
expect(toggleButton).toBeInTheDocument();
|
||||
expect(toggleButton).toHaveAttribute('title', 'Show Panel (Ctrl+J)');
|
||||
|
||||
fireEvent.click(toggleButton);
|
||||
|
||||
expect(useAppStore.getState().panelVisible).toBe(true);
|
||||
expect(toggleButton).toHaveAttribute('title', 'Hide Panel (Ctrl+J)');
|
||||
});
|
||||
|
||||
it('uses a VS Code-like panel toggle icon shape', () => {
|
||||
render(<WindowTitleBar />);
|
||||
|
||||
const toggleButton = screen.getByLabelText('Toggle Panel');
|
||||
const iconFrame = toggleButton.querySelector('.window-titlebar-panel-icon');
|
||||
const iconPane = toggleButton.querySelector('.window-titlebar-panel-pane');
|
||||
|
||||
expect(iconFrame).not.toBeNull();
|
||||
expect(iconPane).not.toBeNull();
|
||||
expect(iconFrame).toHaveAttribute('data-shape', 'frame-square');
|
||||
expect(iconPane).toHaveAttribute('data-shape', 'bottom-half');
|
||||
});
|
||||
|
||||
it('places panel toggle to the right of sidebar toggle', () => {
|
||||
render(<WindowTitleBar />);
|
||||
|
||||
const actionButtons = Array.from(document.querySelectorAll('.window-titlebar-actions .window-titlebar-action-button'));
|
||||
|
||||
expect(actionButtons).toHaveLength(2);
|
||||
expect(actionButtons[0]).toHaveAttribute('aria-label', 'Toggle Sidebar');
|
||||
expect(actionButtons[1]).toHaveAttribute('aria-label', 'Toggle Panel');
|
||||
});
|
||||
|
||||
it('updates overlay inset CSS variables when window controls geometry changes', () => {
|
||||
const geometryListeners = new Set<EventListener>();
|
||||
let rect = {
|
||||
|
||||
Reference in New Issue
Block a user