tiny-essentials 1.11.0 → 1.12.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.
Files changed (72) hide show
  1. package/README.md +12 -3
  2. package/dist/node_modules/firebase-functions/lib/common/trace.cjs +82 -0
  3. package/dist/node_modules/firebase-functions/lib/logger/common.cjs +57 -0
  4. package/dist/node_modules/firebase-functions/lib/logger/index.cjs +158 -0
  5. package/dist/v1/TinyBasicsEs.js +1653 -1
  6. package/dist/v1/TinyBasicsEs.min.js +1 -1
  7. package/dist/v1/TinyDragDropDetector.js +307 -0
  8. package/dist/v1/TinyDragDropDetector.min.js +1 -0
  9. package/dist/v1/TinyDragger.js +3563 -0
  10. package/dist/v1/TinyDragger.min.js +2 -0
  11. package/dist/v1/TinyDragger.min.js.LICENSE.txt +8 -0
  12. package/dist/v1/TinyEssentials.js +2783 -2
  13. package/dist/v1/TinyEssentials.min.js +1 -1
  14. package/dist/v1/TinyNotifyCenter.js +32 -0
  15. package/dist/v1/TinyNotifyCenter.min.js +1 -1
  16. package/dist/v1/TinyToastNotify.js +24 -0
  17. package/dist/v1/TinyToastNotify.min.js +1 -1
  18. package/dist/v1/TinyUploadClicker.js +5235 -0
  19. package/dist/v1/TinyUploadClicker.min.js +2 -0
  20. package/dist/v1/TinyUploadClicker.min.js.LICENSE.txt +8 -0
  21. package/dist/v1/basics/fileManager.cjs +524 -0
  22. package/dist/v1/basics/fileManager.d.mts +209 -0
  23. package/dist/v1/basics/fileManager.mjs +443 -0
  24. package/dist/v1/basics/fullScreen.cjs +134 -0
  25. package/dist/v1/basics/fullScreen.d.mts +8 -0
  26. package/dist/v1/basics/fullScreen.mjs +121 -0
  27. package/dist/v1/basics/html.cjs +262 -0
  28. package/dist/v1/basics/html.d.mts +63 -0
  29. package/dist/v1/basics/html.mjs +208 -0
  30. package/dist/v1/basics/index.cjs +40 -0
  31. package/dist/v1/basics/index.d.mts +38 -1
  32. package/dist/v1/basics/index.mjs +4 -1
  33. package/dist/v1/build/TinyDragDropDetector.cjs +7 -0
  34. package/dist/v1/build/TinyDragDropDetector.d.mts +3 -0
  35. package/dist/v1/build/TinyDragDropDetector.mjs +2 -0
  36. package/dist/v1/build/TinyDragger.cjs +7 -0
  37. package/dist/v1/build/TinyDragger.d.mts +3 -0
  38. package/dist/v1/build/TinyDragger.mjs +2 -0
  39. package/dist/v1/build/TinyUploadClicker.cjs +7 -0
  40. package/dist/v1/build/TinyUploadClicker.d.mts +3 -0
  41. package/dist/v1/build/TinyUploadClicker.mjs +2 -0
  42. package/dist/v1/css/TinyDraggerExample.css +21 -0
  43. package/dist/v1/css/TinyDraggerExample.min.css +1 -0
  44. package/dist/v1/index.cjs +44 -0
  45. package/dist/v1/index.d.mts +40 -1
  46. package/dist/v1/index.mjs +6 -1
  47. package/dist/v1/libs/TinyDragDropDetector.cjs +268 -0
  48. package/dist/v1/libs/TinyDragDropDetector.d.mts +123 -0
  49. package/dist/v1/libs/TinyDragDropDetector.mjs +228 -0
  50. package/dist/v1/libs/TinyDragger.cjs +801 -0
  51. package/dist/v1/libs/TinyDragger.d.mts +300 -0
  52. package/dist/v1/libs/TinyDragger.mjs +689 -0
  53. package/dist/v1/libs/TinyNotifyCenter.cjs +32 -0
  54. package/dist/v1/libs/TinyNotifyCenter.d.mts +9 -0
  55. package/dist/v1/libs/TinyNotifyCenter.mjs +28 -0
  56. package/dist/v1/libs/TinyToastNotify.cjs +24 -0
  57. package/dist/v1/libs/TinyToastNotify.d.mts +8 -0
  58. package/dist/v1/libs/TinyToastNotify.mjs +20 -0
  59. package/dist/v1/libs/TinyUploadClicker.cjs +223 -0
  60. package/dist/v1/libs/TinyUploadClicker.d.mts +80 -0
  61. package/dist/v1/libs/TinyUploadClicker.mjs +182 -0
  62. package/docs/v1/README.md +8 -2
  63. package/docs/v1/basics/fileManager.md +222 -0
  64. package/docs/v1/basics/fullScreen.md +183 -0
  65. package/docs/v1/basics/html.md +243 -0
  66. package/docs/v1/libs/TinyDragDropDetector.md +143 -0
  67. package/docs/v1/libs/TinyDragger.md +415 -0
  68. package/docs/v1/libs/TinyLevelUp.md +1 -1
  69. package/docs/v1/libs/TinyNotifyCenter.md +20 -0
  70. package/docs/v1/libs/TinyToastNotify.md +19 -0
  71. package/docs/v1/libs/TinyUploadClicker.md +108 -0
  72. package/package.json +12 -2
