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};