@blorkfield/blork-tabs 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/index.cjs +1194 -0
- package/dist/index.d.cts +669 -0
- package/dist/index.d.ts +669 -0
- package/dist/index.js +1143 -0
- package/dist/styles.css +186 -0
- package/package.json +62 -0
- package/src/AnchorManager.ts +395 -0
- package/src/DragManager.ts +251 -0
- package/src/Panel.ts +211 -0
- package/src/SnapChain.ts +289 -0
- package/src/SnapPreview.ts +91 -0
- package/src/TabManager.ts +507 -0
- package/src/index.test.ts +9 -0
- package/src/index.ts +105 -0
- package/src/types.ts +320 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @blorkfield/blork-tabs - Type Definitions
|
|
3
|
+
* A framework-agnostic tab/panel management system with snapping and docking
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for initializing the TabManager
|
|
7
|
+
*/
|
|
8
|
+
interface TabManagerConfig {
|
|
9
|
+
/** Distance threshold for panel-to-panel snapping (default: 50) */
|
|
10
|
+
snapThreshold?: number;
|
|
11
|
+
/** Gap between snapped panels (default: 0) */
|
|
12
|
+
panelGap?: number;
|
|
13
|
+
/** Margin from window edges (default: 16) */
|
|
14
|
+
panelMargin?: number;
|
|
15
|
+
/** Distance threshold for anchor snapping (default: 80) */
|
|
16
|
+
anchorThreshold?: number;
|
|
17
|
+
/** Default panel width for anchor calculations (default: 300) */
|
|
18
|
+
defaultPanelWidth?: number;
|
|
19
|
+
/** Container element for panels (default: document.body) */
|
|
20
|
+
container?: HTMLElement;
|
|
21
|
+
/** Whether to automatically initialize default anchors (default: true) */
|
|
22
|
+
initializeDefaultAnchors?: boolean;
|
|
23
|
+
/** Custom CSS class prefix (default: 'blork-tabs') */
|
|
24
|
+
classPrefix?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolved configuration with all defaults applied
|
|
28
|
+
*/
|
|
29
|
+
interface ResolvedTabManagerConfig {
|
|
30
|
+
snapThreshold: number;
|
|
31
|
+
panelGap: number;
|
|
32
|
+
panelMargin: number;
|
|
33
|
+
anchorThreshold: number;
|
|
34
|
+
defaultPanelWidth: number;
|
|
35
|
+
container: HTMLElement;
|
|
36
|
+
initializeDefaultAnchors: boolean;
|
|
37
|
+
classPrefix: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Configuration for creating a new panel
|
|
41
|
+
*/
|
|
42
|
+
interface PanelConfig {
|
|
43
|
+
/** Unique identifier for the panel */
|
|
44
|
+
id: string;
|
|
45
|
+
/** Panel title displayed in header */
|
|
46
|
+
title?: string;
|
|
47
|
+
/** Initial width (default: 300) */
|
|
48
|
+
width?: number;
|
|
49
|
+
/** Initial collapsed state (default: true) */
|
|
50
|
+
startCollapsed?: boolean;
|
|
51
|
+
/** Initial position (optional - will be auto-positioned if not provided) */
|
|
52
|
+
initialPosition?: {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
};
|
|
56
|
+
/** Content element or HTML string */
|
|
57
|
+
content?: HTMLElement | string;
|
|
58
|
+
/** Custom panel element (for existing DOM panels) */
|
|
59
|
+
element?: HTMLDivElement;
|
|
60
|
+
/** Custom drag handle element */
|
|
61
|
+
dragHandle?: HTMLDivElement;
|
|
62
|
+
/** Custom collapse button element */
|
|
63
|
+
collapseButton?: HTMLButtonElement;
|
|
64
|
+
/** Custom content wrapper element */
|
|
65
|
+
contentWrapper?: HTMLDivElement;
|
|
66
|
+
/** Custom detach grip element */
|
|
67
|
+
detachGrip?: HTMLDivElement;
|
|
68
|
+
/** Whether panel can be collapsed (default: true) */
|
|
69
|
+
collapsible?: boolean;
|
|
70
|
+
/** Whether panel can be detached from group (default: true) */
|
|
71
|
+
detachable?: boolean;
|
|
72
|
+
/** Whether panel can be dragged (default: true) */
|
|
73
|
+
draggable?: boolean;
|
|
74
|
+
/** Z-index for panel (default: 1000) */
|
|
75
|
+
zIndex?: number;
|
|
76
|
+
/** Z-index when dragging (default: 1002) */
|
|
77
|
+
dragZIndex?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Configuration for anchor points
|
|
81
|
+
*/
|
|
82
|
+
interface AnchorConfig {
|
|
83
|
+
/** Unique identifier for the anchor */
|
|
84
|
+
id: string;
|
|
85
|
+
/** Function that returns the anchor position (allows dynamic positioning) */
|
|
86
|
+
getPosition: () => Position;
|
|
87
|
+
/** Whether to show visual indicator (default: true) */
|
|
88
|
+
showIndicator?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Preset anchor positions
|
|
92
|
+
*/
|
|
93
|
+
type AnchorPreset = 'top-left' | 'top-right' | 'top-center' | 'bottom-left' | 'bottom-right' | 'bottom-center' | 'center-left' | 'center-right';
|
|
94
|
+
/**
|
|
95
|
+
* Current state of a panel
|
|
96
|
+
*/
|
|
97
|
+
interface PanelState {
|
|
98
|
+
/** Unique panel identifier */
|
|
99
|
+
id: string;
|
|
100
|
+
/** DOM element for the panel */
|
|
101
|
+
element: HTMLDivElement;
|
|
102
|
+
/** Drag handle element */
|
|
103
|
+
dragHandle: HTMLDivElement;
|
|
104
|
+
/** Collapse button element (if collapsible) */
|
|
105
|
+
collapseButton: HTMLButtonElement | null;
|
|
106
|
+
/** Content wrapper element */
|
|
107
|
+
contentWrapper: HTMLDivElement;
|
|
108
|
+
/** Detach grip element (if detachable) */
|
|
109
|
+
detachGrip: HTMLDivElement | null;
|
|
110
|
+
/** Whether panel is currently collapsed */
|
|
111
|
+
isCollapsed: boolean;
|
|
112
|
+
/** ID of panel this is snapped to on its right (outgoing link) */
|
|
113
|
+
snappedTo: string | null;
|
|
114
|
+
/** ID of panel snapped to this on its left (incoming link) */
|
|
115
|
+
snappedFrom: string | null;
|
|
116
|
+
/** Panel configuration */
|
|
117
|
+
config: PanelConfig;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Current drag operation state
|
|
121
|
+
*/
|
|
122
|
+
interface DragState {
|
|
123
|
+
/** Panel that initiated the drag */
|
|
124
|
+
grabbedPanel: PanelState;
|
|
125
|
+
/** Mouse offset from panel left edge */
|
|
126
|
+
offsetX: number;
|
|
127
|
+
/** Mouse offset from panel top edge */
|
|
128
|
+
offsetY: number;
|
|
129
|
+
/** Initial positions of all connected panels */
|
|
130
|
+
initialGroupPositions: Map<string, Position>;
|
|
131
|
+
/** Panels being moved in this drag operation */
|
|
132
|
+
movingPanels: PanelState[];
|
|
133
|
+
/** Drag mode - single panel or entire group */
|
|
134
|
+
mode: DragMode;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Drag mode determines what gets moved
|
|
138
|
+
*/
|
|
139
|
+
type DragMode = 'single' | 'group';
|
|
140
|
+
/**
|
|
141
|
+
* Anchor state including visual indicator
|
|
142
|
+
*/
|
|
143
|
+
interface AnchorState {
|
|
144
|
+
/** Anchor configuration */
|
|
145
|
+
config: AnchorConfig;
|
|
146
|
+
/** Visual indicator element */
|
|
147
|
+
indicator: HTMLDivElement | null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Result of snap target detection
|
|
151
|
+
*/
|
|
152
|
+
interface SnapTarget {
|
|
153
|
+
/** ID of the target panel */
|
|
154
|
+
targetId: string;
|
|
155
|
+
/** Which side of target to snap to */
|
|
156
|
+
side: SnapSide;
|
|
157
|
+
/** X position for snap */
|
|
158
|
+
x: number;
|
|
159
|
+
/** Y position for snap */
|
|
160
|
+
y: number;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Side of panel to snap to
|
|
164
|
+
*/
|
|
165
|
+
type SnapSide = 'left' | 'right';
|
|
166
|
+
/**
|
|
167
|
+
* Result of anchor snap detection
|
|
168
|
+
*/
|
|
169
|
+
interface AnchorSnapResult {
|
|
170
|
+
/** The matched anchor */
|
|
171
|
+
anchor: AnchorState;
|
|
172
|
+
/** Index of panel in group that docks to anchor */
|
|
173
|
+
dockPanelIndex: number;
|
|
174
|
+
/** Final positions for all panels in the group */
|
|
175
|
+
positions: Position[];
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Simple x,y position
|
|
179
|
+
*/
|
|
180
|
+
interface Position {
|
|
181
|
+
x: number;
|
|
182
|
+
y: number;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Bounding rectangle
|
|
186
|
+
*/
|
|
187
|
+
interface Bounds {
|
|
188
|
+
left: number;
|
|
189
|
+
right: number;
|
|
190
|
+
top: number;
|
|
191
|
+
bottom: number;
|
|
192
|
+
width: number;
|
|
193
|
+
height: number;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Events emitted by TabManager
|
|
197
|
+
*/
|
|
198
|
+
interface TabManagerEvents {
|
|
199
|
+
/** Fired when a panel is added */
|
|
200
|
+
'panel:added': PanelAddedEvent;
|
|
201
|
+
/** Fired when a panel is removed */
|
|
202
|
+
'panel:removed': PanelRemovedEvent;
|
|
203
|
+
/** Fired when a panel starts being dragged */
|
|
204
|
+
'drag:start': DragStartEvent;
|
|
205
|
+
/** Fired during drag movement */
|
|
206
|
+
'drag:move': DragMoveEvent;
|
|
207
|
+
/** Fired when drag ends */
|
|
208
|
+
'drag:end': DragEndEvent;
|
|
209
|
+
/** Fired when panels snap together */
|
|
210
|
+
'snap:panel': PanelSnapEvent;
|
|
211
|
+
/** Fired when panels snap to anchor */
|
|
212
|
+
'snap:anchor': AnchorSnapEvent;
|
|
213
|
+
/** Fired when a panel is detached from group */
|
|
214
|
+
'panel:detached': PanelDetachedEvent;
|
|
215
|
+
/** Fired when panel collapse state changes */
|
|
216
|
+
'panel:collapse': PanelCollapseEvent;
|
|
217
|
+
}
|
|
218
|
+
interface PanelAddedEvent {
|
|
219
|
+
panel: PanelState;
|
|
220
|
+
}
|
|
221
|
+
interface PanelRemovedEvent {
|
|
222
|
+
panelId: string;
|
|
223
|
+
}
|
|
224
|
+
interface DragStartEvent {
|
|
225
|
+
panel: PanelState;
|
|
226
|
+
mode: DragMode;
|
|
227
|
+
movingPanels: PanelState[];
|
|
228
|
+
}
|
|
229
|
+
interface DragMoveEvent {
|
|
230
|
+
panel: PanelState;
|
|
231
|
+
position: Position;
|
|
232
|
+
snapTarget: SnapTarget | null;
|
|
233
|
+
anchorTarget: AnchorSnapResult | null;
|
|
234
|
+
}
|
|
235
|
+
interface DragEndEvent {
|
|
236
|
+
panel: PanelState;
|
|
237
|
+
finalPosition: Position;
|
|
238
|
+
snappedToPanel: boolean;
|
|
239
|
+
snappedToAnchor: boolean;
|
|
240
|
+
}
|
|
241
|
+
interface PanelSnapEvent {
|
|
242
|
+
movingPanels: PanelState[];
|
|
243
|
+
targetPanel: PanelState;
|
|
244
|
+
side: SnapSide;
|
|
245
|
+
}
|
|
246
|
+
interface AnchorSnapEvent {
|
|
247
|
+
movingPanels: PanelState[];
|
|
248
|
+
anchor: AnchorState;
|
|
249
|
+
}
|
|
250
|
+
interface PanelDetachedEvent {
|
|
251
|
+
panel: PanelState;
|
|
252
|
+
previousGroup: PanelState[];
|
|
253
|
+
}
|
|
254
|
+
interface PanelCollapseEvent {
|
|
255
|
+
panel: PanelState;
|
|
256
|
+
isCollapsed: boolean;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Event listener function type
|
|
260
|
+
*/
|
|
261
|
+
type EventListener<T> = (event: T) => void;
|
|
262
|
+
/**
|
|
263
|
+
* CSS class names used by the library
|
|
264
|
+
*/
|
|
265
|
+
interface CSSClasses {
|
|
266
|
+
panel: string;
|
|
267
|
+
panelHeader: string;
|
|
268
|
+
panelTitle: string;
|
|
269
|
+
panelContent: string;
|
|
270
|
+
panelContentCollapsed: string;
|
|
271
|
+
detachGrip: string;
|
|
272
|
+
collapseButton: string;
|
|
273
|
+
snapPreview: string;
|
|
274
|
+
snapPreviewVisible: string;
|
|
275
|
+
anchorIndicator: string;
|
|
276
|
+
anchorIndicatorVisible: string;
|
|
277
|
+
anchorIndicatorActive: string;
|
|
278
|
+
dragging: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @blorkfield/blork-tabs - TabManager
|
|
283
|
+
* Main orchestrator for the tab/panel management system
|
|
284
|
+
*/
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Main TabManager class - orchestrates all panel, snap, and anchor functionality
|
|
288
|
+
*/
|
|
289
|
+
declare class TabManager {
|
|
290
|
+
private config;
|
|
291
|
+
private classes;
|
|
292
|
+
private panels;
|
|
293
|
+
private dragManager;
|
|
294
|
+
private anchorManager;
|
|
295
|
+
private snapPreview;
|
|
296
|
+
private eventListeners;
|
|
297
|
+
constructor(userConfig?: TabManagerConfig);
|
|
298
|
+
/**
|
|
299
|
+
* Add a new panel
|
|
300
|
+
*/
|
|
301
|
+
addPanel(panelConfig: PanelConfig): PanelState;
|
|
302
|
+
/**
|
|
303
|
+
* Register an existing panel element
|
|
304
|
+
*/
|
|
305
|
+
registerPanel(id: string, element: HTMLDivElement, options?: {
|
|
306
|
+
dragHandle?: HTMLDivElement;
|
|
307
|
+
collapseButton?: HTMLButtonElement;
|
|
308
|
+
contentWrapper?: HTMLDivElement;
|
|
309
|
+
detachGrip?: HTMLDivElement;
|
|
310
|
+
startCollapsed?: boolean;
|
|
311
|
+
}): PanelState;
|
|
312
|
+
/**
|
|
313
|
+
* Remove a panel
|
|
314
|
+
*/
|
|
315
|
+
removePanel(id: string): boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Get a panel by ID
|
|
318
|
+
*/
|
|
319
|
+
getPanel(id: string): PanelState | undefined;
|
|
320
|
+
/**
|
|
321
|
+
* Get all panels
|
|
322
|
+
*/
|
|
323
|
+
getAllPanels(): PanelState[];
|
|
324
|
+
/**
|
|
325
|
+
* Set up event handlers for a panel
|
|
326
|
+
*/
|
|
327
|
+
private setupPanelEvents;
|
|
328
|
+
/**
|
|
329
|
+
* Get all panels in the same snap chain as the given panel
|
|
330
|
+
*/
|
|
331
|
+
getSnapChain(panelId: string): PanelState[];
|
|
332
|
+
/**
|
|
333
|
+
* Manually snap two panels together
|
|
334
|
+
*/
|
|
335
|
+
snap(leftPanelId: string, rightPanelId: string): boolean;
|
|
336
|
+
/**
|
|
337
|
+
* Detach a panel from its snap chain
|
|
338
|
+
*/
|
|
339
|
+
detach(panelId: string): boolean;
|
|
340
|
+
/**
|
|
341
|
+
* Update snapped positions (call after collapse/expand or resize)
|
|
342
|
+
*/
|
|
343
|
+
updatePositions(): void;
|
|
344
|
+
/**
|
|
345
|
+
* Add a custom anchor
|
|
346
|
+
*/
|
|
347
|
+
addAnchor(config: AnchorConfig): AnchorState;
|
|
348
|
+
/**
|
|
349
|
+
* Add a preset anchor
|
|
350
|
+
*/
|
|
351
|
+
addPresetAnchor(preset: AnchorPreset): AnchorState;
|
|
352
|
+
/**
|
|
353
|
+
* Remove an anchor
|
|
354
|
+
*/
|
|
355
|
+
removeAnchor(id: string): boolean;
|
|
356
|
+
/**
|
|
357
|
+
* Get all anchors
|
|
358
|
+
*/
|
|
359
|
+
getAnchors(): AnchorState[];
|
|
360
|
+
private handleDragStart;
|
|
361
|
+
private handleDragMove;
|
|
362
|
+
private handleDragEnd;
|
|
363
|
+
/**
|
|
364
|
+
* Subscribe to an event
|
|
365
|
+
*/
|
|
366
|
+
on<K extends keyof TabManagerEvents>(event: K, listener: EventListener<TabManagerEvents[K]>): () => void;
|
|
367
|
+
/**
|
|
368
|
+
* Unsubscribe from an event
|
|
369
|
+
*/
|
|
370
|
+
off<K extends keyof TabManagerEvents>(event: K, listener: EventListener<TabManagerEvents[K]>): void;
|
|
371
|
+
/**
|
|
372
|
+
* Emit an event
|
|
373
|
+
*/
|
|
374
|
+
private emit;
|
|
375
|
+
/**
|
|
376
|
+
* Position panels in a row from right edge
|
|
377
|
+
*/
|
|
378
|
+
positionPanelsFromRight(panelIds: string[], gap?: number): void;
|
|
379
|
+
/**
|
|
380
|
+
* Position panels in a row from left edge
|
|
381
|
+
*/
|
|
382
|
+
positionPanelsFromLeft(panelIds: string[], gap?: number): void;
|
|
383
|
+
/**
|
|
384
|
+
* Set up initial snap chain for a list of panels (left to right)
|
|
385
|
+
*/
|
|
386
|
+
createSnapChain(panelIds: string[]): void;
|
|
387
|
+
/**
|
|
388
|
+
* Get the current configuration
|
|
389
|
+
*/
|
|
390
|
+
getConfig(): ResolvedTabManagerConfig;
|
|
391
|
+
/**
|
|
392
|
+
* Get the CSS classes used
|
|
393
|
+
*/
|
|
394
|
+
getClasses(): CSSClasses;
|
|
395
|
+
/**
|
|
396
|
+
* Check if dragging is currently active
|
|
397
|
+
*/
|
|
398
|
+
isDragging(): boolean;
|
|
399
|
+
/**
|
|
400
|
+
* Destroy the TabManager and clean up resources
|
|
401
|
+
*/
|
|
402
|
+
destroy(): void;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* @blorkfield/blork-tabs - AnchorManager
|
|
407
|
+
* Manages screen anchor points for panel docking
|
|
408
|
+
*/
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Creates the default anchor positions
|
|
412
|
+
*/
|
|
413
|
+
declare function getDefaultAnchorConfigs(config: ResolvedTabManagerConfig): AnchorConfig[];
|
|
414
|
+
/**
|
|
415
|
+
* Create an anchor preset config
|
|
416
|
+
*/
|
|
417
|
+
declare function createPresetAnchor(preset: AnchorPreset, config: ResolvedTabManagerConfig): AnchorConfig;
|
|
418
|
+
/**
|
|
419
|
+
* Manages anchor points and docking behavior
|
|
420
|
+
*/
|
|
421
|
+
declare class AnchorManager {
|
|
422
|
+
private anchors;
|
|
423
|
+
private config;
|
|
424
|
+
private classes;
|
|
425
|
+
private container;
|
|
426
|
+
constructor(config: ResolvedTabManagerConfig, classes: CSSClasses);
|
|
427
|
+
/**
|
|
428
|
+
* Create an anchor indicator element
|
|
429
|
+
*/
|
|
430
|
+
private createIndicator;
|
|
431
|
+
/**
|
|
432
|
+
* Add an anchor point
|
|
433
|
+
*/
|
|
434
|
+
addAnchor(anchorConfig: AnchorConfig): AnchorState;
|
|
435
|
+
/**
|
|
436
|
+
* Add multiple default anchors
|
|
437
|
+
*/
|
|
438
|
+
addDefaultAnchors(): void;
|
|
439
|
+
/**
|
|
440
|
+
* Add anchor from preset
|
|
441
|
+
*/
|
|
442
|
+
addPresetAnchor(preset: AnchorPreset): AnchorState;
|
|
443
|
+
/**
|
|
444
|
+
* Remove an anchor
|
|
445
|
+
*/
|
|
446
|
+
removeAnchor(id: string): boolean;
|
|
447
|
+
/**
|
|
448
|
+
* Update position of a single indicator
|
|
449
|
+
*/
|
|
450
|
+
private updateIndicatorPosition;
|
|
451
|
+
/**
|
|
452
|
+
* Update all indicator positions (call on window resize)
|
|
453
|
+
*/
|
|
454
|
+
updateIndicatorPositions(): void;
|
|
455
|
+
/**
|
|
456
|
+
* Find the nearest anchor for a group of moving panels
|
|
457
|
+
*/
|
|
458
|
+
findNearestAnchor(movingPanels: PanelState[]): AnchorSnapResult | null;
|
|
459
|
+
/**
|
|
460
|
+
* Show anchor indicators during drag
|
|
461
|
+
*/
|
|
462
|
+
showIndicators(activeAnchor: AnchorState | null): void;
|
|
463
|
+
/**
|
|
464
|
+
* Hide all anchor indicators
|
|
465
|
+
*/
|
|
466
|
+
hideIndicators(): void;
|
|
467
|
+
/**
|
|
468
|
+
* Get all anchors
|
|
469
|
+
*/
|
|
470
|
+
getAnchors(): AnchorState[];
|
|
471
|
+
/**
|
|
472
|
+
* Get anchor by ID
|
|
473
|
+
*/
|
|
474
|
+
getAnchor(id: string): AnchorState | undefined;
|
|
475
|
+
/**
|
|
476
|
+
* Clean up
|
|
477
|
+
*/
|
|
478
|
+
destroy(): void;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* @blorkfield/blork-tabs - DragManager
|
|
483
|
+
* Handles drag operations for panels including single and group modes
|
|
484
|
+
*/
|
|
485
|
+
|
|
486
|
+
interface DragCallbacks {
|
|
487
|
+
onDragStart?: (state: DragState) => void;
|
|
488
|
+
onDragMove?: (state: DragState, position: Position, snapTarget: SnapTarget | null, anchorResult: AnchorSnapResult | null) => void;
|
|
489
|
+
onDragEnd?: (state: DragState, snapTarget: SnapTarget | null, anchorResult: AnchorSnapResult | null) => void;
|
|
490
|
+
findAnchorTarget?: (movingPanels: PanelState[]) => AnchorSnapResult | null;
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Creates and manages drag operations
|
|
494
|
+
*/
|
|
495
|
+
declare class DragManager {
|
|
496
|
+
private panels;
|
|
497
|
+
private config;
|
|
498
|
+
private callbacks;
|
|
499
|
+
private activeDrag;
|
|
500
|
+
private boundMouseMove;
|
|
501
|
+
private boundMouseUp;
|
|
502
|
+
constructor(panels: Map<string, PanelState>, config: ResolvedTabManagerConfig, callbacks: DragCallbacks);
|
|
503
|
+
/**
|
|
504
|
+
* Start a drag operation
|
|
505
|
+
*/
|
|
506
|
+
startDrag(e: MouseEvent, panel: PanelState, mode: DragMode): void;
|
|
507
|
+
/**
|
|
508
|
+
* Handle mouse movement during drag
|
|
509
|
+
*/
|
|
510
|
+
private handleMouseMove;
|
|
511
|
+
/**
|
|
512
|
+
* Handle mouse up - finalize drag
|
|
513
|
+
*/
|
|
514
|
+
private handleMouseUp;
|
|
515
|
+
/**
|
|
516
|
+
* Check if a drag is currently in progress
|
|
517
|
+
*/
|
|
518
|
+
isActive(): boolean;
|
|
519
|
+
/**
|
|
520
|
+
* Get the current drag state
|
|
521
|
+
*/
|
|
522
|
+
getState(): DragState | null;
|
|
523
|
+
/**
|
|
524
|
+
* Clean up event listeners
|
|
525
|
+
*/
|
|
526
|
+
destroy(): void;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* @blorkfield/blork-tabs - SnapPreview
|
|
531
|
+
* Visual feedback for snap targets during drag operations
|
|
532
|
+
*/
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Manages the visual snap preview indicator
|
|
536
|
+
*/
|
|
537
|
+
declare class SnapPreview {
|
|
538
|
+
private element;
|
|
539
|
+
private classes;
|
|
540
|
+
private container;
|
|
541
|
+
private panels;
|
|
542
|
+
constructor(container: HTMLElement, classes: CSSClasses, panels: Map<string, PanelState>);
|
|
543
|
+
/**
|
|
544
|
+
* Create the preview element lazily
|
|
545
|
+
*/
|
|
546
|
+
private ensureElement;
|
|
547
|
+
/**
|
|
548
|
+
* Update the preview to show a snap target
|
|
549
|
+
*/
|
|
550
|
+
show(snapTarget: SnapTarget): void;
|
|
551
|
+
/**
|
|
552
|
+
* Hide the preview
|
|
553
|
+
*/
|
|
554
|
+
hide(): void;
|
|
555
|
+
/**
|
|
556
|
+
* Update based on current snap target (convenience method)
|
|
557
|
+
*/
|
|
558
|
+
update(snapTarget: SnapTarget | null): void;
|
|
559
|
+
/**
|
|
560
|
+
* Clean up
|
|
561
|
+
*/
|
|
562
|
+
destroy(): void;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* @blorkfield/blork-tabs - Panel
|
|
567
|
+
* Individual panel component with collapse/expand functionality
|
|
568
|
+
*/
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Creates the default panel DOM structure
|
|
572
|
+
*/
|
|
573
|
+
declare function createPanelElement(config: PanelConfig, classes: CSSClasses): {
|
|
574
|
+
element: HTMLDivElement;
|
|
575
|
+
dragHandle: HTMLDivElement;
|
|
576
|
+
collapseButton: HTMLButtonElement | null;
|
|
577
|
+
contentWrapper: HTMLDivElement;
|
|
578
|
+
detachGrip: HTMLDivElement | null;
|
|
579
|
+
};
|
|
580
|
+
/**
|
|
581
|
+
* Creates a PanelState from config, using existing elements or creating new ones
|
|
582
|
+
*/
|
|
583
|
+
declare function createPanelState(config: PanelConfig, classes: CSSClasses): PanelState;
|
|
584
|
+
/**
|
|
585
|
+
* Toggle panel collapse state
|
|
586
|
+
*/
|
|
587
|
+
declare function toggleCollapse(state: PanelState, classes: CSSClasses, collapsed?: boolean): boolean;
|
|
588
|
+
/**
|
|
589
|
+
* Set panel position
|
|
590
|
+
*/
|
|
591
|
+
declare function setPanelPosition(state: PanelState, x: number, y: number): void;
|
|
592
|
+
/**
|
|
593
|
+
* Get panel position from DOM
|
|
594
|
+
*/
|
|
595
|
+
declare function getPanelPosition(state: PanelState): {
|
|
596
|
+
x: number;
|
|
597
|
+
y: number;
|
|
598
|
+
};
|
|
599
|
+
/**
|
|
600
|
+
* Get panel dimensions
|
|
601
|
+
*/
|
|
602
|
+
declare function getPanelDimensions(state: PanelState): {
|
|
603
|
+
width: number;
|
|
604
|
+
height: number;
|
|
605
|
+
};
|
|
606
|
+
/**
|
|
607
|
+
* Set panel z-index
|
|
608
|
+
*/
|
|
609
|
+
declare function setPanelZIndex(state: PanelState, zIndex: number): void;
|
|
610
|
+
/**
|
|
611
|
+
* Get default z-index for panel
|
|
612
|
+
*/
|
|
613
|
+
declare function getDefaultZIndex(state: PanelState): number;
|
|
614
|
+
/**
|
|
615
|
+
* Get drag z-index for panel
|
|
616
|
+
*/
|
|
617
|
+
declare function getDragZIndex(state: PanelState): number;
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* @blorkfield/blork-tabs - SnapChain
|
|
621
|
+
* Manages snap relationships between panels forming linked chains
|
|
622
|
+
*/
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Get all panels connected to a given panel (the entire snap chain)
|
|
626
|
+
* Returns panels ordered from left to right
|
|
627
|
+
*/
|
|
628
|
+
declare function getConnectedGroup(startPanel: PanelState, panels: Map<string, PanelState>): PanelState[];
|
|
629
|
+
/**
|
|
630
|
+
* Detach a panel from its snap chain
|
|
631
|
+
* Clears both incoming and outgoing snap relationships
|
|
632
|
+
*/
|
|
633
|
+
declare function detachFromGroup(panel: PanelState, panels: Map<string, PanelState>): void;
|
|
634
|
+
/**
|
|
635
|
+
* Find a snap target for the moving panels
|
|
636
|
+
* Checks if moving panels are close enough to snap to a stationary panel
|
|
637
|
+
*/
|
|
638
|
+
declare function findSnapTarget(movingPanels: PanelState[], panels: Map<string, PanelState>, config: ResolvedTabManagerConfig): SnapTarget | null;
|
|
639
|
+
/**
|
|
640
|
+
* Execute a snap operation - position panels and establish relationships
|
|
641
|
+
*/
|
|
642
|
+
declare function snapPanelsToTarget(movingPanels: PanelState[], targetId: string, side: SnapSide, x: number, y: number, panels: Map<string, PanelState>, config: ResolvedTabManagerConfig): void;
|
|
643
|
+
/**
|
|
644
|
+
* Update positions of all snapped panels when one changes size
|
|
645
|
+
* Traverses from rightmost panel leftward, repositioning as needed
|
|
646
|
+
*/
|
|
647
|
+
declare function updateSnappedPositions(panels: Map<string, PanelState>, config: ResolvedTabManagerConfig): void;
|
|
648
|
+
/**
|
|
649
|
+
* Get the leftmost panel in a chain
|
|
650
|
+
*/
|
|
651
|
+
declare function getLeftmostPanel(panel: PanelState, panels: Map<string, PanelState>): PanelState;
|
|
652
|
+
/**
|
|
653
|
+
* Get the rightmost panel in a chain
|
|
654
|
+
*/
|
|
655
|
+
declare function getRightmostPanel(panel: PanelState, panels: Map<string, PanelState>): PanelState;
|
|
656
|
+
/**
|
|
657
|
+
* Check if two panels are in the same snap chain
|
|
658
|
+
*/
|
|
659
|
+
declare function areInSameChain(panel1: PanelState, panel2: PanelState, panels: Map<string, PanelState>): boolean;
|
|
660
|
+
/**
|
|
661
|
+
* Establish a snap relationship between two panels
|
|
662
|
+
*/
|
|
663
|
+
declare function snapPanels(leftPanel: PanelState, rightPanel: PanelState): void;
|
|
664
|
+
/**
|
|
665
|
+
* Break the snap relationship between two specific panels
|
|
666
|
+
*/
|
|
667
|
+
declare function unsnap(leftPanel: PanelState, rightPanel: PanelState): void;
|
|
668
|
+
|
|
669
|
+
export { type AnchorConfig, AnchorManager, type AnchorPreset, type AnchorSnapEvent, type AnchorSnapResult, type AnchorState, type Bounds, type CSSClasses, type DragEndEvent, DragManager, type DragMode, type DragMoveEvent, type DragStartEvent, type DragState, type EventListener, type PanelAddedEvent, type PanelCollapseEvent, type PanelConfig, type PanelDetachedEvent, type PanelRemovedEvent, type PanelSnapEvent, type PanelState, type Position, type ResolvedTabManagerConfig, SnapPreview, type SnapSide, type SnapTarget, TabManager, type TabManagerConfig, type TabManagerEvents, areInSameChain, createPanelElement, createPanelState, createPresetAnchor, detachFromGroup, findSnapTarget, getConnectedGroup, getDefaultAnchorConfigs, getDefaultZIndex, getDragZIndex, getLeftmostPanel, getPanelDimensions, getPanelPosition, getRightmostPanel, setPanelPosition, setPanelZIndex, snapPanels, snapPanelsToTarget, toggleCollapse, unsnap, updateSnappedPositions };
|