rails_modal_manager 1.0.12 → 1.0.14
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.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/rails_modal_manager.css +1 -0
- data/app/javascript/rails_modal_manager/controllers/rmm_modal_controller.js +66 -1
- data/app/javascript/rails_modal_manager/controllers/rmm_sidebar_controller.js +5 -0
- data/app/javascript/rails_modal_manager/history_stack_manager.js +32 -0
- data/lib/rails_modal_manager/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b5a9a0c23b9c295ce794dca604668be79268eab2b0ef9aa3a72bce9f31642d37
|
|
4
|
+
data.tar.gz: f341afe4a3bcf1661a80a60fbbd8ad2c34b187f6fe15d04df16c57f9273bafdc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4213097d0638e6e1656a3bab74608e7ab6adcc1aa521532fefbb0fc74e8d248d0e6a5a672f60f9d7a1b0a7a3dd345acdf6f5112ec74ea8a7a97fc3762cc8f913
|
|
7
|
+
data.tar.gz: 5c9bd6533b30f62eae37e28d6ae6532ed7942f74cb45d8d62db8dc6d31c35797322fb83db2e9c258599ef0b78c8ee16f565ae827bc2080a329019719c2a30e56
|
|
@@ -147,6 +147,9 @@ export default class extends Controller {
|
|
|
147
147
|
// Register close callback
|
|
148
148
|
modalStore.registerCloseCallback(modalId, () => this.close('programmatic'))
|
|
149
149
|
|
|
150
|
+
// Move to persistent container (outside Turbo Frame) to survive navigation
|
|
151
|
+
this.moveToChildModalsContainer()
|
|
152
|
+
|
|
150
153
|
// Add to history stack
|
|
151
154
|
if (this.enableHistoryStackValue && !historyStackManager.hasHisData('modal', modalId)) {
|
|
152
155
|
historyStackManager.addHisData('modal', modalId, () => this.close('history'))
|
|
@@ -499,6 +502,10 @@ export default class extends Controller {
|
|
|
499
502
|
if (!config || config.isMaximized) return
|
|
500
503
|
|
|
501
504
|
modalStore.bringToFront(this.effectiveModalId)
|
|
505
|
+
// 히스토리 스택 순서도 동기화
|
|
506
|
+
if (this.enableHistoryStackValue) {
|
|
507
|
+
historyStackManager.moveToTop('modal', this.effectiveModalId)
|
|
508
|
+
}
|
|
502
509
|
this.isDragging = true
|
|
503
510
|
|
|
504
511
|
const clientX = e.type.includes('touch') ? e.touches[0].clientX : e.clientX
|
|
@@ -562,6 +569,10 @@ export default class extends Controller {
|
|
|
562
569
|
if (!config || config.isMaximized) return
|
|
563
570
|
|
|
564
571
|
modalStore.bringToFront(this.effectiveModalId)
|
|
572
|
+
// 히스토리 스택 순서도 동기화
|
|
573
|
+
if (this.enableHistoryStackValue) {
|
|
574
|
+
historyStackManager.moveToTop('modal', this.effectiveModalId)
|
|
575
|
+
}
|
|
565
576
|
this.isResizing = true
|
|
566
577
|
this.resizeDirection = direction
|
|
567
578
|
|
|
@@ -682,9 +693,48 @@ export default class extends Controller {
|
|
|
682
693
|
historyStackManager.removeMultipleHisData('modal', allModalIds)
|
|
683
694
|
}
|
|
684
695
|
|
|
696
|
+
// Move modal DOM to persistent container (outside Turbo Frame)
|
|
697
|
+
// This ensures minimized modals survive Turbo Frame navigation
|
|
698
|
+
this.moveToChildModalsContainer()
|
|
699
|
+
|
|
685
700
|
this.dispatch('minimize', { detail: { modalId: modalId } })
|
|
686
701
|
}
|
|
687
702
|
|
|
703
|
+
/**
|
|
704
|
+
* Move modal (with wrapper if exists) to #child-modals-container
|
|
705
|
+
* This prevents DOM removal when Turbo Frame content is replaced
|
|
706
|
+
*/
|
|
707
|
+
moveToChildModalsContainer() {
|
|
708
|
+
const container = document.getElementById('child-modals-container')
|
|
709
|
+
if (!container) return
|
|
710
|
+
|
|
711
|
+
const overlay = this.getOverlay()
|
|
712
|
+
const parent = this.element.parentElement
|
|
713
|
+
|
|
714
|
+
// Determine what to move: wrapper (if exists) or just modal
|
|
715
|
+
let elementToMove = this.element
|
|
716
|
+
|
|
717
|
+
// Check if parent is a wrapper (has data-controller and is not body/frame/container)
|
|
718
|
+
if (parent &&
|
|
719
|
+
parent.dataset.controller &&
|
|
720
|
+
parent.id !== 'child-modals-container' &&
|
|
721
|
+
parent.tagName !== 'TURBO-FRAME' &&
|
|
722
|
+
parent.tagName !== 'BODY') {
|
|
723
|
+
elementToMove = parent
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// Skip if already in container
|
|
727
|
+
if (elementToMove.parentElement === container) return
|
|
728
|
+
|
|
729
|
+
// If overlay is outside the element to move, move it first
|
|
730
|
+
if (overlay && !elementToMove.contains(overlay) && overlay.parentElement !== container) {
|
|
731
|
+
container.appendChild(overlay)
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Move the element (modal or wrapper including overlay)
|
|
735
|
+
container.appendChild(elementToMove)
|
|
736
|
+
}
|
|
737
|
+
|
|
688
738
|
maximize() {
|
|
689
739
|
const modalId = this.effectiveModalId
|
|
690
740
|
const config = modalStore.getModalConfig(modalId)
|
|
@@ -756,6 +806,10 @@ export default class extends Controller {
|
|
|
756
806
|
|
|
757
807
|
handleClick() {
|
|
758
808
|
modalStore.bringToFront(this.effectiveModalId)
|
|
809
|
+
// 히스토리 스택 순서도 동기화 (뒤로가기 시 현재 최상위 모달이 닫히도록)
|
|
810
|
+
if (this.enableHistoryStackValue) {
|
|
811
|
+
historyStackManager.moveToTop('modal', this.effectiveModalId)
|
|
812
|
+
}
|
|
759
813
|
}
|
|
760
814
|
|
|
761
815
|
// ============================================
|
|
@@ -777,7 +831,18 @@ export default class extends Controller {
|
|
|
777
831
|
// ============================================
|
|
778
832
|
|
|
779
833
|
getOverlay() {
|
|
780
|
-
|
|
834
|
+
const overlayId = `${this.effectiveModalId}-overlay`
|
|
835
|
+
|
|
836
|
+
// If this modal is inside child-modals-container, search there first
|
|
837
|
+
// This prevents finding duplicate overlays in turbo-frame
|
|
838
|
+
const container = document.getElementById('child-modals-container')
|
|
839
|
+
if (container && container.contains(this.element)) {
|
|
840
|
+
const overlayInContainer = container.querySelector(`#${overlayId}`)
|
|
841
|
+
if (overlayInContainer) return overlayInContainer
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// Fallback to document-level search
|
|
845
|
+
return document.getElementById(overlayId)
|
|
781
846
|
}
|
|
782
847
|
|
|
783
848
|
hasAttribute(attr) {
|
|
@@ -31,6 +31,11 @@ export default class extends Controller {
|
|
|
31
31
|
connect() {
|
|
32
32
|
this.currentItemId = null
|
|
33
33
|
|
|
34
|
+
// 모바일 사이즈(768px 미만)에서는 기본적으로 사이드바를 닫힌 상태로 시작
|
|
35
|
+
if (window.innerWidth < 768) {
|
|
36
|
+
this.collapsedValue = true
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
if (this.collapsedValue) {
|
|
35
40
|
this.element.classList.add('rmm-sidebar-collapsed')
|
|
36
41
|
}
|
|
@@ -285,6 +285,37 @@ function hasHisData(type, id) {
|
|
|
285
285
|
return hisData.some((item) => item.type === type && item.id === id);
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Move specific item to the top of the history stack
|
|
290
|
+
* - Used when a modal is brought to front (clicked/focused)
|
|
291
|
+
* - Does not affect browser history, only reorders the internal stack
|
|
292
|
+
*
|
|
293
|
+
* @param {string} type - Target type
|
|
294
|
+
* @param {string} id - Target's unique ID
|
|
295
|
+
* @returns {boolean} Whether move was successful
|
|
296
|
+
*/
|
|
297
|
+
function moveToTop(type, id) {
|
|
298
|
+
if (typeof window === 'undefined') return false;
|
|
299
|
+
if (!isEnabledForDevice(type)) return false;
|
|
300
|
+
|
|
301
|
+
const hisData = loadHisData();
|
|
302
|
+
const index = hisData.findIndex(
|
|
303
|
+
(item) => item.type === type && item.id === id
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
if (index === -1) return false;
|
|
307
|
+
|
|
308
|
+
// Already at top
|
|
309
|
+
if (index === hisData.length - 1) return true;
|
|
310
|
+
|
|
311
|
+
// Remove item from current position and add to end
|
|
312
|
+
const [item] = hisData.splice(index, 1);
|
|
313
|
+
hisData.push(item);
|
|
314
|
+
saveHisData(hisData);
|
|
315
|
+
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
|
|
288
319
|
/**
|
|
289
320
|
* Return current stack size
|
|
290
321
|
* @returns {number} Stack size
|
|
@@ -362,6 +393,7 @@ const historyStackManager = {
|
|
|
362
393
|
removeMultipleHisData,
|
|
363
394
|
silentRemoveHisData,
|
|
364
395
|
popHisData,
|
|
396
|
+
moveToTop,
|
|
365
397
|
|
|
366
398
|
// Utilities
|
|
367
399
|
hasHisData,
|