@eturnity/eturnity_reusable_components 9.25.6 → 9.25.7

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_reusable_components",
3
- "version": "9.25.6",
3
+ "version": "9.25.7",
4
4
  "files": [
5
5
  "dist",
6
6
  "src"
@@ -12,12 +12,13 @@
12
12
  <DotItem />
13
13
  <DotItem />
14
14
  </ButtonContainer>
15
- <DropdownContainer
16
- ref="dropdownContainer"
17
- :container-width="childOpen ? 440 : 240"
18
- @click.stop
19
- >
20
- <template v-if="isOpen">
15
+ <Teleport to="body">
16
+ <DropdownContainer
17
+ v-if="isOpen"
18
+ ref="dropdownContainer"
19
+ :container-width="childOpen ? 440 : 240"
20
+ @click.stop
21
+ >
21
22
  <LoadingContainer v-if="isLoading">
22
23
  <Spinner />
23
24
  </LoadingContainer>
@@ -82,8 +83,8 @@
82
83
  </span>
83
84
  </OptionItem>
84
85
  </OptionsContainer>
85
- </template>
86
- </DropdownContainer>
86
+ </DropdownContainer>
87
+ </Teleport>
87
88
  </PageContainer>
88
89
  </template>
89
90
 
@@ -194,8 +195,10 @@
194
195
  containerWidth: Number,
195
196
  }
196
197
  const DropdownContainer = styled('div', dropdownAttrs)`
197
- z-index: 99;
198
- position: absolute;
198
+ z-index: 9999;
199
+ position: fixed;
200
+ top: 0;
201
+ left: 0;
199
202
  display: grid;
200
203
  grid-template-columns: auto auto;
201
204
  `
@@ -382,19 +385,36 @@
382
385
  theme,
383
386
  }
384
387
  },
388
+ beforeUnmount() {
389
+ this.removeListeners()
390
+ },
385
391
  methods: {
386
392
  toggleButton() {
387
393
  this.isOpen = !this.isOpen
388
394
 
389
395
  if (this.isOpen) {
390
- this.setContextMenuPosition()
396
+ this.$nextTick(() => this.setContextMenuPosition())
391
397
  window.addEventListener('resize', this.toggleButton)
398
+ window.addEventListener('scroll', this.onWindowScroll, true)
392
399
  document.addEventListener('click', this.clickOutside)
393
400
  } else {
394
- window.removeEventListener('resize', this.toggleButton)
395
- document.removeEventListener('click', this.clickOutside)
401
+ this.removeListeners()
396
402
  }
397
403
  },
404
+ removeListeners() {
405
+ window.removeEventListener('resize', this.toggleButton)
406
+ window.removeEventListener('scroll', this.onWindowScroll, true)
407
+ document.removeEventListener('click', this.clickOutside)
408
+ },
409
+ onWindowScroll(event) {
410
+ // Scrolling inside the options list must not close the dropdown
411
+ const dropdownRef = this.$refs.dropdownContainer
412
+ const contextMenu = dropdownRef?.$el ?? dropdownRef
413
+ if (contextMenu && contextMenu.contains(event.target)) {
414
+ return
415
+ }
416
+ this.toggleButton()
417
+ },
398
418
  setContextMenuPosition() {
399
419
  const dropdownRef = this.$refs.dropdownContainer
400
420
  const pageRef = this.$refs.pageContainer
@@ -408,70 +428,39 @@
408
428
  return
409
429
  }
410
430
  const rectButton = button.getBoundingClientRect()
411
- const relativeParent =
412
- this.findRelativeParent(contextMenu) || document.documentElement
413
- if (
414
- !relativeParent ||
415
- typeof relativeParent.getBoundingClientRect !== 'function'
416
- ) {
417
- return
418
- }
419
- const rectRelativeParent = relativeParent.getBoundingClientRect()
420
431
 
421
432
  const positionArray = this.determineElementQuarter(button, rectButton)
422
433
  contextMenu.style.transform = ''
423
434
  if (this.dropdownPosition == 'vertical') {
424
435
  // Position horizontally (left/right/center)
425
436
  if (positionArray.includes('left')) {
426
- contextMenu.style.left =
427
- rectButton.left - rectRelativeParent.left + 'px'
437
+ contextMenu.style.left = rectButton.left + 'px'
428
438
  } else {
429
- contextMenu.style.left =
430
- rectButton.right - rectRelativeParent.left + 'px'
439
+ contextMenu.style.left = rectButton.right + 'px'
431
440
  contextMenu.style.transform = 'translateX(-100%)'
432
441
  }
433
442
  // Position vertically (above/below)
434
443
  if (positionArray.includes('top')) {
435
- contextMenu.style.top =
436
- rectButton.bottom - rectRelativeParent.top + 5 + 'px'
444
+ contextMenu.style.top = rectButton.bottom + 5 + 'px'
437
445
  } else {
438
- contextMenu.style.top =
439
- rectButton.top - rectRelativeParent.top - 5 + 'px'
446
+ contextMenu.style.top = rectButton.top - 5 + 'px'
440
447
  contextMenu.style.transform += ' translateY(-100%)'
441
448
  }
442
449
  } else {
443
450
  if (positionArray.includes('left')) {
444
- contextMenu.style.left =
445
- rectButton.right - rectRelativeParent.left + 5 + 'px'
451
+ contextMenu.style.left = rectButton.right + 5 + 'px'
446
452
  } else {
447
- contextMenu.style.left =
448
- rectButton.left - rectRelativeParent.left - 5 + 'px'
453
+ contextMenu.style.left = rectButton.left - 5 + 'px'
449
454
  contextMenu.style.transform = 'translateX(-100%)'
450
455
  }
451
456
  if (positionArray.includes('top')) {
452
- contextMenu.style.top =
453
- rectButton.top - rectRelativeParent.top + 'px'
457
+ contextMenu.style.top = rectButton.top + 'px'
454
458
  } else {
455
- contextMenu.style.top =
456
- rectButton.bottom - rectRelativeParent.top + 'px'
459
+ contextMenu.style.top = rectButton.bottom + 'px'
457
460
  contextMenu.style.transform += ' translateY(-100%)'
458
461
  }
459
462
  }
460
463
  },
461
- findRelativeParent(element) {
462
- while (element.parentElement) {
463
- if (
464
- window.getComputedStyle(element.parentElement).position ===
465
- 'relative' ||
466
- window.getComputedStyle(element.parentElement).position ===
467
- 'absolute'
468
- ) {
469
- return element.parentElement
470
- }
471
- element = element.parentElement
472
- }
473
- return null
474
- },
475
464
  determineElementQuarter(element, rect) {
476
465
  const viewportWidth = window.innerWidth
477
466
  const viewportHeight = window.innerHeight
@@ -509,7 +498,13 @@
509
498
  this.isOpen = false
510
499
  },
511
500
  clickOutside(event) {
512
- if (this.$el.contains(event.target) || !this.isOpen) {
501
+ if (!this.isOpen || this.$el.contains(event.target)) {
502
+ return
503
+ }
504
+ // The dropdown is teleported to body, so it is not inside this.$el
505
+ const dropdownRef = this.$refs.dropdownContainer
506
+ const contextMenu = dropdownRef?.$el ?? dropdownRef
507
+ if (contextMenu && contextMenu.contains(event.target)) {
513
508
  return
514
509
  }
515
510
  this.toggleButton()