UNPKG

5.61 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5exports.__esModule = true;
6exports["default"] = void 0;
7
8var _addClass = _interopRequireDefault(require("dom-helpers/addClass"));
9
10var _removeClass = _interopRequireDefault(require("dom-helpers/removeClass"));
11
12var _css = _interopRequireDefault(require("dom-helpers/css"));
13
14var _scrollbarSize = _interopRequireDefault(require("dom-helpers/scrollbarSize"));
15
16var _isOverflowing = _interopRequireDefault(require("./isOverflowing"));
17
18var _manageAriaHidden = require("./manageAriaHidden");
19
20function findIndexOf(arr, cb) {
21 var idx = -1;
22 arr.some(function (d, i) {
23 if (cb(d, i)) {
24 idx = i;
25 return true;
26 }
27
28 return false;
29 });
30 return idx;
31}
32
33/**
34 * Proper state management for containers and the modals in those containers.
35 *
36 * @internal Used by the Modal to ensure proper styling of containers.
37 */
38var ModalManager = /*#__PURE__*/function () {
39 function ModalManager(_temp) {
40 var _ref = _temp === void 0 ? {} : _temp,
41 _ref$hideSiblingNodes = _ref.hideSiblingNodes,
42 hideSiblingNodes = _ref$hideSiblingNodes === void 0 ? true : _ref$hideSiblingNodes,
43 _ref$handleContainerO = _ref.handleContainerOverflow,
44 handleContainerOverflow = _ref$handleContainerO === void 0 ? true : _ref$handleContainerO;
45
46 this.hideSiblingNodes = void 0;
47 this.handleContainerOverflow = void 0;
48 this.modals = void 0;
49 this.containers = void 0;
50 this.data = void 0;
51 this.scrollbarSize = void 0;
52 this.hideSiblingNodes = hideSiblingNodes;
53 this.handleContainerOverflow = handleContainerOverflow;
54 this.modals = [];
55 this.containers = [];
56 this.data = [];
57 this.scrollbarSize = (0, _scrollbarSize["default"])();
58 }
59
60 var _proto = ModalManager.prototype;
61
62 _proto.isContainerOverflowing = function isContainerOverflowing(modal) {
63 var data = this.data[this.containerIndexFromModal(modal)];
64 return data && data.overflowing;
65 };
66
67 _proto.containerIndexFromModal = function containerIndexFromModal(modal) {
68 return findIndexOf(this.data, function (d) {
69 return d.modals.indexOf(modal) !== -1;
70 });
71 };
72
73 _proto.setContainerStyle = function setContainerStyle(containerState, container) {
74 var style = {
75 overflow: 'hidden'
76 }; // we are only interested in the actual `style` here
77 // because we will override it
78
79 containerState.style = {
80 overflow: container.style.overflow,
81 paddingRight: container.style.paddingRight
82 };
83
84 if (containerState.overflowing) {
85 // use computed style, here to get the real padding
86 // to add our scrollbar width
87 style.paddingRight = parseInt((0, _css["default"])(container, 'paddingRight') || '0', 10) + this.scrollbarSize + "px";
88 }
89
90 (0, _css["default"])(container, style);
91 };
92
93 _proto.removeContainerStyle = function removeContainerStyle(containerState, container) {
94 var style = containerState.style;
95 Object.keys(style).forEach(function (key) {
96 container.style[key] = style[key];
97 });
98 };
99
100 _proto.add = function add(modal, container, className) {
101 var modalIdx = this.modals.indexOf(modal);
102 var containerIdx = this.containers.indexOf(container);
103
104 if (modalIdx !== -1) {
105 return modalIdx;
106 }
107
108 modalIdx = this.modals.length;
109 this.modals.push(modal);
110
111 if (this.hideSiblingNodes) {
112 (0, _manageAriaHidden.hideSiblings)(container, modal);
113 }
114
115 if (containerIdx !== -1) {
116 this.data[containerIdx].modals.push(modal);
117 return modalIdx;
118 }
119
120 var data = {
121 modals: [modal],
122 // right now only the first modal of a container will have its classes applied
123 classes: className ? className.split(/\s+/) : [],
124 overflowing: (0, _isOverflowing["default"])(container)
125 };
126
127 if (this.handleContainerOverflow) {
128 this.setContainerStyle(data, container);
129 }
130
131 data.classes.forEach(_addClass["default"].bind(null, container));
132 this.containers.push(container);
133 this.data.push(data);
134 return modalIdx;
135 };
136
137 _proto.remove = function remove(modal) {
138 var modalIdx = this.modals.indexOf(modal);
139
140 if (modalIdx === -1) {
141 return;
142 }
143
144 var containerIdx = this.containerIndexFromModal(modal);
145 var data = this.data[containerIdx];
146 var container = this.containers[containerIdx];
147 data.modals.splice(data.modals.indexOf(modal), 1);
148 this.modals.splice(modalIdx, 1); // if that was the last modal in a container,
149 // clean up the container
150
151 if (data.modals.length === 0) {
152 data.classes.forEach(_removeClass["default"].bind(null, container));
153
154 if (this.handleContainerOverflow) {
155 this.removeContainerStyle(data, container);
156 }
157
158 if (this.hideSiblingNodes) {
159 (0, _manageAriaHidden.showSiblings)(container, modal);
160 }
161
162 this.containers.splice(containerIdx, 1);
163 this.data.splice(containerIdx, 1);
164 } else if (this.hideSiblingNodes) {
165 // otherwise make sure the next top modal is visible to a SR
166 var _data$modals = data.modals[data.modals.length - 1],
167 backdrop = _data$modals.backdrop,
168 dialog = _data$modals.dialog;
169 (0, _manageAriaHidden.ariaHidden)(false, dialog);
170 (0, _manageAriaHidden.ariaHidden)(false, backdrop);
171 }
172 };
173
174 _proto.isTopModal = function isTopModal(modal) {
175 return !!this.modals.length && this.modals[this.modals.length - 1] === modal;
176 };
177
178 return ModalManager;
179}();
180
181var _default = ModalManager;
182exports["default"] = _default;
183module.exports = exports.default;
\No newline at end of file