@sveltestrap/sveltestrap
Version:
Bootstrap components for Svelte
122 lines (97 loc) • 3.86 kB
JavaScript
export function getOriginalBodyPadding() {
const style = window ? window.getComputedStyle(document.body, null) : {};
return parseInt((style && style.getPropertyValue('padding-right')) || 0, 10);
}
export function getScrollbarWidth() {
let scrollDiv = document.createElement('div');
// .modal-scrollbar-measure styles // https://github.com/twbs/bootstrap/blob/v4.0.0-alpha.4/scss/_modal.scss#L106-L113
scrollDiv.style.position = 'absolute';
scrollDiv.style.top = '-9999px';
scrollDiv.style.width = '50px';
scrollDiv.style.height = '50px';
scrollDiv.style.overflow = 'scroll';
document.body.appendChild(scrollDiv);
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
}
export function setScrollbarWidth(padding) {
document.body.style.paddingRight = padding > 0 ? `${padding}px` : null;
}
export function isBodyOverflowing() {
return window ? document.body.clientWidth < window.innerWidth : false;
}
export function isObject(value) {
const type = typeof value;
return value !== null && (type === 'object' || type === 'function');
}
export function conditionallyUpdateScrollbar() {
const scrollbarWidth = getScrollbarWidth();
// https://github.com/twbs/bootstrap/blob/v4.0.0-alpha.6/js/src/modal.js#L433
const fixedContent = document.querySelectorAll('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top')[0];
const bodyPadding = fixedContent ? parseInt(fixedContent.style.paddingRight || 0, 10) : 0;
if (isBodyOverflowing()) {
setScrollbarWidth(bodyPadding + scrollbarWidth);
}
}
export function getColumnSizeClass(isXs, colWidth, colSize) {
if (colSize === true || colSize === '') {
return isXs ? 'col' : `col-${colWidth}`;
} else if (colSize === 'auto') {
return isXs ? 'col-auto' : `col-${colWidth}-auto`;
}
return isXs ? `col-${colSize}` : `col-${colWidth}-${colSize}`;
}
export function browserEvent(target, ...args) {
target.addEventListener(...args);
return () => target.removeEventListener(...args);
}
export function getNewCarouselActiveIndex(direction, items, activeIndex) {
if (direction === 'prev') {
return activeIndex === 0 ? items.length - 1 : activeIndex - 1;
}
if (direction === 'next') {
return activeIndex === items.length - 1 ? 0 : activeIndex + 1;
}
}
function toClassName(value) {
let result = '';
if (typeof value === 'string' || typeof value === 'number') {
result += value;
} else if (typeof value === 'object') {
if (Array.isArray(value)) {
result = value.map(toClassName).filter(Boolean).join(' ');
} else {
for (let key in value) {
if (value[key]) {
result && (result += ' ');
result += key;
}
}
}
}
return result;
}
export const classnames = (...args) => args.map(toClassName).filter(Boolean).join(' ');
export function getTransitionDuration(element) {
if (!element) return 0;
// Get transition-duration of the element
let { transitionDuration, transitionDelay } = window.getComputedStyle(element);
const floatTransitionDuration = Number.parseFloat(transitionDuration);
const floatTransitionDelay = Number.parseFloat(transitionDelay);
// Return 0 if element or transition duration is not found
if (!floatTransitionDuration && !floatTransitionDelay) {
return 0;
}
// If multiple durations are defined, take the first
transitionDuration = transitionDuration.split(',')[0];
transitionDelay = transitionDelay.split(',')[0];
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * 1000;
}
export function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}