Dashboard sipadu mbip
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

ModalManager.js 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. import classes from 'dom-helpers/class';
  2. import css from 'dom-helpers/style';
  3. import getScrollbarSize from 'dom-helpers/util/scrollbarSize';
  4. import isOverflowing from './utils/isOverflowing';
  5. import { ariaHidden, hideSiblings, showSiblings } from './utils/manageAriaHidden';
  6. function findIndexOf(arr, cb) {
  7. var idx = -1;
  8. arr.some(function (d, i) {
  9. if (cb(d, i)) {
  10. idx = i;
  11. return true;
  12. }
  13. });
  14. return idx;
  15. }
  16. /**
  17. * Proper state managment for containers and the modals in those containers.
  18. *
  19. * @internal Used by the Modal to ensure proper styling of containers.
  20. */
  21. var ModalManager =
  22. /*#__PURE__*/
  23. function () {
  24. function ModalManager(_temp) {
  25. var _ref = _temp === void 0 ? {} : _temp,
  26. _ref$hideSiblingNodes = _ref.hideSiblingNodes,
  27. hideSiblingNodes = _ref$hideSiblingNodes === void 0 ? true : _ref$hideSiblingNodes,
  28. _ref$handleContainerO = _ref.handleContainerOverflow,
  29. handleContainerOverflow = _ref$handleContainerO === void 0 ? true : _ref$handleContainerO;
  30. this.hideSiblingNodes = hideSiblingNodes;
  31. this.handleContainerOverflow = handleContainerOverflow;
  32. this.modals = [];
  33. this.containers = [];
  34. this.data = [];
  35. this.scrollbarSize = getScrollbarSize();
  36. }
  37. var _proto = ModalManager.prototype;
  38. _proto.isContainerOverflowing = function isContainerOverflowing(modal) {
  39. var data = this.data[this.containerIndexFromModal(modal)];
  40. return data && data.overflowing;
  41. };
  42. _proto.containerIndexFromModal = function containerIndexFromModal(modal) {
  43. return findIndexOf(this.data, function (d) {
  44. return d.modals.indexOf(modal) !== -1;
  45. });
  46. };
  47. _proto.setContainerStyle = function setContainerStyle(containerState, container) {
  48. var style = {
  49. overflow: 'hidden' // we are only interested in the actual `style` here
  50. // becasue we will override it
  51. };
  52. containerState.style = {
  53. overflow: container.style.overflow,
  54. paddingRight: container.style.paddingRight
  55. };
  56. if (containerState.overflowing) {
  57. // use computed style, here to get the real padding
  58. // to add our scrollbar width
  59. style.paddingRight = parseInt(css(container, 'paddingRight') || 0, 10) + this.scrollbarSize + "px";
  60. }
  61. css(container, style);
  62. };
  63. _proto.removeContainerStyle = function removeContainerStyle(containerState, container) {
  64. var style = containerState.style;
  65. Object.keys(style).forEach(function (key) {
  66. container.style[key] = style[key];
  67. });
  68. };
  69. _proto.add = function add(modal, container, className) {
  70. var modalIdx = this.modals.indexOf(modal);
  71. var containerIdx = this.containers.indexOf(container);
  72. if (modalIdx !== -1) {
  73. return modalIdx;
  74. }
  75. modalIdx = this.modals.length;
  76. this.modals.push(modal);
  77. if (this.hideSiblingNodes) {
  78. hideSiblings(container, modal);
  79. }
  80. if (containerIdx !== -1) {
  81. this.data[containerIdx].modals.push(modal);
  82. return modalIdx;
  83. }
  84. var data = {
  85. modals: [modal],
  86. //right now only the first modal of a container will have its classes applied
  87. classes: className ? className.split(/\s+/) : [],
  88. overflowing: isOverflowing(container)
  89. };
  90. if (this.handleContainerOverflow) {
  91. this.setContainerStyle(data, container);
  92. }
  93. data.classes.forEach(classes.addClass.bind(null, container));
  94. this.containers.push(container);
  95. this.data.push(data);
  96. return modalIdx;
  97. };
  98. _proto.remove = function remove(modal) {
  99. var modalIdx = this.modals.indexOf(modal);
  100. if (modalIdx === -1) {
  101. return;
  102. }
  103. var containerIdx = this.containerIndexFromModal(modal);
  104. var data = this.data[containerIdx];
  105. var container = this.containers[containerIdx];
  106. data.modals.splice(data.modals.indexOf(modal), 1);
  107. this.modals.splice(modalIdx, 1); // if that was the last modal in a container,
  108. // clean up the container
  109. if (data.modals.length === 0) {
  110. data.classes.forEach(classes.removeClass.bind(null, container));
  111. if (this.handleContainerOverflow) {
  112. this.removeContainerStyle(data, container);
  113. }
  114. if (this.hideSiblingNodes) {
  115. showSiblings(container, modal);
  116. }
  117. this.containers.splice(containerIdx, 1);
  118. this.data.splice(containerIdx, 1);
  119. } else if (this.hideSiblingNodes) {
  120. //otherwise make sure the next top modal is visible to a SR
  121. var _data$modals = data.modals[data.modals.length - 1],
  122. backdrop = _data$modals.backdrop,
  123. dialog = _data$modals.dialog;
  124. ariaHidden(false, dialog);
  125. ariaHidden(false, backdrop);
  126. }
  127. };
  128. _proto.isTopModal = function isTopModal(modal) {
  129. return !!this.modals.length && this.modals[this.modals.length - 1] === modal;
  130. };
  131. return ModalManager;
  132. }();
  133. export default ModalManager;