UNPKG

5.53 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 Object.assign(container.style, containerState.style);
95 };
96
97 _proto.add = function add(modal, container, className) {
98 var modalIdx = this.modals.indexOf(modal);
99 var containerIdx = this.containers.indexOf(container);
100
101 if (modalIdx !== -1) {
102 return modalIdx;
103 }
104
105 modalIdx = this.modals.length;
106 this.modals.push(modal);
107
108 if (this.hideSiblingNodes) {
109 (0, _manageAriaHidden.hideSiblings)(container, modal);
110 }
111
112 if (containerIdx !== -1) {
113 this.data[containerIdx].modals.push(modal);
114 return modalIdx;
115 }
116
117 var data = {
118 modals: [modal],
119 // right now only the first modal of a container will have its classes applied
120 classes: className ? className.split(/\s+/) : [],
121 overflowing: (0, _isOverflowing["default"])(container)
122 };
123
124 if (this.handleContainerOverflow) {
125 this.setContainerStyle(data, container);
126 }
127
128 data.classes.forEach(_addClass["default"].bind(null, container));
129 this.containers.push(container);
130 this.data.push(data);
131 return modalIdx;
132 };
133
134 _proto.remove = function remove(modal) {
135 var modalIdx = this.modals.indexOf(modal);
136
137 if (modalIdx === -1) {
138 return;
139 }
140
141 var containerIdx = this.containerIndexFromModal(modal);
142 var data = this.data[containerIdx];
143 var container = this.containers[containerIdx];
144 data.modals.splice(data.modals.indexOf(modal), 1);
145 this.modals.splice(modalIdx, 1); // if that was the last modal in a container,
146 // clean up the container
147
148 if (data.modals.length === 0) {
149 data.classes.forEach(_removeClass["default"].bind(null, container));
150
151 if (this.handleContainerOverflow) {
152 this.removeContainerStyle(data, container);
153 }
154
155 if (this.hideSiblingNodes) {
156 (0, _manageAriaHidden.showSiblings)(container, modal);
157 }
158
159 this.containers.splice(containerIdx, 1);
160 this.data.splice(containerIdx, 1);
161 } else if (this.hideSiblingNodes) {
162 // otherwise make sure the next top modal is visible to a SR
163 var _data$modals = data.modals[data.modals.length - 1],
164 backdrop = _data$modals.backdrop,
165 dialog = _data$modals.dialog;
166 (0, _manageAriaHidden.ariaHidden)(false, dialog);
167 (0, _manageAriaHidden.ariaHidden)(false, backdrop);
168 }
169 };
170
171 _proto.isTopModal = function isTopModal(modal) {
172 return !!this.modals.length && this.modals[this.modals.length - 1] === modal;
173 };
174
175 return ModalManager;
176}();
177
178var _default = ModalManager;
179exports["default"] = _default;
180module.exports = exports.default;
\No newline at end of file