rails_modal_manager 1.0.38 → 1.0.40

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e635b4d1de69eb311d4d9e6e4784019f6bd66318c0a2212dcd0b0e20c6f1f21
4
- data.tar.gz: b96cb63a48fde00310a2754d4fdd0810ee8a5021deaf7aab05d593fea6413343
3
+ metadata.gz: 0df266d9e80cbe4f6999522dfc7d42dd07614651f4e85fca57cd43bd59bd1f56
4
+ data.tar.gz: fd760622af26da416a71bf8928ae5247db821de551111f6b60d54c9f9462b01b
5
5
  SHA512:
6
- metadata.gz: 1fca82ee462c8aaedaebe54ccc4760a35efe957f04a98508dc100d618a08d9c0c7e0e9fa768ac0336d604110627dfd1554c3cc3bf2c414de71bb3b29c1a99823
7
- data.tar.gz: d7b73a297f1c4461bdec59e3fa9cb007f9102a39ffc6dc4938e6d4722ee67be5fbe149d1d3fef6773d771cd7ab2c2ffb128f2b476ba832b32e4679fdd8ab2701
6
+ metadata.gz: b121a1d40ea4d3f3f368e4f3cf69de017f2afa3fc999c3bc03377a376d0011912d970966e34d6d5310e42d5c65c2dc8aeeb1c5b398bfb7b53da14d5459d48a15
7
+ data.tar.gz: 169d8b9067a9ea55f0749324e1a349a634f0741a42c776b30e9410478dc20e6d0f1be3f50d2f0c30a048a4a00a45ee2cc9db92f10e1759de3817294e2b2e2fde
@@ -48,6 +48,8 @@ export default class extends Controller {
48
48
  this.previousFocus = null
49
49
  this.isDragging = false
50
50
  this.isResizing = false
51
+ this.isClosing = false
52
+ this.closeTimeout = null
51
53
  this.dragStart = { x: 0, y: 0 }
52
54
  this.initialPos = { top: 0, left: 0 }
53
55
  this.resizeDirection = null
@@ -107,6 +109,12 @@ export default class extends Controller {
107
109
  open() {
108
110
  const modalId = this.effectiveModalId
109
111
 
112
+ // 닫기 애니메이션 중이면 취소하고 다시 열기
113
+ if (this.isClosing) {
114
+ this.cancelClose()
115
+ return
116
+ }
117
+
110
118
  if (modalStore.getModalConfig(modalId)) {
111
119
  return // Already open
112
120
  }
@@ -177,6 +185,12 @@ export default class extends Controller {
177
185
  close(source = 'button') {
178
186
  const modalId = this.effectiveModalId
179
187
 
188
+ // 이미 닫는 중이면 무시
189
+ if (this.isClosing) return
190
+
191
+ // store에 없으면 이미 닫힌 상태
192
+ if (!modalStore.getModalConfig(modalId)) return
193
+
180
194
  // Allow closing from programmatic source, footer button, or if closable is true
181
195
  if (!this.closableValue && source !== 'programmatic' && source !== 'footer') {
182
196
  return
@@ -188,6 +202,9 @@ export default class extends Controller {
188
202
  return
189
203
  }
190
204
 
205
+ // 닫기 시작
206
+ this.isClosing = true
207
+
191
208
  // Get all descendants to close them too
192
209
  const descendants = modalStore.getAllDescendants(modalId)
193
210
 
@@ -402,7 +419,13 @@ export default class extends Controller {
402
419
  modal.classList.remove('rmm-active')
403
420
  if (overlay) overlay.classList.remove('rmm-active')
404
421
 
405
- setTimeout(() => {
422
+ // 타이머 저장 (취소 가능하도록)
423
+ this.closeTimeout = setTimeout(() => {
424
+ this.closeTimeout = null
425
+
426
+ // 닫기가 취소되었으면 콜백 실행 안 함
427
+ if (!this.isClosing) return
428
+
406
429
  // 애니메이션 완료 후 드래그로 인한 커스텀 위치 클래스 및 인라인 스타일 제거
407
430
  modal.classList.remove('rmm-custom-position')
408
431
  modal.classList.remove('rmm-dragging')
@@ -416,10 +439,32 @@ export default class extends Controller {
416
439
  this.openValue = false
417
440
  this._closingProgrammatically = false
418
441
 
442
+ // 닫기 완료
443
+ this.isClosing = false
444
+
419
445
  if (callback) callback()
420
446
  }, this.animationDurationValue)
421
447
  }
422
448
 
449
+ /**
450
+ * Cancel ongoing close animation and restore modal visibility
451
+ * Called when open() is triggered during close animation
452
+ */
453
+ cancelClose() {
454
+ if (this.closeTimeout) {
455
+ clearTimeout(this.closeTimeout)
456
+ this.closeTimeout = null
457
+ }
458
+ this.isClosing = false
459
+
460
+ // UI 다시 활성화
461
+ const modal = this.element
462
+ const overlay = this.getOverlay()
463
+
464
+ modal.classList.add('rmm-active')
465
+ if (overlay) overlay.classList.add('rmm-active')
466
+ }
467
+
423
468
  /**
424
469
  * Reset sidebar and submenu controllers to first item
425
470
  * Called when modal is closed to ensure clean state on next open
@@ -240,9 +240,19 @@ export default class extends Controller {
240
240
  e.stopPropagation()
241
241
  const modalId = e.currentTarget.dataset.modalId
242
242
  if (modalId) {
243
- const confirmed = window.confirm('이 모달을 닫으시겠습니까?')
244
- if (confirmed) {
245
- modalStore.closeModalWithDescendants(modalId)
243
+ // 해당 그룹이 복구된 상태인지 확인
244
+ const groups = modalStore.getMinimizedModalGroups()
245
+ const group = groups.find(g => g.rootModalId === modalId)
246
+
247
+ if (group && group.isRestored) {
248
+ // 복구된 상태: taskbar에서만 제거, 모달은 유지
249
+ modalStore.clearMinimizedStateGroup(modalId)
250
+ } else {
251
+ // 최소화 상태: 확인 후 모달 닫기
252
+ const confirmed = window.confirm('이 모달을 닫으시겠습니까?')
253
+ if (confirmed) {
254
+ modalStore.closeModalWithDescendants(modalId)
255
+ }
246
256
  }
247
257
  }
248
258
  }
@@ -575,6 +575,29 @@ class ModalStore {
575
575
  this.notify();
576
576
  }
577
577
 
578
+ /**
579
+ * Clear minimized state for a modal group (remove from taskbar but keep modal open)
580
+ * Used when closing taskbar item for a restored (visible) modal
581
+ * @param {string} modalId - Any modal ID in the group
582
+ */
583
+ clearMinimizedStateGroup(modalId) {
584
+ const rootId = this.getRootModal(modalId);
585
+ const descendants = this.getAllDescendants(rootId);
586
+ const allModalIds = [rootId, ...descendants];
587
+
588
+ // isMinimized와 isRestored 모두 false로 설정 (taskbar에서 제거, 모달은 유지)
589
+ allModalIds.forEach(id => {
590
+ if (this.activeModals[id]) {
591
+ this.activeModals[id].isMinimized = false;
592
+ this.activeModals[id].isRestored = false;
593
+ delete this.activeModals[id].minimizedAt;
594
+ }
595
+ });
596
+
597
+ this.updateBodyScroll();
598
+ this.notify();
599
+ }
600
+
578
601
  getMinimizedModalGroups() {
579
602
  const minimizedRoots = new Set();
580
603
  const processedModals = new Set();
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsModalManager
4
- VERSION = "1.0.38"
4
+ VERSION = "1.0.40"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_modal_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.38
4
+ version: 1.0.40
5
5
  platform: ruby
6
6
  authors:
7
7
  - reshacs