mnfst 0.5.225 → 0.5.227

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.
@@ -1,488 +0,0 @@
1
- /* Manifest Resizer */
2
-
3
- (function () {
4
-
5
-
6
- function initializeResizablePlugin() {
7
- // Cache for unit conversions to avoid repeated DOM manipulation
8
- const unitCache = new Map();
9
- let tempConversionEl = null;
10
-
11
- // Helper to parse value and unit from CSS dimension
12
- const parseDimension = (value) => {
13
- if (typeof value === 'number') return { value, unit: 'px' };
14
- const match = String(value).match(/^([\d.]+)(.*)$/);
15
- return match ? { value: parseFloat(match[1]), unit: match[2] || 'px' } : { value: 0, unit: 'px' };
16
- };
17
-
18
- // Helper to convert any unit to pixels (cached and optimized)
19
- const convertToPixels = (value, unit) => {
20
- if (unit === 'px') return value;
21
-
22
- const cacheKey = `${value}${unit}`;
23
- if (unitCache.has(cacheKey)) {
24
- return unitCache.get(cacheKey);
25
- }
26
-
27
- // Use a single cached conversion element
28
- if (!tempConversionEl) {
29
- tempConversionEl = document.createElement('div');
30
- tempConversionEl.style.cssText = 'visibility:hidden;position:absolute;top:-9999px;left:-9999px;width:0;height:0;';
31
- document.body.appendChild(tempConversionEl);
32
- }
33
-
34
- tempConversionEl.style.width = `${value}${unit}`;
35
- const pixels = tempConversionEl.getBoundingClientRect().width;
36
-
37
- unitCache.set(cacheKey, pixels);
38
- return pixels;
39
- };
40
-
41
- // Helper to convert pixels back to original unit (cached)
42
- const convertFromPixels = (pixels, unit, element) => {
43
- if (unit === 'px') return pixels;
44
-
45
- const cacheKey = `${pixels}${unit}${element.tagName}`;
46
- if (unitCache.has(cacheKey)) {
47
- return unitCache.get(cacheKey);
48
- }
49
-
50
- let result;
51
- switch (unit) {
52
- case '%':
53
- result = (pixels / element.parentElement.getBoundingClientRect().width) * 100;
54
- break;
55
- case 'rem':
56
- const remSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
57
- result = pixels / remSize;
58
- break;
59
- case 'em':
60
- const emSize = parseFloat(getComputedStyle(element).fontSize);
61
- result = pixels / emSize;
62
- break;
63
- default:
64
- result = pixels;
65
- }
66
-
67
- unitCache.set(cacheKey, result);
68
- return result;
69
- };
70
-
71
- Alpine.directive('resize', (el, { modifiers, expression }, { evaluate }) => {
72
- // Store configuration on the element for lazy initialization
73
- el._resizeConfig = {
74
- expression,
75
- evaluate,
76
- handles: null,
77
- initialized: false
78
- };
79
-
80
- // Load saved width and height immediately if specified
81
- if (expression) {
82
- try {
83
- const options = evaluate(expression);
84
- if (options) {
85
- if (options.saveWidth) {
86
- const savedWidth = localStorage.getItem(`resizable-${options.saveWidth}`);
87
- if (savedWidth) {
88
- // Preserve the original unit if saved
89
- const [value, unit] = savedWidth.split('|');
90
- el.style.width = `${value}${unit || 'px'}`;
91
- }
92
- }
93
- if (options.saveHeight) {
94
- const savedHeight = localStorage.getItem(`resizable-${options.saveHeight}`);
95
- if (savedHeight) {
96
- // Preserve the original unit if saved
97
- const [value, unit] = savedHeight.split('|');
98
- el.style.height = `${value}${unit || 'px'}`;
99
- }
100
- }
101
- }
102
- } catch (error) {
103
- // Ignore parsing errors here, they'll be handled in initializeResizeElement
104
- }
105
- }
106
-
107
- // Add hover listener to create handles on first interaction
108
- el.addEventListener('mouseenter', initializeResizeElement, { once: true });
109
- });
110
-
111
- function initializeResizeElement(event) {
112
- const el = event.target;
113
- const config = el._resizeConfig;
114
- if (config.initialized) return;
115
-
116
- config.initialized = true;
117
-
118
- // Helper to parse value and unit from CSS dimension
119
- const parseDimension = (value) => {
120
- if (typeof value === 'number') return { value, unit: 'px' };
121
- const match = String(value).match(/^([\d.]+)(.*)$/);
122
- return match ? { value: parseFloat(match[1]), unit: match[2] || 'px' } : { value: 0, unit: 'px' };
123
- };
124
-
125
- // Parse options from expression or use defaults
126
- let options = {};
127
- if (config.expression) {
128
- try {
129
- options = config.evaluate(config.expression);
130
- } catch (error) {
131
- console.error('Error parsing x-resize expression:', config.expression, error);
132
- options = {};
133
- }
134
- }
135
- const {
136
- snapDistance = 0,
137
- snapPoints = [],
138
- snapCloseX = null,
139
- snapDistanceX = null,
140
- snapDistanceY = null,
141
- snapPointsX = [],
142
- snapPointsY = [],
143
- snapCloseY = null,
144
- toggle = null,
145
- handles = ['top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'],
146
- saveWidth = null,
147
- saveHeight = null
148
- } = options;
149
-
150
- // Store handles for cleanup
151
- config.handles = [];
152
-
153
- // Parse constraints with units
154
- const constraints = {
155
- closeX: snapCloseX ? parseDimension(snapCloseX) : null,
156
- closeY: snapCloseY ? parseDimension(snapCloseY) : null
157
- };
158
-
159
- // Parse snap points with units
160
- const parsedSnapPoints = snapPoints.map(point => parseDimension(point));
161
- const parsedSnapPointsX = snapPointsX.map(point => parseDimension(point));
162
- const parsedSnapPointsY = snapPointsY.map(point => parseDimension(point));
163
-
164
- // Detect RTL context
165
- const isRTL = getComputedStyle(el).direction === 'rtl';
166
-
167
- // Handle mapping for resize behavior
168
- const handleMap = {
169
- // Physical directions (fixed)
170
- top: { edge: 'top', direction: 'vertical' },
171
- bottom: { edge: 'bottom', direction: 'vertical' },
172
- left: { edge: 'left', direction: 'horizontal' },
173
- right: { edge: 'right', direction: 'horizontal' },
174
-
175
- // Corners
176
- 'top-left': { edge: 'top-left', direction: 'both', edges: ['top', 'left'] },
177
- 'top-right': { edge: 'top-right', direction: 'both', edges: ['top', 'right'] },
178
- 'bottom-left': { edge: 'bottom-left', direction: 'both', edges: ['bottom', 'left'] },
179
- 'bottom-right': { edge: 'bottom-right', direction: 'both', edges: ['bottom', 'right'] },
180
-
181
- // Logical directions (RTL-aware)
182
- start: {
183
- edge: isRTL ? 'right' : 'left',
184
- direction: 'horizontal',
185
- logical: true
186
- },
187
- end: {
188
- edge: isRTL ? 'left' : 'right',
189
- direction: 'horizontal',
190
- logical: true
191
- },
192
-
193
- // Logical corners
194
- 'top-start': {
195
- edge: isRTL ? 'top-right' : 'top-left',
196
- direction: 'both',
197
- edges: isRTL ? ['top', 'right'] : ['top', 'left'],
198
- logical: true
199
- },
200
- 'top-end': {
201
- edge: isRTL ? 'top-left' : 'top-right',
202
- direction: 'both',
203
- edges: isRTL ? ['top', 'left'] : ['top', 'right'],
204
- logical: true
205
- },
206
- 'bottom-start': {
207
- edge: isRTL ? 'bottom-right' : 'bottom-left',
208
- direction: 'both',
209
- edges: isRTL ? ['bottom', 'right'] : ['bottom', 'left'],
210
- logical: true
211
- },
212
- 'bottom-end': {
213
- edge: isRTL ? 'bottom-left' : 'bottom-right',
214
- direction: 'both',
215
- edges: isRTL ? ['bottom', 'left'] : ['bottom', 'right'],
216
- logical: true
217
- }
218
- };
219
-
220
- // Create handles for each specified handle
221
- handles.forEach(handleName => {
222
- const handleInfo = handleMap[handleName];
223
- if (!handleInfo) return;
224
-
225
- const handle = document.createElement('span');
226
- handle.className = `resize-handle resize-handle-${handleName}`;
227
- handle.setAttribute('data-handle', handleName);
228
-
229
- let startX, startY, startWidth, startHeight;
230
- let currentSnap = null;
231
- let lastWidth, lastHeight;
232
-
233
- // Convert constraints to pixels for calculations
234
- const pixelConstraints = {
235
- closeX: constraints.closeX ? convertToPixels(constraints.closeX.value, constraints.closeX.unit) : null,
236
- closeY: constraints.closeY ? convertToPixels(constraints.closeY.value, constraints.closeY.unit) : null
237
- };
238
-
239
- // Convert snap points to pixels
240
- const pixelSnapPoints = parsedSnapPoints.map(point => ({
241
- value: convertToPixels(point.value, point.unit),
242
- unit: point.unit
243
- }));
244
- const pixelSnapPointsX = parsedSnapPointsX.map(point => ({
245
- value: convertToPixels(point.value, point.unit),
246
- unit: point.unit
247
- }));
248
- const pixelSnapPointsY = parsedSnapPointsY.map(point => ({
249
- value: convertToPixels(point.value, point.unit),
250
- unit: point.unit
251
- }));
252
-
253
- const snapDistancePixels = convertToPixels(snapDistance, 'px');
254
- const snapDistanceXPixels = snapDistanceX ? convertToPixels(snapDistanceX, 'px') : snapDistancePixels;
255
- const snapDistanceYPixels = snapDistanceY ? convertToPixels(snapDistanceY, 'px') : snapDistancePixels;
256
-
257
- const handleMouseDown = (e) => {
258
- e.preventDefault();
259
- e.stopPropagation();
260
-
261
- el.classList.add('resizable-dragging');
262
-
263
- startX = e.clientX;
264
- startY = e.clientY;
265
- startWidth = el.getBoundingClientRect().width;
266
- startHeight = el.getBoundingClientRect().height;
267
-
268
- // Each drag starts with clean snap state
269
- currentSnap = null;
270
- lastWidth = startWidth;
271
- lastHeight = startHeight;
272
-
273
- // Show overlay
274
- const overlay = document.querySelector('.resize-overlay') || createOverlay();
275
- overlay.style.display = 'block';
276
- document.body.appendChild(overlay);
277
-
278
- document.addEventListener('mousemove', handleMouseMove);
279
- document.addEventListener('mouseup', handleMouseUp);
280
- };
281
-
282
- const handleMouseMove = (e) => {
283
- const deltaX = e.clientX - startX;
284
- const deltaY = e.clientY - startY;
285
-
286
- let newWidth = startWidth;
287
- let newHeight = startHeight;
288
-
289
- // Calculate new dimensions based on handle type
290
- if (handleInfo.direction === 'horizontal' || handleInfo.direction === 'both') {
291
- if (handleInfo.edge === 'left' || handleInfo.edge === 'top-left' || handleInfo.edge === 'bottom-left') {
292
- newWidth = startWidth - deltaX;
293
- } else if (handleInfo.edge === 'right' || handleInfo.edge === 'top-right' || handleInfo.edge === 'bottom-right') {
294
- newWidth = startWidth + deltaX;
295
- }
296
- }
297
-
298
- if (handleInfo.direction === 'vertical' || handleInfo.direction === 'both') {
299
- if (handleInfo.edge === 'top' || handleInfo.edge === 'top-left' || handleInfo.edge === 'top-right') {
300
- newHeight = startHeight - deltaY;
301
- } else if (handleInfo.edge === 'bottom' || handleInfo.edge === 'bottom-left' || handleInfo.edge === 'bottom-right') {
302
- newHeight = startHeight + deltaY;
303
- }
304
- }
305
-
306
- // Handle snap-close behavior for width
307
- if (pixelConstraints.closeX !== null && newWidth <= pixelConstraints.closeX) {
308
- // Close only while shrinking toward the close edge
309
- if (newWidth < lastWidth || currentSnap === 'closing') {
310
- el.classList.add('resizable-closing');
311
- currentSnap = 'closing';
312
-
313
- if (toggle) {
314
- config.evaluate(`${toggle} = false`);
315
- }
316
-
317
- el.dispatchEvent(new CustomEvent('resize', {
318
- detail: {
319
- width: newWidth,
320
- height: newHeight,
321
- unit: 'px',
322
- snap: currentSnap,
323
- closing: true
324
- }
325
- }));
326
- }
327
- lastWidth = newWidth;
328
- lastHeight = newHeight;
329
- return; // Exit early to prevent further width calculations
330
- }
331
-
332
- // Handle snap-close behavior for height
333
- if (pixelConstraints.closeY !== null && newHeight <= pixelConstraints.closeY) {
334
- // Close only while shrinking toward the close edge
335
- if (newHeight < lastHeight || currentSnap === 'closing') {
336
- el.classList.add('resizable-closing');
337
- currentSnap = 'closing';
338
-
339
- if (toggle) {
340
- config.evaluate(`${toggle} = false`);
341
- }
342
-
343
- el.dispatchEvent(new CustomEvent('resize', {
344
- detail: {
345
- width: newWidth,
346
- height: newHeight,
347
- unit: 'px',
348
- snap: currentSnap,
349
- closing: true
350
- }
351
- }));
352
- }
353
- lastWidth = newWidth;
354
- lastHeight = newHeight;
355
- return; // Exit early to prevent further height calculations
356
- }
357
-
358
- // Above close thresholds: clear any closing state
359
- if (currentSnap === 'closing') {
360
- currentSnap = null;
361
- }
362
-
363
- // Apply constraints only if we're not closing
364
- // Note: maxWidth and maxHeight are now handled by CSS (e.g., Tailwind classes)
365
-
366
- // Handle normal snap points for width
367
- const widthSnapPoints = pixelSnapPointsX.length > 0 ? pixelSnapPointsX : pixelSnapPoints;
368
- const widthSnapDistance = snapDistanceXPixels;
369
- for (const point of widthSnapPoints) {
370
- const distance = Math.abs(newWidth - point.value);
371
- if (distance < widthSnapDistance) {
372
- newWidth = point.value;
373
- currentSnap = `${convertFromPixels(newWidth, point.unit, el)}${point.unit}`;
374
- break;
375
- }
376
- }
377
-
378
- // Handle normal snap points for height
379
- const heightSnapPoints = pixelSnapPointsY.length > 0 ? pixelSnapPointsY : pixelSnapPoints;
380
- const heightSnapDistance = snapDistanceYPixels;
381
- for (const point of heightSnapPoints) {
382
- const distance = Math.abs(newHeight - point.value);
383
- if (distance < heightSnapDistance) {
384
- newHeight = point.value;
385
- currentSnap = `${convertFromPixels(newHeight, point.unit, el)}${point.unit}`;
386
- break;
387
- }
388
- }
389
-
390
- // Convert back to original unit for display
391
- el.style.width = `${newWidth}px`;
392
- el.style.height = `${newHeight}px`;
393
- lastWidth = newWidth;
394
- lastHeight = newHeight;
395
- el.classList.remove('resizable-closing', 'resizable-closed');
396
- if (toggle) {
397
- config.evaluate(`${toggle} = true`);
398
- }
399
-
400
- if (currentSnap !== 'closing') {
401
- if (saveWidth) {
402
- localStorage.setItem(`resizable-${saveWidth}`,
403
- `${newWidth}|px`);
404
- }
405
- if (saveHeight) {
406
- localStorage.setItem(`resizable-${saveHeight}`,
407
- `${newHeight}|px`);
408
- }
409
- }
410
-
411
- // Dispatch resize event
412
- el.dispatchEvent(new CustomEvent('resize', {
413
- detail: {
414
- width: newWidth,
415
- height: newHeight,
416
- unit: 'px',
417
- snap: currentSnap,
418
- closing: currentSnap === 'closing'
419
- }
420
- }));
421
- };
422
-
423
- const handleMouseUp = () => {
424
- document.removeEventListener('mousemove', handleMouseMove);
425
- document.removeEventListener('mouseup', handleMouseUp);
426
-
427
- el.classList.remove('resizable-dragging');
428
-
429
- // Hide overlay
430
- const overlay = document.querySelector('.resize-overlay');
431
- if (overlay) {
432
- overlay.style.display = 'none';
433
- }
434
-
435
- if (currentSnap === 'closing') {
436
- el.classList.add('resizable-closed');
437
- }
438
- };
439
-
440
- handle.addEventListener('mousedown', handleMouseDown);
441
- el.appendChild(handle);
442
- config.handles.push(handle);
443
- });
444
- }
445
-
446
- function createOverlay() {
447
- const overlay = document.createElement('div');
448
- overlay.className = 'resize-overlay';
449
- overlay.style.display = 'none';
450
- return overlay;
451
- }
452
- }
453
-
454
- // Track initialization to prevent duplicates
455
- let resizePluginInitialized = false;
456
-
457
- function ensureResizePluginInitialized() {
458
- if (resizePluginInitialized) return;
459
- if (!window.Alpine || typeof window.Alpine.directive !== 'function') return;
460
-
461
- resizePluginInitialized = true;
462
- initializeResizablePlugin();
463
- }
464
-
465
- // Expose on window for loader to call if needed
466
- window.ensureResizePluginInitialized = ensureResizePluginInitialized;
467
-
468
- // Handle both DOMContentLoaded and alpine:init
469
- if (document.readyState === 'loading') {
470
- document.addEventListener('DOMContentLoaded', ensureResizePluginInitialized);
471
- }
472
-
473
- document.addEventListener('alpine:init', ensureResizePluginInitialized);
474
-
475
- // If Alpine is already initialized when this script loads, initialize immediately
476
- if (window.Alpine && typeof window.Alpine.directive === 'function') {
477
- setTimeout(ensureResizePluginInitialized, 0);
478
- } else {
479
- const checkAlpine = setInterval(() => {
480
- if (window.Alpine && typeof window.Alpine.directive === 'function') {
481
- clearInterval(checkAlpine);
482
- ensureResizePluginInitialized();
483
- }
484
- }, 10);
485
- setTimeout(() => clearInterval(checkAlpine), 5000);
486
- }
487
-
488
- })();