@easyquery/ui 7.4.0-rc01 → 7.4.0-rc02

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.
@@ -682,20 +682,20 @@ class MenuLevel {
682
682
  const applyItem = this._applyItem;
683
683
  //if multiselect option is on - then we should add special "apply" item
684
684
  if (multiselect && this.levelIndex === 0 && this.parentMenu.options.hideButtons !== true) {
685
- const applyDiv = document.createElement("div");
686
- applyDiv.classList.add(`${this.cssPrefix}-applyDiv`);
687
- applyDiv['menuItem'] = applyItem;
685
+ this.applyDiv = document.createElement("div");
686
+ this.applyDiv.classList.add(`${this.cssPrefix}-applyDiv`);
687
+ this.applyDiv['menuItem'] = applyItem;
688
688
  this.applyBtn = document.createElement('button');
689
689
  if (this.parentMenu.options.useDefaultStyles) {
690
- applyDiv.style.borderBottom = '1px solid';
691
- applyDiv.style.padding = '5px';
692
- applyDiv.style.marginBottom = '5px';
690
+ this.applyDiv.style.borderBottom = '1px solid';
691
+ this.applyDiv.style.padding = '5px';
692
+ this.applyDiv.style.marginBottom = '5px';
693
693
  this.applyBtn.style.padding = '0 5px';
694
694
  this.applyBtn.style.cursor = "pointer";
695
695
  }
696
696
  const applyTextNode = document.createTextNode(this.parentMenu.options.buttons.submit);
697
697
  this.applyBtn.appendChild(applyTextNode);
698
- applyDiv.appendChild(this.applyBtn);
698
+ this.applyDiv.appendChild(this.applyBtn);
699
699
  //cancel btn
700
700
  const cancelBtn = document.createElement('button');
701
701
  cancelBtn.classList.add(`${this.cssPrefix}-cancel`);
@@ -706,9 +706,9 @@ class MenuLevel {
706
706
  }
707
707
  const cancelText = document.createTextNode(this.parentMenu.options.buttons.cancel);
708
708
  cancelBtn.appendChild(cancelText);
709
- applyDiv.appendChild(cancelBtn);
710
- baseDiv.appendChild(applyDiv);
711
- applyItem.itemDiv = applyDiv;
709
+ this.applyDiv.appendChild(cancelBtn);
710
+ baseDiv.appendChild(this.applyDiv);
711
+ applyItem.itemDiv = this.applyDiv;
712
712
  this.applyBtn.addEventListener('click', () => {
713
713
  this.submit(this._applyItem);
714
714
  });
@@ -1436,78 +1436,52 @@ class MenuLevel {
1436
1436
  levelStyle.top = y + 'px';
1437
1437
  this.scrollDiv.style.width = "auto";
1438
1438
  this.scrollDiv.style.height = "auto";
1439
+ this.scrollDiv.style.maxHeight = null;
1439
1440
  const useMaxSpace = this.parentMenu.options.useMaxSpace;
1440
1441
  const viewportHeight = ui.getViewportSize().height;
1441
- const top = y - scrollY;
1442
- const bottom = viewportHeight - top;
1443
1442
  const anchorRect = anchor ? anchor.getBoundingClientRect() : null;
1444
1443
  const anchorHeight = anchorRect ? anchorRect.height : 0;
1445
- const magic = 24;
1446
- if (this.levelIndex > 0) {
1447
- let maxHeight = viewportHeight - 30;
1448
- if (this.searchDiv) {
1449
- maxHeight -= this.searchDiv.scrollHeight;
1450
- y -= this.searchDiv.scrollHeight;
1451
- }
1452
- if (this.closeDiv) {
1453
- maxHeight -= this.closeDiv.offsetHeight;
1454
- y -= this.closeDiv.offsetHeight;
1455
- }
1456
- this.scrollDiv.style.maxHeight = maxHeight + 'px';
1457
- levelStyle.top = this.adjustTopPos(y) + 'px';
1458
- }
1459
- else if (useMaxSpace) {
1460
- let maxHeight = viewportHeight - 30;
1461
- if (this.searchDiv) {
1462
- maxHeight -= this.searchDiv.scrollHeight;
1463
- }
1464
- if (this.closeDiv) {
1465
- maxHeight -= this.closeDiv.offsetHeight;
1466
- }
1467
- this.scrollDiv.style.maxHeight = maxHeight + 'px';
1468
- const levelDivRect = this.levelDiv.getBoundingClientRect();
1469
- const levelDivHeight = levelDivRect.height;
1470
- if (levelDivHeight < bottom - anchorHeight) {
1471
- levelStyle.top = y + anchorHeight + 'px';
1472
- }
1473
- else {
1474
- if (top < bottom) {
1475
- levelStyle.top = y - top + 5 + 'px';
1476
- }
1477
- else {
1478
- levelStyle.top = Math.max(5, viewportHeight - levelDivHeight - 30) + 'px';
1479
- }
1480
- }
1481
- }
1482
- else {
1483
- let maxHeight = Math.max(top, bottom) - magic;
1484
- if (this.searchDiv) {
1485
- maxHeight -= this.searchDiv.scrollHeight;
1486
- }
1487
- if (this.closeDiv) {
1488
- maxHeight -= this.closeDiv.offsetHeight;
1489
- }
1490
- // Рахуємо початковий контейнер
1491
- let levelDivRect = this.levelDiv.getBoundingClientRect();
1492
- if (levelDivRect.height < bottom - anchorHeight) {
1493
- // Контейнер може впасти вниз
1494
- this.scrollDiv.style.maxHeight = maxHeight - magic + 'px';
1495
- levelStyle.top = y + anchorHeight + 'px';
1496
- }
1497
- else {
1498
- // Визначаємо більший простір зверху чи знизу від анкора
1499
- if (top > bottom) {
1500
- // Падаємо вверх
1501
- this.scrollDiv.style.maxHeight = maxHeight + 'px';
1502
- levelDivRect = this.levelDiv.getBoundingClientRect();
1503
- levelStyle.top = y - levelDivRect.height + 'px'; // - anchorHeight
1504
- }
1505
- else {
1506
- // Падаємо вниз
1507
- this.scrollDiv.style.maxHeight = maxHeight - magic - anchorHeight + 'px';
1508
- levelStyle.top = y + anchorHeight + 'px';
1509
- }
1510
- }
1444
+ const upperSpace = y - scrollY;
1445
+ const lowerSpace = viewportHeight - upperSpace - anchorHeight;
1446
+ const minOffset = 15;
1447
+ // Рахуємо початковий контейнер
1448
+ let levelDivRect = this.levelDiv.getBoundingClientRect();
1449
+ if (this.levelIndex == 0 && levelDivRect.height < lowerSpace - minOffset) { //root level. Have enough space to drop down without scroll
1450
+ levelStyle.top = (y + anchorHeight) + 'px';
1451
+ }
1452
+ else if (this.levelIndex == 0 && levelDivRect.height < upperSpace - minOffset) { //root level. Have enough space to drop up without scroll
1453
+ levelStyle.top = (y - levelDivRect.height) + 'px';
1454
+ }
1455
+ else if (useMaxSpace || this.levelIndex > 0) { //sub-level or useMaxSpace option set. Use all the space
1456
+ const outsideBottom = levelDivRect.bottom + minOffset - scrollY - viewportHeight;
1457
+ if (outsideBottom > 0) {
1458
+ levelStyle.top = levelDivRect.top - outsideBottom + 'px';
1459
+ }
1460
+ levelDivRect = this.levelDiv.getBoundingClientRect();
1461
+ const outsideTop = scrollY + minOffset - levelDivRect.top;
1462
+ if (outsideTop > 0) {
1463
+ const scrollDivRect = this.scrollDiv.getBoundingClientRect();
1464
+ this.scrollDiv.style.maxHeight = scrollDivRect.height - outsideTop + 'px';
1465
+ levelStyle.top = levelDivRect.top + outsideTop + 'px';
1466
+ }
1467
+ }
1468
+ else if (upperSpace <= lowerSpace) { //root level. Drop down with scroll
1469
+ levelStyle.top = (y + anchorHeight) + 'px';
1470
+ const outsideBottom = levelDivRect.height + minOffset - lowerSpace;
1471
+ if (outsideBottom > 0) {
1472
+ const scrollDivRect = this.scrollDiv.getBoundingClientRect();
1473
+ this.scrollDiv.style.maxHeight = scrollDivRect.height - outsideBottom + 'px';
1474
+ }
1475
+ }
1476
+ else { //root level. Drop up with scroll
1477
+ y -= levelDivRect.height;
1478
+ const outsideTop = scrollY + minOffset - y;
1479
+ if (outsideTop > 0) {
1480
+ const scrollDivRect = this.scrollDiv.getBoundingClientRect();
1481
+ this.scrollDiv.style.maxHeight = scrollDivRect.height - outsideTop + 'px';
1482
+ y += outsideTop;
1483
+ }
1484
+ levelStyle.top = y + 'px';
1511
1485
  }
1512
1486
  //setting minimal level width if it is defined
1513
1487
  let minItemWidth = this.parentMenu.minItemWidth;
@@ -1805,12 +1779,13 @@ class PopupMenu {
1805
1779
  this.active = true;
1806
1780
  this.setSelectedItems(this.options.items, selectedIds);
1807
1781
  if (ui.browserUtils.isMobileMode()) {
1808
- this.rootLevel.showAt(0, 0, true, true);
1782
+ this.rootLevel.initLevelDiv();
1809
1783
  this.rootLevel.levelDiv.style.top = '0px';
1810
1784
  this.rootLevel.levelDiv.style.bottom = '0px';
1811
1785
  this.rootLevel.levelDiv.style.right = '0px';
1812
1786
  this.rootLevel.levelDiv.style.position = 'fixed';
1813
1787
  this.rootLevel.levelDiv.style.fontSize = '20px';
1788
+ this.rootLevel.showAt(0, 0, true, true);
1814
1789
  }
1815
1790
  else {
1816
1791
  const anchor = options.anchor || document.documentElement;
@@ -1827,9 +1802,13 @@ class PopupMenu {
1827
1802
  const leftSpace = pos.x + anchorWidth - scroll.left;
1828
1803
  const rightSpace = winSize.width - leftSpace + anchorWidth;
1829
1804
  pos.x += 2;
1830
- this.rootLevel.showAt(pos.x, pos.y, true, true, anchor);
1805
+ this.rootLevel.initLevelDiv();
1831
1806
  this.rootLevel.levelDiv.style.width = '';
1832
1807
  this.rootLevel.levelDiv.style.right = '';
1808
+ this.rootLevel.levelDiv.style.bottom = '';
1809
+ this.rootLevel.levelDiv.style.position = 'absolute';
1810
+ this.rootLevel.levelDiv.style.fontSize = '14px';
1811
+ this.rootLevel.showAt(pos.x, pos.y, true, true, anchor);
1833
1812
  if (!this.rootLevel.levelDiv.style.zIndex) {
1834
1813
  // z-index is at least 10000 and more if anchor has bigger
1835
1814
  this.rootLevel.levelDiv.style.zIndex = `${Math.max(10000, findHighestZIndex(anchor) + 1)}`;
@@ -1850,7 +1829,6 @@ class PopupMenu {
1850
1829
  }
1851
1830
  this.rootLevel.levelDiv.style.right = ui.getViewportSize().width - pos.x - anchorWidth + 'px';
1852
1831
  }
1853
- this.rootLevel.levelDiv.style.fontSize = '14px';
1854
1832
  }
1855
1833
  this.rootLevel.levelDiv.style.visibility = 'visible';
1856
1834
  this.rootLevel.focus();
@@ -680,20 +680,20 @@ class MenuLevel {
680
680
  const applyItem = this._applyItem;
681
681
  //if multiselect option is on - then we should add special "apply" item
682
682
  if (multiselect && this.levelIndex === 0 && this.parentMenu.options.hideButtons !== true) {
683
- const applyDiv = document.createElement("div");
684
- applyDiv.classList.add(`${this.cssPrefix}-applyDiv`);
685
- applyDiv['menuItem'] = applyItem;
683
+ this.applyDiv = document.createElement("div");
684
+ this.applyDiv.classList.add(`${this.cssPrefix}-applyDiv`);
685
+ this.applyDiv['menuItem'] = applyItem;
686
686
  this.applyBtn = document.createElement('button');
687
687
  if (this.parentMenu.options.useDefaultStyles) {
688
- applyDiv.style.borderBottom = '1px solid';
689
- applyDiv.style.padding = '5px';
690
- applyDiv.style.marginBottom = '5px';
688
+ this.applyDiv.style.borderBottom = '1px solid';
689
+ this.applyDiv.style.padding = '5px';
690
+ this.applyDiv.style.marginBottom = '5px';
691
691
  this.applyBtn.style.padding = '0 5px';
692
692
  this.applyBtn.style.cursor = "pointer";
693
693
  }
694
694
  const applyTextNode = document.createTextNode(this.parentMenu.options.buttons.submit);
695
695
  this.applyBtn.appendChild(applyTextNode);
696
- applyDiv.appendChild(this.applyBtn);
696
+ this.applyDiv.appendChild(this.applyBtn);
697
697
  //cancel btn
698
698
  const cancelBtn = document.createElement('button');
699
699
  cancelBtn.classList.add(`${this.cssPrefix}-cancel`);
@@ -704,9 +704,9 @@ class MenuLevel {
704
704
  }
705
705
  const cancelText = document.createTextNode(this.parentMenu.options.buttons.cancel);
706
706
  cancelBtn.appendChild(cancelText);
707
- applyDiv.appendChild(cancelBtn);
708
- baseDiv.appendChild(applyDiv);
709
- applyItem.itemDiv = applyDiv;
707
+ this.applyDiv.appendChild(cancelBtn);
708
+ baseDiv.appendChild(this.applyDiv);
709
+ applyItem.itemDiv = this.applyDiv;
710
710
  this.applyBtn.addEventListener('click', () => {
711
711
  this.submit(this._applyItem);
712
712
  });
@@ -1434,78 +1434,52 @@ class MenuLevel {
1434
1434
  levelStyle.top = y + 'px';
1435
1435
  this.scrollDiv.style.width = "auto";
1436
1436
  this.scrollDiv.style.height = "auto";
1437
+ this.scrollDiv.style.maxHeight = null;
1437
1438
  const useMaxSpace = this.parentMenu.options.useMaxSpace;
1438
1439
  const viewportHeight = getViewportSize().height;
1439
- const top = y - scrollY;
1440
- const bottom = viewportHeight - top;
1441
1440
  const anchorRect = anchor ? anchor.getBoundingClientRect() : null;
1442
1441
  const anchorHeight = anchorRect ? anchorRect.height : 0;
1443
- const magic = 24;
1444
- if (this.levelIndex > 0) {
1445
- let maxHeight = viewportHeight - 30;
1446
- if (this.searchDiv) {
1447
- maxHeight -= this.searchDiv.scrollHeight;
1448
- y -= this.searchDiv.scrollHeight;
1449
- }
1450
- if (this.closeDiv) {
1451
- maxHeight -= this.closeDiv.offsetHeight;
1452
- y -= this.closeDiv.offsetHeight;
1453
- }
1454
- this.scrollDiv.style.maxHeight = maxHeight + 'px';
1455
- levelStyle.top = this.adjustTopPos(y) + 'px';
1456
- }
1457
- else if (useMaxSpace) {
1458
- let maxHeight = viewportHeight - 30;
1459
- if (this.searchDiv) {
1460
- maxHeight -= this.searchDiv.scrollHeight;
1461
- }
1462
- if (this.closeDiv) {
1463
- maxHeight -= this.closeDiv.offsetHeight;
1464
- }
1465
- this.scrollDiv.style.maxHeight = maxHeight + 'px';
1466
- const levelDivRect = this.levelDiv.getBoundingClientRect();
1467
- const levelDivHeight = levelDivRect.height;
1468
- if (levelDivHeight < bottom - anchorHeight) {
1469
- levelStyle.top = y + anchorHeight + 'px';
1470
- }
1471
- else {
1472
- if (top < bottom) {
1473
- levelStyle.top = y - top + 5 + 'px';
1474
- }
1475
- else {
1476
- levelStyle.top = Math.max(5, viewportHeight - levelDivHeight - 30) + 'px';
1477
- }
1478
- }
1479
- }
1480
- else {
1481
- let maxHeight = Math.max(top, bottom) - magic;
1482
- if (this.searchDiv) {
1483
- maxHeight -= this.searchDiv.scrollHeight;
1484
- }
1485
- if (this.closeDiv) {
1486
- maxHeight -= this.closeDiv.offsetHeight;
1487
- }
1488
- // Рахуємо початковий контейнер
1489
- let levelDivRect = this.levelDiv.getBoundingClientRect();
1490
- if (levelDivRect.height < bottom - anchorHeight) {
1491
- // Контейнер може впасти вниз
1492
- this.scrollDiv.style.maxHeight = maxHeight - magic + 'px';
1493
- levelStyle.top = y + anchorHeight + 'px';
1494
- }
1495
- else {
1496
- // Визначаємо більший простір зверху чи знизу від анкора
1497
- if (top > bottom) {
1498
- // Падаємо вверх
1499
- this.scrollDiv.style.maxHeight = maxHeight + 'px';
1500
- levelDivRect = this.levelDiv.getBoundingClientRect();
1501
- levelStyle.top = y - levelDivRect.height + 'px'; // - anchorHeight
1502
- }
1503
- else {
1504
- // Падаємо вниз
1505
- this.scrollDiv.style.maxHeight = maxHeight - magic - anchorHeight + 'px';
1506
- levelStyle.top = y + anchorHeight + 'px';
1507
- }
1508
- }
1442
+ const upperSpace = y - scrollY;
1443
+ const lowerSpace = viewportHeight - upperSpace - anchorHeight;
1444
+ const minOffset = 15;
1445
+ // Рахуємо початковий контейнер
1446
+ let levelDivRect = this.levelDiv.getBoundingClientRect();
1447
+ if (this.levelIndex == 0 && levelDivRect.height < lowerSpace - minOffset) { //root level. Have enough space to drop down without scroll
1448
+ levelStyle.top = (y + anchorHeight) + 'px';
1449
+ }
1450
+ else if (this.levelIndex == 0 && levelDivRect.height < upperSpace - minOffset) { //root level. Have enough space to drop up without scroll
1451
+ levelStyle.top = (y - levelDivRect.height) + 'px';
1452
+ }
1453
+ else if (useMaxSpace || this.levelIndex > 0) { //sub-level or useMaxSpace option set. Use all the space
1454
+ const outsideBottom = levelDivRect.bottom + minOffset - scrollY - viewportHeight;
1455
+ if (outsideBottom > 0) {
1456
+ levelStyle.top = levelDivRect.top - outsideBottom + 'px';
1457
+ }
1458
+ levelDivRect = this.levelDiv.getBoundingClientRect();
1459
+ const outsideTop = scrollY + minOffset - levelDivRect.top;
1460
+ if (outsideTop > 0) {
1461
+ const scrollDivRect = this.scrollDiv.getBoundingClientRect();
1462
+ this.scrollDiv.style.maxHeight = scrollDivRect.height - outsideTop + 'px';
1463
+ levelStyle.top = levelDivRect.top + outsideTop + 'px';
1464
+ }
1465
+ }
1466
+ else if (upperSpace <= lowerSpace) { //root level. Drop down with scroll
1467
+ levelStyle.top = (y + anchorHeight) + 'px';
1468
+ const outsideBottom = levelDivRect.height + minOffset - lowerSpace;
1469
+ if (outsideBottom > 0) {
1470
+ const scrollDivRect = this.scrollDiv.getBoundingClientRect();
1471
+ this.scrollDiv.style.maxHeight = scrollDivRect.height - outsideBottom + 'px';
1472
+ }
1473
+ }
1474
+ else { //root level. Drop up with scroll
1475
+ y -= levelDivRect.height;
1476
+ const outsideTop = scrollY + minOffset - y;
1477
+ if (outsideTop > 0) {
1478
+ const scrollDivRect = this.scrollDiv.getBoundingClientRect();
1479
+ this.scrollDiv.style.maxHeight = scrollDivRect.height - outsideTop + 'px';
1480
+ y += outsideTop;
1481
+ }
1482
+ levelStyle.top = y + 'px';
1509
1483
  }
1510
1484
  //setting minimal level width if it is defined
1511
1485
  let minItemWidth = this.parentMenu.minItemWidth;
@@ -1803,12 +1777,13 @@ class PopupMenu {
1803
1777
  this.active = true;
1804
1778
  this.setSelectedItems(this.options.items, selectedIds);
1805
1779
  if (browserUtils.isMobileMode()) {
1806
- this.rootLevel.showAt(0, 0, true, true);
1780
+ this.rootLevel.initLevelDiv();
1807
1781
  this.rootLevel.levelDiv.style.top = '0px';
1808
1782
  this.rootLevel.levelDiv.style.bottom = '0px';
1809
1783
  this.rootLevel.levelDiv.style.right = '0px';
1810
1784
  this.rootLevel.levelDiv.style.position = 'fixed';
1811
1785
  this.rootLevel.levelDiv.style.fontSize = '20px';
1786
+ this.rootLevel.showAt(0, 0, true, true);
1812
1787
  }
1813
1788
  else {
1814
1789
  const anchor = options.anchor || document.documentElement;
@@ -1825,9 +1800,13 @@ class PopupMenu {
1825
1800
  const leftSpace = pos.x + anchorWidth - scroll.left;
1826
1801
  const rightSpace = winSize.width - leftSpace + anchorWidth;
1827
1802
  pos.x += 2;
1828
- this.rootLevel.showAt(pos.x, pos.y, true, true, anchor);
1803
+ this.rootLevel.initLevelDiv();
1829
1804
  this.rootLevel.levelDiv.style.width = '';
1830
1805
  this.rootLevel.levelDiv.style.right = '';
1806
+ this.rootLevel.levelDiv.style.bottom = '';
1807
+ this.rootLevel.levelDiv.style.position = 'absolute';
1808
+ this.rootLevel.levelDiv.style.fontSize = '14px';
1809
+ this.rootLevel.showAt(pos.x, pos.y, true, true, anchor);
1831
1810
  if (!this.rootLevel.levelDiv.style.zIndex) {
1832
1811
  // z-index is at least 10000 and more if anchor has bigger
1833
1812
  this.rootLevel.levelDiv.style.zIndex = `${Math.max(10000, findHighestZIndex(anchor) + 1)}`;
@@ -1848,7 +1827,6 @@ class PopupMenu {
1848
1827
  }
1849
1828
  this.rootLevel.levelDiv.style.right = getViewportSize().width - pos.x - anchorWidth + 'px';
1850
1829
  }
1851
- this.rootLevel.levelDiv.style.fontSize = '14px';
1852
1830
  }
1853
1831
  this.rootLevel.levelDiv.style.visibility = 'visible';
1854
1832
  this.rootLevel.focus();
@@ -17,6 +17,7 @@ declare class MenuLevel {
17
17
  private levelIndex;
18
18
  private searchDiv;
19
19
  private searchBox;
20
+ private applyDiv;
20
21
  private closeDiv;
21
22
  private scrollDiv;
22
23
  private domWriteItemsId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easyquery/ui",
3
- "version": "7.4.0-rc01",
3
+ "version": "7.4.0-rc02",
4
4
  "description": "EasyQuery.JS Community UI widgets",
5
5
  "types": "./dist/types/public_api.d.ts",
6
6
  "main": "./dist/easyquery.ui.cjs.js",
@@ -30,7 +30,7 @@
30
30
  "bugs": "https://korzh.com/support",
31
31
  "license": "LGPL-3.0",
32
32
  "peerDependencies": {
33
- "@easyquery/core": "^7.4.0-rc01"
33
+ "@easyquery/core": "^7.4.0-rc02"
34
34
  },
35
35
  "files": [
36
36
  "dist",