main f6d8405

maximizable.ts RawHistoryFolder

1import type { Action } from 'svelte/action';
2interface MaximizableParameters {
3	enabled?: boolean;
4	padding?: number;
5}
6
7interface MaximizableAttributes {
8	onmaximize?: (
9		e: CustomEvent<{
10			isMaximized: boolean;
11			width: number;
12			height: number;
13			x: number;
14			y: number;
15		}>
16	) => void;
17}
18
19interface StoredState {
20	width: number;
21	height: number;
22	x: number;
23	y: number;
24}
25
26export const maximizable: Action<HTMLDivElement, MaximizableParameters, MaximizableAttributes> = (
27	node,
28	params = {}
29) => {
30	const { enabled = true, padding = 0 } = params;
31
32	let isMaximized = false;
33	let storedState: StoredState | null = null;
34
35	function maximize() {
36		if (!enabled || isMaximized) return;
37
38		// Store current state
39		storedState = {
40			width: node.offsetWidth,
41			height: node.offsetHeight,
42			x: parseInt(node.style.left) || 0,
43			y: parseInt(node.style.top) || 0
44		};
45
46		// Set maximized state
47		const maxWidth = window.innerWidth - padding * 2;
48		const maxHeight = window.innerHeight - padding * 2;
49
50		node.style.width = `${maxWidth}px`;
51		node.style.height = `${maxHeight}px`;
52		node.style.left = `${padding}px`;
53		node.style.top = `${padding}px`;
54
55		isMaximized = true;
56
57		node.dispatchEvent(
58			new CustomEvent('maximize', {
59				detail: {
60					isMaximized: true,
61					width: maxWidth,
62					height: maxHeight,
63					x: padding,
64					y: padding
65				}
66			})
67		);
68	}
69
70	function restore() {
71		if (!enabled || !isMaximized || !storedState) return;
72
73		// Restore previous state
74		node.style.width = `${storedState.width}px`;
75		node.style.height = `${storedState.height}px`;
76		node.style.left = `${storedState.x}px`;
77		node.style.top = `${storedState.y}px`;
78
79		isMaximized = false;
80
81		node.dispatchEvent(
82			new CustomEvent('maximize', {
83				detail: {
84					isMaximized: false,
85					...storedState
86				}
87			})
88		);
89	}
90
91	function toggle() {
92		if (isMaximized) {
93			restore();
94		} else {
95			maximize();
96		}
97	}
98
99	// Expose methods to the node
100	Object.assign(node, {
101		maximize,
102		restore,
103		toggleMaximize: toggle,
104		isMaximized: () => isMaximized
105	});
106
107	return {
108		update(newParams: MaximizableParameters) {
109			Object.assign(params, newParams);
110		},
111		destroy() {
112			// Clean up if needed
113		}
114	};
115};

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 3

Tags 8

↑↓ moveenter openesc close