@alekstar79/draggable-resizable-container 1.0.0

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.
@@ -0,0 +1,112 @@
1
+ import { Plugin, ContainerManagerInterface } from '../core/types';
2
+
3
+ export type Edge = 'top' | 'bottom' | 'left' | 'right';
4
+ export interface DockedContainer {
5
+ element: HTMLElement;
6
+ originalPosition: {
7
+ top: number;
8
+ left: number;
9
+ width: number;
10
+ height: number;
11
+ transform: string;
12
+ position: string;
13
+ };
14
+ edge: Edge;
15
+ screenPosition: {
16
+ x: number;
17
+ y: number;
18
+ };
19
+ }
20
+ export interface EdgeDockingConfig {
21
+ edgeThreshold?: number;
22
+ visiblePeek?: number;
23
+ animationDuration?: number;
24
+ enabled?: boolean;
25
+ }
26
+ export declare class EdgeDockingPlugin implements Plugin {
27
+ private static _pluginId;
28
+ get pluginId(): Symbol;
29
+ private dockedContainers;
30
+ private occupiedEdges;
31
+ private tracker;
32
+ private manager;
33
+ private readonly edgeThreshold;
34
+ constructor(config?: EdgeDockingConfig);
35
+ install(manager: ContainerManagerInterface): void;
36
+ /**
37
+ * Handle edge enter for visual feedback
38
+ */
39
+ private handleEdgeEnter;
40
+ /**
41
+ * Handle edge leave - remove visual feedback
42
+ */
43
+ private handleEdgeLeave;
44
+ /**
45
+ * Check if an edge is occupied by another container
46
+ */
47
+ private isEdgeOccupied;
48
+ /**
49
+ * Attach event handlers to container manager
50
+ */
51
+ private attachEventHandlers;
52
+ /**
53
+ * Handle mouse enter - show docked container
54
+ */
55
+ private onMouseEnter;
56
+ /**
57
+ * Handle mouse leave - hide docked container
58
+ */
59
+ private onMouseLeave;
60
+ /**
61
+ * Handle drag start - undock if docked
62
+ */
63
+ private onDragStart;
64
+ /**
65
+ * Handle drag - update edge hints based on position
66
+ */
67
+ private onDrag;
68
+ /**
69
+ * Handle drag end - dock if close to edge
70
+ */
71
+ private onDragEnd;
72
+ /**
73
+ * Update visual hints for edge docking
74
+ */
75
+ private updateEdgeHints;
76
+ /**
77
+ * Get the closest edge to the container
78
+ */
79
+ private getClosestEdge;
80
+ /**
81
+ * Dock container to specified edge
82
+ */
83
+ private dockContainer;
84
+ /**
85
+ * Apply proper positioning for each edge to prevent shifting
86
+ */
87
+ private applyEdgePositioning;
88
+ /**
89
+ * Undock container from edge
90
+ */
91
+ private undockContainer;
92
+ /**
93
+ * Restore container to its original position without shifting
94
+ */
95
+ private restoreOriginalPosition;
96
+ /**
97
+ * Get the docked container for a specific edge
98
+ */
99
+ getDockedContainer(edge: Edge): DockedContainer | null;
100
+ /**
101
+ * Check if container is docked
102
+ */
103
+ isContainerDocked(element: HTMLElement): boolean;
104
+ /**
105
+ * Get the edge where container is docked
106
+ */
107
+ getContainerDockEdge(element: HTMLElement): Edge | null;
108
+ /**
109
+ * Clean up resources
110
+ */
111
+ destroy(): void;
112
+ }
@@ -0,0 +1,53 @@
1
+ import { ContainerManagerInterface, Plugin } from '../core/types';
2
+
3
+ /**
4
+ * Logging plugin for Container Manager
5
+ * Logs container events and displays notifications
6
+ */
7
+ export declare class LoggingPlugin implements Plugin {
8
+ private static _pluginId;
9
+ get pluginId(): Symbol;
10
+ private manager?;
11
+ private containerName;
12
+ private notificationSystem;
13
+ /**
14
+ * Install plugin on container manager instance
15
+ */
16
+ install(manager: ContainerManagerInterface, options?: any): void;
17
+ /**
18
+ * Bind to container events
19
+ */
20
+ private bindEvents;
21
+ /**
22
+ * Log resize event
23
+ */
24
+ private logResize;
25
+ /**
26
+ * Log drag event
27
+ */
28
+ private logDrag;
29
+ /**
30
+ * Log mode change event
31
+ */
32
+ private logModeChange;
33
+ /**
34
+ * Log viewport resize adjustment event
35
+ */
36
+ private logViewportResize;
37
+ /**
38
+ * Log snapping enabled/disabled
39
+ */
40
+ private logSnappingEnabled;
41
+ /**
42
+ * Log snap step change
43
+ */
44
+ private logSnapStep;
45
+ /**
46
+ * Log direction change
47
+ */
48
+ private logDirectionChange;
49
+ /**
50
+ * Show notification using notification system
51
+ */
52
+ private showNotification;
53
+ }
@@ -0,0 +1,70 @@
1
+ import { ContainerManagerInterface, Plugin } from '../core/types';
2
+
3
+ /**
4
+ * Configuration options for SnappingPlugin
5
+ */
6
+ export interface SnappingPluginOptions {
7
+ snapStep?: number;
8
+ enabled?: boolean;
9
+ }
10
+ /**
11
+ * Extended container manager interface with plugin methods
12
+ */
13
+ export interface SnappingContainerManager extends ContainerManagerInterface {
14
+ setSnapStep?(step: number): void;
15
+ setSnappingEnabled?(enabled: boolean): void;
16
+ getSnappingConfig?(): SnappingPluginOptions;
17
+ }
18
+ /**
19
+ * Snapping plugin for Container Manager
20
+ */
21
+ export declare class SnappingPlugin implements Plugin {
22
+ private static _pluginId;
23
+ get pluginId(): Symbol;
24
+ private reactiveState;
25
+ private manager;
26
+ private startState;
27
+ private startX;
28
+ private startY;
29
+ constructor(options?: SnappingPluginOptions);
30
+ /**
31
+ * Install plugin on container manager instance with reactive state
32
+ */
33
+ install(manager: ContainerManagerInterface, options?: SnappingPluginOptions): void;
34
+ /**
35
+ * Override drag handling methods to add snapping functionality
36
+ */
37
+ private overrideDragMethods;
38
+ /**
39
+ * Handle drag start event with snapping support
40
+ */
41
+ private onDragStart;
42
+ /**
43
+ * Handle drag movement with reactive snapping
44
+ */
45
+ private onDragMove;
46
+ /**
47
+ * Handle drag end event
48
+ */
49
+ private onDragEnd;
50
+ /**
51
+ * Apply snapping to drag movement based on current mode
52
+ */
53
+ private applySnapping;
54
+ /**
55
+ * Snap value to grid using reactive step
56
+ */
57
+ private snapToGrid;
58
+ /**
59
+ * Constrain container to viewport boundaries
60
+ */
61
+ private constrainToViewport;
62
+ /**
63
+ * Add plugin methods to container manager
64
+ */
65
+ private addPluginMethods;
66
+ /**
67
+ * Clean up plugin resources
68
+ */
69
+ destroy(): void;
70
+ }
@@ -0,0 +1,159 @@
1
+ import { ContainerManagerInterface, Plugin, DirectionMode, MovementMode, ResizeConfig } from '../core/types';
2
+
3
+ /**
4
+ * Saved state for a container
5
+ */
6
+ export interface SavedContainerState {
7
+ x: number;
8
+ y: number;
9
+ width: number;
10
+ height: number;
11
+ mode: MovementMode;
12
+ draggingDirection: DirectionMode;
13
+ isMaximized: boolean;
14
+ containerType: string;
15
+ title?: string;
16
+ color?: string;
17
+ useSnapping?: boolean;
18
+ isClosed?: boolean;
19
+ parentElementId?: string;
20
+ closedTimestamp?: number;
21
+ resize?: ResizeConfig;
22
+ isDemoContainer?: boolean;
23
+ [p: string]: any;
24
+ }
25
+ /**
26
+ * State persistence plugin for Container Manager
27
+ */
28
+ export declare class StatePersistencePlugin implements Plugin {
29
+ private static _pluginId;
30
+ get pluginId(): Symbol;
31
+ private static readonly STORAGE_KEY;
32
+ private static readonly CLOSED_QUEUE_KEY;
33
+ private static readonly DEMO_CONTAINERS_KEY;
34
+ private static reactiveState;
35
+ private static get containerStates();
36
+ private static get closedQueue();
37
+ private static get demoContainers();
38
+ private static isGlobalEventsInitialized;
39
+ private manager?;
40
+ private containerId?;
41
+ private isDemoContainer;
42
+ private autoSaveEffect?;
43
+ static containers: {
44
+ manager: ContainerManagerInterface;
45
+ containerId: string;
46
+ isDemo?: boolean;
47
+ }[];
48
+ /**
49
+ * Install plugin on container manager instance with reactive state management
50
+ */
51
+ install(manager: ContainerManagerInterface, options?: {
52
+ containerId: string;
53
+ isDemo?: boolean;
54
+ }): void;
55
+ /**
56
+ * Set up reactive auto-save effect for container state changes
57
+ */
58
+ private setupAutoSaveEffect;
59
+ /**
60
+ * Bind to container-specific events to save state on changes
61
+ * Simplified since most saving handled using effects
62
+ */
63
+ private bindContainerEvents;
64
+ /**
65
+ * Initialize global event handlers for all containers
66
+ */
67
+ private static initializeGlobalEvents;
68
+ /**
69
+ * Register a container as a demo container
70
+ */
71
+ static registerDemoContainer(containerId: string): void;
72
+ /**
73
+ * Save demo containers to localStorage
74
+ */
75
+ private static saveDemoContainersToStorage;
76
+ /**
77
+ * Get list of all demo containers
78
+ */
79
+ private static getDemoContainers;
80
+ /**
81
+ * Check if a container is a demo container
82
+ */
83
+ static isDemoContainer(containerId: string): boolean;
84
+ /**
85
+ * Get all saved states from localStorage
86
+ */
87
+ private static getAllStates;
88
+ /**
89
+ * Add container ID to closed containers queue
90
+ */
91
+ static addToClosedQueue(containerId: string): void;
92
+ /**
93
+ * Save closed queue to localStorage
94
+ */
95
+ private static saveClosedQueueToStorage;
96
+ /**
97
+ * Get closed containers queue (LIFO - last in first out)
98
+ */
99
+ static getClosedQueue(): string[];
100
+ private saveState;
101
+ /**
102
+ * Save container state with current manager state before closing
103
+ */
104
+ static saveContainerStateBeforeClose(manager: ContainerManagerInterface, containerId: string): void;
105
+ /**
106
+ * Save all containers state (for global events) - including closed ones
107
+ */
108
+ static saveAllContainers(): void;
109
+ /**
110
+ * Remove the most recently closed container from queue and return its ID
111
+ */
112
+ static popLastClosedContainer(): string | null;
113
+ /**
114
+ * Check if there are any closed containers that can be restored
115
+ */
116
+ static hasClosedContainers(): boolean;
117
+ /**
118
+ * Get saved state for specific container (including closed ones)
119
+ */
120
+ static getContainerState(containerId: string): SavedContainerState | null;
121
+ /**
122
+ * Get all container states including closed ones
123
+ */
124
+ static getAllContainerStates(): Record<string, SavedContainerState>;
125
+ /**
126
+ * Check if container state exists (including closed)
127
+ */
128
+ static hasContainerState(containerId: string): boolean;
129
+ /**
130
+ * Update container state in storage
131
+ */
132
+ static updateContainerState(containerId: string, updates: Partial<SavedContainerState>): void;
133
+ /**
134
+ * Clear all saved states from localStorage
135
+ */
136
+ static clearStorage(): void;
137
+ /**
138
+ * Initialize reactive state from localStorage on plugin load
139
+ */
140
+ static initializeReactiveState(): void;
141
+ /**
142
+ * Get plugin metrics and statistics
143
+ */
144
+ static getMetrics(): {
145
+ totalContainers: number;
146
+ demoContainers: number;
147
+ closedContainers: number;
148
+ lastSaved: number | null;
149
+ isSaving: boolean;
150
+ };
151
+ /**
152
+ * Debug method to check the current state of localStorage
153
+ */
154
+ static debugStorage(): void;
155
+ /**
156
+ * Clean up plugin resources
157
+ */
158
+ destroy(): void;
159
+ }
@@ -0,0 +1,7 @@
1
+ export { SnappingPlugin } from './SnappingPlugin';
2
+ export { EdgeDockingPlugin } from './EdgeDockingPlugin';
3
+ export { StatePersistencePlugin } from './StatePersistencePlugin';
4
+ export { LoggingPlugin } from './LoggingPlugin';
5
+ export type { EdgeDockingConfig, Edge } from './EdgeDockingPlugin';
6
+ export type { SavedContainerState } from './StatePersistencePlugin';
7
+ export type { SnappingPluginOptions } from './SnappingPlugin';
@@ -0,0 +1,155 @@
1
+ /**
2
+ * BoundaryTracker.ts
3
+ * Tracks the approach of the dragged element to the edges of the viewport
4
+ * The element remains inside the viewport, and the detection zones are also inside
5
+ */
6
+ export type Event = 'edge:enter' | 'edge:leave' | 'cursor:enter' | 'cursor:leave';
7
+ export type Edge = 'top' | 'right' | 'bottom' | 'left';
8
+ export interface Options {
9
+ emitter?: EventEmitter | boolean;
10
+ edgeThreshold?: number;
11
+ }
12
+ export interface EdgeZoneInfo {
13
+ top: boolean;
14
+ right: boolean;
15
+ bottom: boolean;
16
+ left: boolean;
17
+ edge: Edge | null;
18
+ }
19
+ export interface SourceEdgeInfo extends EdgeZoneInfo {
20
+ source: 'element' | 'cursor';
21
+ element: HTMLElement | null;
22
+ }
23
+ export interface IBoundaryTracker {
24
+ start(): void;
25
+ stop(): void;
26
+ addTarget(element: HTMLElement): void;
27
+ removeTarget(element: HTMLElement): void;
28
+ onChange(callback: EdgeChangeCallback): () => void;
29
+ getCursorEdgeInfo(): EdgeZoneInfo;
30
+ setEdgeThreshold(threshold: number): void;
31
+ destroy(): void;
32
+ }
33
+ export interface IEdgeController extends IBoundaryTracker {
34
+ getCurrentEdge(): Partial<SourceEdgeInfo>;
35
+ on(event: Event, callback: EdgeChangeCallback): void;
36
+ onCursorEnter(data: SourceEdgeInfo): void;
37
+ onCursorLeave(data: SourceEdgeInfo): void;
38
+ onEdgeEnter(data: SourceEdgeInfo): void;
39
+ onEdgeLeave(data: SourceEdgeInfo): void;
40
+ setEmitter(emitter: EventEmitter): void;
41
+ }
42
+ export type EdgeChangeCallback = (data: Partial<SourceEdgeInfo>) => void;
43
+ export type EventCallback<T = any> = (data?: T) => void;
44
+ export type EventMap = Record<string, any>;
45
+ export declare class EdgeInfo implements SourceEdgeInfo {
46
+ source: 'element' | 'cursor';
47
+ element: HTMLElement | null;
48
+ top: boolean;
49
+ right: boolean;
50
+ bottom: boolean;
51
+ left: boolean;
52
+ edge: Edge | null;
53
+ constructor(info: SourceEdgeInfo);
54
+ }
55
+ export declare class EventEmitter<T extends EventMap = any> {
56
+ private listeners;
57
+ on<K extends keyof T>(event: K, callback: EventCallback<T[K]>): () => void;
58
+ emit<K extends keyof T>(event: K, data?: T[K]): void;
59
+ off?<K extends keyof T>(event: K, callback: EventCallback<T[K]>): void;
60
+ destroy?(): void;
61
+ }
62
+ /**
63
+ * The main class for tracking borders
64
+ * Uses requestAnimationFrame for accurate tracking during drag
65
+ */
66
+ export declare class InternalBoundaryTracker implements IBoundaryTracker {
67
+ private readonly root;
68
+ private edgeThreshold;
69
+ private targets;
70
+ private currentEdges;
71
+ private rafId;
72
+ private isActive;
73
+ private callbacks;
74
+ private currentMousePos;
75
+ private currentCursorEdge;
76
+ constructor(edgeThreshold?: number, targets?: HTMLElement[] | Set<HTMLElement>, root?: HTMLElement | null);
77
+ /**
78
+ * Start tracking the approach to the edges
79
+ */
80
+ start(): void;
81
+ /**
82
+ * Stop tracking
83
+ */
84
+ stop(): void;
85
+ addTarget(element: HTMLElement): void;
86
+ removeTarget(element: HTMLElement): void;
87
+ /**
88
+ * Subscribe to boundary changes
89
+ */
90
+ onChange(callback: EdgeChangeCallback): () => void;
91
+ /**
92
+ * Get current information about cursor boundaries
93
+ */
94
+ getCursorEdgeInfo(): EdgeZoneInfo;
95
+ /**
96
+ * Update threshold (distance to edge)
97
+ */
98
+ setEdgeThreshold(threshold: number): void;
99
+ /**
100
+ * Set up Mouse Tracking
101
+ */
102
+ private setupMouseTracking;
103
+ private getViewportSize;
104
+ private getRelativeRect;
105
+ private getCursorPosition;
106
+ /**
107
+ * Check the proximity to the borders (element and cursor)
108
+ */
109
+ private checkBoundaries;
110
+ /**
111
+ * Emulating Bounding Rect for cursor
112
+ */
113
+ private getCursorBoundingClientRect;
114
+ /**
115
+ * Check the boundaries of an element
116
+ */
117
+ private checkElementBoundaries;
118
+ /**
119
+ * Check the boundaries of a cursor
120
+ */
121
+ private checkCursorBoundaries;
122
+ /**
123
+ * Check if the state has changed
124
+ */
125
+ private hasEdgeChanged;
126
+ /**
127
+ * Determine a priority edge-side (or several)
128
+ */
129
+ private determineEdge;
130
+ /**
131
+ * Notify all subscribers of the change
132
+ */
133
+ private notifyCallbacks;
134
+ /**
135
+ * Clear resources
136
+ */
137
+ destroy(): void;
138
+ }
139
+ export declare class EdgeController extends InternalBoundaryTracker implements IEdgeController {
140
+ private static instance;
141
+ static init(edgeThreshold?: number, elements?: HTMLElement[]): IEdgeController;
142
+ private lastEdge;
143
+ emitter: EventEmitter | null;
144
+ constructor(edgeThreshold?: number, elements?: HTMLElement[]);
145
+ private changed;
146
+ private onBoundaryChange;
147
+ onEdgeEnter(data: Partial<SourceEdgeInfo>): void;
148
+ onEdgeLeave(data: Partial<SourceEdgeInfo>): void;
149
+ onCursorEnter(data: Partial<SourceEdgeInfo>): void;
150
+ onCursorLeave(data: Partial<SourceEdgeInfo>): void;
151
+ setEmitter(emitter: EventEmitter): void;
152
+ on(event: Event, callback: EdgeChangeCallback): void;
153
+ getCurrentEdge(): Partial<SourceEdgeInfo>;
154
+ }
155
+ export declare function createTracker(options?: Options, elements?: HTMLElement[]): IEdgeController;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Utility for proper container initialization and state synchronization
3
+ */
4
+ export declare class ContainerInitializer {
5
+ /**
6
+ * Create container element with proper initialization
7
+ */
8
+ static createContainerElement(width: number, height: number, x?: number, y?: number, color?: string): HTMLElement;
9
+ }
@@ -0,0 +1,22 @@
1
+ import { TemplateLoader } from './index';
2
+
3
+ /**
4
+ * Content creator utility for flexible content handling
5
+ * Supports strings, DOM elements, and template loading
6
+ */
7
+ export declare class ContentCreator {
8
+ private templateLoader;
9
+ constructor(templateLoader: TemplateLoader);
10
+ /**
11
+ * Create content from various sources
12
+ * @param content - String, HTMLElement, or template name
13
+ * @param container - Container element to append content to
14
+ */
15
+ createContent(content: string | HTMLElement | {
16
+ template: string;
17
+ }, container: HTMLElement): Promise<HTMLElement>;
18
+ /**
19
+ * Set template loader instance
20
+ */
21
+ setTemplateLoader(loader: TemplateLoader): void;
22
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Notification system for displaying toast messages
3
+ * Adapted for TypeScript with improved functionality
4
+ */
5
+ export declare class NotificationSystem {
6
+ private container;
7
+ constructor(container?: HTMLElement);
8
+ /**
9
+ * Create notifications container
10
+ */
11
+ private createContainer;
12
+ /**
13
+ * Show notification toast
14
+ */
15
+ show(text: string, type?: 'success' | 'error' | 'warning' | 'info'): void;
16
+ /**
17
+ * Generate toast HTML based on type
18
+ */
19
+ private getToastHTML;
20
+ /**
21
+ * Remove toast with animation
22
+ */
23
+ private removeToast;
24
+ /**
25
+ * Clear all notifications
26
+ */
27
+ clear(): void;
28
+ }
29
+ export declare const defaultNotificationSystem: NotificationSystem;
@@ -0,0 +1,51 @@
1
+ import { DirectionMode } from '../core/types';
2
+
3
+ /**
4
+ * Interface for container statistics
5
+ */
6
+ export interface ContainerStats {
7
+ activeBlock: string;
8
+ lock: 'opened' | 'locked';
9
+ direction: DirectionMode;
10
+ step?: number;
11
+ hasSnapping: boolean;
12
+ }
13
+ /**
14
+ * Interface for global statistics
15
+ */
16
+ export interface GlobalStats {
17
+ containerCount: number;
18
+ contentTypes: string;
19
+ pinnedMode: string;
20
+ snappingCount: number;
21
+ }
22
+ /**
23
+ * Statistics manager for handling both global and per-container stats
24
+ */
25
+ export declare class StatsManager {
26
+ private globalStatsElement;
27
+ /**
28
+ * Initialize stats manager
29
+ */
30
+ initialize(globalStatsElement: HTMLElement): void;
31
+ /**
32
+ * Show container-specific statistics
33
+ */
34
+ showContainerStats(containerStats: ContainerStats): void;
35
+ /**
36
+ * Show global statistics
37
+ */
38
+ showGlobalStats(globalStats: GlobalStats): void;
39
+ /**
40
+ * Generate HTML for container statistics
41
+ */
42
+ private generateContainerStatsHTML;
43
+ /**
44
+ * Generate HTML for global statistics
45
+ */
46
+ private generateGlobalStatsHTML;
47
+ /**
48
+ * Update stats panel with new HTML content
49
+ */
50
+ private updateStatsPanel;
51
+ }
@@ -0,0 +1,24 @@
1
+ import { LoaderConfig, LoaderMetrics, TemplateConfig, TemplateSource, TemplateCache, TemplateLoader, TemplateRegistry } from '@alekstar79/template-loader';
2
+
3
+ /**
4
+ * Create a fully functional loader for the demo
5
+ */
6
+ export declare function createDemoLoader(fallbackTemplates?: {
7
+ name: string;
8
+ source: string;
9
+ }[]): Promise<TemplateLoader>;
10
+ /**
11
+ * Create a loader for the library
12
+ */
13
+ export declare function createLibraryLoader(): TemplateLoader & {
14
+ registry: TemplateRegistry;
15
+ };
16
+ /**
17
+ * System initialization (called in main.ts or app initialization)
18
+ */
19
+ export declare function initializeTemplateSystem(): Promise<TemplateLoader>;
20
+ /**
21
+ * Get a global instance
22
+ */
23
+ export declare function getTemplateLoader(): TemplateLoader;
24
+ export { LoaderConfig, LoaderMetrics, TemplateConfig, TemplateSource, TemplateCache, TemplateLoader, TemplateRegistry };