UNPKG

12.4 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.DOMElement = DOMElement;
7exports.TransitionTimeouts = exports.TransitionStatuses = exports.TransitionPropTypeKeys = exports.PopperPlacements = void 0;
8exports.addDefaultProps = addDefaultProps;
9exports.addMultipleEventListeners = addMultipleEventListeners;
10exports.canUseDOM = void 0;
11exports.conditionallyUpdateScrollbar = conditionallyUpdateScrollbar;
12exports.defaultToggleEvents = void 0;
13exports.deprecated = deprecated;
14exports.findDOMElements = findDOMElements;
15exports.focusableElements = void 0;
16exports.getOriginalBodyPadding = getOriginalBodyPadding;
17exports.getScrollbarWidth = getScrollbarWidth;
18exports.getTarget = getTarget;
19exports.isArrayOrNodeList = isArrayOrNodeList;
20exports.isBodyOverflowing = isBodyOverflowing;
21exports.isFunction = isFunction;
22exports.isObject = isObject;
23exports.isReactRefObj = isReactRefObj;
24exports.keyCodes = void 0;
25exports.mapToCssModules = mapToCssModules;
26exports.omit = omit;
27exports.pick = pick;
28exports.setGlobalCssModule = setGlobalCssModule;
29exports.setScrollbarWidth = setScrollbarWidth;
30exports.targetPropType = exports.tagPropType = void 0;
31exports.toNumber = toNumber;
32exports.warnOnce = warnOnce;
33var _propTypes = _interopRequireDefault(require("prop-types"));
34function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
36function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
37function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
38// https://github.com/twbs/bootstrap/blob/v4.0.0-alpha.4/js/src/modal.js#L436-L443
39function getScrollbarWidth() {
40 let scrollDiv = document.createElement('div');
41 // .modal-scrollbar-measure styles // https://github.com/twbs/bootstrap/blob/v4.0.0-alpha.4/scss/_modal.scss#L106-L113
42 scrollDiv.style.position = 'absolute';
43 scrollDiv.style.top = '-9999px';
44 scrollDiv.style.width = '50px';
45 scrollDiv.style.height = '50px';
46 scrollDiv.style.overflow = 'scroll';
47 document.body.appendChild(scrollDiv);
48 const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
49 document.body.removeChild(scrollDiv);
50 return scrollbarWidth;
51}
52function setScrollbarWidth(padding) {
53 document.body.style.paddingRight = padding > 0 ? `${padding}px` : null;
54}
55function isBodyOverflowing() {
56 return document.body.clientWidth < window.innerWidth;
57}
58function getOriginalBodyPadding() {
59 const style = window.getComputedStyle(document.body, null);
60 return parseInt(style && style.getPropertyValue('padding-right') || 0, 10);
61}
62function conditionallyUpdateScrollbar() {
63 const scrollbarWidth = getScrollbarWidth();
64 // https://github.com/twbs/bootstrap/blob/v4.0.0-alpha.6/js/src/modal.js#L433
65 const fixedContent = document.querySelectorAll('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top')[0];
66 const bodyPadding = fixedContent ? parseInt(fixedContent.style.paddingRight || 0, 10) : 0;
67 if (isBodyOverflowing()) {
68 setScrollbarWidth(bodyPadding + scrollbarWidth);
69 }
70}
71let globalCssModule;
72function setGlobalCssModule(cssModule) {
73 globalCssModule = cssModule;
74}
75function mapToCssModules(className = '', cssModule = globalCssModule) {
76 if (!cssModule) return className;
77 return className.split(' ').map(c => cssModule[c] || c).join(' ');
78}
79
80/**
81 * Returns a new object with the key/value pairs from `obj` that are not in the array `omitKeys`.
82 */
83function omit(obj, omitKeys) {
84 const result = {};
85 Object.keys(obj).forEach(key => {
86 if (omitKeys.indexOf(key) === -1) {
87 result[key] = obj[key];
88 }
89 });
90 return result;
91}
92
93/**
94 * Returns a filtered copy of an object with only the specified keys.
95 */
96function pick(obj, keys) {
97 const pickKeys = Array.isArray(keys) ? keys : [keys];
98 let {
99 length
100 } = pickKeys;
101 let key;
102 const result = {};
103 while (length > 0) {
104 length -= 1;
105 key = pickKeys[length];
106 result[key] = obj[key];
107 }
108 return result;
109}
110let warned = {};
111function warnOnce(message) {
112 if (!warned[message]) {
113 /* istanbul ignore else */
114 if (typeof console !== 'undefined') {
115 console.error(message); // eslint-disable-line no-console
116 }
117
118 warned[message] = true;
119 }
120}
121function deprecated(propType, explanation) {
122 return function validate(props, propName, componentName, ...rest) {
123 if (props[propName] !== null && typeof props[propName] !== 'undefined') {
124 warnOnce(`"${propName}" property of "${componentName}" has been deprecated.\n${explanation}`);
125 }
126 return propType(props, propName, componentName, ...rest);
127 };
128}
129
130// Shim Element if needed (e.g. in Node environment)
131const Element = typeof window === 'object' && window.Element || function () {};
132function DOMElement(props, propName, componentName) {
133 if (!(props[propName] instanceof Element)) {
134 return new Error('Invalid prop `' + propName + '` supplied to `' + componentName + '`. Expected prop to be an instance of Element. Validation failed.');
135 }
136}
137const targetPropType = _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func, DOMElement, _propTypes.default.shape({
138 current: _propTypes.default.any
139})]);
140exports.targetPropType = targetPropType;
141const tagPropType = _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.string, _propTypes.default.shape({
142 $$typeof: _propTypes.default.symbol,
143 render: _propTypes.default.func
144}), _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.string, _propTypes.default.shape({
145 $$typeof: _propTypes.default.symbol,
146 render: _propTypes.default.func
147})]))]);
148
149// These are all setup to match what is in the bootstrap _variables.scss
150// https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss
151exports.tagPropType = tagPropType;
152const TransitionTimeouts = {
153 Fade: 150,
154 // $transition-fade
155 Collapse: 350,
156 // $transition-collapse
157 Modal: 300,
158 // $modal-transition
159 Carousel: 600,
160 // $carousel-transition
161 Offcanvas: 300 // $offcanvas-transition
162};
163
164// Duplicated Transition.propType keys to ensure that Reactstrap builds
165// for distribution properly exclude these keys for nested child HTML attributes
166// since `react-transition-group` removes propTypes in production builds.
167exports.TransitionTimeouts = TransitionTimeouts;
168const TransitionPropTypeKeys = ['in', 'mountOnEnter', 'unmountOnExit', 'appear', 'enter', 'exit', 'timeout', 'onEnter', 'onEntering', 'onEntered', 'onExit', 'onExiting', 'onExited'];
169exports.TransitionPropTypeKeys = TransitionPropTypeKeys;
170const TransitionStatuses = {
171 ENTERING: 'entering',
172 ENTERED: 'entered',
173 EXITING: 'exiting',
174 EXITED: 'exited'
175};
176exports.TransitionStatuses = TransitionStatuses;
177const keyCodes = {
178 esc: 27,
179 space: 32,
180 enter: 13,
181 tab: 9,
182 up: 38,
183 down: 40,
184 home: 36,
185 end: 35,
186 n: 78,
187 p: 80
188};
189exports.keyCodes = keyCodes;
190const PopperPlacements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
191exports.PopperPlacements = PopperPlacements;
192const canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
193exports.canUseDOM = canUseDOM;
194function isReactRefObj(target) {
195 if (target && typeof target === 'object') {
196 return 'current' in target;
197 }
198 return false;
199}
200function getTag(value) {
201 if (value == null) {
202 return value === undefined ? '[object Undefined]' : '[object Null]';
203 }
204 return Object.prototype.toString.call(value);
205}
206function isObject(value) {
207 const type = typeof value;
208 return value != null && (type === 'object' || type === 'function');
209}
210function toNumber(value) {
211 const type = typeof value;
212 const NAN = 0 / 0;
213 if (type === 'number') {
214 return value;
215 }
216 if (type === 'symbol' || type === 'object' && getTag(value) === '[object Symbol]') {
217 return NAN;
218 }
219 if (isObject(value)) {
220 const other = typeof value.valueOf === 'function' ? value.valueOf() : value;
221 value = isObject(other) ? `${other}` : other;
222 }
223 if (type !== 'string') {
224 return value === 0 ? value : +value;
225 }
226 value = value.replace(/^\s+|\s+$/g, '');
227 const isBinary = /^0b[01]+$/i.test(value);
228 return isBinary || /^0o[0-7]+$/i.test(value) ? parseInt(value.slice(2), isBinary ? 2 : 8) : /^[-+]0x[0-9a-f]+$/i.test(value) ? NAN : +value;
229}
230function isFunction(value) {
231 if (!isObject(value)) {
232 return false;
233 }
234 const tag = getTag(value);
235 return tag === '[object Function]' || tag === '[object AsyncFunction]' || tag === '[object GeneratorFunction]' || tag === '[object Proxy]';
236}
237function findDOMElements(target) {
238 if (isReactRefObj(target)) {
239 return target.current;
240 }
241 if (isFunction(target)) {
242 return target();
243 }
244 if (typeof target === 'string' && canUseDOM) {
245 let selection = document.querySelectorAll(target);
246 if (!selection.length) {
247 selection = document.querySelectorAll(`#${target}`);
248 }
249 if (!selection.length) {
250 throw new Error(`The target '${target}' could not be identified in the dom, tip: check spelling`);
251 }
252 return selection;
253 }
254 return target;
255}
256function isArrayOrNodeList(els) {
257 if (els === null) {
258 return false;
259 }
260 return Array.isArray(els) || canUseDOM && typeof els.length === 'number';
261}
262function getTarget(target, allElements) {
263 const els = findDOMElements(target);
264 if (allElements) {
265 if (isArrayOrNodeList(els)) {
266 return els;
267 }
268 if (els === null) {
269 return [];
270 }
271 return [els];
272 }
273 if (isArrayOrNodeList(els)) {
274 return els[0];
275 }
276 return els;
277}
278const defaultToggleEvents = ['touchstart', 'click'];
279exports.defaultToggleEvents = defaultToggleEvents;
280function addMultipleEventListeners(_els, handler, _events, useCapture) {
281 let els = _els;
282 if (!isArrayOrNodeList(els)) {
283 els = [els];
284 }
285 let events = _events;
286 if (typeof events === 'string') {
287 events = events.split(/\s+/);
288 }
289 if (!isArrayOrNodeList(els) || typeof handler !== 'function' || !Array.isArray(events)) {
290 throw new Error(`
291 The first argument of this function must be DOM node or an array on DOM nodes or NodeList.
292 The second must be a function.
293 The third is a string or an array of strings that represents DOM events
294 `);
295 }
296 Array.prototype.forEach.call(events, event => {
297 Array.prototype.forEach.call(els, el => {
298 el.addEventListener(event, handler, useCapture);
299 });
300 });
301 return function removeEvents() {
302 Array.prototype.forEach.call(events, event => {
303 Array.prototype.forEach.call(els, el => {
304 el.removeEventListener(event, handler, useCapture);
305 });
306 });
307 };
308}
309const focusableElements = ['a[href]', 'area[href]', 'input:not([disabled]):not([type=hidden])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'object', 'embed', '[tabindex]:not(.modal):not(.offcanvas)', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])'];
310exports.focusableElements = focusableElements;
311function addDefaultProps(defaultProps, props) {
312 if (!defaultProps || !props) return props;
313 let result = _objectSpread({}, props);
314 Object.keys(defaultProps).forEach(key => {
315 if (result[key] === undefined) {
316 result[key] = defaultProps[key];
317 }
318 if (Object.keys(defaultProps[key] || {}).length > 0 && typeof defaultProps[key] === 'object') {
319 addDefaultProps(defaultProps[key], result);
320 }
321 });
322 return result;
323}
\No newline at end of file