@@ -0,0 +1,268 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @typedef {Object} DragAndDropOptions
5
+ * @property {HTMLElement} [target=document.body] - The DOM element where drag listeners will be attached. Defaults to `document.body` if `fullscreen` is true or no target is provided.
6
+ * @property {boolean} [fullscreen=true] - If true, listeners are attached to the entire page (`document.body`). If false, the `target` must be specified.
7
+ * @property {string} [hoverClass="dnd-hover"] - CSS class applied to the target element while files are being dragged over it.
8
+ * @property {(files: FileList, event: DragEvent) => void} [onDrop] - Callback function executed when files are dropped onto the target.
9
+ * @property {(event: DragEvent) => void} [onEnter] - Optional callback triggered when dragging enters the target area.
10
+ * @property {(event: DragEvent) => void} [onLeave] - Optional callback triggered when dragging leaves the target area.
11
+ */
12
+
13
+ /**
14
+ * TinyDragDropDetector
15
+ *
16
+ * A lightweight utility to detect drag-and-drop file operations on a specific DOM element or the entire page.
17
+ * It handles the drag lifecycle (enter, over, leave, drop) and provides hooks for developers to handle file uploads or UI changes.
18
+ *
19
+ * @class
20
+ */
21
+ class TinyDragDropDetector {
22
+ /** @type {HTMLElement} */
23
+ #target;
24
+
25
+ /** @type {boolean} */
26
+ #fullscreen;
27
+
28
+ /** @type {string} */
29
+ #hoverClass;
30
+
31
+ /** @type {(files: FileList, event: DragEvent) => void} */
32
+ #onDropCallback;
33
+
34
+ /** @type {(event: DragEvent) => void} */
35
+ #onEnterCallback;
36
+
37
+ /** @type {(event: DragEvent) => void} */
38
+ #onLeaveCallback;
39
+
40
+ /** @type {boolean} */
41
+ #isDragging;
42
+
43
+ /** @type {boolean} */
44
+ #bound;
45
+
46
+ /**
47
+ * Creates a new instance of TinyDragDropDetector to handle drag-and-drop file detection.
48
+ *
49
+ * @param {DragAndDropOptions} [options={}] - Configuration options for the detector.
50
+ * @throws {TypeError} If `target` is not an HTMLElement.
51
+ * @throws {TypeError} If `fullscreen` is not a boolean.
52
+ * @throws {TypeError} If `hoverClass` is not a string.
53
+ * @throws {TypeError} If `onDrop` is defined but not a function.
54
+ * @throws {TypeError} If `onEnter` is defined but not a function.
55
+ * @throws {TypeError} If `onLeave` is defined but not a function.
56
+ */
57
+ constructor(options = {}) {
58
+ const {
59
+ target,
60
+ fullscreen = true,
61
+ hoverClass = 'dnd-hover',
62
+ onDrop,
63
+ onEnter,
64
+ onLeave,
65
+ } = options;
66
+
67
+ // Validate fullscreen
68
+ if (typeof fullscreen !== 'boolean')
69
+ throw new TypeError('The "fullscreen" option must be a boolean.');
70
+
71
+ // Validate target
72
+ const resolvedTarget = fullscreen ? document.body : target || document.body;
73
+ if (!(resolvedTarget instanceof HTMLElement))
74
+ throw new TypeError('The "target" option must be an instance of HTMLElement.');
75
+
76
+ // Validate hoverClass
77
+ if (typeof hoverClass !== 'string')
78
+ throw new TypeError('The "hoverClass" option must be a string.');
79
+
80
+ // Validate onDrop
81
+ if (typeof onDrop !== 'function')
82
+ throw new TypeError('The "onDrop" option must be a function.');
83
+
84
+ // Validate onEnter
85
+ if (typeof onEnter !== 'function')
86
+ throw new TypeError('The "onEnter" option must be a function.');
87
+
88
+ // Validate onLeave
89
+ if (typeof onLeave !== 'function')
90
+ throw new TypeError('The "onLeave" option must be a function.');
91
+
92
+ // Store properties
93
+ this.#target = resolvedTarget;
94
+ this.#fullscreen = fullscreen;
95
+ this.#hoverClass = hoverClass;
96
+
97
+ this.#onDropCallback = onDrop || (() => {});
98
+ this.#onEnterCallback = onEnter;
99
+ this.#onLeaveCallback = onLeave;
100
+
101
+ this.#isDragging = false;
102
+ this.#bound = false;
103
+
104
+ // Bind event handlers
105
+ this._handleDragEnter = this._handleDragEnter.bind(this);
106
+ this._handleDragOver = this._handleDragOver.bind(this);
107
+ this._handleDragLeave = this._handleDragLeave.bind(this);
108
+ this._handleDrop = this._handleDrop.bind(this);
109
+
110
+ this.#bindEvents();
111
+ }
112
+
113
+ /**
114
+ * Returns the current target DOM element where the listeners are attached.
115
+ * @returns {HTMLElement}
116
+ */
117
+ getTarget() {
118
+ return this.#target;
119
+ }
120
+
121
+ /**
122
+ * Returns the CSS class applied during drag hover.
123
+ * @returns {string}
124
+ */
125
+ getHoverClass() {
126
+ return this.#hoverClass;
127
+ }
128
+
129
+ /**
130
+ * Indicates whether the detector is operating in fullscreen mode.
131
+ * @returns {boolean}
132
+ */
133
+ isFullScreen() {
134
+ return this.#fullscreen;
135
+ }
136
+
137
+ /**
138
+ * Returns whether a drag operation is currently active over the target.
139
+ * @returns {boolean}
140
+ */
141
+ isDragging() {
142
+ return this.#isDragging;
143
+ }
144
+
145
+ /**
146
+ * Returns whether the event listeners are currently bound to the target.
147
+ * @returns {boolean}
148
+ */
149
+ bound() {
150
+ return this.#bound;
151
+ }
152
+
153
+ /**
154
+ * Binds the drag-and-drop event listeners to the target element.
155
+ * Automatically called on instantiation.
156
+ * @returns {void}
157
+ */
158
+ #bindEvents() {
159
+ if (this.#bound) return;
160
+ const target = this.getTarget();
161
+ target.addEventListener('dragenter', this._handleDragEnter);
162
+ target.addEventListener('dragover', this._handleDragOver);
163
+ target.addEventListener('dragleave', this._handleDragLeave);
164
+ target.addEventListener('drop', this._handleDrop);
165
+ this.#bound = true;
166
+ }
167
+
168
+ /**
169
+ * Removes all previously attached drag-and-drop event listeners from the target.
170
+ * @returns {void}
171
+ */
172
+ #unbindEvents() {
173
+ if (!this.#bound) return;
174
+ const target = this.getTarget();
175
+ target.removeEventListener('dragenter', this._handleDragEnter);
176
+ target.removeEventListener('dragover', this._handleDragOver);
177
+ target.removeEventListener('dragleave', this._handleDragLeave);
178
+ target.removeEventListener('drop', this._handleDrop);
179
+ this.#bound = false;
180
+ }
181
+
182
+ /**
183
+ * Handles the `dragenter` event.
184
+ * Adds the hover CSS class and triggers the `onEnter` callback if provided.
185
+ * @private
186
+ * @param {DragEvent} event - The dragenter event.
187
+ * @returns {void}
188
+ */
189
+ _handleDragEnter(event) {
190
+ event.preventDefault();
191
+ if (!this.#isDragging) {
192
+ const target = this.getTarget();
193
+ this.#isDragging = true;
194
+ target.classList.add(this.#hoverClass);
195
+ this.#onEnterCallback(event);
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Handles the `dragover` event.
201
+ * Prevents default to allow drop and sets the drop effect.
202
+ * @private
203
+ * @param {DragEvent} event - The dragover event.
204
+ * @returns {void}
205
+ */
206
+ _handleDragOver(event) {
207
+ event.preventDefault(); // Required to allow drop
208
+ if (!event.dataTransfer) {
209
+ console.warn('[TinyDragDropDetector] [handleDragOver] DragOver event missing dataTransfer.');
210
+ return;
211
+ }
212
+ event.dataTransfer.dropEffect = 'copy';
213
+ }
214
+
215
+ /**
216
+ * Handles the `dragleave` event.
217
+ * Removes the hover class and triggers the `onLeave` callback if provided.
218
+ * @private
219
+ * @param {DragEvent} event - The dragleave event.
220
+ * @returns {void}
221
+ */
222
+ _handleDragLeave(event) {
223
+ event.preventDefault();
224
+ const target = this.getTarget();
225
+ // Check if you've completely left the area
226
+ // @ts-ignore
227
+ if (event.relatedTarget === null || !target.contains(event.relatedTarget)) {
228
+ this.#isDragging = false;
229
+ target.classList.remove(this.#hoverClass);
230
+ this.#onLeaveCallback(event);
231
+ }
232
+ }
233
+
234
+ /**
235
+ * Handles the `drop` event.
236
+ * Removes the hover class, resets dragging state, and triggers the `onDrop` callback.
237
+ * @private
238
+ * @param {DragEvent} event - The drop event.
239
+ * @returns {void}
240
+ */
241
+ _handleDrop(event) {
242
+ event.preventDefault();
243
+ if (!event.dataTransfer) {
244
+ console.warn('[TinyDragDropDetector] [handleDrop] DragOver event missing dataTransfer.');
245
+ return;
246
+ }
247
+ const target = this.getTarget();
248
+ this.#isDragging = false;
249
+ target.classList.remove(this.#hoverClass);
250
+ const files = event.dataTransfer.files;
251
+ if (files.length > 0) {
252
+ this.#onDropCallback(files, event);
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Destroys the detector instance, unbinding all event listeners and cleaning up.
258
+ * Should be called when the detector is no longer needed to avoid memory leaks.
259
+ * @returns {void}
260
+ */
261
+ destroy() {
262
+ this.#unbindEvents();
263
+ const target = this.getTarget();
264
+ target.classList.remove(this.#hoverClass);
265
+ }
266
+ }
267
+
268
+ module.exports = TinyDragDropDetector;
@@ -0,0 +1,123 @@
1
+ export default TinyDragDropDetector;
2
+ export type DragAndDropOptions = {
3
+ /**
4
+ * - The DOM element where drag listeners will be attached. Defaults to `document.body` if `fullscreen` is true or no target is provided.
5
+ */
6
+ target?: HTMLElement | undefined;
7
+ /**
8
+ * - If true, listeners are attached to the entire page (`document.body`). If false, the `target` must be specified.
9
+ */
10
+ fullscreen?: boolean | undefined;
11
+ /**
12
+ * - CSS class applied to the target element while files are being dragged over it.
13
+ */
14
+ hoverClass?: string | undefined;
15
+ /**
16
+ * - Callback function executed when files are dropped onto the target.
17
+ */
18
+ onDrop?: ((files: FileList, event: DragEvent) => void) | undefined;
19
+ /**
20
+ * - Optional callback triggered when dragging enters the target area.
21
+ */
22
+ onEnter?: ((event: DragEvent) => void) | undefined;
23
+ /**
24
+ * - Optional callback triggered when dragging leaves the target area.
25
+ */
26
+ onLeave?: ((event: DragEvent) => void) | undefined;
27
+ };
28
+ /**
29
+ * @typedef {Object} DragAndDropOptions
30
+ * @property {HTMLElement} [target=document.body] - The DOM element where drag listeners will be attached. Defaults to `document.body` if `fullscreen` is true or no target is provided.
31
+ * @property {boolean} [fullscreen=true] - If true, listeners are attached to the entire page (`document.body`). If false, the `target` must be specified.
32
+ * @property {string} [hoverClass="dnd-hover"] - CSS class applied to the target element while files are being dragged over it.
33
+ * @property {(files: FileList, event: DragEvent) => void} [onDrop] - Callback function executed when files are dropped onto the target.
34
+ * @property {(event: DragEvent) => void} [onEnter] - Optional callback triggered when dragging enters the target area.
35
+ * @property {(event: DragEvent) => void} [onLeave] - Optional callback triggered when dragging leaves the target area.
36
+ */
37
+ /**
38
+ * TinyDragDropDetector
39
+ *
40
+ * A lightweight utility to detect drag-and-drop file operations on a specific DOM element or the entire page.
41
+ * It handles the drag lifecycle (enter, over, leave, drop) and provides hooks for developers to handle file uploads or UI changes.
42
+ *
43
+ * @class
44
+ */
45
+ declare class TinyDragDropDetector {
46
+ /**
47
+ * Creates a new instance of TinyDragDropDetector to handle drag-and-drop file detection.
48
+ *
49
+ * @param {DragAndDropOptions} [options={}] - Configuration options for the detector.
50
+ * @throws {TypeError} If `target` is not an HTMLElement.
51
+ * @throws {TypeError} If `fullscreen` is not a boolean.
52
+ * @throws {TypeError} If `hoverClass` is not a string.
53
+ * @throws {TypeError} If `onDrop` is defined but not a function.
54
+ * @throws {TypeError} If `onEnter` is defined but not a function.
55
+ * @throws {TypeError} If `onLeave` is defined but not a function.
56
+ */
57
+ constructor(options?: DragAndDropOptions);
58
+ /**
59
+ * Handles the `dragenter` event.
60
+ * Adds the hover CSS class and triggers the `onEnter` callback if provided.
61
+ * @private
62
+ * @param {DragEvent} event - The dragenter event.
63
+ * @returns {void}
64
+ */
65
+ private _handleDragEnter;
66
+ /**
67
+ * Handles the `dragover` event.
68
+ * Prevents default to allow drop and sets the drop effect.
69
+ * @private
70
+ * @param {DragEvent} event - The dragover event.
71
+ * @returns {void}
72
+ */
73
+ private _handleDragOver;
74
+ /**
75
+ * Handles the `dragleave` event.
76
+ * Removes the hover class and triggers the `onLeave` callback if provided.
77
+ * @private
78
+ * @param {DragEvent} event - The dragleave event.
79
+ * @returns {void}
80
+ */
81
+ private _handleDragLeave;
82
+ /**
83
+ * Handles the `drop` event.
84
+ * Removes the hover class, resets dragging state, and triggers the `onDrop` callback.
85
+ * @private
86
+ * @param {DragEvent} event - The drop event.
87
+ * @returns {void}
88
+ */
89
+ private _handleDrop;
90
+ /**
91
+ * Returns the current target DOM element where the listeners are attached.
92
+ * @returns {HTMLElement}
93
+ */
94
+ getTarget(): HTMLElement;
95
+ /**
96
+ * Returns the CSS class applied during drag hover.
97
+ * @returns {string}
98
+ */
99
+ getHoverClass(): string;
100
+ /**
101
+ * Indicates whether the detector is operating in fullscreen mode.
102
+ * @returns {boolean}
103
+ */
104
+ isFullScreen(): boolean;
105
+ /**
106
+ * Returns whether a drag operation is currently active over the target.
107
+ * @returns {boolean}
108
+ */
109
+ isDragging(): boolean;
110
+ /**
111
+ * Returns whether the event listeners are currently bound to the target.
112
+ * @returns {boolean}
113
+ */
114
+ bound(): boolean;
115
+ /**
116
+ * Destroys the detector instance, unbinding all event listeners and cleaning up.
117
+ * Should be called when the detector is no longer needed to avoid memory leaks.
118
+ * @returns {void}
119
+ */
120
+ destroy(): void;
121
+ #private;
122
+ }
123
+ //# sourceMappingURL=TinyDragDropDetector.d.mts.map
@@ -0,0 +1,228 @@
1
+ /**
2
+ * @typedef {Object} DragAndDropOptions
3
+ * @property {HTMLElement} [target=document.body] - The DOM element where drag listeners will be attached. Defaults to `document.body` if `fullscreen` is true or no target is provided.
4
+ * @property {boolean} [fullscreen=true] - If true, listeners are attached to the entire page (`document.body`). If false, the `target` must be specified.
5
+ * @property {string} [hoverClass="dnd-hover"] - CSS class applied to the target element while files are being dragged over it.
6
+ * @property {(files: FileList, event: DragEvent) => void} [onDrop] - Callback function executed when files are dropped onto the target.
7
+ * @property {(event: DragEvent) => void} [onEnter] - Optional callback triggered when dragging enters the target area.
8
+ * @property {(event: DragEvent) => void} [onLeave] - Optional callback triggered when dragging leaves the target area.
9
+ */
10
+ /**
11
+ * TinyDragDropDetector
12
+ *
13
+ * A lightweight utility to detect drag-and-drop file operations on a specific DOM element or the entire page.
14
+ * It handles the drag lifecycle (enter, over, leave, drop) and provides hooks for developers to handle file uploads or UI changes.
15
+ *
16
+ * @class
17
+ */
18
+ class TinyDragDropDetector {
19
+ /** @type {HTMLElement} */
20
+ #target;
21
+ /** @type {boolean} */
22
+ #fullscreen;
23
+ /** @type {string} */
24
+ #hoverClass;
25
+ /** @type {(files: FileList, event: DragEvent) => void} */
26
+ #onDropCallback;
27
+ /** @type {(event: DragEvent) => void} */
28
+ #onEnterCallback;
29
+ /** @type {(event: DragEvent) => void} */
30
+ #onLeaveCallback;
31
+ /** @type {boolean} */
32
+ #isDragging;
33
+ /** @type {boolean} */
34
+ #bound;
35
+ /**
36
+ * Creates a new instance of TinyDragDropDetector to handle drag-and-drop file detection.
37
+ *
38
+ * @param {DragAndDropOptions} [options={}] - Configuration options for the detector.
39
+ * @throws {TypeError} If `target` is not an HTMLElement.
40
+ * @throws {TypeError} If `fullscreen` is not a boolean.
41
+ * @throws {TypeError} If `hoverClass` is not a string.
42
+ * @throws {TypeError} If `onDrop` is defined but not a function.
43
+ * @throws {TypeError} If `onEnter` is defined but not a function.
44
+ * @throws {TypeError} If `onLeave` is defined but not a function.
45
+ */
46
+ constructor(options = {}) {
47
+ const { target, fullscreen = true, hoverClass = 'dnd-hover', onDrop, onEnter, onLeave, } = options;
48
+ // Validate fullscreen
49
+ if (typeof fullscreen !== 'boolean')
50
+ throw new TypeError('The "fullscreen" option must be a boolean.');
51
+ // Validate target
52
+ const resolvedTarget = fullscreen ? document.body : target || document.body;
53
+ if (!(resolvedTarget instanceof HTMLElement))
54
+ throw new TypeError('The "target" option must be an instance of HTMLElement.');
55
+ // Validate hoverClass
56
+ if (typeof hoverClass !== 'string')
57
+ throw new TypeError('The "hoverClass" option must be a string.');
58
+ // Validate onDrop
59
+ if (typeof onDrop !== 'function')
60
+ throw new TypeError('The "onDrop" option must be a function.');
61
+ // Validate onEnter
62
+ if (typeof onEnter !== 'function')
63
+ throw new TypeError('The "onEnter" option must be a function.');
64
+ // Validate onLeave
65
+ if (typeof onLeave !== 'function')
66
+ throw new TypeError('The "onLeave" option must be a function.');
67
+ // Store properties
68
+ this.#target = resolvedTarget;
69
+ this.#fullscreen = fullscreen;
70
+ this.#hoverClass = hoverClass;
71
+ this.#onDropCallback = onDrop || (() => { });
72
+ this.#onEnterCallback = onEnter;
73
+ this.#onLeaveCallback = onLeave;
74
+ this.#isDragging = false;
75
+ this.#bound = false;
76
+ // Bind event handlers
77
+ this._handleDragEnter = this._handleDragEnter.bind(this);
78
+ this._handleDragOver = this._handleDragOver.bind(this);
79
+ this._handleDragLeave = this._handleDragLeave.bind(this);
80
+ this._handleDrop = this._handleDrop.bind(this);
81
+ this.#bindEvents();
82
+ }
83
+ /**
84
+ * Returns the current target DOM element where the listeners are attached.
85
+ * @returns {HTMLElement}
86
+ */
87
+ getTarget() {
88
+ return this.#target;
89
+ }
90
+ /**
91
+ * Returns the CSS class applied during drag hover.
92
+ * @returns {string}
93
+ */
94
+ getHoverClass() {
95
+ return this.#hoverClass;
96
+ }
97
+ /**
98
+ * Indicates whether the detector is operating in fullscreen mode.
99
+ * @returns {boolean}
100
+ */
101
+ isFullScreen() {
102
+ return this.#fullscreen;
103
+ }
104
+ /**
105
+ * Returns whether a drag operation is currently active over the target.
106
+ * @returns {boolean}
107
+ */
108
+ isDragging() {
109
+ return this.#isDragging;
110
+ }
111
+ /**
112
+ * Returns whether the event listeners are currently bound to the target.
113
+ * @returns {boolean}
114
+ */
115
+ bound() {
116
+ return this.#bound;
117
+ }
118
+ /**
119
+ * Binds the drag-and-drop event listeners to the target element.
120
+ * Automatically called on instantiation.
121
+ * @returns {void}
122
+ */
123
+ #bindEvents() {
124
+ if (this.#bound)
125
+ return;
126
+ const target = this.getTarget();
127
+ target.addEventListener('dragenter', this._handleDragEnter);
128
+ target.addEventListener('dragover', this._handleDragOver);
129
+ target.addEventListener('dragleave', this._handleDragLeave);
130
+ target.addEventListener('drop', this._handleDrop);
131
+ this.#bound = true;
132
+ }
133
+ /**
134
+ * Removes all previously attached drag-and-drop event listeners from the target.
135
+ * @returns {void}
136
+ */
137
+ #unbindEvents() {
138
+ if (!this.#bound)
139
+ return;
140
+ const target = this.getTarget();
141
+ target.removeEventListener('dragenter', this._handleDragEnter);
142
+ target.removeEventListener('dragover', this._handleDragOver);
143
+ target.removeEventListener('dragleave', this._handleDragLeave);
144
+ target.removeEventListener('drop', this._handleDrop);
145
+ this.#bound = false;
146
+ }
147
+ /**
148
+ * Handles the `dragenter` event.
149
+ * Adds the hover CSS class and triggers the `onEnter` callback if provided.
150
+ * @private
151
+ * @param {DragEvent} event - The dragenter event.
152
+ * @returns {void}
153
+ */
154
+ _handleDragEnter(event) {
155
+ event.preventDefault();
156
+ if (!this.#isDragging) {
157
+ const target = this.getTarget();
158
+ this.#isDragging = true;
159
+ target.classList.add(this.#hoverClass);
160
+ this.#onEnterCallback(event);
161
+ }
162
+ }
163
+ /**
164
+ * Handles the `dragover` event.
165
+ * Prevents default to allow drop and sets the drop effect.
166
+ * @private
167
+ * @param {DragEvent} event - The dragover event.
168
+ * @returns {void}
169
+ */
170
+ _handleDragOver(event) {
171
+ event.preventDefault(); // Required to allow drop
172
+ if (!event.dataTransfer) {
173
+ console.warn('[TinyDragDropDetector] [handleDragOver] DragOver event missing dataTransfer.');
174
+ return;
175
+ }
176
+ event.dataTransfer.dropEffect = 'copy';
177
+ }
178
+ /**
179
+ * Handles the `dragleave` event.
180
+ * Removes the hover class and triggers the `onLeave` callback if provided.
181
+ * @private
182
+ * @param {DragEvent} event - The dragleave event.
183
+ * @returns {void}
184
+ */
185
+ _handleDragLeave(event) {
186
+ event.preventDefault();
187
+ const target = this.getTarget();
188
+ // Check if you've completely left the area
189
+ // @ts-ignore
190
+ if (event.relatedTarget === null || !target.contains(event.relatedTarget)) {
191
+ this.#isDragging = false;
192
+ target.classList.remove(this.#hoverClass);
193
+ this.#onLeaveCallback(event);
194
+ }
195
+ }
196
+ /**
197
+ * Handles the `drop` event.
198
+ * Removes the hover class, resets dragging state, and triggers the `onDrop` callback.
199
+ * @private
200
+ * @param {DragEvent} event - The drop event.
201
+ * @returns {void}
202
+ */
203
+ _handleDrop(event) {
204
+ event.preventDefault();
205
+ if (!event.dataTransfer) {
206
+ console.warn('[TinyDragDropDetector] [handleDrop] DragOver event missing dataTransfer.');
207
+ return;
208
+ }
209
+ const target = this.getTarget();
210
+ this.#isDragging = false;
211
+ target.classList.remove(this.#hoverClass);
212
+ const files = event.dataTransfer.files;
213
+ if (files.length > 0) {
214
+ this.#onDropCallback(files, event);
215
+ }
216
+ }
217
+ /**
218
+ * Destroys the detector instance, unbinding all event listeners and cleaning up.
219
+ * Should be called when the detector is no longer needed to avoid memory leaks.
220
+ * @returns {void}
221
+ */
222
+ destroy() {
223
+ this.#unbindEvents();
224
+ const target = this.getTarget();
225
+ target.classList.remove(this.#hoverClass);
226
+ }
227
+ }
228
+ export default TinyDragDropDetector;