get_my/client/lib/assets/materialize.js

7714 lines
301 KiB
JavaScript
Raw Normal View History

2022-08-04 19:50:18 -05:00
/*!
* Materialize v2.1.0 (https://materializeweb.com)
* Copyright 2014-2024 Materialize
2022-08-04 19:50:18 -05:00
* MIT License (https://raw.githubusercontent.com/materializecss/materialize/master/LICENSE)
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = factory();
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(this, function() {
return /******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/autocomplete.ts":
/*!*****************************!*\
!*** ./src/autocomplete.ts ***!
\*****************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Autocomplete = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const dropdown_1 = __webpack_require__(/*! ./dropdown */ "./src/dropdown.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
let _defaults = {
data: [], // Autocomplete data set
onAutocomplete: null, // Callback for when autocompleted
dropdownOptions: {
// Default dropdown options
autoFocus: false,
closeOnClick: false,
coverTrigger: false
},
minLength: 1, // Min characters before autocomplete starts
isMultiSelect: false,
onSearch: (text, autocomplete) => {
const normSearch = text.toLocaleLowerCase();
autocomplete.setMenuItems(autocomplete.options.data.filter((option) => {
var _a;
return option.id.toString().toLocaleLowerCase().includes(normSearch)
|| ((_a = option.text) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase().includes(normSearch));
}));
},
maxDropDownHeight: '300px',
allowUnsafeHTML: false
};
class Autocomplete extends component_1.Component {
constructor(el, options) {
super(el, options, Autocomplete);
this._handleInputBlur = () => {
if (!this._mousedown) {
this.close();
this._resetAutocomplete();
}
};
this._handleInputKeyupAndFocus = (e) => {
if (e.type === 'keyup')
Autocomplete._keydown = false;
this.count = 0;
const actualValue = this.el.value.toLocaleLowerCase();
// Don't capture enter or arrow key usage.
if (utils_1.Utils.keys.ENTER.includes(e.key) || utils_1.Utils.keys.ARROW_UP.includes(e.key) || utils_1.Utils.keys.ARROW_DOWN.includes(e.key))
return;
// Check if the input isn't empty
// Check if focus triggered by tab
if (this.oldVal !== actualValue && (utils_1.Utils.tabPressed || e.type !== 'focus')) {
this.open();
}
// Value has changed!
if (this.oldVal !== actualValue) {
this._setStatusLoading();
this.options.onSearch(this.el.value, this);
}
// Reset Single-Select when Input cleared
if (!this.options.isMultiSelect && this.el.value.length === 0) {
this.selectedValues = [];
this._triggerChanged();
}
this.oldVal = actualValue;
};
this._handleInputKeydown = (e) => {
var _a, _b;
Autocomplete._keydown = true;
// Arrow keys and enter key usage
const numItems = this.container.querySelectorAll('li').length;
// select element on Enter
if (utils_1.Utils.keys.ENTER.includes(e.key) && this.activeIndex >= 0) {
const liElement = this.container.querySelectorAll('li')[this.activeIndex];
if (liElement) {
this.selectOption(liElement.getAttribute('data-id'));
e.preventDefault();
}
return;
}
// Capture up and down key
if (utils_1.Utils.keys.ARROW_UP.includes(e.key) || utils_1.Utils.keys.ARROW_DOWN.includes(e.key)) {
e.preventDefault();
if (utils_1.Utils.keys.ARROW_UP.includes(e.key) && this.activeIndex > 0)
this.activeIndex--;
if (utils_1.Utils.keys.ARROW_DOWN.includes(e.key) && this.activeIndex < numItems - 1)
this.activeIndex++;
(_a = this.$active) === null || _a === void 0 ? void 0 : _a.classList.remove('active');
if (this.activeIndex >= 0) {
this.$active = this.container.querySelectorAll('li')[this.activeIndex];
(_b = this.$active) === null || _b === void 0 ? void 0 : _b.classList.add('active');
// Focus selected
this.container.children[this.activeIndex].scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
});
}
}
};
this._handleInputClick = () => {
this.open();
};
this._handleContainerMousedownAndTouchstart = () => {
this._mousedown = true;
};
this._handleContainerMouseupAndTouchend = () => {
this._mousedown = false;
};
/**
* Show autocomplete.
*/
this.open = () => {
const inputText = this.el.value.toLocaleLowerCase();
this._resetAutocomplete();
if (inputText.length >= this.options.minLength) {
this.isOpen = true;
this._renderDropdown();
}
// Open dropdown
if (!this.dropdown.isOpen) {
setTimeout(() => {
this.dropdown.open();
}, 100);
}
else
this.dropdown.recalculateDimensions(); // Recalculate dropdown when its already open
};
/**
* Hide autocomplete.
*/
this.close = () => {
this.dropdown.close();
};
this.el.M_Autocomplete = this;
this.options = Object.assign(Object.assign({}, Autocomplete.defaults), options);
this.isOpen = false;
this.count = 0;
this.activeIndex = -1;
this.oldVal = "";
this.selectedValues = [];
this.menuItems = [];
this.$active = null;
this._mousedown = false;
this._setupDropdown();
this._setupEventHandlers();
2022-08-04 19:50:18 -05:00
}
static get defaults() {
return _defaults;
2022-08-04 19:50:18 -05:00
}
/**
* Initializes instances of Autocomplete.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Autocomplete);
2022-08-04 19:50:18 -05:00
}
static getInstance(el) {
return el.M_Autocomplete;
2022-08-04 19:50:18 -05:00
}
destroy() {
this._removeEventHandlers();
this._removeDropdown();
this.el.M_Autocomplete = undefined;
2022-08-04 19:50:18 -05:00
}
_setupEventHandlers() {
this.el.addEventListener('blur', this._handleInputBlur);
this.el.addEventListener('keyup', this._handleInputKeyupAndFocus);
this.el.addEventListener('focus', this._handleInputKeyupAndFocus);
this.el.addEventListener('keydown', this._handleInputKeydown);
this.el.addEventListener('click', this._handleInputClick);
this.container.addEventListener('mousedown', this._handleContainerMousedownAndTouchstart);
this.container.addEventListener('mouseup', this._handleContainerMouseupAndTouchend);
if (typeof window.ontouchstart !== 'undefined') {
this.container.addEventListener('touchstart', this._handleContainerMousedownAndTouchstart);
this.container.addEventListener('touchend', this._handleContainerMouseupAndTouchend);
}
2022-08-04 19:50:18 -05:00
}
_removeEventHandlers() {
this.el.removeEventListener('blur', this._handleInputBlur);
this.el.removeEventListener('keyup', this._handleInputKeyupAndFocus);
this.el.removeEventListener('focus', this._handleInputKeyupAndFocus);
this.el.removeEventListener('keydown', this._handleInputKeydown);
this.el.removeEventListener('click', this._handleInputClick);
this.container.removeEventListener('mousedown', this._handleContainerMousedownAndTouchstart);
this.container.removeEventListener('mouseup', this._handleContainerMouseupAndTouchend);
if (typeof window.ontouchstart !== 'undefined') {
this.container.removeEventListener('touchstart', this._handleContainerMousedownAndTouchstart);
this.container.removeEventListener('touchend', this._handleContainerMouseupAndTouchend);
}
2022-08-04 19:50:18 -05:00
}
_setupDropdown() {
this.container = document.createElement('ul');
this.container.style.maxHeight = this.options.maxDropDownHeight;
this.container.id = `autocomplete-options-${utils_1.Utils.guid()}`;
this.container.classList.add('autocomplete-content', 'dropdown-content');
this.el.setAttribute('data-target', this.container.id);
// ! Issue in Component Dropdown: _placeDropdown moves dom-position
this.el.parentElement.appendChild(this.container);
// Initialize dropdown
let dropdownOptions = Object.assign(Object.assign({}, Autocomplete.defaults.dropdownOptions), this.options.dropdownOptions);
let userOnItemClick = dropdownOptions.onItemClick;
// Ensuring the select Option call when user passes custom onItemClick function to dropdown
dropdownOptions.onItemClick = (li) => {
if (!li)
return;
const entryID = li.getAttribute('data-id');
this.selectOption(entryID);
// Handle user declared onItemClick if needed
if (userOnItemClick && typeof userOnItemClick === 'function')
userOnItemClick.call(this.dropdown, this.el);
};
this.dropdown = dropdown_1.Dropdown.init(this.el, dropdownOptions);
// ! Workaround for Label: move label up again
// TODO: Just use PopperJS in future!
const label = this.el.parentElement.querySelector('label');
if (label)
this.el.after(label);
// Sketchy removal of dropdown click handler
this.el.removeEventListener('click', this.dropdown._handleClick);
// Set Value if already set in HTML
if (this.el.value)
this.selectOption(this.el.value);
// Add StatusInfo
const div = document.createElement('div');
div.classList.add('status-info');
div.setAttribute('style', 'position: absolute;right:0;top:0;');
this.el.parentElement.appendChild(div);
this._updateSelectedInfo();
2022-08-04 19:50:18 -05:00
}
_removeDropdown() {
this.container.parentNode.removeChild(this.container);
2022-08-04 19:50:18 -05:00
}
_resetCurrentElementPosition() {
var _a;
this.activeIndex = -1;
(_a = this.$active) === null || _a === void 0 ? void 0 : _a.classList.remove('active');
}
_resetAutocomplete() {
this.container.replaceChildren();
this._resetCurrentElementPosition();
this.oldVal = null;
this.isOpen = false;
this._mousedown = false;
}
_highlightPartialText(input, label) {
const start = label.toLocaleLowerCase().indexOf('' + input.toLocaleLowerCase() + '');
const end = start + input.length - 1;
//custom filters may return results where the string does not match any part
if (start == -1 || end == -1) {
return [label, '', ''];
2022-08-04 19:50:18 -05:00
}
return [label.slice(0, start), label.slice(start, end + 1), label.slice(end + 1)];
2022-08-04 19:50:18 -05:00
}
_createDropdownItem(entry) {
const item = document.createElement('li');
item.setAttribute('data-id', entry.id);
item.setAttribute('style', 'display:grid; grid-auto-flow: column; user-select: none; align-items: center;');
// Checkbox
if (this.options.isMultiSelect) {
item.innerHTML = `
<div class="item-selection" style="text-align:center;">
<input type="checkbox"${this.selectedValues.some((sel) => sel.id === entry.id) ? ' checked="checked"' : ''}><span style="padding-left:21px;"></span>
</div>`;
}
// Image
if (entry.image) {
const img = document.createElement('img');
img.classList.add('circle');
img.src = entry.image;
item.appendChild(img);
2022-08-04 19:50:18 -05:00
}
// Text
const inputText = this.el.value.toLocaleLowerCase();
const parts = this._highlightPartialText(inputText, (entry.text || entry.id).toString());
const div = document.createElement('div');
div.setAttribute('style', 'line-height:1.2;font-weight:500;');
if (this.options.allowUnsafeHTML) {
div.innerHTML = parts[0] + '<span class="highlight">' + parts[1] + '</span>' + parts[2];
}
else {
div.appendChild(document.createTextNode(parts[0]));
if (parts[1]) {
const highlight = document.createElement('span');
highlight.textContent = parts[1];
highlight.classList.add('highlight');
div.appendChild(highlight);
div.appendChild(document.createTextNode(parts[2]));
2022-08-04 19:50:18 -05:00
}
}
const itemText = document.createElement('div');
itemText.classList.add('item-text');
itemText.setAttribute('style', 'padding:5px;overflow:hidden;');
item.appendChild(itemText);
item.querySelector('.item-text').appendChild(div);
// Description
if (typeof entry.description === 'string' || (typeof entry.description === 'number' && !isNaN(entry.description))) {
const description = document.createElement('small');
description.setAttribute('style', 'line-height:1.3;color:grey;white-space:nowrap;text-overflow:ellipsis;display:block;width:90%;overflow:hidden;');
description.innerText = entry.description;
item.querySelector('.item-text').appendChild(description);
}
// Set Grid
const getGridConfig = () => {
if (this.options.isMultiSelect) {
if (entry.image)
return '40px min-content auto'; // cb-img-txt
return '40px auto'; // cb-txt
}
if (entry.image)
return 'min-content auto'; // img-txt
return 'auto'; // txt
2022-08-04 19:50:18 -05:00
};
item.style.gridTemplateColumns = getGridConfig();
return item;
}
_renderDropdown() {
this._resetAutocomplete();
// Check if Data is empty
if (this.menuItems.length === 0) {
this.menuItems = this.selectedValues; // Show selected Items
2022-08-04 19:50:18 -05:00
}
for (let i = 0; i < this.menuItems.length; i++) {
const item = this._createDropdownItem(this.menuItems[i]);
this.container.append(item);
}
}
_setStatusLoading() {
this.el.parentElement.querySelector('.status-info').innerHTML = `<div style="height:100%;width:50px;"><svg version="1.1" id="L4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">
<circle fill="#888c" stroke="none" cx="6" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.1"/></circle>
<circle fill="#888c" stroke="none" cx="26" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.2"/></circle>
<circle fill="#888c" stroke="none" cx="46" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.3"/></circle>
</svg></div>`;
}
_updateSelectedInfo() {
const statusElement = this.el.parentElement.querySelector('.status-info');
if (statusElement) {
if (this.options.isMultiSelect)
statusElement.innerHTML = this.selectedValues.length.toString();
else
statusElement.innerHTML = '';
}
}
_refreshInputText() {
if (this.selectedValues.length === 1) {
const entry = this.selectedValues[0];
this.el.value = entry.text || entry.id; // Write Text to Input
}
}
_triggerChanged() {
this.el.dispatchEvent(new Event('change'));
// Trigger Autocomplete Event
if (typeof this.options.onAutocomplete === 'function')
this.options.onAutocomplete.call(this, this.selectedValues);
}
2022-08-04 19:50:18 -05:00
/**
* Updates the visible or selectable items shown in the menu.
* @param menuItems Items to be available.
2022-08-04 19:50:18 -05:00
*/
setMenuItems(menuItems) {
this.menuItems = menuItems;
this.open();
this._updateSelectedInfo();
2022-08-04 19:50:18 -05:00
}
/**
* Sets selected values.
* @param entries
*/
setValues(entries) {
this.selectedValues = entries;
this._updateSelectedInfo();
if (!this.options.isMultiSelect) {
this._refreshInputText();
}
this._triggerChanged();
2022-08-04 19:50:18 -05:00
}
/**
* Select a specific autocomplete option via id-property.
* @param id The id of a data-entry.
*/
selectOption(id) {
const entry = this.menuItems.find((item) => item.id == id);
if (!entry)
return;
// Toggle Checkbox
const li = this.container.querySelector('li[data-id="' + id + '"]');
if (!li)
return;
if (this.options.isMultiSelect) {
const checkbox = li.querySelector('input[type="checkbox"]');
checkbox.checked = !checkbox.checked;
if (checkbox.checked)
this.selectedValues.push(entry);
else
this.selectedValues = this.selectedValues.filter((selectedEntry) => selectedEntry.id !== entry.id);
this.el.focus();
}
else {
// Single-Select
this.selectedValues = [entry];
this._refreshInputText();
this._resetAutocomplete();
this.close();
}
this._updateSelectedInfo();
this._triggerChanged();
2022-08-04 19:50:18 -05:00
}
}
exports.Autocomplete = Autocomplete;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/buttons.ts":
/*!************************!*\
!*** ./src/buttons.ts ***!
\************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.FloatingActionButton = void 0;
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
let _defaults = {
direction: 'top',
hoverEnabled: true,
toolbarEnabled: false
};
class FloatingActionButton extends component_1.Component {
constructor(el, options) {
super(el, options, FloatingActionButton);
this._handleFABClick = () => {
if (this.isOpen) {
this.close();
}
else {
this.open();
}
};
this._handleDocumentClick = (e) => {
const elem = e.target;
if (elem !== this._menu)
this.close;
};
/**
* Open FAB.
*/
this.open = () => {
if (this.isOpen)
return;
if (this.options.toolbarEnabled)
this._animateInToolbar();
else
this._animateInFAB();
this.isOpen = true;
};
/**
* Close FAB.
*/
this.close = () => {
if (!this.isOpen)
return;
if (this.options.toolbarEnabled) {
window.removeEventListener('scroll', this.close, true);
document.body.removeEventListener('click', this._handleDocumentClick, true);
}
else {
this._animateOutFAB();
}
this.isOpen = false;
};
this.el.M_FloatingActionButton = this;
this.options = Object.assign(Object.assign({}, FloatingActionButton.defaults), options);
this.isOpen = false;
this._anchor = this.el.querySelector('a');
this._menu = this.el.querySelector('ul');
this._floatingBtns = Array.from(this.el.querySelectorAll('ul .btn-floating'));
this._floatingBtnsReverse = this._floatingBtns.reverse();
this.offsetY = 0;
this.offsetX = 0;
this.el.classList.add(`direction-${this.options.direction}`);
if (this.options.direction === 'top')
this.offsetY = 40;
else if (this.options.direction === 'right')
this.offsetX = -40;
else if (this.options.direction === 'bottom')
this.offsetY = -40;
else
this.offsetX = 40;
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of FloatingActionButton.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, FloatingActionButton);
}
static getInstance(el) {
return el.M_FloatingActionButton;
}
destroy() {
this._removeEventHandlers();
this.el.M_FloatingActionButton = undefined;
}
_setupEventHandlers() {
if (this.options.hoverEnabled && !this.options.toolbarEnabled) {
this.el.addEventListener('mouseenter', this.open);
this.el.addEventListener('mouseleave', this.close);
}
else {
this.el.addEventListener('click', this._handleFABClick);
}
}
_removeEventHandlers() {
if (this.options.hoverEnabled && !this.options.toolbarEnabled) {
this.el.removeEventListener('mouseenter', this.open);
this.el.removeEventListener('mouseleave', this.close);
}
else {
this.el.removeEventListener('click', this._handleFABClick);
}
}
_animateInFAB() {
this.el.classList.add('active');
const delayIncrement = 40;
const duration = 275;
this._floatingBtnsReverse.forEach((el, index) => {
const delay = delayIncrement * index;
el.style.transition = 'none';
el.style.opacity = '0';
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
setTimeout(() => {
// from:
el.style.opacity = '0.4';
// easeInOutQuad
setTimeout(() => {
// to:
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
el.style.opacity = '1';
el.style.transform = 'translate(0, 0) scale(1)';
}, 1);
}, delay);
});
}
_animateOutFAB() {
const duration = 175;
setTimeout(() => this.el.classList.remove('active'), duration);
this._floatingBtnsReverse.forEach((el) => {
el.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
// to
el.style.opacity = '0';
el.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px) scale(0.4)`;
});
}
_animateInToolbar() {
let scaleFactor;
let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;
let btnRect = this.el.getBoundingClientRect();
const backdrop = document.createElement('div');
backdrop.classList.add('fab-backdrop'); // $('<div class="fab-backdrop"></div>');
const fabColor = getComputedStyle(this._anchor).backgroundColor; // css('background-color');
this._anchor.append(backdrop);
this.offsetX = btnRect.left - windowWidth / 2 + btnRect.width / 2;
this.offsetY = windowHeight - btnRect.bottom;
scaleFactor = windowWidth / backdrop[0].clientWidth;
this.btnBottom = btnRect.bottom;
this.btnLeft = btnRect.left;
this.btnWidth = btnRect.width;
// Set initial state
this.el.classList.add('active');
this.el.style.textAlign = 'center';
this.el.style.width = '100%';
this.el.style.bottom = '0';
this.el.style.left = '0';
this.el.style.transform = 'translateX(' + this.offsetX + 'px)';
this.el.style.transition = 'none';
this._anchor.style.transform = `translateY(${this.offsetY}px`;
this._anchor.style.transition = 'none';
backdrop.style.backgroundColor = fabColor;
setTimeout(() => {
this.el.style.transform = '';
this.el.style.transition = 'transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s';
this._anchor.style.overflow = 'visible';
this._anchor.style.transform = '';
this._anchor.style.transition = 'transform .2s';
setTimeout(() => {
this.el.style.overflow = 'hidden';
this.el.style.backgroundColor = fabColor;
backdrop.style.transform = 'scale(' + scaleFactor + ')';
backdrop.style.transition = 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)';
this._menu.querySelectorAll('li > a').forEach((a) => a.style.opacity = '1');
// Scroll to close.
window.addEventListener('scroll', this.close, true);
document.body.addEventListener('click', this._handleDocumentClick, true);
}, 100);
}, 0);
}
}
exports.FloatingActionButton = FloatingActionButton;
/***/ }),
/***/ "./src/cards.ts":
/*!**********************!*\
!*** ./src/cards.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Cards = void 0;
class Cards {
static Init() {
document.addEventListener("DOMContentLoaded", () => {
document.body.addEventListener('click', e => {
const trigger = e.target;
const card = trigger.closest('.card');
if (!card)
return;
const cardReveal = Array.from(card.children).find(elem => elem.classList.contains('card-reveal'));
if (!cardReveal)
return;
const initialOverflow = getComputedStyle(card).overflow;
// Close Card
const closeArea = cardReveal.querySelector('.card-reveal .card-title');
if (trigger === closeArea || closeArea.contains(trigger)) {
const duration = 225;
cardReveal.style.transition = `transform ${duration}ms ease`; //easeInOutQuad
cardReveal.style.transform = 'translateY(0)';
setTimeout(() => {
cardReveal.style.display = 'none';
card.style.overflow = initialOverflow;
}, duration);
}
;
// Reveal Card
const activators = card.querySelectorAll('.activator');
activators.forEach(activator => {
if (trigger === activator || activator.contains(trigger)) {
card.style.overflow = 'hidden';
cardReveal.style.display = 'block';
setTimeout(() => {
const duration = 300;
cardReveal.style.transition = `transform ${duration}ms ease`; //easeInOutQuad
cardReveal.style.transform = 'translateY(-100%)';
}, 1);
}
});
});
});
}
}
exports.Cards = Cards;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/carousel.ts":
/*!*************************!*\
!*** ./src/carousel.ts ***!
\*************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Carousel = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
let _defaults = {
duration: 200, // ms
dist: -100, // zoom scale TODO: make this more intuitive as an option
shift: 0, // spacing for center image
padding: 0, // Padding between non center items
numVisible: 5, // Number of visible items in carousel
fullWidth: false, // Change to full width styles
indicators: false, // Toggle indicators
noWrap: false, // Don't wrap around and cycle through items.
onCycleTo: null // Callback for when a new slide is cycled to.
};
class Carousel extends component_1.Component {
constructor(el, options) {
var _a;
super(el, options, Carousel);
/** The index of the center carousel item. */
this.center = 0;
this._handleThrottledResize = utils_1.Utils.throttle(function () { this._handleResize(); }, 200, null).bind(this);
this._handleCarouselTap = (e) => {
// Fixes firefox draggable image bug
if (e.type === 'mousedown' && e.target.tagName === 'IMG') {
e.preventDefault();
}
this.pressed = true;
this.dragged = false;
this.verticalDragged = false;
this.reference = this._xpos(e);
this.referenceY = this._ypos(e);
this.velocity = this.amplitude = 0;
this.frame = this.offset;
this.timestamp = Date.now();
clearInterval(this.ticker);
this.ticker = setInterval(this._track, 100);
2022-08-04 19:50:18 -05:00
};
this._handleCarouselDrag = (e) => {
let x, y, delta, deltaY;
if (this.pressed) {
x = this._xpos(e);
y = this._ypos(e);
delta = this.reference - x;
deltaY = Math.abs(this.referenceY - y);
if (deltaY < 30 && !this.verticalDragged) {
// If vertical scrolling don't allow dragging.
if (delta > 2 || delta < -2) {
this.dragged = true;
this.reference = x;
this._scroll(this.offset + delta);
}
}
else if (this.dragged) {
// If dragging don't allow vertical scroll.
e.preventDefault();
e.stopPropagation();
return false;
}
else {
// Vertical scrolling.
this.verticalDragged = true;
}
}
if (this.dragged) {
// If dragging don't allow vertical scroll.
e.preventDefault();
e.stopPropagation();
return false;
}
2022-08-04 19:50:18 -05:00
};
this._handleCarouselRelease = (e) => {
if (this.pressed) {
this.pressed = false;
}
else {
return;
}
clearInterval(this.ticker);
this.target = this.offset;
if (this.velocity > 10 || this.velocity < -10) {
this.amplitude = 0.9 * this.velocity;
this.target = this.offset + this.amplitude;
}
this.target = Math.round(this.target / this.dim) * this.dim;
// No wrap of items.
if (this.noWrap) {
if (this.target >= this.dim * (this.count - 1)) {
this.target = this.dim * (this.count - 1);
}
else if (this.target < 0) {
this.target = 0;
}
}
this.amplitude = this.target - this.offset;
this.timestamp = Date.now();
requestAnimationFrame(this._autoScroll);
if (this.dragged) {
e.preventDefault();
e.stopPropagation();
}
return false;
2022-08-04 19:50:18 -05:00
};
this._handleCarouselClick = (e) => {
// Disable clicks if carousel was dragged.
if (this.dragged) {
e.preventDefault();
e.stopPropagation();
return false;
}
else if (!this.options.fullWidth) {
const clickedElem = e.target.closest('.carousel-item');
if (!clickedElem)
return;
const clickedIndex = [...clickedElem.parentNode.children].indexOf(clickedElem);
const diff = this._wrap(this.center) - clickedIndex;
// Disable clicks if carousel was shifted by click
if (diff !== 0) {
e.preventDefault();
e.stopPropagation();
}
// fixes https://github.com/materializecss/materialize/issues/180
if (clickedIndex < 0) {
// relative X position > center of carousel = clicked at the right part of the carousel
if (e.clientX - e.target.getBoundingClientRect().left > this.el.clientWidth / 2) {
this.next();
}
else {
this.prev();
}
}
else {
this._cycleTo(clickedIndex);
}
}
};
this._handleIndicatorClick = (e) => {
e.stopPropagation();
const indicator = e.target.closest('.indicator-item');
if (indicator) {
const index = [...indicator.parentNode.children].indexOf(indicator);
this._cycleTo(index);
}
};
this._handleResize = () => {
if (this.options.fullWidth) {
this.itemWidth = this.el.querySelector('.carousel-item').clientWidth;
this.imageHeight = this.el.querySelector('.carousel-item.active').clientHeight;
this.dim = this.itemWidth * 2 + this.options.padding;
this.offset = this.center * 2 * this.itemWidth;
this.target = this.offset;
this._setCarouselHeight(true);
}
else {
this._scroll();
}
};
this._track = () => {
let now, elapsed, delta, v;
now = Date.now();
elapsed = now - this.timestamp;
this.timestamp = now;
delta = this.offset - this.frame;
this.frame = this.offset;
v = (1000 * delta) / (1 + elapsed);
this.velocity = 0.8 * v + 0.2 * this.velocity;
};
this._autoScroll = () => {
let elapsed, delta;
if (this.amplitude) {
elapsed = Date.now() - this.timestamp;
delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
if (delta > 2 || delta < -2) {
this._scroll(this.target - delta);
requestAnimationFrame(this._autoScroll);
}
else {
this._scroll(this.target);
}
}
};
this.el.M_Carousel = this;
this.options = Object.assign(Object.assign({}, Carousel.defaults), options);
// Setup
this.hasMultipleSlides = this.el.querySelectorAll('.carousel-item').length > 1;
this.showIndicators = this.options.indicators && this.hasMultipleSlides;
this.noWrap = this.options.noWrap || !this.hasMultipleSlides;
this.pressed = false;
this.dragged = false;
this.offset = this.target = 0;
this.images = [];
this.itemWidth = this.el.querySelector('.carousel-item').clientWidth;
this.itemHeight = this.el.querySelector('.carousel-item').clientHeight;
this.dim = this.itemWidth * 2 + this.options.padding || 1; // Make sure dim is non zero for divisions.
// Full Width carousel setup
if (this.options.fullWidth) {
this.options.dist = 0;
this._setCarouselHeight();
// Offset fixed items when indicators.
if (this.showIndicators) {
(_a = this.el.querySelector('.carousel-fixed-item')) === null || _a === void 0 ? void 0 : _a.classList.add('with-indicators');
}
2022-08-04 19:50:18 -05:00
}
// Iterate through slides
this._indicators = document.createElement('ul');
this._indicators.classList.add('indicators');
this.el.querySelectorAll('.carousel-item').forEach((item, i) => {
this.images.push(item);
if (this.showIndicators) {
const indicator = document.createElement('li');
indicator.classList.add('indicator-item');
if (i === 0) {
indicator.classList.add('active');
}
this._indicators.appendChild(indicator);
}
});
if (this.showIndicators)
this.el.appendChild(this._indicators);
this.count = this.images.length;
// Cap numVisible at count
this.options.numVisible = Math.min(this.count, this.options.numVisible);
// Setup cross browser string
this.xform = 'transform';
['webkit', 'Moz', 'O', 'ms'].every((prefix) => {
var e = prefix + 'Transform';
if (typeof document.body.style[e] !== 'undefined') {
this.xform = e;
return false;
}
return true;
});
this._setupEventHandlers();
this._scroll(this.offset);
2022-08-04 19:50:18 -05:00
}
static get defaults() {
return _defaults;
2022-08-04 19:50:18 -05:00
}
/**
* Initializes instances of Carousel.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Carousel);
2022-08-04 19:50:18 -05:00
}
static getInstance(el) {
return el.M_Carousel;
2022-08-04 19:50:18 -05:00
}
destroy() {
this._removeEventHandlers();
this.el.M_Carousel = undefined;
2022-08-04 19:50:18 -05:00
}
_setupEventHandlers() {
if (typeof window.ontouchstart !== 'undefined') {
this.el.addEventListener('touchstart', this._handleCarouselTap);
this.el.addEventListener('touchmove', this._handleCarouselDrag);
this.el.addEventListener('touchend', this._handleCarouselRelease);
}
this.el.addEventListener('mousedown', this._handleCarouselTap);
this.el.addEventListener('mousemove', this._handleCarouselDrag);
this.el.addEventListener('mouseup', this._handleCarouselRelease);
this.el.addEventListener('mouseleave', this._handleCarouselRelease);
this.el.addEventListener('click', this._handleCarouselClick);
if (this.showIndicators && this._indicators) {
this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
el.addEventListener('click', this._handleIndicatorClick);
});
2022-08-04 19:50:18 -05:00
}
// Resize
window.addEventListener('resize', this._handleThrottledResize);
2022-08-04 19:50:18 -05:00
}
_removeEventHandlers() {
if (typeof window.ontouchstart !== 'undefined') {
this.el.removeEventListener('touchstart', this._handleCarouselTap);
this.el.removeEventListener('touchmove', this._handleCarouselDrag);
this.el.removeEventListener('touchend', this._handleCarouselRelease);
}
this.el.removeEventListener('mousedown', this._handleCarouselTap);
this.el.removeEventListener('mousemove', this._handleCarouselDrag);
this.el.removeEventListener('mouseup', this._handleCarouselRelease);
this.el.removeEventListener('mouseleave', this._handleCarouselRelease);
this.el.removeEventListener('click', this._handleCarouselClick);
if (this.showIndicators && this._indicators) {
this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
el.removeEventListener('click', this._handleIndicatorClick);
});
2022-08-04 19:50:18 -05:00
}
window.removeEventListener('resize', this._handleThrottledResize);
}
_setCarouselHeight(imageOnly = false) {
const firstSlide = this.el.querySelector('.carousel-item.active')
? this.el.querySelector('.carousel-item.active')
: this.el.querySelector('.carousel-item');
const firstImage = firstSlide.querySelector('img');
if (firstImage) {
if (firstImage.complete) {
// If image won't trigger the load event
const imageHeight = firstImage.clientHeight;
if (imageHeight > 0) {
this.el.style.height = imageHeight + 'px';
}
else {
// If image still has no height, use the natural dimensions to calculate
const naturalWidth = firstImage.naturalWidth;
const naturalHeight = firstImage.naturalHeight;
const adjustedHeight = (this.el.clientWidth / naturalWidth) * naturalHeight;
this.el.style.height = adjustedHeight + 'px';
}
2022-08-04 19:50:18 -05:00
}
else {
// Get height when image is loaded normally
firstImage.addEventListener('load', () => {
this.el.style.height = firstImage.offsetHeight + 'px';
});
2022-08-04 19:50:18 -05:00
}
}
else if (!imageOnly) {
const slideHeight = firstSlide.clientHeight;
this.el.style.height = slideHeight + 'px';
2022-08-04 19:50:18 -05:00
}
}
_xpos(e) {
// touch event
if (e.type.startsWith("touch") && e.targetTouches.length >= 1) {
return e.targetTouches[0].clientX;
2022-08-04 19:50:18 -05:00
}
// mouse event
return e.clientX;
}
_ypos(e) {
// touch event
if (e.type.startsWith("touch") && e.targetTouches.length >= 1) {
return e.targetTouches[0].clientY;
2022-08-04 19:50:18 -05:00
}
// mouse event
return e.clientY;
}
_wrap(x) {
return x >= this.count
? x % this.count
: x < 0
? this._wrap(this.count + (x % this.count))
: x;
}
_scroll(x = 0) {
// Track scrolling state
if (!this.el.classList.contains('scrolling')) {
this.el.classList.add('scrolling');
2022-08-04 19:50:18 -05:00
}
if (this.scrollingTimeout != null) {
window.clearTimeout(this.scrollingTimeout);
2022-08-04 19:50:18 -05:00
}
this.scrollingTimeout = window.setTimeout(() => {
this.el.classList.remove('scrolling');
}, this.options.duration);
// Start actual scroll
let i, half, delta, dir, tween, el, alignment, zTranslation, tweenedOpacity, centerTweenedOpacity;
let lastCenter = this.center;
let numVisibleOffset = 1 / this.options.numVisible;
this.offset = typeof x === 'number' ? x : this.offset;
this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
delta = this.offset - this.center * this.dim;
dir = delta < 0 ? 1 : -1;
tween = (-dir * delta * 2) / this.dim;
half = this.count >> 1;
if (this.options.fullWidth) {
alignment = 'translateX(0)';
centerTweenedOpacity = 1;
2022-08-04 19:50:18 -05:00
}
else {
alignment = 'translateX(' + (this.el.clientWidth - this.itemWidth) / 2 + 'px) ';
alignment += 'translateY(' + (this.el.clientHeight - this.itemHeight) / 2 + 'px)';
centerTweenedOpacity = 1 - numVisibleOffset * tween;
2022-08-04 19:50:18 -05:00
}
// Set indicator active
if (this.showIndicators) {
const diff = this.center % this.count;
const activeIndicator = this._indicators.querySelector('.indicator-item.active');
const activeIndicatorIndex = [...activeIndicator.parentNode.children].indexOf(activeIndicator);
if (activeIndicatorIndex !== diff) {
activeIndicator.classList.remove('active');
const pos = diff < 0 ? this.count + diff : diff;
this._indicators.querySelectorAll('.indicator-item')[pos].classList.add('active');
}
2022-08-04 19:50:18 -05:00
}
// center
// Don't show wrapped items.
if (!this.noWrap || (this.center >= 0 && this.center < this.count)) {
el = this.images[this._wrap(this.center)];
// Add active class to center item.
if (!el.classList.contains('active')) {
this.el.querySelector('.carousel-item').classList.remove('active');
el.classList.add('active');
}
let transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir *
this.options.shift *
tween *
i}px) translateZ(${this.options.dist * tween}px)`;
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
2022-08-04 19:50:18 -05:00
}
for (i = 1; i <= half; ++i) {
// right side
if (this.options.fullWidth) {
zTranslation = this.options.dist;
tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
}
else {
zTranslation = this.options.dist * (i * 2 + tween * dir);
tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
}
// Don't show wrapped items.
if (!this.noWrap || this.center + i < this.count) {
el = this.images[this._wrap(this.center + i)];
let transformString = `${alignment} translateX(${this.options.shift +
(this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
}
// left side
if (this.options.fullWidth) {
zTranslation = this.options.dist;
tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
}
else {
zTranslation = this.options.dist * (i * 2 - tween * dir);
tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
}
// Don't show wrapped items.
if (!this.noWrap || this.center - i >= 0) {
el = this.images[this._wrap(this.center - i)];
let transformString = `${alignment} translateX(${-this.options.shift +
(-this.dim * i - delta) / 2}px) translateZ(${zTranslation}px)`;
this._updateItemStyle(el, tweenedOpacity, -i, transformString);
}
2022-08-04 19:50:18 -05:00
}
// center
// Don't show wrapped items.
if (!this.noWrap || (this.center >= 0 && this.center < this.count)) {
el = this.images[this._wrap(this.center)];
let transformString = `${alignment} translateX(${-delta / 2}px) translateX(${dir *
this.options.shift *
tween}px) translateZ(${this.options.dist * tween}px)`;
this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
2022-08-04 19:50:18 -05:00
}
// onCycleTo callback
const _currItem = this.el.querySelectorAll('.carousel-item')[this._wrap(this.center)];
if (lastCenter !== this.center && typeof this.options.onCycleTo === 'function') {
this.options.onCycleTo.call(this, _currItem, this.dragged);
2022-08-04 19:50:18 -05:00
}
// One time callback
if (typeof this.oneTimeCallback === 'function') {
this.oneTimeCallback.call(this, _currItem, this.dragged);
this.oneTimeCallback = null;
2022-08-04 19:50:18 -05:00
}
}
_updateItemStyle(el, opacity, zIndex, transform) {
el.style[this.xform] = transform;
el.style.zIndex = zIndex.toString();
el.style.opacity = opacity.toString();
el.style.visibility = 'visible';
}
_cycleTo(n, callback = null) {
let diff = (this.center % this.count) - n;
// Account for wraparound.
if (!this.noWrap) {
if (diff < 0) {
if (Math.abs(diff + this.count) < Math.abs(diff)) {
diff += this.count;
}
}
else if (diff > 0) {
if (Math.abs(diff - this.count) < diff) {
diff -= this.count;
}
}
2022-08-04 19:50:18 -05:00
}
this.target = this.dim * Math.round(this.offset / this.dim);
// Next
if (diff < 0) {
this.target += this.dim * Math.abs(diff);
} // Prev
else if (diff > 0) {
this.target -= this.dim * diff;
2022-08-04 19:50:18 -05:00
}
// Set one time callback
if (typeof callback === 'function') {
this.oneTimeCallback = callback;
2022-08-04 19:50:18 -05:00
}
// Scroll
if (this.offset !== this.target) {
this.amplitude = this.target - this.offset;
this.timestamp = Date.now();
requestAnimationFrame(this._autoScroll);
2022-08-04 19:50:18 -05:00
}
}
/**
* Move carousel to next slide or go forward a given amount of slides.
* @param n How many times the carousel slides.
*/
next(n = 1) {
if (n === undefined || isNaN(n)) {
n = 1;
2022-08-04 19:50:18 -05:00
}
let index = this.center + n;
if (index >= this.count || index < 0) {
if (this.noWrap)
return;
index = this._wrap(index);
2022-08-04 19:50:18 -05:00
}
this._cycleTo(index);
}
/**
* Move carousel to previous slide or go back a given amount of slides.
* @param n How many times the carousel slides.
*/
prev(n = 1) {
if (n === undefined || isNaN(n)) {
n = 1;
2022-08-04 19:50:18 -05:00
}
let index = this.center - n;
if (index >= this.count || index < 0) {
if (this.noWrap)
return;
index = this._wrap(index);
2022-08-04 19:50:18 -05:00
}
this._cycleTo(index);
}
/**
* Move carousel to nth slide.
* @param n Index of slide.
* @param callback "onCycleTo" optional callback.
*/
set(n, callback) {
if (n === undefined || isNaN(n)) {
n = 0;
2022-08-04 19:50:18 -05:00
}
if (n > this.count || n < 0) {
if (this.noWrap)
return;
n = this._wrap(n);
}
this._cycleTo(n, callback);
}
}
exports.Carousel = Carousel;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/characterCounter.ts":
/*!*********************************!*\
!*** ./src/characterCounter.ts ***!
\*********************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CharacterCounter = void 0;
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
const _defaults = Object.freeze({});
class CharacterCounter extends component_1.Component {
constructor(el, options) {
super(el, {}, CharacterCounter);
this.updateCounter = () => {
let maxLength = parseInt(this.el.getAttribute('maxlength')), actualLength = this.el.value.length;
this.isValidLength = actualLength <= maxLength;
let counterString = actualLength.toString();
if (maxLength) {
counterString += '/' + maxLength;
this._validateInput();
}
this.counterEl.innerHTML = counterString;
};
this.el.M_CharacterCounter = this;
this.options = Object.assign(Object.assign({}, CharacterCounter.defaults), options);
this.isInvalid = false;
this.isValidLength = false;
this._setupCounter();
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
2022-08-04 19:50:18 -05:00
}
/**
* Initializes instances of CharacterCounter.
* @param els HTML elements.
* @param options Component options.
2022-08-04 19:50:18 -05:00
*/
static init(els, options = {}) {
return super.init(els, options, CharacterCounter);
}
static getInstance(el) {
return el.M_CharacterCounter;
}
destroy() {
2022-08-04 19:50:18 -05:00
this._removeEventHandlers();
this.el.CharacterCounter = undefined;
this._removeCounter();
}
_setupEventHandlers() {
this.el.addEventListener('focus', this.updateCounter, true);
this.el.addEventListener('input', this.updateCounter, true);
}
_removeEventHandlers() {
this.el.removeEventListener('focus', this.updateCounter, true);
this.el.removeEventListener('input', this.updateCounter, true);
}
_setupCounter() {
this.counterEl = document.createElement('span');
this.counterEl.classList.add('character-counter');
this.counterEl.style.float = 'right';
this.counterEl.style.fontSize = '12px';
this.counterEl.style.height = '1';
this.el.parentElement.appendChild(this.counterEl);
}
_removeCounter() {
this.counterEl.remove();
}
_validateInput() {
if (this.isValidLength && this.isInvalid) {
this.isInvalid = false;
this.el.classList.remove('invalid');
2022-08-04 19:50:18 -05:00
}
else if (!this.isValidLength && !this.isInvalid) {
this.isInvalid = true;
this.el.classList.remove('valid');
this.el.classList.add('invalid');
2022-08-04 19:50:18 -05:00
}
}
}
exports.CharacterCounter = CharacterCounter;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/chips.ts":
/*!**********************!*\
!*** ./src/chips.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Chips = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const autocomplete_1 = __webpack_require__(/*! ./autocomplete */ "./src/autocomplete.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
let _defaults = {
data: [],
placeholder: '',
secondaryPlaceholder: '',
closeIconClass: 'material-icons',
autocompleteOptions: {},
autocompleteOnly: false,
limit: Infinity,
onChipAdd: null,
onChipSelect: null,
onChipDelete: null
};
function gGetIndex(el) {
return [...el.parentNode.children].indexOf(el);
}
class Chips extends component_1.Component {
constructor(el, options) {
super(el, options, Chips);
this._handleChipClick = (e) => {
const _chip = e.target.closest('.chip');
const clickedClose = e.target.classList.contains('close');
if (_chip) {
const index = [..._chip.parentNode.children].indexOf(_chip);
if (clickedClose) {
this.deleteChip(index);
this._input.focus();
}
else {
this.selectChip(index);
}
// Default handle click to focus on input
2022-08-04 19:50:18 -05:00
}
else {
this._input.focus();
}
};
this._handleInputFocus = () => {
this.el.classList.add('focus');
};
this._handleInputBlur = () => {
this.el.classList.remove('focus');
};
this._handleInputKeydown = (e) => {
Chips._keydown = true;
if (utils_1.Utils.keys.ENTER.includes(e.key)) {
// Override enter if autocompleting.
if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
return;
}
e.preventDefault();
if (!this.hasAutocomplete || (this.hasAutocomplete && !this.options.autocompleteOnly)) {
this.addChip({ id: this._input.value });
}
this._input.value = '';
}
else if ((utils_1.Utils.keys.BACKSPACE.includes(e.key) || utils_1.Utils.keys.ARROW_LEFT.includes(e.key)) &&
this._input.value === '' &&
this.chipsData.length) {
e.preventDefault();
this.selectChip(this.chipsData.length - 1);
}
};
this.el.M_Chips = this;
this.options = Object.assign(Object.assign({}, Chips.defaults), options);
this.el.classList.add('chips', 'input-field');
this.chipsData = [];
this._chips = [];
this._setupInput();
this.hasAutocomplete = Object.keys(this.options.autocompleteOptions).length > 0;
// Set input id
if (!this._input.getAttribute('id'))
this._input.setAttribute('id', utils_1.Utils.guid());
// Render initial chips
if (this.options.data.length) {
this.chipsData = this.options.data;
this._renderChips();
}
// Setup autocomplete if needed
if (this.hasAutocomplete)
this._setupAutocomplete();
this._setPlaceholder();
this._setupLabel();
this._setupEventHandlers();
}
static get defaults() {
2022-08-04 19:50:18 -05:00
return _defaults;
}
2022-08-04 19:50:18 -05:00
/**
* Initializes instances of Chips.
* @param els HTML elements.
* @param options Component options.
2022-08-04 19:50:18 -05:00
*/
static init(els, options = {}) {
return super.init(els, options, Chips);
}
static getInstance(el) {
return el.M_Chips;
}
getData() {
return this.chipsData;
}
destroy() {
2022-08-04 19:50:18 -05:00
this._removeEventHandlers();
this._chips.forEach(c => c.remove());
this._chips = [];
this.el.M_Chips = undefined;
}
_setupEventHandlers() {
this.el.addEventListener('click', this._handleChipClick);
document.addEventListener('keydown', Chips._handleChipsKeydown);
document.addEventListener('keyup', Chips._handleChipsKeyup);
this.el.addEventListener('blur', Chips._handleChipsBlur, true);
this._input.addEventListener('focus', this._handleInputFocus);
this._input.addEventListener('blur', this._handleInputBlur);
this._input.addEventListener('keydown', this._handleInputKeydown);
}
_removeEventHandlers() {
this.el.removeEventListener('click', this._handleChipClick);
document.removeEventListener('keydown', Chips._handleChipsKeydown);
document.removeEventListener('keyup', Chips._handleChipsKeyup);
this.el.removeEventListener('blur', Chips._handleChipsBlur, true);
this._input.removeEventListener('focus', this._handleInputFocus);
this._input.removeEventListener('blur', this._handleInputBlur);
this._input.removeEventListener('keydown', this._handleInputKeydown);
}
static _handleChipsKeydown(e) {
Chips._keydown = true;
const chips = e.target.closest('.chips');
const chipsKeydown = e.target && chips;
// Don't handle keydown inputs on input and textarea
const tag = e.target.tagName;
if (tag === 'INPUT' || tag === 'TEXTAREA' || !chipsKeydown)
return;
const currChips = chips.M_Chips;
if (utils_1.Utils.keys.BACKSPACE.includes(e.key) || utils_1.Utils.keys.DELETE.includes(e.key)) {
e.preventDefault();
let selectIndex = currChips.chipsData.length;
if (currChips._selectedChip) {
const index = gGetIndex(currChips._selectedChip);
currChips.deleteChip(index);
currChips._selectedChip = null;
// Make sure selectIndex doesn't go negative
selectIndex = Math.max(index - 1, 0);
}
if (currChips.chipsData.length)
currChips.selectChip(selectIndex);
else
currChips._input.focus();
}
else if (utils_1.Utils.keys.ARROW_LEFT.includes(e.key)) {
if (currChips._selectedChip) {
const selectIndex = gGetIndex(currChips._selectedChip) - 1;
if (selectIndex < 0)
return;
currChips.selectChip(selectIndex);
}
}
else if (utils_1.Utils.keys.ARROW_RIGHT.includes(e.key)) {
if (currChips._selectedChip) {
const selectIndex = gGetIndex(currChips._selectedChip) + 1;
if (selectIndex >= currChips.chipsData.length)
currChips._input.focus();
else
currChips.selectChip(selectIndex);
}
}
}
static _handleChipsKeyup(e) {
Chips._keydown = false;
}
static _handleChipsBlur(e) {
if (!Chips._keydown && document.hidden) {
const chips = e.target.closest('.chips');
const currChips = chips.M_Chips;
currChips._selectedChip = null;
}
}
_renderChip(chip) {
if (!chip.id)
return;
const renderedChip = document.createElement('div');
renderedChip.classList.add('chip');
renderedChip.innerText = chip.text || chip.id;
renderedChip.setAttribute('tabindex', "0");
const closeIcon = document.createElement('i');
closeIcon.classList.add(this.options.closeIconClass, 'close');
closeIcon.innerText = 'close';
// attach image if needed
if (chip.image) {
const img = document.createElement('img');
img.setAttribute('src', chip.image);
renderedChip.insertBefore(img, renderedChip.firstChild);
2022-08-04 19:50:18 -05:00
}
renderedChip.appendChild(closeIcon);
return renderedChip;
}
_renderChips() {
this._chips = []; //.remove();
for (let i = 0; i < this.chipsData.length; i++) {
const chipElem = this._renderChip(this.chipsData[i]);
this.el.appendChild(chipElem);
this._chips.push(chipElem);
}
// move input to end
this.el.append(this._input);
}
_setupAutocomplete() {
this.options.autocompleteOptions.onAutocomplete = (items) => {
if (items.length > 0)
this.addChip({
id: items[0].id,
text: items[0].text,
image: items[0].image
});
this._input.value = '';
this._input.focus();
2022-08-04 19:50:18 -05:00
};
this.autocomplete = autocomplete_1.Autocomplete.init(this._input, this.options.autocompleteOptions);
}
_setupInput() {
this._input = this.el.querySelector('input');
if (!this._input) {
this._input = document.createElement('input');
this.el.append(this._input);
2022-08-04 19:50:18 -05:00
}
this._input.classList.add('input');
}
_setupLabel() {
this._label = this.el.querySelector('label');
if (this._label)
this._label.setAttribute('for', this._input.getAttribute('id'));
}
_setPlaceholder() {
if (this.chipsData !== undefined && !this.chipsData.length && this.options.placeholder) {
this._input.placeholder = this.options.placeholder;
2022-08-04 19:50:18 -05:00
}
else if ((this.chipsData === undefined || !!this.chipsData.length) &&
this.options.secondaryPlaceholder) {
this._input.placeholder = this.options.secondaryPlaceholder;
2022-08-04 19:50:18 -05:00
}
}
_isValidAndNotExist(chip) {
const isValid = !!chip.id;
const doesNotExist = !this.chipsData.some(item => item.id == chip.id);
return isValid && doesNotExist;
}
/**
* Add chip to input.
* @param chip Chip data object
*/
addChip(chip) {
if (!this._isValidAndNotExist(chip) || this.chipsData.length >= this.options.limit)
return;
const renderedChip = this._renderChip(chip);
this._chips.push(renderedChip);
this.chipsData.push(chip);
//$(this._input).before(renderedChip);
this._input.before(renderedChip);
this._setPlaceholder();
// fire chipAdd callback
if (typeof this.options.onChipAdd === 'function') {
this.options.onChipAdd(this.el, renderedChip);
2022-08-04 19:50:18 -05:00
}
}
/**
* Delete nth chip.
* @param chipIndex Index of chip
*/
deleteChip(chipIndex) {
const chip = this._chips[chipIndex];
this._chips[chipIndex].remove();
this._chips.splice(chipIndex, 1);
this.chipsData.splice(chipIndex, 1);
this._setPlaceholder();
// fire chipDelete callback
if (typeof this.options.onChipDelete === 'function') {
this.options.onChipDelete(this.el, chip);
2022-08-04 19:50:18 -05:00
}
}
/**
* Select nth chip.
* @param chipIndex Index of chip
*/
selectChip(chipIndex) {
const chip = this._chips[chipIndex];
this._selectedChip = chip;
chip.focus();
// fire chipSelect callback
if (typeof this.options.onChipSelect === 'function') {
this.options.onChipSelect(this.el, chip);
2022-08-04 19:50:18 -05:00
}
}
static Init() {
document.addEventListener("DOMContentLoaded", () => {
// Handle removal of static chips.
document.body.addEventListener('click', e => {
if (e.target.closest('.chip .close')) {
const chips = e.target.closest('.chips');
if (chips && chips.M_Chips == undefined)
return;
e.target.closest('.chip').remove();
}
});
});
}
}
exports.Chips = Chips;
(() => {
Chips._keydown = false;
})();
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/collapsible.ts":
/*!****************************!*\
!*** ./src/collapsible.ts ***!
\****************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Collapsible = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
const _defaults = {
accordion: true,
onOpenStart: null,
onOpenEnd: null,
onCloseStart: null,
onCloseEnd: null,
inDuration: 300,
outDuration: 300
};
class Collapsible extends component_1.Component {
constructor(el, options) {
super(el, options, Collapsible);
this._handleCollapsibleClick = (e) => {
const header = e.target.closest('.collapsible-header');
if (e.target && header) {
const collapsible = header.closest('.collapsible');
if (collapsible !== this.el)
return;
const li = header.closest('li');
const isActive = li.classList.contains('active');
const index = [...li.parentNode.children].indexOf(li);
if (isActive)
this.close(index);
else
this.open(index);
}
};
this._handleCollapsibleKeydown = (e) => {
if (utils_1.Utils.keys.ENTER.includes(e.key)) {
this._handleCollapsibleClick(e);
}
};
/**
* Open collapsible section.
* @param n Nth section to open.
*/
this.open = (index) => {
const listItems = Array.from(this.el.children).filter(c => c.tagName === 'LI');
const li = listItems[index];
if (li && !li.classList.contains('active')) {
// onOpenStart callback
if (typeof this.options.onOpenStart === 'function') {
this.options.onOpenStart.call(this, li);
}
// Handle accordion behavior
if (this.options.accordion) {
const activeLis = listItems.filter(li => li.classList.contains('active'));
activeLis.forEach(activeLi => {
const index = listItems.indexOf(activeLi);
this.close(index);
});
}
// Animate in
li.classList.add('active');
this._animateIn(index);
}
};
/**
* Close collapsible section.
* @param n Nth section to close.
*/
this.close = (index) => {
const li = Array.from(this.el.children).filter(c => c.tagName === 'LI')[index];
if (li && li.classList.contains('active')) {
// onCloseStart callback
if (typeof this.options.onCloseStart === 'function') {
this.options.onCloseStart.call(this, li);
}
// Animate out
li.classList.remove('active');
this._animateOut(index);
}
};
this.el.M_Collapsible = this;
this.options = Object.assign(Object.assign({}, Collapsible.defaults), options);
// Setup tab indices
this._headers = Array.from(this.el.querySelectorAll('li > .collapsible-header'));
this._headers.forEach(el => el.tabIndex = 0);
this._setupEventHandlers();
// Open active
const activeBodies = Array.from(this.el.querySelectorAll('li.active > .collapsible-body'));
if (this.options.accordion) {
if (activeBodies.length > 0) {
// Accordion => open first active only
this._setExpanded(activeBodies[0]);
}
2022-08-04 19:50:18 -05:00
}
else {
// Expandables => all active
activeBodies.forEach(el => this._setExpanded(el));
}
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Collapsible.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Collapsible);
}
static getInstance(el) {
return el.M_Collapsible;
}
destroy() {
this._removeEventHandlers();
this.el.M_Collapsible = undefined;
}
_setupEventHandlers() {
this.el.addEventListener('click', this._handleCollapsibleClick);
this._headers.forEach(header => header.addEventListener('keydown', this._handleCollapsibleKeydown));
}
_removeEventHandlers() {
this.el.removeEventListener('click', this._handleCollapsibleClick);
this._headers.forEach(header => header.removeEventListener('keydown', this._handleCollapsibleKeydown));
}
_setExpanded(li) {
li.style.maxHeight = li.scrollHeight + "px";
}
_animateIn(index) {
const li = this.el.children[index];
if (!li)
return;
const body = li.querySelector('.collapsible-body');
const duration = this.options.inDuration; // easeInOutCubic
body.style.transition = `max-height ${duration}ms ease-out`;
this._setExpanded(body);
setTimeout(() => {
if (typeof this.options.onOpenEnd === 'function') {
this.options.onOpenEnd.call(this, li);
}
}, duration);
}
_animateOut(index) {
const li = this.el.children[index];
if (!li)
return;
const body = li.querySelector('.collapsible-body');
const duration = this.options.outDuration; // easeInOutCubic
body.style.transition = `max-height ${duration}ms ease-out`;
body.style.maxHeight = "0";
setTimeout(() => {
if (typeof this.options.onCloseEnd === 'function') {
this.options.onCloseEnd.call(this, li);
}
}, duration);
}
}
exports.Collapsible = Collapsible;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/component.ts":
/*!**************************!*\
!*** ./src/component.ts ***!
\**************************/
/***/ (function(__unused_webpack_module, exports) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Component = void 0;
;
;
/**
* Base class implementation for Materialize components.
*/
class Component {
/**
* Constructs component instance and set everything up.
*/
constructor(el, options, classDef) {
// Display error if el is not a valid HTML Element
if (!(el instanceof HTMLElement)) {
console.error(Error(el + ' is not an HTML Element'));
2022-08-04 19:50:18 -05:00
}
// If exists, destroy and reinitialize in child
let ins = classDef.getInstance(el);
if (!!ins) {
ins.destroy();
2022-08-04 19:50:18 -05:00
}
this.el = el;
}
/**
* Initializes component instances.
* @param els HTML elements.
* @param options Component options.
* @param classDef Class definition.
*/
static init(els, options, classDef) {
let instances = null;
if (els instanceof Element) {
instances = new classDef(els, options);
}
else if (!!els && els.length) {
instances = [];
for (let i = 0; i < els.length; i++) {
instances.push(new classDef(els[i], options));
2022-08-04 19:50:18 -05:00
}
}
return instances;
}
/**
* @returns default options for component instance.
*/
static get defaults() { return {}; }
/**
* Retrieves component instance for the given element.
* @param el Associated HTML Element.
*/
static getInstance(el) {
throw new Error("This method must be implemented.");
}
/**
* Destroy plugin instance and teardown.
*/
destroy() { throw new Error("This method must be implemented."); }
}
exports.Component = Component;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/datepicker.ts":
/*!***************************!*\
!*** ./src/datepicker.ts ***!
\***************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Datepicker = void 0;
const modal_1 = __webpack_require__(/*! ./modal */ "./src/modal.ts");
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const select_1 = __webpack_require__(/*! ./select */ "./src/select.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
let _defaults = {
// Close when date is selected
autoClose: false,
// the default output format for the input field value
format: 'mmm dd, yyyy',
// Used to create date object from current input string
parse: null,
// The initial date to view when first opened
defaultDate: null,
// Make the `defaultDate` the initial selected value
setDefaultDate: false,
disableWeekends: false,
disableDayFn: null,
// First day of week (0: Sunday, 1: Monday etc)
firstDay: 0,
// The earliest date that can be selected
minDate: null,
// Thelatest date that can be selected
maxDate: null,
// Number of years either side, or array of upper/lower range
yearRange: 10,
// used internally (don't config outside)
minYear: 0,
maxYear: 9999,
minMonth: undefined,
maxMonth: undefined,
startRange: null,
endRange: null,
isRTL: false,
yearRangeReverse: false,
// Render the month after year in the calendar title
showMonthAfterYear: false,
// Render days of the calendar grid that fall in the next or previous month
showDaysInNextAndPreviousMonths: false,
// Specify a DOM element to render the calendar in
container: null,
// Show clear button
showClearBtn: false,
// internationalization
i18n: {
cancel: 'Cancel',
clear: 'Clear',
done: 'Ok',
previousMonth: '',
nextMonth: '',
months: [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
],
monthsShort: [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
],
weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
weekdaysAbbrev: ['S', 'M', 'T', 'W', 'T', 'F', 'S']
},
// events array
events: [],
// callback function
onSelect: null,
onOpen: null,
onClose: null,
onDraw: null
};
class Datepicker extends component_1.Component {
constructor(el, options) {
super(el, options, Datepicker);
this._handleInputClick = () => {
this.open();
};
this._handleInputKeydown = (e) => {
if (utils_1.Utils.keys.ENTER.includes(e.key)) {
e.preventDefault();
this.open();
}
};
this._handleCalendarClick = (e) => {
if (!this.isOpen)
return;
const target = (e.target);
if (!target.classList.contains('is-disabled')) {
if (target.classList.contains('datepicker-day-button') &&
!target.classList.contains('is-empty') &&
!target.parentElement.classList.contains('is-disabled')) {
this.setDate(new Date(e.target.getAttribute('data-year'), e.target.getAttribute('data-month'), e.target.getAttribute('data-day')));
if (this.options.autoClose) {
this._finishSelection();
}
}
else if (target.closest('.month-prev')) {
this.prevMonth();
}
else if (target.closest('.month-next')) {
this.nextMonth();
}
}
};
this._handleClearClick = () => {
this.date = null;
this.setInputValue();
this.close();
};
this._handleMonthChange = (e) => {
this.gotoMonth(e.target.value);
};
this._handleYearChange = (e) => {
this.gotoYear(e.target.value);
};
this._handleInputChange = (e) => {
var _a;
let date;
// Prevent change event from being fired when triggered by the plugin
if (((_a = e['detail']) === null || _a === void 0 ? void 0 : _a.firedBy) === this)
return;
if (this.options.parse) {
date = this.options.parse(this.el.value, typeof this.options.format === "function"
? this.options.format(new Date(this.el.value))
: this.options.format);
}
else {
date = new Date(Date.parse(this.el.value));
}
if (Datepicker._isDate(date))
this.setDate(date);
};
// Set input value to the selected date and close Datepicker
this._finishSelection = () => {
this.setInputValue();
this.close();
};
/**
* Open datepicker.
*/
this.open = () => {
if (this.isOpen)
return;
this.isOpen = true;
if (typeof this.options.onOpen === 'function') {
this.options.onOpen.call(this);
}
this.draw();
this.modal.open(undefined);
return this;
};
/**
* Close datepicker.
*/
this.close = () => {
if (!this.isOpen)
return;
this.isOpen = false;
if (typeof this.options.onClose === 'function') {
this.options.onClose.call(this);
}
this.modal.close();
return this;
};
this.el.M_Datepicker = this;
this.options = Object.assign(Object.assign({}, Datepicker.defaults), options);
// make sure i18n defaults are not lost when only few i18n option properties are passed
if (!!options && options.hasOwnProperty('i18n') && typeof options.i18n === 'object') {
this.options.i18n = Object.assign(Object.assign({}, Datepicker.defaults.i18n), options.i18n);
}
// Remove time component from minDate and maxDate options
if (this.options.minDate)
this.options.minDate.setHours(0, 0, 0, 0);
if (this.options.maxDate)
this.options.maxDate.setHours(0, 0, 0, 0);
this.id = utils_1.Utils.guid();
this._setupVariables();
this._insertHTMLIntoDOM();
this._setupModal();
this._setupEventHandlers();
if (!this.options.defaultDate) {
this.options.defaultDate = new Date(Date.parse(this.el.value));
}
let defDate = this.options.defaultDate;
if (Datepicker._isDate(defDate)) {
if (this.options.setDefaultDate) {
this.setDate(defDate, true);
this.setInputValue();
}
else {
this.gotoDate(defDate);
}
}
else {
this.gotoDate(new Date());
2022-08-04 19:50:18 -05:00
}
this.isOpen = false;
2022-08-04 19:50:18 -05:00
}
static get defaults() {
return _defaults;
2022-08-04 19:50:18 -05:00
}
/**
* Initializes instances of Datepicker.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Datepicker);
2022-08-04 19:50:18 -05:00
}
static _isDate(obj) {
return /Date/.test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
2022-08-04 19:50:18 -05:00
}
static _isWeekend(date) {
let day = date.getDay();
return day === 0 || day === 6;
2022-08-04 19:50:18 -05:00
}
static _setToStartOfDay(date) {
if (Datepicker._isDate(date))
date.setHours(0, 0, 0, 0);
2022-08-04 19:50:18 -05:00
}
static _getDaysInMonth(year, month) {
return [31, Datepicker._isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
2022-08-04 19:50:18 -05:00
}
static _isLeapYear(year) {
// solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
2022-08-04 19:50:18 -05:00
}
static _compareDates(a, b) {
// weak date comparison (use setToStartOfDay(date) to ensure correct result)
return a.getTime() === b.getTime();
2022-08-04 19:50:18 -05:00
}
static getInstance(el) {
return el.M_Datepicker;
2022-08-04 19:50:18 -05:00
}
destroy() {
this._removeEventHandlers();
this.modal.destroy();
this.modalEl.remove();
this.destroySelects();
this.el.M_Datepicker = undefined;
2022-08-04 19:50:18 -05:00
}
destroySelects() {
let oldYearSelect = this.calendarEl.querySelector('.orig-select-year');
if (oldYearSelect) {
select_1.FormSelect.getInstance(oldYearSelect).destroy();
}
let oldMonthSelect = this.calendarEl.querySelector('.orig-select-month');
if (oldMonthSelect) {
select_1.FormSelect.getInstance(oldMonthSelect).destroy();
}
2022-08-04 19:50:18 -05:00
}
_insertHTMLIntoDOM() {
if (this.options.showClearBtn) {
this.clearBtn.style.visibility = '';
this.clearBtn.innerText = this.options.i18n.clear;
}
this.doneBtn.innerText = this.options.i18n.done;
this.cancelBtn.innerText = this.options.i18n.cancel;
if (this.options.container) {
const optEl = this.options.container;
this.options.container =
optEl instanceof HTMLElement ? optEl : document.querySelector(optEl);
this.options.container.append(this.modalEl);
}
else {
//this.modalEl.before(this.el);
this.el.parentElement.appendChild(this.modalEl);
}
2022-08-04 19:50:18 -05:00
}
_setupModal() {
this.modalEl.id = 'modal-' + this.id;
this.modal = modal_1.Modal.init(this.modalEl, {
onCloseEnd: () => {
this.isOpen = false;
}
});
2022-08-04 19:50:18 -05:00
}
/**
* Gets a string representation of the selected date.
2022-08-04 19:50:18 -05:00
*/
toString(format = null) {
format = format || this.options.format;
if (typeof format === 'function')
return format(this.date);
if (!Datepicker._isDate(this.date))
return '';
// String Format
const formatArray = format.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g);
const formattedDate = formatArray
.map(label => this.formats[label] ? this.formats[label]() : label)
.join('');
return formattedDate;
}
2022-08-04 19:50:18 -05:00
/**
* Set a date on the datepicker.
* @param date Date to set on the datepicker.
* @param preventOnSelect Undocumented as of 5 March 2018.
2022-08-04 19:50:18 -05:00
*/
setDate(date = null, preventOnSelect = false) {
if (!date) {
this.date = null;
this._renderDateDisplay();
return this.draw();
}
if (typeof date === 'string') {
date = new Date(Date.parse(date));
}
if (!Datepicker._isDate(date)) {
return;
}
let min = this.options.minDate, max = this.options.maxDate;
if (Datepicker._isDate(min) && date < min) {
date = min;
}
else if (Datepicker._isDate(max) && date > max) {
date = max;
}
this.date = new Date(date.getTime());
this._renderDateDisplay();
Datepicker._setToStartOfDay(this.date);
this.gotoDate(this.date);
if (!preventOnSelect && typeof this.options.onSelect === 'function') {
this.options.onSelect.call(this, this.date);
}
}
2022-08-04 19:50:18 -05:00
/**
* Sets current date as the input value.
2022-08-04 19:50:18 -05:00
*/
setInputValue() {
this.el.value = this.toString();
this.el.dispatchEvent(new CustomEvent('change', { bubbles: true, cancelable: true, composed: true, detail: { firedBy: this } }));
}
_renderDateDisplay() {
let displayDate = Datepicker._isDate(this.date) ? this.date : new Date();
let i18n = this.options.i18n;
let day = i18n.weekdaysShort[displayDate.getDay()];
let month = i18n.monthsShort[displayDate.getMonth()];
let date = displayDate.getDate();
this.yearTextEl.innerHTML = displayDate.getFullYear().toString();
this.dateTextEl.innerHTML = `${day}, ${month} ${date}`;
}
2022-08-04 19:50:18 -05:00
/**
* Change date view to a specific date on the datepicker.
* @param date Date to show on the datepicker.
2022-08-04 19:50:18 -05:00
*/
gotoDate(date) {
let newCalendar = true;
if (!Datepicker._isDate(date)) {
return;
2022-08-04 19:50:18 -05:00
}
if (this.calendars) {
let firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1), lastVisibleDate = new Date(this.calendars[this.calendars.length - 1].year, this.calendars[this.calendars.length - 1].month, 1), visibleDate = date.getTime();
// get the end of the month
lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1);
lastVisibleDate.setDate(lastVisibleDate.getDate() - 1);
newCalendar =
visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate;
}
if (newCalendar) {
this.calendars = [
{
month: date.getMonth(),
year: date.getFullYear()
}
];
}
this.adjustCalendars();
2022-08-04 19:50:18 -05:00
}
adjustCalendars() {
this.calendars[0] = this.adjustCalendar(this.calendars[0]);
this.draw();
}
adjustCalendar(calendar) {
if (calendar.month < 0) {
calendar.year -= Math.ceil(Math.abs(calendar.month) / 12);
calendar.month += 12;
2022-08-04 19:50:18 -05:00
}
if (calendar.month > 11) {
calendar.year += Math.floor(Math.abs(calendar.month) / 12);
calendar.month -= 12;
2022-08-04 19:50:18 -05:00
}
return calendar;
}
nextMonth() {
this.calendars[0].month++;
this.adjustCalendars();
}
prevMonth() {
this.calendars[0].month--;
this.adjustCalendars();
}
render(year, month, randId) {
let opts = this.options, now = new Date(), days = Datepicker._getDaysInMonth(year, month), before = new Date(year, month, 1).getDay(), data = [], row = [];
Datepicker._setToStartOfDay(now);
if (opts.firstDay > 0) {
before -= opts.firstDay;
if (before < 0) {
before += 7;
}
2022-08-04 19:50:18 -05:00
}
let previousMonth = month === 0 ? 11 : month - 1, nextMonth = month === 11 ? 0 : month + 1, yearOfPreviousMonth = month === 0 ? year - 1 : year, yearOfNextMonth = month === 11 ? year + 1 : year, daysInPreviousMonth = Datepicker._getDaysInMonth(yearOfPreviousMonth, previousMonth);
let cells = days + before, after = cells;
while (after > 7) {
after -= 7;
}
cells += 7 - after;
let isWeekSelected = false;
for (let i = 0, r = 0; i < cells; i++) {
let day = new Date(year, month, 1 + (i - before)), isSelected = Datepicker._isDate(this.date)
? Datepicker._compareDates(day, this.date)
: false, isToday = Datepicker._compareDates(day, now), hasEvent = opts.events.indexOf(day.toDateString()) !== -1 ? true : false, isEmpty = i < before || i >= days + before, dayNumber = 1 + (i - before), monthNumber = month, yearNumber = year, isStartRange = opts.startRange && Datepicker._compareDates(opts.startRange, day), isEndRange = opts.endRange && Datepicker._compareDates(opts.endRange, day), isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange, isDisabled = (opts.minDate && day < opts.minDate) ||
(opts.maxDate && day > opts.maxDate) ||
(opts.disableWeekends && Datepicker._isWeekend(day)) ||
(opts.disableDayFn && opts.disableDayFn(day));
if (isEmpty) {
if (i < before) {
dayNumber = daysInPreviousMonth + dayNumber;
monthNumber = previousMonth;
yearNumber = yearOfPreviousMonth;
}
else {
dayNumber = dayNumber - days;
monthNumber = nextMonth;
yearNumber = yearOfNextMonth;
}
2022-08-04 19:50:18 -05:00
}
let dayConfig = {
day: dayNumber,
month: monthNumber,
year: yearNumber,
hasEvent: hasEvent,
isSelected: isSelected,
isToday: isToday,
isDisabled: isDisabled,
isEmpty: isEmpty,
isStartRange: isStartRange,
isEndRange: isEndRange,
isInRange: isInRange,
showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths
};
row.push(this.renderDay(dayConfig));
if (++r === 7) {
data.push(this.renderRow(row, opts.isRTL, isWeekSelected));
row = [];
r = 0;
isWeekSelected = false;
}
}
return this.renderTable(opts, data, randId);
2022-08-04 19:50:18 -05:00
}
renderDay(opts) {
let arr = [];
let ariaSelected = 'false';
if (opts.isEmpty) {
if (opts.showDaysInNextAndPreviousMonths) {
arr.push('is-outside-current-month');
arr.push('is-selection-disabled');
}
else {
return '<td class="is-empty"></td>';
}
2022-08-04 19:50:18 -05:00
}
if (opts.isDisabled) {
arr.push('is-disabled');
2022-08-04 19:50:18 -05:00
}
if (opts.isToday) {
arr.push('is-today');
2022-08-04 19:50:18 -05:00
}
if (opts.isSelected) {
arr.push('is-selected');
ariaSelected = 'true';
2022-08-04 19:50:18 -05:00
}
if (opts.hasEvent) {
arr.push('has-event');
}
if (opts.isInRange) {
arr.push('is-inrange');
}
if (opts.isStartRange) {
arr.push('is-startrange');
}
if (opts.isEndRange) {
arr.push('is-endrange');
}
return (`<td data-day="${opts.day}" class="${arr.join(' ')}" aria-selected="${ariaSelected}">` +
`<button class="datepicker-day-button" type="button" data-year="${opts.year}" data-month="${opts.month}" data-day="${opts.day}">${opts.day}</button>` +
'</td>');
}
renderRow(days, isRTL, isRowSelected) {
return ('<tr class="datepicker-row' +
(isRowSelected ? ' is-selected' : '') +
'">' +
(isRTL ? days.reverse() : days).join('') +
'</tr>');
}
renderTable(opts, data, randId) {
return ('<div class="datepicker-table-wrapper"><table cellpadding="0" cellspacing="0" class="datepicker-table" role="grid" aria-labelledby="' +
randId +
'">' +
this.renderHead(opts) +
this.renderBody(data) +
'</table></div>');
}
renderHead(opts) {
let i, arr = [];
for (i = 0; i < 7; i++) {
arr.push(`<th scope="col"><abbr title="${this.renderDayName(opts, i)}">${this.renderDayName(opts, i, true)}</abbr></th>`);
}
return '<thead><tr>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</tr></thead>';
}
renderBody(rows) {
return '<tbody>' + rows.join('') + '</tbody>';
}
renderTitle(instance, c, year, month, refYear, randId) {
let i, j, arr, opts = this.options, isMinYear = year === opts.minYear, isMaxYear = year === opts.maxYear, html = '<div id="' +
randId +
'" class="datepicker-controls" role="heading" aria-live="assertive">', monthHtml, yearHtml, prev = true, next = true;
for (arr = [], i = 0; i < 12; i++) {
arr.push('<option value="' +
(year === refYear ? i - c : 12 + i - c) +
'"' +
(i === month ? ' selected="selected"' : '') +
((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth)
? 'disabled="disabled"'
: '') +
'>' +
opts.i18n.months[i] +
'</option>');
}
monthHtml = '<select class="datepicker-select orig-select-month" tabindex="-1">' + arr.join('') + '</select>';
if (Array.isArray(opts.yearRange)) {
i = opts.yearRange[0];
j = opts.yearRange[1] + 1;
}
else {
i = year - opts.yearRange;
j = 1 + year + opts.yearRange;
}
for (arr = []; i < j && i <= opts.maxYear; i++) {
if (i >= opts.minYear) {
arr.push(`<option value="${i}" ${i === year ? 'selected="selected"' : ''}>${i}</option>`);
}
}
if (opts.yearRangeReverse)
arr.reverse();
yearHtml = `<select class="datepicker-select orig-select-year" tabindex="-1">${arr.join('')}</select>`;
let leftArrow = '<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"/><path d="M0-.5h24v24H0z" fill="none"/></svg>';
html += `<button class="month-prev${prev ? '' : ' is-disabled'} btn-flat" type="button">${leftArrow}</button>`;
html += '<div class="selects-container">';
if (opts.showMonthAfterYear) {
html += yearHtml + monthHtml;
}
else {
html += monthHtml + yearHtml;
}
html += '</div>';
if (isMinYear && (month === 0 || opts.minMonth >= month)) {
prev = false;
2022-08-04 19:50:18 -05:00
}
if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
next = false;
2022-08-04 19:50:18 -05:00
}
let rightArrow = '<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/><path d="M0-.25h24v24H0z" fill="none"/></svg>';
html += `<button class="month-next${next ? '' : ' is-disabled'} btn-flat" type="button">${rightArrow}</button>`;
return (html += '</div>');
}
// refresh HTML
draw(force = false) {
if (!this.isOpen && !force)
return;
let opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth, html = '', randId;
if (this._y <= minYear) {
this._y = minYear;
if (!isNaN(minMonth) && this._m < minMonth) {
this._m = minMonth;
}
2022-08-04 19:50:18 -05:00
}
if (this._y >= maxYear) {
this._y = maxYear;
if (!isNaN(maxMonth) && this._m > maxMonth) {
this._m = maxMonth;
2022-08-04 19:50:18 -05:00
}
}
randId =
'datepicker-title-' +
Math.random()
.toString(36)
.replace(/[^a-z]+/g, '')
.substr(0, 2);
for (let c = 0; c < 1; c++) {
this._renderDateDisplay();
html +=
this.renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId);
2022-08-04 19:50:18 -05:00
}
this.destroySelects();
this.calendarEl.innerHTML = html;
// Init Materialize Select
let yearSelect = this.calendarEl.querySelector('.orig-select-year');
let monthSelect = this.calendarEl.querySelector('.orig-select-month');
select_1.FormSelect.init(yearSelect, {
classes: 'select-year',
dropdownOptions: { container: document.body, constrainWidth: false }
2022-08-04 19:50:18 -05:00
});
select_1.FormSelect.init(monthSelect, {
classes: 'select-month',
dropdownOptions: { container: document.body, constrainWidth: false }
});
// Add change handlers for select
yearSelect.addEventListener('change', this._handleYearChange);
monthSelect.addEventListener('change', this._handleMonthChange);
if (typeof this.options.onDraw === 'function') {
this.options.onDraw.call(this);
2022-08-04 19:50:18 -05:00
}
}
_setupEventHandlers() {
this.el.addEventListener('click', this._handleInputClick);
this.el.addEventListener('keydown', this._handleInputKeydown);
this.el.addEventListener('change', this._handleInputChange);
this.calendarEl.addEventListener('click', this._handleCalendarClick);
this.doneBtn.addEventListener('click', this._finishSelection);
this.cancelBtn.addEventListener('click', this.close);
if (this.options.showClearBtn) {
this.clearBtn.addEventListener('click', this._handleClearClick);
2022-08-04 19:50:18 -05:00
}
}
_setupVariables() {
const template = document.createElement('template');
template.innerHTML = Datepicker._template.trim();
this.modalEl = template.content.firstChild;
this.calendarEl = this.modalEl.querySelector('.datepicker-calendar');
this.yearTextEl = this.modalEl.querySelector('.year-text');
this.dateTextEl = this.modalEl.querySelector('.date-text');
if (this.options.showClearBtn) {
this.clearBtn = this.modalEl.querySelector('.datepicker-clear');
}
this.doneBtn = this.modalEl.querySelector('.datepicker-done');
this.cancelBtn = this.modalEl.querySelector('.datepicker-cancel');
this.formats = {
d: () => {
return this.date.getDate();
},
dd: () => {
let d = this.date.getDate();
return (d < 10 ? '0' : '') + d;
},
ddd: () => {
return this.options.i18n.weekdaysShort[this.date.getDay()];
},
dddd: () => {
return this.options.i18n.weekdays[this.date.getDay()];
},
m: () => {
return this.date.getMonth() + 1;
},
mm: () => {
let m = this.date.getMonth() + 1;
return (m < 10 ? '0' : '') + m;
},
mmm: () => {
return this.options.i18n.monthsShort[this.date.getMonth()];
},
mmmm: () => {
return this.options.i18n.months[this.date.getMonth()];
},
yy: () => {
return ('' + this.date.getFullYear()).slice(2);
},
yyyy: () => {
return this.date.getFullYear();
2022-08-04 19:50:18 -05:00
}
};
}
_removeEventHandlers() {
this.el.removeEventListener('click', this._handleInputClick);
this.el.removeEventListener('keydown', this._handleInputKeydown);
this.el.removeEventListener('change', this._handleInputChange);
this.calendarEl.removeEventListener('click', this._handleCalendarClick);
}
// change view to a specific month (zero-index, e.g. 0: January)
gotoMonth(month) {
if (!isNaN(month)) {
this.calendars[0].month = parseInt(month, 10);
this.adjustCalendars();
2022-08-04 19:50:18 -05:00
}
}
// change view to a specific full year (e.g. "2012")
gotoYear(year) {
if (!isNaN(year)) {
this.calendars[0].year = parseInt(year, 10);
this.adjustCalendars();
}
}
renderDayName(opts, day, abbr = false) {
day += opts.firstDay;
while (day >= 7) {
day -= 7;
2022-08-04 19:50:18 -05:00
}
return abbr ? opts.i18n.weekdaysAbbrev[day] : opts.i18n.weekdays[day];
}
}
exports.Datepicker = Datepicker;
(() => {
Datepicker._template = `
<div class="modal datepicker-modal">
<div class="modal-content datepicker-container">
<div class="datepicker-date-display">
<span class="year-text"></span>
<span class="date-text"></span>
</div>
<div class="datepicker-calendar-container">
<div class="datepicker-calendar"></div>
<div class="datepicker-footer">
<button class="btn-flat datepicker-clear waves-effect" style="visibility: hidden;" type="button"></button>
<div class="confirmation-btns">
<button class="btn-flat datepicker-cancel waves-effect" type="button"></button>
<button class="btn-flat datepicker-done waves-effect" type="button"></button>
</div>
</div>
</div>
</div>
</div>`;
})();
/***/ }),
/***/ "./src/dropdown.ts":
/*!*************************!*\
!*** ./src/dropdown.ts ***!
\*************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Dropdown = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
const _defaults = {
alignment: 'left',
autoFocus: true,
constrainWidth: true,
container: null,
coverTrigger: true,
closeOnClick: true,
hover: false,
inDuration: 150,
outDuration: 250,
onOpenStart: null,
onOpenEnd: null,
onCloseStart: null,
onCloseEnd: null,
onItemClick: null
};
class Dropdown extends component_1.Component {
constructor(el, options) {
super(el, options, Dropdown);
this._handleClick = (e) => {
e.preventDefault();
if (this.isOpen) {
this.close();
}
else {
this.open();
}
};
this._handleMouseEnter = () => {
this.open();
};
this._handleMouseLeave = (e) => {
const toEl = e.relatedTarget;
const leaveToDropdownContent = !!toEl.closest('.dropdown-content');
let leaveToActiveDropdownTrigger = false;
const closestTrigger = toEl.closest('.dropdown-trigger');
if (closestTrigger &&
!!closestTrigger.M_Dropdown &&
closestTrigger.M_Dropdown.isOpen) {
leaveToActiveDropdownTrigger = true;
}
// Close hover dropdown if mouse did not leave to either active dropdown-trigger or dropdown-content
if (!leaveToActiveDropdownTrigger && !leaveToDropdownContent) {
this.close();
}
};
this._handleDocumentClick = (e) => {
const target = e.target;
if (this.options.closeOnClick &&
target.closest('.dropdown-content') &&
!this.isTouchMoving) {
// isTouchMoving to check if scrolling on mobile.
this.close();
}
else if (!target.closest('.dropdown-content')) {
// Do this one frame later so that if the element clicked also triggers _handleClick
// For example, if a label for a select was clicked, that we don't close/open the dropdown
setTimeout(() => {
if (this.isOpen) {
this.close();
}
}, 0);
}
this.isTouchMoving = false;
};
this._handleTriggerKeydown = (e) => {
// ARROW DOWN OR ENTER WHEN SELECT IS CLOSED - open Dropdown
const arrowDownOrEnter = utils_1.Utils.keys.ARROW_DOWN.includes(e.key) || utils_1.Utils.keys.ENTER.includes(e.key);
if (arrowDownOrEnter && !this.isOpen) {
e.preventDefault();
this.open();
}
};
this._handleDocumentTouchmove = (e) => {
const target = e.target;
if (target.closest('.dropdown-content')) {
this.isTouchMoving = true;
}
};
this._handleDropdownClick = (e) => {
// onItemClick callback
if (typeof this.options.onItemClick === 'function') {
const itemEl = e.target.closest('li');
this.options.onItemClick.call(this, itemEl);
}
};
this._handleDropdownKeydown = (e) => {
const arrowUpOrDown = utils_1.Utils.keys.ARROW_DOWN.includes(e.key) || utils_1.Utils.keys.ARROW_UP.includes(e.key);
if (utils_1.Utils.keys.TAB.includes(e.key)) {
e.preventDefault();
this.close();
}
// Navigate down dropdown list
else if (arrowUpOrDown && this.isOpen) {
e.preventDefault();
const direction = utils_1.Utils.keys.ARROW_DOWN.includes(e.key) ? 1 : -1;
let newFocusedIndex = this.focusedIndex;
let hasFoundNewIndex = false;
do {
newFocusedIndex = newFocusedIndex + direction;
if (!!this.dropdownEl.children[newFocusedIndex] &&
this.dropdownEl.children[newFocusedIndex].tabIndex !== -1) {
hasFoundNewIndex = true;
break;
}
} while (newFocusedIndex < this.dropdownEl.children.length && newFocusedIndex >= 0);
if (hasFoundNewIndex) {
// Remove active class from old element
if (this.focusedIndex >= 0)
this.dropdownEl.children[this.focusedIndex].classList.remove('active');
this.focusedIndex = newFocusedIndex;
this._focusFocusedItem();
}
}
// ENTER selects choice on focused item
else if (utils_1.Utils.keys.ENTER.includes(e.key) && this.isOpen) {
// Search for <a> and <button>
const focusedElement = this.dropdownEl.children[this.focusedIndex];
const activatableElement = focusedElement.querySelector('a, button');
// Click a or button tag if exists, otherwise click li tag
if (!!activatableElement) {
activatableElement.click();
}
else if (!!focusedElement) {
if (focusedElement instanceof HTMLElement) {
focusedElement.click();
}
}
}
// Close dropdown on ESC
else if (utils_1.Utils.keys.ESC.includes(e.key) && this.isOpen) {
e.preventDefault();
this.close();
}
// CASE WHEN USER TYPE LTTERS
const keyText = e.key.toLowerCase();
const isLetter = /[a-zA-Z0-9-_]/.test(keyText);
const specialKeys = [...utils_1.Utils.keys.ARROW_DOWN, ...utils_1.Utils.keys.ARROW_UP, ...utils_1.Utils.keys.ENTER, ...utils_1.Utils.keys.ESC, ...utils_1.Utils.keys.TAB];
if (isLetter && !specialKeys.includes(e.key)) {
this.filterQuery.push(keyText);
const string = this.filterQuery.join('');
const newOptionEl = Array.from(this.dropdownEl.querySelectorAll('li'))
.find((el) => el.innerText.toLowerCase().indexOf(string) === 0);
if (newOptionEl) {
this.focusedIndex = [...newOptionEl.parentNode.children].indexOf(newOptionEl);
this._focusFocusedItem();
}
}
this.filterTimeout = setTimeout(this._resetFilterQuery, 1000);
};
this._handleWindowResize = (e) => {
// Only re-place the dropdown if it's still visible
// Accounts for elements hiding via media queries
if (this.el.offsetParent) {
this.recalculateDimensions();
}
};
this._resetFilterQuery = () => {
this.filterQuery = [];
};
/**
* Open dropdown.
*/
this.open = () => {
if (this.isOpen)
return;
this.isOpen = true;
// onOpenStart callback
if (typeof this.options.onOpenStart === 'function') {
this.options.onOpenStart.call(this, this.el);
}
// Reset styles
this._resetDropdownStyles();
this.dropdownEl.style.display = 'block';
this._placeDropdown();
this._animateIn();
// Do this one frame later so that we don't bind an event handler that's immediately
// called when the event bubbles up to the document and closes the dropdown
setTimeout(() => this._setupTemporaryEventHandlers(), 0);
};
/**
* Close dropdown.
*/
this.close = () => {
if (!this.isOpen)
return;
this.isOpen = false;
this.focusedIndex = -1;
// onCloseStart callback
if (typeof this.options.onCloseStart === 'function') {
this.options.onCloseStart.call(this, this.el);
}
this._animateOut();
this._removeTemporaryEventHandlers();
if (this.options.autoFocus) {
this.el.focus();
}
};
/**
* While dropdown is open, you can recalculate its dimensions if its contents have changed.
*/
this.recalculateDimensions = () => {
if (this.isOpen) {
this.dropdownEl.style.width = '';
this.dropdownEl.style.height = '';
this.dropdownEl.style.left = '';
this.dropdownEl.style.top = '';
this.dropdownEl.style.transformOrigin = '';
this._placeDropdown();
}
};
this.el.M_Dropdown = this;
Dropdown._dropdowns.push(this);
this.id = utils_1.Utils.getIdFromTrigger(el);
this.dropdownEl = document.getElementById(this.id);
this.options = Object.assign(Object.assign({}, Dropdown.defaults), options);
this.isOpen = false;
this.isScrollable = false;
this.isTouchMoving = false;
this.focusedIndex = -1;
this.filterQuery = [];
// Move dropdown-content after dropdown-trigger
this._moveDropdown();
this._makeDropdownFocusable();
this._setupEventHandlers();
}
static get defaults() {
2022-08-04 19:50:18 -05:00
return _defaults;
}
2022-08-04 19:50:18 -05:00
/**
* Initializes instances of Dropdown.
* @param els HTML elements.
* @param options Component options.
2022-08-04 19:50:18 -05:00
*/
static init(els, options = {}) {
return super.init(els, options, Dropdown);
2022-08-04 19:50:18 -05:00
}
static getInstance(el) {
return el.M_Dropdown;
}
destroy() {
this._resetDropdownStyles();
this._removeEventHandlers();
Dropdown._dropdowns.splice(Dropdown._dropdowns.indexOf(this), 1);
this.el.M_Dropdown = undefined;
}
_setupEventHandlers() {
var _a;
// Trigger keydown handler
this.el.addEventListener('keydown', this._handleTriggerKeydown);
// Item click handler
(_a = this.dropdownEl) === null || _a === void 0 ? void 0 : _a.addEventListener('click', this._handleDropdownClick);
// Hover event handlers
if (this.options.hover) {
this.el.addEventListener('mouseenter', this._handleMouseEnter);
this.el.addEventListener('mouseleave', this._handleMouseLeave);
this.dropdownEl.addEventListener('mouseleave', this._handleMouseLeave);
// Click event handlers
2022-08-04 19:50:18 -05:00
}
else {
this.el.addEventListener('click', this._handleClick);
2022-08-04 19:50:18 -05:00
}
}
_removeEventHandlers() {
this.el.removeEventListener('keydown', this._handleTriggerKeydown);
this.dropdownEl.removeEventListener('click', this._handleDropdownClick);
if (this.options.hover) {
this.el.removeEventListener('mouseenter', this._handleMouseEnter);
this.el.removeEventListener('mouseleave', this._handleMouseLeave);
this.dropdownEl.removeEventListener('mouseleave', this._handleMouseLeave);
2022-08-04 19:50:18 -05:00
}
else {
this.el.removeEventListener('click', this._handleClick);
2022-08-04 19:50:18 -05:00
}
}
_setupTemporaryEventHandlers() {
document.body.addEventListener('click', this._handleDocumentClick);
document.body.addEventListener('touchmove', this._handleDocumentTouchmove);
this.dropdownEl.addEventListener('keydown', this._handleDropdownKeydown);
window.addEventListener('resize', this._handleWindowResize);
}
_removeTemporaryEventHandlers() {
document.body.removeEventListener('click', this._handleDocumentClick);
document.body.removeEventListener('touchmove', this._handleDocumentTouchmove);
this.dropdownEl.removeEventListener('keydown', this._handleDropdownKeydown);
window.removeEventListener('resize', this._handleWindowResize);
}
_resetDropdownStyles() {
this.dropdownEl.style.display = '';
this.dropdownEl.style.width = '';
this.dropdownEl.style.height = '';
this.dropdownEl.style.left = '';
this.dropdownEl.style.top = '';
this.dropdownEl.style.transformOrigin = '';
this.dropdownEl.style.transform = '';
this.dropdownEl.style.opacity = '';
}
// Move dropdown after container or trigger
_moveDropdown(containerEl = null) {
if (!!this.options.container) {
this.options.container.append(this.dropdownEl);
2022-08-04 19:50:18 -05:00
}
else if (containerEl) {
if (!containerEl.contains(this.dropdownEl)) {
containerEl.append(this.dropdownEl);
}
2022-08-04 19:50:18 -05:00
}
else {
this.el.after(this.dropdownEl);
}
}
_makeDropdownFocusable() {
if (!this.dropdownEl)
return;
// Needed for arrow key navigation
this.dropdownEl.tabIndex = 0;
// Only set tabindex if it hasn't been set by user
Array.from(this.dropdownEl.children).forEach((el) => {
if (!el.getAttribute('tabindex'))
el.setAttribute('tabindex', '0');
});
}
_focusFocusedItem() {
if (this.focusedIndex >= 0 &&
this.focusedIndex < this.dropdownEl.children.length &&
this.options.autoFocus) {
this.dropdownEl.children[this.focusedIndex].focus({
preventScroll: true
});
this.dropdownEl.children[this.focusedIndex].scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest'
});
2022-08-04 19:50:18 -05:00
}
}
_getDropdownPosition(closestOverflowParent) {
const offsetParentBRect = this.el.offsetParent.getBoundingClientRect();
const triggerBRect = this.el.getBoundingClientRect();
const dropdownBRect = this.dropdownEl.getBoundingClientRect();
let idealHeight = dropdownBRect.height;
let idealWidth = dropdownBRect.width;
let idealXPos = triggerBRect.left - dropdownBRect.left;
let idealYPos = triggerBRect.top - dropdownBRect.top;
const dropdownBounds = {
left: idealXPos,
top: idealYPos,
height: idealHeight,
width: idealWidth
};
const alignments = utils_1.Utils.checkPossibleAlignments(this.el, closestOverflowParent, dropdownBounds, this.options.coverTrigger ? 0 : triggerBRect.height);
let verticalAlignment = 'top';
let horizontalAlignment = this.options.alignment;
idealYPos += this.options.coverTrigger ? 0 : triggerBRect.height;
// Reset isScrollable
this.isScrollable = false;
if (!alignments.top) {
if (alignments.bottom) {
verticalAlignment = 'bottom';
if (!this.options.coverTrigger) {
idealYPos -= triggerBRect.height;
}
}
else {
this.isScrollable = true;
// Determine which side has most space and cutoff at correct height
idealHeight -= 20; // Add padding when cutoff
if (alignments.spaceOnTop > alignments.spaceOnBottom) {
verticalAlignment = 'bottom';
idealHeight += alignments.spaceOnTop;
idealYPos -= this.options.coverTrigger
? alignments.spaceOnTop - 20
: alignments.spaceOnTop - 20 + triggerBRect.height;
}
else {
idealHeight += alignments.spaceOnBottom;
}
}
2022-08-04 19:50:18 -05:00
}
// If preferred horizontal alignment is possible
if (!alignments[horizontalAlignment]) {
const oppositeAlignment = horizontalAlignment === 'left' ? 'right' : 'left';
if (alignments[oppositeAlignment]) {
horizontalAlignment = oppositeAlignment;
}
else {
// Determine which side has most space and cutoff at correct height
if (alignments.spaceOnLeft > alignments.spaceOnRight) {
horizontalAlignment = 'right';
idealWidth += alignments.spaceOnLeft;
idealXPos -= alignments.spaceOnLeft;
}
else {
horizontalAlignment = 'left';
idealWidth += alignments.spaceOnRight;
}
}
2022-08-04 19:50:18 -05:00
}
if (verticalAlignment === 'bottom') {
idealYPos =
idealYPos - dropdownBRect.height + (this.options.coverTrigger ? triggerBRect.height : 0);
2022-08-04 19:50:18 -05:00
}
if (horizontalAlignment === 'right') {
idealXPos = idealXPos - dropdownBRect.width + triggerBRect.width;
2022-08-04 19:50:18 -05:00
}
return {
x: idealXPos,
y: idealYPos,
verticalAlignment: verticalAlignment,
horizontalAlignment: horizontalAlignment,
height: idealHeight,
width: idealWidth
};
}
_animateIn() {
const duration = this.options.inDuration;
this.dropdownEl.style.transition = 'none';
// from
this.dropdownEl.style.opacity = '0';
this.dropdownEl.style.transform = 'scale(0.3, 0.3)';
setTimeout(() => {
// easeOutQuad (opacity) & easeOutQuint
this.dropdownEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
// to
this.dropdownEl.style.opacity = '1';
this.dropdownEl.style.transform = 'scale(1, 1)';
}, 1);
setTimeout(() => {
if (this.options.autoFocus)
this.dropdownEl.focus();
if (typeof this.options.onOpenEnd === 'function')
this.options.onOpenEnd.call(this, this.el);
}, duration);
}
_animateOut() {
const duration = this.options.outDuration;
// easeOutQuad (opacity) & easeOutQuint
this.dropdownEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
// to
this.dropdownEl.style.opacity = '0';
this.dropdownEl.style.transform = 'scale(0.3, 0.3)';
setTimeout(() => {
this._resetDropdownStyles();
if (typeof this.options.onCloseEnd === 'function')
this.options.onCloseEnd.call(this, this.el);
}, duration);
}
_getClosestAncestor(el, condition) {
let ancestor = el.parentNode;
while (ancestor !== null && ancestor !== document) {
if (condition(ancestor)) {
return ancestor;
}
ancestor = ancestor.parentElement;
2022-08-04 19:50:18 -05:00
}
return null;
}
;
_placeDropdown() {
// Container here will be closest ancestor with overflow: hidden
let closestOverflowParent = this._getClosestAncestor(this.dropdownEl, (ancestor) => {
return !['HTML', 'BODY'].includes(ancestor.tagName) && getComputedStyle(ancestor).overflow !== 'visible';
2022-08-04 19:50:18 -05:00
});
// Fallback
if (!closestOverflowParent) {
closestOverflowParent = (!!this.dropdownEl.offsetParent
? this.dropdownEl.offsetParent
: this.dropdownEl.parentNode);
}
if (getComputedStyle(closestOverflowParent).position === 'static')
closestOverflowParent.style.position = 'relative';
this._moveDropdown(closestOverflowParent);
// Set width before calculating positionInfo
const idealWidth = this.options.constrainWidth
? this.el.getBoundingClientRect().width
: this.dropdownEl.getBoundingClientRect().width;
this.dropdownEl.style.width = idealWidth + 'px';
const positionInfo = this._getDropdownPosition(closestOverflowParent);
this.dropdownEl.style.left = positionInfo.x + 'px';
this.dropdownEl.style.top = positionInfo.y + 'px';
this.dropdownEl.style.height = positionInfo.height + 'px';
this.dropdownEl.style.width = positionInfo.width + 'px';
this.dropdownEl.style.transformOrigin = `${positionInfo.horizontalAlignment === 'left' ? '0' : '100%'} ${positionInfo.verticalAlignment === 'top' ? '0' : '100%'}`;
}
}
exports.Dropdown = Dropdown;
Dropdown._dropdowns = [];
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/forms.ts":
/*!**********************!*\
!*** ./src/forms.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Forms = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
class Forms {
/**
* Resizes the given TextArea after updating the
* value content dynamically.
* @param textarea TextArea to be resized
*/
static textareaAutoResize(textarea) {
if (!textarea) {
console.error('No textarea element found');
return;
}
// Textarea Auto Resize
let hiddenDiv = document.querySelector('.hiddendiv');
if (!hiddenDiv) {
hiddenDiv = document.createElement('div');
hiddenDiv.classList.add('hiddendiv', 'common');
document.body.append(hiddenDiv);
}
const style = getComputedStyle(textarea);
// Set font properties of hiddenDiv
const fontFamily = style.fontFamily; //textarea.css('font-family');
const fontSize = style.fontSize; //textarea.css('font-size');
const lineHeight = style.lineHeight; //textarea.css('line-height');
// Firefox can't handle padding shorthand.
const paddingTop = style.paddingTop; //getComputedStyle(textarea).css('padding-top');
const paddingRight = style.paddingRight; //textarea.css('padding-right');
const paddingBottom = style.paddingBottom; //textarea.css('padding-bottom');
const paddingLeft = style.paddingLeft; //textarea.css('padding-left');
if (fontSize)
hiddenDiv.style.fontSize = fontSize; //('font-size', fontSize);
if (fontFamily)
hiddenDiv.style.fontFamily = fontFamily; //css('font-family', fontFamily);
if (lineHeight)
hiddenDiv.style.lineHeight = lineHeight; //css('line-height', lineHeight);
if (paddingTop)
hiddenDiv.style.paddingTop = paddingTop; //ss('padding-top', paddingTop);
if (paddingRight)
hiddenDiv.style.paddingRight = paddingRight; //css('padding-right', paddingRight);
if (paddingBottom)
hiddenDiv.style.paddingBottom = paddingBottom; //css('padding-bottom', paddingBottom);
if (paddingLeft)
hiddenDiv.style.paddingLeft = paddingLeft; //css('padding-left', paddingLeft);
// Set original-height, if none
if (!textarea.hasAttribute('original-height'))
textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());
if (textarea.getAttribute('wrap') === 'off') {
hiddenDiv.style.overflowWrap = 'normal'; // ('overflow-wrap', 'normal')
hiddenDiv.style.whiteSpace = 'pre'; //.css('white-space', 'pre');
}
hiddenDiv.innerText = textarea.value + '\n';
const content = hiddenDiv.innerHTML.replace(/\n/g, '<br>');
hiddenDiv.innerHTML = content;
// When textarea is hidden, width goes crazy.
// Approximate with half of window size
if (textarea.offsetWidth > 0 && textarea.offsetHeight > 0) {
hiddenDiv.style.width = textarea.getBoundingClientRect().width + 'px'; // ('width', textarea.width() + 'px');
}
else {
hiddenDiv.style.width = (window.innerWidth / 2) + 'px'; //css('width', window.innerWidth / 2 + 'px');
}
// Resize if the new height is greater than the
// original height of the textarea
const originalHeight = parseInt(textarea.getAttribute('original-height'));
const prevLength = parseInt(textarea.getAttribute('previous-length'));
if (isNaN(originalHeight))
return;
if (originalHeight <= hiddenDiv.clientHeight) {
textarea.style.height = hiddenDiv.clientHeight + 'px'; //css('height', hiddenDiv.innerHeight() + 'px');
}
else if (textarea.value.length < prevLength) {
// In case the new height is less than original height, it
// means the textarea has less text than before
// So we set the height to the original one
textarea.style.height = originalHeight + 'px';
}
textarea.setAttribute('previous-length', textarea.value.length.toString());
}
;
static Init() {
document.addEventListener("DOMContentLoaded", () => {
document.addEventListener('keyup', (e) => {
const target = e.target;
// Radio and Checkbox focus class
if (target instanceof HTMLInputElement && ['radio', 'checkbox'].includes(target.type)) {
// TAB, check if tabbing to radio or checkbox.
if (utils_1.Utils.keys.TAB.includes(e.key)) {
target.classList.add('tabbed');
target.addEventListener('blur', e => target.classList.remove('tabbed'), { once: true });
}
}
2022-08-04 19:50:18 -05:00
});
document.querySelectorAll('.materialize-textarea').forEach((textArea) => {
Forms.textareaAutoResize(textArea);
2022-08-04 19:50:18 -05:00
});
// File Input Path
document.querySelectorAll('.file-field input[type="file"]').forEach((fileInput) => {
Forms.InitFileInputPath(fileInput);
2022-08-04 19:50:18 -05:00
});
});
}
static InitTextarea(textarea) {
// Save Data in Element
textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());
textarea.setAttribute('previous-length', textarea.value.length.toString());
Forms.textareaAutoResize(textarea);
textarea.addEventListener('keyup', e => Forms.textareaAutoResize(textarea));
textarea.addEventListener('keydown', e => Forms.textareaAutoResize(textarea));
}
static InitFileInputPath(fileInput) {
fileInput.addEventListener('change', e => {
const fileField = fileInput.closest('.file-field');
const pathInput = fileField.querySelector('input.file-path');
const files = fileInput.files;
const filenames = [];
for (let i = 0; i < files.length; i++) {
filenames.push(files[i].name);
}
pathInput.value = filenames.join(', ');
pathInput.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true }));
2022-08-04 19:50:18 -05:00
});
}
}
exports.Forms = Forms;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/materialbox.ts":
/*!****************************!*\
!*** ./src/materialbox.ts ***!
\****************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Materialbox = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
const _defaults = {
inDuration: 275,
outDuration: 200,
onOpenStart: null,
onOpenEnd: null,
onCloseStart: null,
onCloseEnd: null
};
class Materialbox extends component_1.Component {
constructor(el, options) {
super(el, options, Materialbox);
this._handleMaterialboxClick = () => {
// If already modal, return to original
if (this.doneAnimating === false || (this.overlayActive && this.doneAnimating))
this.close();
else
this.open();
};
this._handleWindowScroll = () => {
if (this.overlayActive)
this.close();
};
this._handleWindowResize = () => {
if (this.overlayActive)
this.close();
};
this._handleWindowEscape = (e) => {
if (utils_1.Utils.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive)
this.close();
};
/**
* Open materialbox.
*/
this.open = () => {
this._updateVars();
this.originalWidth = this.el.getBoundingClientRect().width;
this.originalHeight = this.el.getBoundingClientRect().height;
// Set states
this.doneAnimating = false;
this.el.classList.add('active');
this.overlayActive = true;
// onOpenStart callback
if (typeof this.options.onOpenStart === 'function')
this.options.onOpenStart.call(this, this.el);
// Set positioning for placeholder
this.placeholder.style.width = this.placeholder.getBoundingClientRect().width + 'px';
this.placeholder.style.height = this.placeholder.getBoundingClientRect().height + 'px';
this.placeholder.style.position = 'relative';
this.placeholder.style.top = '0';
this.placeholder.style.left = '0';
this._makeAncestorsOverflowVisible();
// Set css on origin
this.el.style.position = 'absolute';
this.el.style.zIndex = '1000';
this.el.style.willChange = 'left, top, width, height';
// Change from width or height attribute to css
this.attrWidth = this.el.getAttribute('width');
this.attrHeight = this.el.getAttribute('height');
if (this.attrWidth) {
this.el.style.width = this.attrWidth + 'px';
this.el.removeAttribute('width');
}
if (this.attrHeight) {
this.el.style.width = this.attrHeight + 'px';
this.el.removeAttribute('height');
}
this._addOverlay();
// Add and animate caption if it exists
if (this.caption !== '')
this._addCaption();
// Resize Image
const widthPercent = this.originalWidth / this.windowWidth;
const heightPercent = this.originalHeight / this.windowHeight;
this.newWidth = 0;
this.newHeight = 0;
if (widthPercent > heightPercent) {
// Width first
const ratio = this.originalHeight / this.originalWidth;
this.newWidth = this.windowWidth * 0.9;
this.newHeight = this.windowWidth * 0.9 * ratio;
}
else {
// Height first
const ratio = this.originalWidth / this.originalHeight;
this.newWidth = this.windowHeight * 0.9 * ratio;
this.newHeight = this.windowHeight * 0.9;
}
this._animateImageIn();
// Handle Exit triggers
window.addEventListener('scroll', this._handleWindowScroll);
window.addEventListener('resize', this._handleWindowResize);
window.addEventListener('keyup', this._handleWindowEscape);
};
/**
* Close materialbox.
*/
this.close = () => {
this._updateVars();
this.doneAnimating = false;
// onCloseStart callback
if (typeof this.options.onCloseStart === 'function')
this.options.onCloseStart.call(this, this.el);
//anim.remove(this.el);
//anim.remove(this._overlay);
//if (this.caption !== '') anim.remove(this._photoCaption);
// disable exit handlers
window.removeEventListener('scroll', this._handleWindowScroll);
window.removeEventListener('resize', this._handleWindowResize);
window.removeEventListener('keyup', this._handleWindowEscape);
this._removeOverlay();
this._animateImageOut();
if (this.caption !== '')
this._removeCaption();
};
this.el.M_Materialbox = this;
this.options = Object.assign(Object.assign({}, Materialbox.defaults), options);
this.overlayActive = false;
this.doneAnimating = true;
this.placeholder = document.createElement('div');
this.placeholder.classList.add('material-placeholder');
this.originalWidth = 0;
this.originalHeight = 0;
this.originInlineStyles = this.el.getAttribute('style');
this.caption = this.el.getAttribute('data-caption') || '';
// Wrap
this.el.before(this.placeholder);
this.placeholder.append(this.el);
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of MaterialBox.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Materialbox);
}
static getInstance(el) {
return el.M_Materialbox;
}
destroy() {
this._removeEventHandlers();
this.el.M_Materialbox = undefined;
// Unwrap image
//this.placeholder.after(this.el).remove();
this.placeholder.remove();
this.el.removeAttribute('style');
}
_setupEventHandlers() {
this.el.addEventListener('click', this._handleMaterialboxClick);
}
_removeEventHandlers() {
this.el.removeEventListener('click', this._handleMaterialboxClick);
}
_makeAncestorsOverflowVisible() {
this._changedAncestorList = [];
let ancestor = this.placeholder.parentNode;
while (ancestor !== null && ancestor !== document) {
const curr = ancestor;
if (curr.style.overflow !== 'visible') {
curr.style.overflow = 'visible';
this._changedAncestorList.push(curr);
}
ancestor = ancestor.parentNode;
}
}
_offset(el) {
const box = el.getBoundingClientRect();
const docElem = document.documentElement;
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
_updateVars() {
this.windowWidth = window.innerWidth;
this.windowHeight = window.innerHeight;
this.caption = this.el.getAttribute('data-caption') || '';
}
// Image
_animateImageIn() {
this.el.style.maxHeight = this.newHeight.toString() + 'px';
this.el.style.maxWidth = this.newWidth.toString() + 'px';
const duration = this.options.inDuration;
// from
this.el.style.transition = 'none';
this.el.style.height = this.originalHeight + 'px';
this.el.style.width = this.originalWidth + 'px';
setTimeout(() => {
// easeOutQuad
this.el.style.transition = `height ${duration}ms ease,
width ${duration}ms ease,
left ${duration}ms ease,
top ${duration}ms ease
`;
// to
this.el.style.height = this.newHeight + 'px';
this.el.style.width = this.newWidth + 'px';
this.el.style.left = (utils_1.Utils.getDocumentScrollLeft() +
this.windowWidth / 2 -
this._offset(this.placeholder).left -
this.newWidth / 2) + 'px';
this.el.style.top = (utils_1.Utils.getDocumentScrollTop() +
this.windowHeight / 2 -
this._offset(this.placeholder).top -
this.newHeight / 2) + 'px';
}, 1);
setTimeout(() => {
this.doneAnimating = true;
if (typeof this.options.onOpenEnd === 'function')
this.options.onOpenEnd.call(this, this.el);
}, duration);
/*
anim({
targets: this.el, // image
height: [this.originalHeight, this.newHeight],
width: [this.originalWidth, this.newWidth],
left:
Utils.getDocumentScrollLeft() +
this.windowWidth / 2 -
this._offset(this.placeholder).left -
this.newWidth / 2,
top:
Utils.getDocumentScrollTop() +
this.windowHeight / 2 -
this._offset(this.placeholder).top -
this.newHeight / 2,
duration: this.options.inDuration,
easing: 'easeOutQuad',
complete: () => {
this.doneAnimating = true;
if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el);
}
});
*/
}
_animateImageOut() {
const duration = this.options.outDuration;
// easeOutQuad
this.el.style.transition = `height ${duration}ms ease,
width ${duration}ms ease,
left ${duration}ms ease,
top ${duration}ms ease
`;
// to
this.el.style.height = this.originalWidth + 'px';
this.el.style.width = this.originalWidth + 'px';
this.el.style.left = '0';
this.el.style.top = '0';
setTimeout(() => {
this.placeholder.style.height = '';
this.placeholder.style.width = '';
this.placeholder.style.position = '';
this.placeholder.style.top = '';
this.placeholder.style.left = '';
// Revert to width or height attribute
if (this.attrWidth)
this.el.setAttribute('width', this.attrWidth.toString());
if (this.attrHeight)
this.el.setAttribute('height', this.attrHeight.toString());
this.el.removeAttribute('style');
this.originInlineStyles && this.el.setAttribute('style', this.originInlineStyles);
// Remove class
this.el.classList.remove('active');
this.doneAnimating = true;
// Remove overflow overrides on ancestors
this._changedAncestorList.forEach(anchestor => anchestor.style.overflow = '');
// onCloseEnd callback
if (typeof this.options.onCloseEnd === 'function')
this.options.onCloseEnd.call(this, this.el);
}, duration);
}
// Caption
_addCaption() {
this._photoCaption = document.createElement('div');
this._photoCaption.classList.add('materialbox-caption');
this._photoCaption.innerText = this.caption;
document.body.append(this._photoCaption);
this._photoCaption.style.display = 'inline';
// Animate
this._photoCaption.style.transition = 'none';
this._photoCaption.style.opacity = '0';
const duration = this.options.inDuration;
setTimeout(() => {
this._photoCaption.style.transition = `opacity ${duration}ms ease`;
this._photoCaption.style.opacity = '1';
}, 1);
}
_removeCaption() {
const duration = this.options.outDuration;
this._photoCaption.style.transition = `opacity ${duration}ms ease`;
this._photoCaption.style.opacity = '0';
setTimeout(() => {
this._photoCaption.remove();
}, duration);
}
// Overlay
_addOverlay() {
this._overlay = document.createElement('div');
this._overlay.id = 'materialbox-overlay';
this._overlay.addEventListener('click', e => {
if (this.doneAnimating)
this.close();
}, { once: true });
// Put before in origin image to preserve z-index layering.
this.el.before(this._overlay);
// Set dimensions if needed
const overlayOffset = this._overlay.getBoundingClientRect();
this._overlay.style.width = this.windowWidth + 'px';
this._overlay.style.height = this.windowHeight + 'px';
this._overlay.style.left = -1 * overlayOffset.left + 'px';
this._overlay.style.top = -1 * overlayOffset.top + 'px';
// Animate
this._overlay.style.transition = 'none';
this._overlay.style.opacity = '0';
const duration = this.options.inDuration;
setTimeout(() => {
this._overlay.style.transition = `opacity ${duration}ms ease`;
this._overlay.style.opacity = '1';
}, 1);
}
_removeOverlay() {
const duration = this.options.outDuration;
this._overlay.style.transition = `opacity ${duration}ms ease`;
this._overlay.style.opacity = '0';
setTimeout(() => {
this.overlayActive = false;
this._overlay.remove();
}, duration);
}
}
exports.Materialbox = Materialbox;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/modal.ts":
/*!**********************!*\
!*** ./src/modal.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Modal = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
const _defaults = {
opacity: 0.5,
inDuration: 250,
outDuration: 250,
onOpenStart: null,
onOpenEnd: null,
onCloseStart: null,
onCloseEnd: null,
preventScrolling: true,
dismissible: true,
startingTop: '4%',
endingTop: '10%'
};
class Modal extends component_1.Component {
constructor(el, options) {
super(el, options, Modal);
this._handleTriggerClick = (e) => {
const trigger = e.target.closest('.modal-trigger');
if (!trigger)
return;
const modalId = utils_1.Utils.getIdFromTrigger(trigger);
const modalInstance = document.getElementById(modalId).M_Modal;
if (modalInstance)
modalInstance.open(trigger);
e.preventDefault();
};
this._handleOverlayClick = () => {
if (this.options.dismissible)
this.close();
};
this._handleModalCloseClick = (e) => {
const closeTrigger = e.target.closest('.modal-close');
if (closeTrigger)
this.close();
};
this._handleKeydown = (e) => {
if (utils_1.Utils.keys.ESC.includes(e.key) && this.options.dismissible)
this.close();
};
this._handleFocus = (e) => {
// Only trap focus if this modal is the last model opened (prevents loops in nested modals).
if (!this.el.contains(e.target) && this._nthModalOpened === Modal._modalsOpen) {
this.el.focus();
}
};
/**
* Open modal.
*/
this.open = (trigger) => {
if (this.isOpen)
return;
this.isOpen = true;
Modal._modalsOpen++;
this._nthModalOpened = Modal._modalsOpen;
// Set Z-Index based on number of currently open modals
this._overlay.style.zIndex = (1000 + Modal._modalsOpen * 2).toString();
this.el.style.zIndex = (1000 + Modal._modalsOpen * 2 + 1).toString();
// Set opening trigger, undefined indicates modal was opened by javascript
this._openingTrigger = !!trigger ? trigger : undefined;
// onOpenStart callback
if (typeof this.options.onOpenStart === 'function') {
this.options.onOpenStart.call(this, this.el, this._openingTrigger);
}
if (this.options.preventScrolling) {
const hasVerticalScrollBar = document.documentElement.scrollHeight > document.documentElement.clientHeight;
if (hasVerticalScrollBar) {
const scrollTop = document.documentElement.scrollTop;
document.documentElement.style.top = '-' + scrollTop + "px";
document.documentElement.classList.add('noscroll');
}
}
this.el.classList.add('open');
this.el.insertAdjacentElement('afterend', this._overlay);
if (this.options.dismissible) {
document.addEventListener('keydown', this._handleKeydown);
document.addEventListener('focus', this._handleFocus, true);
}
this._animateIn();
// Focus modal
this.el.focus();
return this;
};
/**
* Close modal.
*/
this.close = () => {
if (!this.isOpen)
return;
this.isOpen = false;
Modal._modalsOpen--;
this._nthModalOpened = 0;
// Call onCloseStart callback
if (typeof this.options.onCloseStart === 'function') {
this.options.onCloseStart.call(this, this.el);
}
this.el.classList.remove('open');
// Enable body scrolling only if there are no more modals open.
if (Modal._modalsOpen === 0) {
const scrollTop = -parseInt(document.documentElement.style.top);
document.documentElement.style.removeProperty("top");
document.documentElement.classList.remove('noscroll');
document.documentElement.scrollTop = scrollTop;
}
if (this.options.dismissible) {
document.removeEventListener('keydown', this._handleKeydown);
document.removeEventListener('focus', this._handleFocus, true);
}
this._animateOut();
return this;
};
this.el.M_Modal = this;
this.options = Object.assign(Object.assign({}, Modal.defaults), options);
this.isOpen = false;
this.id = this.el.id;
this._openingTrigger = undefined;
this._overlay = document.createElement('div');
this._overlay.classList.add('modal-overlay');
this.el.tabIndex = 0;
this._nthModalOpened = 0;
Modal._count++;
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Modal.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Modal);
}
static getInstance(el) {
return el.M_Modal;
}
destroy() {
Modal._count--;
this._removeEventHandlers();
this.el.removeAttribute('style');
this._overlay.remove();
this.el.M_Modal = undefined;
}
_setupEventHandlers() {
if (Modal._count === 1) {
document.body.addEventListener('click', this._handleTriggerClick);
}
this._overlay.addEventListener('click', this._handleOverlayClick);
this.el.addEventListener('click', this._handleModalCloseClick);
}
_removeEventHandlers() {
if (Modal._count === 0) {
document.body.removeEventListener('click', this._handleTriggerClick);
}
this._overlay.removeEventListener('click', this._handleOverlayClick);
this.el.removeEventListener('click', this._handleModalCloseClick);
}
_animateIn() {
// Set initial styles
this._overlay.style.display = 'block';
this._overlay.style.opacity = '0';
this.el.style.display = 'block';
this.el.style.opacity = '0';
const duration = this.options.inDuration;
const isBottomSheet = this.el.classList.contains('bottom-sheet');
if (!isBottomSheet) {
this.el.style.top = this.options.startingTop;
this.el.style.transform = 'scaleX(0.9) scaleY(0.9)';
}
// Overlay
this._overlay.style.transition = `opacity ${duration}ms ease-out`; // v1: easeOutQuad
// Modal
this.el.style.transition = `
top ${duration}ms ease-out,
bottom ${duration}ms ease-out,
opacity ${duration}ms ease-out,
transform ${duration}ms ease-out
`;
setTimeout(() => {
this._overlay.style.opacity = this.options.opacity.toString();
this.el.style.opacity = '1';
if (isBottomSheet) {
this.el.style.bottom = '0';
}
else {
this.el.style.top = this.options.endingTop;
this.el.style.transform = 'scaleX(1) scaleY(1)';
}
setTimeout(() => {
if (typeof this.options.onOpenEnd === 'function') {
this.options.onOpenEnd.call(this, this.el, this._openingTrigger);
}
}, duration);
}, 1);
}
_animateOut() {
const duration = this.options.outDuration;
const isBottomSheet = this.el.classList.contains('bottom-sheet');
if (!isBottomSheet) {
this.el.style.top = this.options.endingTop;
}
// Overlay
this._overlay.style.transition = `opacity ${duration}ms ease-out`; // v1: easeOutQuart
// Modal // easeOutCubic
this.el.style.transition = `
top ${duration}ms ease-out,
bottom ${duration}ms ease-out,
opacity ${duration}ms ease-out,
transform ${duration}ms ease-out
`;
setTimeout(() => {
this._overlay.style.opacity = '0';
this.el.style.opacity = '0';
if (isBottomSheet) {
this.el.style.bottom = '-100%';
}
else {
this.el.style.top = this.options.startingTop;
this.el.style.transform = 'scaleX(0.9) scaleY(0.9)';
}
setTimeout(() => {
this.el.style.display = 'none';
this._overlay.remove();
if (typeof this.options.onCloseEnd === 'function') {
this.options.onCloseEnd.call(this, this.el);
}
}, duration);
}, 1);
}
}
exports.Modal = Modal;
(() => {
Modal._modalsOpen = 0;
Modal._count = 0;
})();
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/parallax.ts":
/*!*************************!*\
!*** ./src/parallax.ts ***!
\*************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Parallax = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
let _defaults = {
responsiveThreshold: 0 // breakpoint for swipeable
};
class Parallax extends component_1.Component {
constructor(el, options) {
super(el, options, Parallax);
this._handleImageLoad = () => {
this._updateParallax();
};
this.el.M_Parallax = this;
this.options = Object.assign(Object.assign({}, Parallax.defaults), options);
this._enabled = window.innerWidth > this.options.responsiveThreshold;
this._img = this.el.querySelector('img');
this._updateParallax();
this._setupEventHandlers();
this._setupStyles();
Parallax._parallaxes.push(this);
}
static get defaults() {
return _defaults;
}
2022-08-04 19:50:18 -05:00
/**
* Initializes instances of Parallax.
* @param els HTML elements.
* @param options Component options.
2022-08-04 19:50:18 -05:00
*/
static init(els, options = {}) {
return super.init(els, options, Parallax);
}
static getInstance(el) {
return el.M_Parallax;
}
destroy() {
Parallax._parallaxes.splice(Parallax._parallaxes.indexOf(this), 1);
this._img.style.transform = '';
this._removeEventHandlers();
this.el.M_Parallax = undefined;
}
static _handleScroll() {
for (let i = 0; i < Parallax._parallaxes.length; i++) {
let parallaxInstance = Parallax._parallaxes[i];
parallaxInstance._updateParallax.call(parallaxInstance);
}
}
static _handleWindowResize() {
for (let i = 0; i < Parallax._parallaxes.length; i++) {
let parallaxInstance = Parallax._parallaxes[i];
parallaxInstance._enabled =
window.innerWidth > parallaxInstance.options.responsiveThreshold;
}
}
_setupEventHandlers() {
this._img.addEventListener('load', this._handleImageLoad);
if (Parallax._parallaxes.length === 0) {
if (!Parallax._handleScrollThrottled) {
Parallax._handleScrollThrottled = utils_1.Utils.throttle(Parallax._handleScroll, 5);
}
if (!Parallax._handleWindowResizeThrottled) {
Parallax._handleWindowResizeThrottled = utils_1.Utils.throttle(Parallax._handleWindowResize, 5);
}
window.addEventListener('scroll', Parallax._handleScrollThrottled);
window.addEventListener('resize', Parallax._handleWindowResizeThrottled);
}
}
_removeEventHandlers() {
this._img.removeEventListener('load', this._handleImageLoad);
if (Parallax._parallaxes.length === 0) {
window.removeEventListener('scroll', Parallax._handleScrollThrottled);
window.removeEventListener('resize', Parallax._handleWindowResizeThrottled);
}
}
_setupStyles() {
this._img.style.opacity = '1';
}
_offset(el) {
const box = el.getBoundingClientRect();
const docElem = document.documentElement;
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
_updateParallax() {
const containerHeight = this.el.getBoundingClientRect().height > 0 ? this.el.parentNode.offsetHeight : 500;
const imgHeight = this._img.offsetHeight;
const parallaxDist = imgHeight - containerHeight;
const bottom = this._offset(this.el).top + containerHeight;
const top = this._offset(this.el).top;
const scrollTop = utils_1.Utils.getDocumentScrollTop();
const windowHeight = window.innerHeight;
const windowBottom = scrollTop + windowHeight;
const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight);
const parallax = parallaxDist * percentScrolled;
if (!this._enabled) {
this._img.style.transform = '';
}
else if (bottom > scrollTop && top < scrollTop + windowHeight) {
this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`;
}
}
}
exports.Parallax = Parallax;
Parallax._parallaxes = [];
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/pushpin.ts":
/*!************************!*\
!*** ./src/pushpin.ts ***!
\************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Pushpin = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
let _defaults = {
top: 0,
bottom: Infinity,
offset: 0,
onPositionChange: null
};
class Pushpin extends component_1.Component {
constructor(el, options) {
super(el, options, Pushpin);
this.el.M_Pushpin = this;
this.options = Object.assign(Object.assign({}, Pushpin.defaults), options);
this.originalOffset = this.el.offsetTop;
Pushpin._pushpins.push(this);
this._setupEventHandlers();
this._updatePosition();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Pushpin.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Pushpin);
}
static getInstance(el) {
return el.M_Pushpin;
}
destroy() {
this.el.style.top = null;
this._removePinClasses();
// Remove pushpin Inst
let index = Pushpin._pushpins.indexOf(this);
Pushpin._pushpins.splice(index, 1);
if (Pushpin._pushpins.length === 0) {
this._removeEventHandlers();
}
this.el.M_Pushpin = undefined;
}
static _updateElements() {
for (let elIndex in Pushpin._pushpins) {
let pInstance = Pushpin._pushpins[elIndex];
pInstance._updatePosition();
}
}
_setupEventHandlers() {
document.addEventListener('scroll', Pushpin._updateElements);
}
_removeEventHandlers() {
document.removeEventListener('scroll', Pushpin._updateElements);
}
_updatePosition() {
let scrolled = utils_1.Utils.getDocumentScrollTop() + this.options.offset;
if (this.options.top <= scrolled &&
this.options.bottom >= scrolled &&
!this.el.classList.contains('pinned')) {
this._removePinClasses();
this.el.style.top = `${this.options.offset}px`;
this.el.classList.add('pinned');
// onPositionChange callback
if (typeof this.options.onPositionChange === 'function') {
this.options.onPositionChange.call(this, 'pinned');
}
}
// Add pin-top (when scrolled position is above top)
if (scrolled < this.options.top && !this.el.classList.contains('pin-top')) {
this._removePinClasses();
this.el.style.top = '0';
this.el.classList.add('pin-top');
// onPositionChange callback
if (typeof this.options.onPositionChange === 'function') {
this.options.onPositionChange.call(this, 'pin-top');
}
}
// Add pin-bottom (when scrolled position is below bottom)
if (scrolled > this.options.bottom && !this.el.classList.contains('pin-bottom')) {
this._removePinClasses();
this.el.classList.add('pin-bottom');
this.el.style.top = `${this.options.bottom - this.originalOffset}px`;
// onPositionChange callback
if (typeof this.options.onPositionChange === 'function') {
this.options.onPositionChange.call(this, 'pin-bottom');
}
}
}
_removePinClasses() {
// IE 11 bug (can't remove multiple classes in one line)
this.el.classList.remove('pin-top');
this.el.classList.remove('pinned');
this.el.classList.remove('pin-bottom');
}
}
exports.Pushpin = Pushpin;
(() => {
Pushpin._pushpins = [];
})();
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/range.ts":
/*!**********************!*\
!*** ./src/range.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Range = void 0;
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
const _defaults = {};
// TODO: !!!!!
class Range extends component_1.Component {
constructor(el, options) {
super(el, options, Range);
this._handleRangeChange = () => {
this.value.innerHTML = this.el.value;
if (!this.thumb.classList.contains('active')) {
this._showRangeBubble();
}
const offsetLeft = this._calcRangeOffset();
this.thumb.classList.add('active');
this.thumb.style.left = offsetLeft + 'px';
};
this._handleRangeMousedownTouchstart = (e) => {
// Set indicator value
this.value.innerHTML = this.el.value;
this._mousedown = true;
this.el.classList.add('active');
if (!this.thumb.classList.contains('active')) {
this._showRangeBubble();
}
if (e.type !== 'input') {
const offsetLeft = this._calcRangeOffset();
this.thumb.classList.add('active');
this.thumb.style.left = offsetLeft + 'px';
}
};
this._handleRangeInputMousemoveTouchmove = () => {
if (this._mousedown) {
if (!this.thumb.classList.contains('active')) {
this._showRangeBubble();
}
const offsetLeft = this._calcRangeOffset();
this.thumb.classList.add('active');
this.thumb.style.left = offsetLeft + 'px';
this.value.innerHTML = this.el.value;
}
};
this._handleRangeMouseupTouchend = () => {
this._mousedown = false;
this.el.classList.remove('active');
};
this._handleRangeBlurMouseoutTouchleave = () => {
if (!this._mousedown) {
const paddingLeft = parseInt(getComputedStyle(this.el).paddingLeft);
const marginLeftText = 7 + paddingLeft + 'px';
if (this.thumb.classList.contains('active')) {
const duration = 100;
// from
this.thumb.style.transition = 'none';
setTimeout(() => {
this.thumb.style.transition = `
height ${duration}ms ease,
width ${duration}ms ease,
top ${duration}ms ease,
margin ${duration}ms ease
`;
// to
this.thumb.style.height = '0';
this.thumb.style.width = '0';
this.thumb.style.top = '0';
this.thumb.style.marginLeft = marginLeftText;
}, 1);
}
this.thumb.classList.remove('active');
}
};
this.el.M_Range = this;
this.options = Object.assign(Object.assign({}, Range.defaults), options);
this._mousedown = false;
this._setupThumb();
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Range.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Range);
}
static getInstance(el) {
return el.M_Range;
}
destroy() {
this._removeEventHandlers();
this._removeThumb();
this.el.M_Range = undefined;
}
_setupEventHandlers() {
this.el.addEventListener('change', this._handleRangeChange);
this.el.addEventListener('mousedown', this._handleRangeMousedownTouchstart);
this.el.addEventListener('touchstart', this._handleRangeMousedownTouchstart);
this.el.addEventListener('input', this._handleRangeInputMousemoveTouchmove);
this.el.addEventListener('mousemove', this._handleRangeInputMousemoveTouchmove);
this.el.addEventListener('touchmove', this._handleRangeInputMousemoveTouchmove);
this.el.addEventListener('mouseup', this._handleRangeMouseupTouchend);
this.el.addEventListener('touchend', this._handleRangeMouseupTouchend);
this.el.addEventListener('blur', this._handleRangeBlurMouseoutTouchleave);
this.el.addEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave);
this.el.addEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave);
}
_removeEventHandlers() {
this.el.removeEventListener('change', this._handleRangeChange);
this.el.removeEventListener('mousedown', this._handleRangeMousedownTouchstart);
this.el.removeEventListener('touchstart', this._handleRangeMousedownTouchstart);
this.el.removeEventListener('input', this._handleRangeInputMousemoveTouchmove);
this.el.removeEventListener('mousemove', this._handleRangeInputMousemoveTouchmove);
this.el.removeEventListener('touchmove', this._handleRangeInputMousemoveTouchmove);
this.el.removeEventListener('mouseup', this._handleRangeMouseupTouchend);
this.el.removeEventListener('touchend', this._handleRangeMouseupTouchend);
this.el.removeEventListener('blur', this._handleRangeBlurMouseoutTouchleave);
this.el.removeEventListener('mouseout', this._handleRangeBlurMouseoutTouchleave);
this.el.removeEventListener('touchleave', this._handleRangeBlurMouseoutTouchleave);
}
_setupThumb() {
this.thumb = document.createElement('span');
this.value = document.createElement('span');
this.thumb.classList.add('thumb');
this.value.classList.add('value');
this.thumb.append(this.value);
this.el.after(this.thumb);
}
_removeThumb() {
this.thumb.remove();
}
_showRangeBubble() {
const paddingLeft = parseInt(getComputedStyle(this.thumb.parentElement).paddingLeft);
const marginLeftText = -7 + paddingLeft + 'px'; // TODO: fix magic number?
const duration = 300;
// easeOutQuint
this.thumb.style.transition = `
height ${duration}ms ease,
width ${duration}ms ease,
top ${duration}ms ease,
margin ${duration}ms ease
`;
// to
this.thumb.style.height = '30px';
this.thumb.style.width = '30px';
this.thumb.style.top = '-30px';
this.thumb.style.marginLeft = marginLeftText;
}
_calcRangeOffset() {
const width = this.el.getBoundingClientRect().width - 15;
const max = parseFloat(this.el.getAttribute('max')) || 100; // Range default max
const min = parseFloat(this.el.getAttribute('min')) || 0; // Range default min
const percent = (parseFloat(this.el.value) - min) / (max - min);
return percent * width;
}
/**
* Initializes every range input in the current document.
*/
static Init() {
Range.init((document.querySelectorAll('input[type=range]')), {});
2022-08-04 19:50:18 -05:00
}
}
exports.Range = Range;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/scrollspy.ts":
/*!**************************!*\
!*** ./src/scrollspy.ts ***!
\**************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ScrollSpy = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
let _defaults = {
throttle: 100,
scrollOffset: 200, // offset - 200 allows elements near bottom of page to scroll
activeClass: 'active',
getActiveElement: (id) => { return 'a[href="#' + id + '"]'; }
};
class ScrollSpy extends component_1.Component {
constructor(el, options) {
super(el, options, ScrollSpy);
this._handleThrottledResize = utils_1.Utils.throttle(function () { this._handleWindowScroll(); }, 200).bind(this);
this._handleTriggerClick = (e) => {
const trigger = e.target;
for (let i = ScrollSpy._elements.length - 1; i >= 0; i--) {
const scrollspy = ScrollSpy._elements[i];
const x = document.querySelector('a[href="#' + scrollspy.el.id + '"]');
if (trigger === x) {
e.preventDefault();
scrollspy.el.scrollIntoView({ behavior: 'smooth' });
break;
}
}
};
this._handleWindowScroll = () => {
// unique tick id
ScrollSpy._ticks++;
// viewport rectangle
let top = utils_1.Utils.getDocumentScrollTop(), left = utils_1.Utils.getDocumentScrollLeft(), right = left + window.innerWidth, bottom = top + window.innerHeight;
// determine which elements are in view
let intersections = ScrollSpy._findElements(top, right, bottom, left);
for (let i = 0; i < intersections.length; i++) {
let scrollspy = intersections[i];
let lastTick = scrollspy.tickId;
if (lastTick < 0) {
// entered into view
scrollspy._enter();
}
// update tick id
scrollspy.tickId = ScrollSpy._ticks;
}
for (let i = 0; i < ScrollSpy._elementsInView.length; i++) {
let scrollspy = ScrollSpy._elementsInView[i];
let lastTick = scrollspy.tickId;
if (lastTick >= 0 && lastTick !== ScrollSpy._ticks) {
// exited from view
scrollspy._exit();
scrollspy.tickId = -1;
}
}
// remember elements in view for next tick
ScrollSpy._elementsInView = intersections;
};
this.el.M_ScrollSpy = this;
this.options = Object.assign(Object.assign({}, ScrollSpy.defaults), options);
ScrollSpy._elements.push(this);
ScrollSpy._count++;
ScrollSpy._increment++;
this.tickId = -1;
this.id = ScrollSpy._increment;
this._setupEventHandlers();
this._handleWindowScroll();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of ScrollSpy.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, ScrollSpy);
}
static getInstance(el) {
return el.M_ScrollSpy;
}
destroy() {
ScrollSpy._elements.splice(ScrollSpy._elements.indexOf(this), 1);
ScrollSpy._elementsInView.splice(ScrollSpy._elementsInView.indexOf(this), 1);
ScrollSpy._visibleElements.splice(ScrollSpy._visibleElements.indexOf(this.el), 1);
ScrollSpy._count--;
2022-08-04 19:50:18 -05:00
this._removeEventHandlers();
const actElem = document.querySelector(this.options.getActiveElement(this.el.id));
actElem.classList.remove(this.options.activeClass);
this.el.M_ScrollSpy = undefined;
}
_setupEventHandlers() {
if (ScrollSpy._count === 1) {
window.addEventListener('scroll', this._handleWindowScroll);
window.addEventListener('resize', this._handleThrottledResize);
document.body.addEventListener('click', this._handleTriggerClick);
2022-08-04 19:50:18 -05:00
}
}
_removeEventHandlers() {
if (ScrollSpy._count === 0) {
window.removeEventListener('scroll', this._handleWindowScroll);
window.removeEventListener('resize', this._handleThrottledResize);
document.body.removeEventListener('click', this._handleTriggerClick);
2022-08-04 19:50:18 -05:00
}
}
static _offset(el) {
const box = el.getBoundingClientRect();
const docElem = document.documentElement;
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
static _findElements(top, right, bottom, left) {
let hits = [];
for (let i = 0; i < ScrollSpy._elements.length; i++) {
let scrollspy = ScrollSpy._elements[i];
let currTop = top + scrollspy.options.scrollOffset || 200;
if (scrollspy.el.getBoundingClientRect().height > 0) {
let elTop = ScrollSpy._offset(scrollspy.el).top, elLeft = ScrollSpy._offset(scrollspy.el).left, elRight = elLeft + scrollspy.el.getBoundingClientRect().width, elBottom = elTop + scrollspy.el.getBoundingClientRect().height;
let isIntersect = !(elLeft > right ||
elRight < left ||
elTop > bottom ||
elBottom < currTop);
if (isIntersect) {
hits.push(scrollspy);
}
}
2022-08-04 19:50:18 -05:00
}
return hits;
}
_enter() {
var _a;
ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter(value => value.getBoundingClientRect().height !== 0);
if (ScrollSpy._visibleElements[0]) {
const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id));
actElem === null || actElem === void 0 ? void 0 : actElem.classList.remove(this.options.activeClass);
if (ScrollSpy._visibleElements[0].M_ScrollSpy && this.id < ScrollSpy._visibleElements[0].M_ScrollSpy.id) {
ScrollSpy._visibleElements.unshift(this.el);
}
else {
ScrollSpy._visibleElements.push(this.el);
}
2022-08-04 19:50:18 -05:00
}
else {
ScrollSpy._visibleElements.push(this.el);
2022-08-04 19:50:18 -05:00
}
const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id);
(_a = document.querySelector(selector)) === null || _a === void 0 ? void 0 : _a.classList.add(this.options.activeClass);
}
_exit() {
var _a;
ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter(value => value.getBoundingClientRect().height !== 0);
if (ScrollSpy._visibleElements[0]) {
const actElem = document.querySelector(this.options.getActiveElement(ScrollSpy._visibleElements[0].id));
actElem === null || actElem === void 0 ? void 0 : actElem.classList.remove(this.options.activeClass);
ScrollSpy._visibleElements = ScrollSpy._visibleElements.filter((x) => x.id != this.el.id);
if (ScrollSpy._visibleElements[0]) {
// Check if empty
const selector = this.options.getActiveElement(ScrollSpy._visibleElements[0].id);
(_a = document.querySelector(selector)) === null || _a === void 0 ? void 0 : _a.classList.add(this.options.activeClass);
}
2022-08-04 19:50:18 -05:00
}
}
}
exports.ScrollSpy = ScrollSpy;
(() => {
ScrollSpy._elements = [];
ScrollSpy._elementsInView = [];
ScrollSpy._visibleElements = []; // Array.<cash>
ScrollSpy._count = 0;
ScrollSpy._increment = 0;
ScrollSpy._ticks = 0;
})();
/***/ }),
/***/ "./src/select.ts":
/*!***********************!*\
!*** ./src/select.ts ***!
\***********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.FormSelect = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const dropdown_1 = __webpack_require__(/*! ./dropdown */ "./src/dropdown.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
let _defaults = {
classes: '',
dropdownOptions: {}
};
class FormSelect extends component_1.Component {
constructor(el, options) {
super(el, options, FormSelect);
this._handleSelectChange = () => {
this._setValueToInput();
};
this._handleOptionClick = (e) => {
e.preventDefault();
const virtualOption = e.target.closest('li');
this._selectOptionElement(virtualOption);
e.stopPropagation();
};
this._handleInputClick = () => {
if (this.dropdown && this.dropdown.isOpen) {
this._setValueToInput();
this._setSelectedStates();
}
};
if (this.el.classList.contains('browser-default'))
return;
this.el.M_FormSelect = this;
this.options = Object.assign(Object.assign({}, FormSelect.defaults), options);
this.isMultiple = this.el.multiple;
this.el.tabIndex = -1;
this._values = [];
//this.labelEl = null;
//this._labelFor = false;
this._setupDropdown();
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of FormSelect.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, FormSelect);
}
static getInstance(el) {
return el.M_FormSelect;
}
destroy() {
// Returns label to its original owner
//if (this._labelFor) this.labelEl.setAttribute("for", this.el.id);
this._removeEventHandlers();
this._removeDropdown();
this.el.M_FormSelect = undefined;
}
_setupEventHandlers() {
this.dropdownOptions.querySelectorAll('li:not(.optgroup)').forEach((el) => {
el.addEventListener('click', this._handleOptionClick);
el.addEventListener('keydown', (e) => {
if (e.key === " " || e.key === "Enter")
this._handleOptionClick(e);
});
});
this.el.addEventListener('change', this._handleSelectChange);
this.input.addEventListener('click', this._handleInputClick);
}
_removeEventHandlers() {
this.dropdownOptions.querySelectorAll('li:not(.optgroup)').forEach((el) => {
el.removeEventListener('click', this._handleOptionClick);
});
this.el.removeEventListener('change', this._handleSelectChange);
this.input.removeEventListener('click', this._handleInputClick);
}
_arraysEqual(a, b) {
if (a === b)
return true;
if (a == null || b == null)
return false;
if (a.length !== b.length)
return false;
for (let i = 0; i < a.length; ++i)
if (a[i] !== b[i])
return false;
return true;
}
_selectOptionElement(virtualOption) {
if (!virtualOption.classList.contains('disabled') && !virtualOption.classList.contains('optgroup')) {
const value = this._values.find((value) => value.optionEl === virtualOption);
const previousSelectedValues = this.getSelectedValues();
if (this.isMultiple) {
// Multi-Select
this._toggleEntryFromArray(value);
}
else {
// Single-Select
this._deselectAll();
this._selectValue(value);
}
// Refresh Input-Text
this._setValueToInput();
// Trigger Change-Event only when data is different
const actualSelectedValues = this.getSelectedValues();
const selectionHasChanged = !this._arraysEqual(previousSelectedValues, actualSelectedValues);
if (selectionHasChanged)
this.el.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); // trigger('change');
}
if (!this.isMultiple)
this.dropdown.close();
}
_setupDropdown() {
// Get Label
this.labelEl = this.el.parentElement.querySelector('label');
// Create Wrapper
this.wrapper = document.createElement('div');
this.wrapper.classList.add('select-wrapper', 'input-field');
if (this.options.classes.length > 0) {
this.wrapper.classList.add(...this.options.classes.split(' '));
2022-08-04 19:50:18 -05:00
}
this.el.before(this.wrapper);
// Move actual select element into overflow hidden wrapper
const hideSelect = document.createElement('div');
hideSelect.classList.add('hide-select');
this.wrapper.append(hideSelect);
hideSelect.appendChild(this.el);
if (this.el.disabled)
this.wrapper.classList.add('disabled');
this.selectOptions = Array.from(this.el.children).filter(el => ['OPTION', 'OPTGROUP'].includes(el.tagName));
// Create dropdown
this.dropdownOptions = document.createElement('ul');
this.dropdownOptions.id = `select-options-${utils_1.Utils.guid()}`;
this.dropdownOptions.classList.add('dropdown-content', 'select-dropdown');
this.dropdownOptions.setAttribute('role', 'listbox');
this.dropdownOptions.ariaMultiSelectable = this.isMultiple.toString();
if (this.isMultiple)
this.dropdownOptions.classList.add('multiple-select-dropdown');
// Create dropdown structure
if (this.selectOptions.length > 0) {
this.selectOptions.forEach((realOption) => {
if (realOption.tagName === 'OPTION') {
// Option
const virtualOption = this._createAndAppendOptionWithIcon(realOption, this.isMultiple ? 'multiple' : undefined);
this._addOptionToValues(realOption, virtualOption);
}
else if (realOption.tagName === 'OPTGROUP') {
// Optgroup
const groupId = "opt-group-" + utils_1.Utils.guid();
const groupParent = document.createElement('li');
groupParent.classList.add('optgroup');
groupParent.tabIndex = -1;
groupParent.setAttribute('role', 'group');
groupParent.setAttribute('aria-labelledby', groupId);
groupParent.innerHTML = `<span id="${groupId}" role="presentation">${realOption.getAttribute('label')}</span>`;
this.dropdownOptions.append(groupParent);
const groupChildren = [];
const selectOptions = Array.from(realOption.children).filter(el => el.tagName === 'OPTION');
selectOptions.forEach(realOption => {
const virtualOption = this._createAndAppendOptionWithIcon(realOption, 'optgroup-option');
const childId = "opt-child-" + utils_1.Utils.guid();
virtualOption.id = childId;
groupChildren.push(childId);
this._addOptionToValues(realOption, virtualOption);
});
groupParent.setAttribute("aria-owns", groupChildren.join(" "));
}
});
2022-08-04 19:50:18 -05:00
}
this.wrapper.append(this.dropdownOptions);
// Add input dropdown
this.input = document.createElement('input');
this.input.id = "m_select-input-" + utils_1.Utils.guid();
this.input.classList.add('select-dropdown', 'dropdown-trigger');
this.input.type = 'text';
this.input.readOnly = true;
this.input.setAttribute('data-target', this.dropdownOptions.id);
this.input.ariaReadOnly = 'true';
this.input.ariaRequired = this.el.hasAttribute("required").toString(); //setAttribute("aria-required", this.el.hasAttribute("required"));
if (this.el.disabled)
this.input.disabled = true; // 'true');
// Place Label after input
if (this.labelEl) {
this.input.after(this.labelEl);
this.labelEl.setAttribute('for', this.input.id);
this.labelEl.id = "m_select-label-" + utils_1.Utils.guid();
this.dropdownOptions.setAttribute("aria-labelledby", this.labelEl.id);
}
// Makes new element to assume HTML's select label and aria-attributes, if exists
/*
if (this.el.hasAttribute("aria-labelledby")){
this.labelEl = <HTMLLabelElement>document.getElementById(this.el.getAttribute("aria-labelledby"));
}
else if (this.el.id != ""){
const label = document.createElement('label');
label.setAttribute('for', this.el.id);
if (label){
this.labelEl = label;
this.labelEl.removeAttribute("for");
this._labelFor = true;
}
}
*/
// Tries to find a valid label in parent element
// if (!this.labelEl) {
// this.labelEl = this.el.parentElement.querySelector('label');
// }
// if (this.labelEl && this.labelEl.id == "") {
// this.labelEl.id = "m_select-label-" + Utils.guid();
// }
// if (this.labelEl) {
// this.labelEl.setAttribute("for", this.input.id);
// this.dropdownOptions.setAttribute("aria-labelledby", this.labelEl.id);
// }
// else
// this.dropdownOptions.ariaLabel = '';
const attrs = this.el.attributes;
for (let i = 0; i < attrs.length; ++i) {
const attr = attrs[i];
if (attr.name.startsWith("aria-"))
this.input.setAttribute(attr.name, attr.value);
}
// Adds aria-attributes to input element
this.input.setAttribute('role', 'combobox');
this.input.ariaExpanded = 'false';
this.input.setAttribute("aria-owns", this.dropdownOptions.id);
this.input.setAttribute("aria-controls", this.dropdownOptions.id);
this.input.placeholder = " ";
this.wrapper.prepend(this.input);
this._setValueToInput();
// Add caret
const dropdownIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); //document.createElement('svg')
dropdownIcon.classList.add('caret');
dropdownIcon.setAttribute('height', '24');
dropdownIcon.setAttribute('width', '24');
dropdownIcon.setAttribute('viewBox', '0 0 24 24');
dropdownIcon.ariaHidden = 'true';
dropdownIcon.innerHTML = `<path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/>`;
this.wrapper.prepend(dropdownIcon);
// Initialize dropdown
if (!this.el.disabled) {
const dropdownOptions = Object.assign({}, this.options.dropdownOptions); // TODO:
dropdownOptions.coverTrigger = false;
const userOnOpenEnd = dropdownOptions.onOpenEnd;
const userOnCloseEnd = dropdownOptions.onCloseEnd;
// Add callback for centering selected option when dropdown content is scrollable
dropdownOptions.onOpenEnd = (el) => {
const selectedOption = this.dropdownOptions.querySelector('.selected');
if (selectedOption) {
// Focus selected option in dropdown
utils_1.Utils.keyDown = true;
this.dropdown.focusedIndex = [...selectedOption.parentNode.children].indexOf(selectedOption);
this.dropdown._focusFocusedItem();
utils_1.Utils.keyDown = false;
// Handle scrolling to selected option
if (this.dropdown.isScrollable) {
let scrollOffset = selectedOption.getBoundingClientRect().top -
this.dropdownOptions.getBoundingClientRect().top; // scroll to selected option
scrollOffset -= this.dropdownOptions.clientHeight / 2; // center in dropdown
this.dropdownOptions.scrollTop = scrollOffset;
}
}
this.input.ariaExpanded = 'true';
// Handle user declared onOpenEnd if needed
if (userOnOpenEnd && typeof userOnOpenEnd === 'function')
userOnOpenEnd.call(this.dropdown, this.el);
};
// Add callback for reseting "expanded" state
dropdownOptions.onCloseEnd = (el) => {
this.input.ariaExpanded = 'false';
// Handle user declared onOpenEnd if needed
if (userOnCloseEnd && typeof userOnCloseEnd === 'function')
userOnCloseEnd.call(this.dropdown, this.el);
};
// Prevent dropdown from closing too early
dropdownOptions.closeOnClick = false;
this.dropdown = dropdown_1.Dropdown.init(this.input, dropdownOptions);
}
// Add initial selections
this._setSelectedStates();
// ! Workaround for Label: move label up again
if (this.labelEl)
this.input.after(this.labelEl);
}
_addOptionToValues(realOption, virtualOption) {
this._values.push({ el: realOption, optionEl: virtualOption });
}
_removeDropdown() {
this.wrapper.querySelector('.caret').remove();
this.input.remove();
this.dropdownOptions.remove();
this.wrapper.before(this.el);
this.wrapper.remove();
}
_createAndAppendOptionWithIcon(realOption, type) {
var _a;
const li = document.createElement('li');
li.setAttribute('role', 'option');
if (realOption.disabled) {
li.classList.add('disabled');
li.ariaDisabled = 'true';
}
if (type === 'optgroup-option')
li.classList.add(type);
// Text / Checkbox
const span = document.createElement('span');
if (this.isMultiple)
span.innerHTML = `<label><input type="checkbox"${realOption.disabled ? ' disabled="disabled"' : ''}><span>${realOption.innerHTML}</span></label>`;
else
span.innerHTML = realOption.innerHTML;
li.appendChild(span);
// add Icon
const iconUrl = realOption.getAttribute('data-icon');
const classes = (_a = realOption.getAttribute('class')) === null || _a === void 0 ? void 0 : _a.split();
if (iconUrl) {
const img = document.createElement('img');
if (classes)
img.classList.add(classes);
img.src = iconUrl;
img.ariaHidden = 'true';
li.prepend(img);
}
// Check for multiple type
this.dropdownOptions.append(li);
return li;
}
_selectValue(value) {
value.el.selected = true;
value.optionEl.classList.add('selected');
value.optionEl.ariaSelected = 'true'; // setAttribute("aria-selected", true);
const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
if (checkbox)
checkbox.checked = true;
}
_deselectValue(value) {
value.el.selected = false;
value.optionEl.classList.remove('selected');
value.optionEl.ariaSelected = 'false'; //setAttribute("aria-selected", false);
const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
if (checkbox)
checkbox.checked = false;
}
_deselectAll() {
this._values.forEach(value => this._deselectValue(value));
}
_isValueSelected(value) {
const realValues = this.getSelectedValues();
return realValues.some((realValue) => realValue === value.el.value);
}
_toggleEntryFromArray(value) {
if (this._isValueSelected(value))
this._deselectValue(value);
else
this._selectValue(value);
}
_getSelectedOptions() {
// remove null, false, ... values
return Array.prototype.filter.call(this.el.selectedOptions, (realOption) => realOption);
}
_setValueToInput() {
const realOptions = this._getSelectedOptions();
const values = this._values.filter((value) => realOptions.indexOf(value.el) >= 0);
const texts = values.map((value) => value.optionEl.querySelector('span').innerText.trim());
// Set input-text to first Option with empty value which indicates a description like "choose your option"
if (texts.length === 0) {
const firstDisabledOption = this.el.querySelector('option:disabled');
if (firstDisabledOption && firstDisabledOption.value === '') {
this.input.value = firstDisabledOption.innerText;
return;
}
2022-08-04 19:50:18 -05:00
}
this.input.value = texts.join(', ');
}
_setSelectedStates() {
this._values.forEach((value) => {
const optionIsSelected = value.el.selected;
const cb = value.optionEl.querySelector('input[type="checkbox"]');
if (cb)
cb.checked = optionIsSelected;
if (optionIsSelected) {
this._activateOption(this.dropdownOptions, value.optionEl);
}
else {
value.optionEl.classList.remove('selected');
value.optionEl.ariaSelected = 'false'; // attr("aria-selected", 'false');
}
});
}
_activateOption(ul, li) {
if (!li)
return;
if (!this.isMultiple)
ul.querySelectorAll('li.selected').forEach(li => li.classList.remove('selected'));
li.classList.add('selected');
li.ariaSelected = 'true';
}
getSelectedValues() {
return this._getSelectedOptions().map((realOption) => realOption.value);
}
}
exports.FormSelect = FormSelect;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/sidenav.ts":
/*!************************!*\
!*** ./src/sidenav.ts ***!
\************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Sidenav = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
const _defaults = {
edge: 'left',
draggable: true,
dragTargetWidth: '10px',
inDuration: 250,
outDuration: 200,
onOpenStart: null,
onOpenEnd: null,
onCloseStart: null,
onCloseEnd: null,
preventScrolling: true
};
class Sidenav extends component_1.Component {
constructor(el, options) {
super(el, options, Sidenav);
this._handleDragTargetDrag = (e) => {
// Check if draggable
if (!this.options.draggable || this._isCurrentlyFixed() || this._verticallyScrolling) {
return;
}
// If not being dragged, set initial drag start variables
if (!this.isDragged) {
this._startDrag(e);
}
// Run touchmove updates
this._dragMoveUpdate(e);
// Calculate raw deltaX
let totalDeltaX = this._xPos - this._startingXpos;
// dragDirection is the attempted user drag direction
const dragDirection = totalDeltaX > 0 ? 'right' : 'left';
// Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction
totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX));
if (this.options.edge === dragDirection) {
totalDeltaX = 0;
}
/**
* transformX is the drag displacement
* transformPrefix is the initial transform placement
* Invert values if Sidenav is right edge
*/
let transformX = totalDeltaX;
let transformPrefix = 'translateX(-100%)';
if (this.options.edge === 'right') {
transformPrefix = 'translateX(100%)';
transformX = -transformX;
}
// Calculate open/close percentage of sidenav, with open = 1 and close = 0
this.percentOpen = Math.min(1, totalDeltaX / this._width);
// Set transform and opacity styles
this.el.style.transform = `${transformPrefix} translateX(${transformX}px)`;
this._overlay.style.opacity = this.percentOpen.toString();
};
this._handleDragTargetRelease = () => {
if (this.isDragged) {
if (this.percentOpen > 0.2) {
this.open();
}
else {
this._animateOut();
}
this.isDragged = false;
this._verticallyScrolling = false;
}
};
this._handleCloseDrag = (e) => {
if (this.isOpen) {
// Check if draggable
if (!this.options.draggable || this._isCurrentlyFixed() || this._verticallyScrolling) {
return;
}
// If not being dragged, set initial drag start variables
if (!this.isDragged) {
this._startDrag(e);
}
// Run touchmove updates
this._dragMoveUpdate(e);
// Calculate raw deltaX
let totalDeltaX = this._xPos - this._startingXpos;
// dragDirection is the attempted user drag direction
let dragDirection = totalDeltaX > 0 ? 'right' : 'left';
// Don't allow totalDeltaX to exceed Sidenav width or be dragged in the opposite direction
totalDeltaX = Math.min(this._width, Math.abs(totalDeltaX));
if (this.options.edge !== dragDirection) {
totalDeltaX = 0;
}
let transformX = -totalDeltaX;
if (this.options.edge === 'right') {
transformX = -transformX;
}
// Calculate open/close percentage of sidenav, with open = 1 and close = 0
this.percentOpen = Math.min(1, 1 - totalDeltaX / this._width);
// Set transform and opacity styles
this.el.style.transform = `translateX(${transformX}px)`;
this._overlay.style.opacity = this.percentOpen.toString();
}
};
this._handleCloseRelease = () => {
if (this.isOpen && this.isDragged) {
if (this.percentOpen > 0.8) {
this._animateIn();
}
else {
this.close();
}
this.isDragged = false;
this._verticallyScrolling = false;
}
};
// Handles closing of Sidenav when element with class .sidenav-close
this._handleCloseTriggerClick = (e) => {
const closeTrigger = e.target.closest('.sidenav-close');
if (closeTrigger && !this._isCurrentlyFixed()) {
this.close();
}
};
this._handleWindowResize = () => {
// Only handle horizontal resizes
if (this.lastWindowWidth !== window.innerWidth) {
if (window.innerWidth > 992) {
this.open();
}
else {
this.close();
}
}
this.lastWindowWidth = window.innerWidth;
this.lastWindowHeight = window.innerHeight;
};
/**
* Opens Sidenav.
*/
this.open = () => {
if (this.isOpen === true)
return;
this.isOpen = true;
// Run onOpenStart callback
if (typeof this.options.onOpenStart === 'function') {
this.options.onOpenStart.call(this, this.el);
}
// Handle fixed Sidenav
if (this._isCurrentlyFixed()) {
// Show if fixed
this.el.style.transform = 'translateX(0)';
this._enableBodyScrolling();
this._overlay.style.display = 'none';
}
// Handle non-fixed Sidenav
else {
if (this.options.preventScrolling)
this._preventBodyScrolling();
if (!this.isDragged || this.percentOpen != 1)
this._animateIn();
}
};
/**
* Closes Sidenav.
*/
this.close = () => {
if (this.isOpen === false)
return;
this.isOpen = false;
// Run onCloseStart callback
if (typeof this.options.onCloseStart === 'function') {
this.options.onCloseStart.call(this, this.el);
}
// Handle fixed Sidenav
if (this._isCurrentlyFixed()) {
const transformX = this.options.edge === 'left' ? '-105%' : '105%';
this.el.style.transform = `translateX(${transformX})`;
}
// Handle non-fixed Sidenav
else {
this._enableBodyScrolling();
if (!this.isDragged || this.percentOpen != 0) {
this._animateOut();
}
else {
this._overlay.style.display = 'none';
}
}
};
this.el.M_Sidenav = this;
this.options = Object.assign(Object.assign({}, Sidenav.defaults), options);
this.id = this.el.id;
this.isOpen = false;
this.isFixed = this.el.classList.contains('sidenav-fixed');
this.isDragged = false;
// Window size variables for window resize checks
this.lastWindowWidth = window.innerWidth;
this.lastWindowHeight = window.innerHeight;
this._createOverlay();
this._createDragTarget();
this._setupEventHandlers();
this._setupClasses();
this._setupFixed();
Sidenav._sidenavs.push(this);
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Sidenav.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Sidenav);
}
static getInstance(el) {
return el.M_Sidenav;
}
destroy() {
this._removeEventHandlers();
this._enableBodyScrolling();
this._overlay.parentNode.removeChild(this._overlay);
this.dragTarget.parentNode.removeChild(this.dragTarget);
this.el.M_Sidenav = undefined;
this.el.style.transform = '';
const index = Sidenav._sidenavs.indexOf(this);
if (index >= 0) {
Sidenav._sidenavs.splice(index, 1);
2022-08-04 19:50:18 -05:00
}
}
_createOverlay() {
this._overlay = document.createElement('div');
this._overlay.classList.add('sidenav-overlay');
this._overlay.addEventListener('click', this.close);
document.body.appendChild(this._overlay);
}
_setupEventHandlers() {
if (Sidenav._sidenavs.length === 0) {
document.body.addEventListener('click', this._handleTriggerClick);
}
var passiveIfSupported = null;
this.dragTarget.addEventListener('touchmove', this._handleDragTargetDrag, passiveIfSupported);
this.dragTarget.addEventListener('touchend', this._handleDragTargetRelease);
this._overlay.addEventListener('touchmove', this._handleCloseDrag, passiveIfSupported);
this._overlay.addEventListener('touchend', this._handleCloseRelease);
this.el.addEventListener('touchmove', this._handleCloseDrag, passiveIfSupported);
this.el.addEventListener('touchend', this._handleCloseRelease);
this.el.addEventListener('click', this._handleCloseTriggerClick);
// Add resize for side nav fixed
if (this.isFixed) {
window.addEventListener('resize', this._handleWindowResize);
2022-08-04 19:50:18 -05:00
}
}
_removeEventHandlers() {
if (Sidenav._sidenavs.length === 1) {
document.body.removeEventListener('click', this._handleTriggerClick);
}
this.dragTarget.removeEventListener('touchmove', this._handleDragTargetDrag);
this.dragTarget.removeEventListener('touchend', this._handleDragTargetRelease);
this._overlay.removeEventListener('touchmove', this._handleCloseDrag);
this._overlay.removeEventListener('touchend', this._handleCloseRelease);
this.el.removeEventListener('touchmove', this._handleCloseDrag);
this.el.removeEventListener('touchend', this._handleCloseRelease);
this.el.removeEventListener('click', this._handleCloseTriggerClick);
// Remove resize for side nav fixed
if (this.isFixed) {
window.removeEventListener('resize', this._handleWindowResize);
2022-08-04 19:50:18 -05:00
}
}
_handleTriggerClick(e) {
const trigger = e.target.closest('.sidenav-trigger');
if (e.target && trigger) {
const sidenavId = utils_1.Utils.getIdFromTrigger(trigger);
const sidenavInstance = document.getElementById(sidenavId).M_Sidenav;
if (sidenavInstance) {
sidenavInstance.open(trigger);
2022-08-04 19:50:18 -05:00
}
e.preventDefault();
2022-08-04 19:50:18 -05:00
}
}
// Set variables needed at the beginning of drag and stop any current transition.
_startDrag(e) {
const clientX = e.targetTouches[0].clientX;
this.isDragged = true;
this._startingXpos = clientX;
this._xPos = this._startingXpos;
this._time = Date.now();
this._width = this.el.getBoundingClientRect().width;
this._overlay.style.display = 'block';
this._initialScrollTop = this.isOpen ? this.el.scrollTop : utils_1.Utils.getDocumentScrollTop();
this._verticallyScrolling = false;
}
//Set variables needed at each drag move update tick
_dragMoveUpdate(e) {
const clientX = e.targetTouches[0].clientX;
const currentScrollTop = this.isOpen ? this.el.scrollTop : utils_1.Utils.getDocumentScrollTop();
this.deltaX = Math.abs(this._xPos - clientX);
this._xPos = clientX;
this.velocityX = this.deltaX / (Date.now() - this._time);
this._time = Date.now();
if (this._initialScrollTop !== currentScrollTop) {
this._verticallyScrolling = true;
2022-08-04 19:50:18 -05:00
}
}
_setupClasses() {
if (this.options.edge === 'right') {
this.el.classList.add('right-aligned');
this.dragTarget.classList.add('right-aligned');
2022-08-04 19:50:18 -05:00
}
}
_removeClasses() {
this.el.classList.remove('right-aligned');
this.dragTarget.classList.remove('right-aligned');
}
_setupFixed() {
if (this._isCurrentlyFixed())
this.open();
}
_isCurrentlyFixed() {
return this.isFixed && window.innerWidth > 992;
}
_createDragTarget() {
const dragTarget = document.createElement('div');
dragTarget.classList.add('drag-target');
dragTarget.style.width = this.options.dragTargetWidth;
document.body.appendChild(dragTarget);
this.dragTarget = dragTarget;
}
_preventBodyScrolling() {
document.body.style.overflow = 'hidden';
}
_enableBodyScrolling() {
document.body.style.overflow = '';
}
_animateIn() {
this._animateSidenavIn();
this._animateOverlayIn();
}
_animateOut() {
this._animateSidenavOut();
this._animateOverlayOut();
}
_animateSidenavIn() {
let slideOutPercent = this.options.edge === 'left' ? -1 : 1;
if (this.isDragged) {
slideOutPercent =
this.options.edge === 'left'
? slideOutPercent + this.percentOpen
: slideOutPercent - this.percentOpen;
}
const duration = this.options.inDuration;
// from
this.el.style.transition = 'none';
this.el.style.transform = 'translateX(' + (slideOutPercent * 100) + '%)';
setTimeout(() => {
this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad
// to
this.el.style.transform = 'translateX(0)';
}, 1);
setTimeout(() => {
if (typeof this.options.onOpenEnd === 'function')
this.options.onOpenEnd.call(this, this.el);
}, duration);
}
_animateSidenavOut() {
const endPercent = this.options.edge === 'left' ? -1 : 1;
let slideOutPercent = 0;
if (this.isDragged) {
slideOutPercent =
this.options.edge === 'left'
? endPercent + this.percentOpen
: endPercent - this.percentOpen;
}
const duration = this.options.outDuration;
this.el.style.transition = `transform ${duration}ms ease`; // easeOutQuad
// to
this.el.style.transform = 'translateX(' + (endPercent * 100) + '%)';
setTimeout(() => {
if (typeof this.options.onCloseEnd === 'function')
this.options.onCloseEnd.call(this, this.el);
}, duration);
}
_animateOverlayIn() {
let start = 0;
if (this.isDragged)
start = this.percentOpen;
else
this._overlay.style.display = 'block';
// Animation
const duration = this.options.inDuration;
// from
this._overlay.style.transition = 'none';
this._overlay.style.opacity = start.toString();
// easeOutQuad
setTimeout(() => {
this._overlay.style.transition = `opacity ${duration}ms ease`;
// to
this._overlay.style.opacity = '1';
}, 1);
}
_animateOverlayOut() {
const duration = this.options.outDuration;
// easeOutQuad
this._overlay.style.transition = `opacity ${duration}ms ease`;
// to
this._overlay.style.opacity = '0';
setTimeout(() => {
this._overlay.style.display = 'none';
}, duration);
}
}
exports.Sidenav = Sidenav;
(() => {
Sidenav._sidenavs = [];
})();
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/slider.ts":
/*!***********************!*\
!*** ./src/slider.ts ***!
\***********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Slider = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
let _defaults = {
indicators: true,
height: 400,
duration: 500,
interval: 6000,
pauseOnFocus: true,
pauseOnHover: true,
indicatorLabelFunc: null // Function which will generate a label for the indicators (ARIA)
};
class Slider extends component_1.Component {
constructor(el, options) {
super(el, options, Slider);
this._handleIndicatorClick = (e) => {
const el = e.target.parentElement;
const currIndex = [...el.parentNode.children].indexOf(el);
this._focusCurrent = true;
this.set(currIndex);
};
this._handleAutoPauseHover = () => {
this._hovered = true;
if (this.interval != null) {
this._pause(true);
}
};
this._handleAutoPauseFocus = () => {
this._focused = true;
if (this.interval != null) {
this._pause(true);
}
};
this._handleAutoStartHover = () => {
this._hovered = false;
if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) {
this.start();
}
};
this._handleAutoStartFocus = () => {
this._focused = false;
if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
this.start();
}
};
this._handleInterval = () => {
const activeElem = this._slider.querySelector('.active');
let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem);
if (this._slides.length === newActiveIndex + 1)
newActiveIndex = 0; // loop to start
else
newActiveIndex += 1;
this.set(newActiveIndex);
};
/**
* Pause slider autoslide.
*/
this.pause = () => {
this._pause(false);
};
/**
* Start slider autoslide.
*/
this.start = () => {
clearInterval(this.interval);
this.interval = setInterval(this._handleInterval, this.options.duration + this.options.interval);
this.eventPause = false;
};
/**
* Move to next slider.
*/
this.next = () => {
let newIndex = this.activeIndex + 1;
// Wrap around indices.
if (newIndex >= this._slides.length)
newIndex = 0;
else if (newIndex < 0)
newIndex = this._slides.length - 1;
this.set(newIndex);
};
/**
* Move to prev slider.
*/
this.prev = () => {
let newIndex = this.activeIndex - 1;
// Wrap around indices.
if (newIndex >= this._slides.length)
newIndex = 0;
else if (newIndex < 0)
newIndex = this._slides.length - 1;
this.set(newIndex);
};
this.el.M_Slider = this;
this.options = Object.assign(Object.assign({}, Slider.defaults), options);
// init props
this.interval = null;
this.eventPause = false;
this._hovered = false;
this._focused = false;
this._focusCurrent = false;
// setup
this._slider = this.el.querySelector('.slides');
this._slides = Array.from(this._slider.querySelectorAll('li'));
this.activeIndex = this._slides.findIndex(li => li.classList.contains('active'));
if (this.activeIndex !== -1) {
this._activeSlide = this._slides[this.activeIndex];
}
this._setSliderHeight();
// Sets element id if it does not have one
if (this._slider.hasAttribute('id'))
this._sliderId = this._slider.getAttribute('id');
else {
this._sliderId = 'slider-' + utils_1.Utils.guid();
this._slider.setAttribute('id', this._sliderId);
}
const placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
// Set initial positions of captions
this._slides.forEach(slide => {
// Caption
//const caption = <HTMLElement|null>slide.querySelector('.caption');
//if (caption) this._animateCaptionIn(caption, 0);
// Set Images as Background Images
const img = slide.querySelector('img');
if (img) {
if (img.src !== placeholderBase64) {
img.style.backgroundImage = 'url(' + img.src + ')';
img.src = placeholderBase64;
}
}
// Sets slide as focusable by code
if (!slide.hasAttribute('tabindex'))
slide.setAttribute('tabindex', '-1');
// Removes initial visibility from "inactive" slides
slide.style.visibility = 'hidden';
});
this._setupIndicators();
// Show active slide
if (this._activeSlide) {
this._activeSlide.style.display = 'block';
this._activeSlide.style.visibility = 'visible';
}
else {
this.activeIndex = 0;
this._slides[0].classList.add('active');
this._slides[0].style.visibility = 'visible';
this._activeSlide = this._slides[0];
this._animateSlide(this._slides[0], true);
// Update indicators
if (this.options.indicators) {
this._indicators[this.activeIndex].children[0].classList.add('active');
}
2022-08-04 19:50:18 -05:00
}
this._setupEventHandlers();
// auto scroll
this.start();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Slider.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Slider);
}
static getInstance(el) {
return el.M_Slider;
}
destroy() {
this.pause();
this._removeIndicators();
this._removeEventHandlers();
this.el.M_Slider = undefined;
}
_setupEventHandlers() {
if (this.options.pauseOnFocus) {
this.el.addEventListener('focusin', this._handleAutoPauseFocus);
this.el.addEventListener('focusout', this._handleAutoStartFocus);
2022-08-04 19:50:18 -05:00
}
if (this.options.pauseOnHover) {
this.el.addEventListener('mouseenter', this._handleAutoPauseHover);
this.el.addEventListener('mouseleave', this._handleAutoStartHover);
2022-08-04 19:50:18 -05:00
}
if (this.options.indicators) {
this._indicators.forEach((el) => {
el.addEventListener('click', this._handleIndicatorClick);
});
2022-08-04 19:50:18 -05:00
}
}
_removeEventHandlers() {
if (this.options.pauseOnFocus) {
this.el.removeEventListener('focusin', this._handleAutoPauseFocus);
this.el.removeEventListener('focusout', this._handleAutoStartFocus);
2022-08-04 19:50:18 -05:00
}
if (this.options.pauseOnHover) {
this.el.removeEventListener('mouseenter', this._handleAutoPauseHover);
this.el.removeEventListener('mouseleave', this._handleAutoStartHover);
2022-08-04 19:50:18 -05:00
}
if (this.options.indicators) {
this._indicators.forEach((el) => {
el.removeEventListener('click', this._handleIndicatorClick);
});
2022-08-04 19:50:18 -05:00
}
}
_animateSlide(slide, isDirectionIn) {
let dx = 0, dy = 0;
// from
slide.style.opacity = isDirectionIn ? '0' : '1';
setTimeout(() => {
slide.style.transition = `opacity ${this.options.duration}ms ease`;
// to
slide.style.opacity = isDirectionIn ? '1' : '0';
}, 1);
// Caption
const caption = slide.querySelector('.caption');
if (!caption)
return;
if (caption.classList.contains('center-align'))
dy = -100;
else if (caption.classList.contains('right-align'))
dx = 100;
else if (caption.classList.contains('left-align'))
dx = -100;
// from
caption.style.opacity = isDirectionIn ? '0' : '1';
caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`;
setTimeout(() => {
caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`;
// to
caption.style.opacity = isDirectionIn ? '1' : '0';
caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`;
}, this.options.duration); // delay
}
_setSliderHeight() {
// If fullscreen, do nothing
if (!this.el.classList.contains('fullscreen')) {
if (this.options.indicators) {
// Add height if indicators are present
this.el.style.height = (this.options.height + 40) + 'px'; //.css('height', this.options.height + 40 + 'px');
}
else {
this.el.style.height = this.options.height + 'px';
}
this._slider.style.height = this.options.height + 'px';
}
}
_setupIndicators() {
if (this.options.indicators) {
const ul = document.createElement('ul');
ul.classList.add('indicators');
const arrLi = [];
this._slides.forEach((el, i) => {
const label = this.options.indicatorLabelFunc
? this.options.indicatorLabelFunc.call(this, i + 1, i === 0)
: `${i + 1}`;
const li = document.createElement('li');
li.classList.add('indicator-item');
li.innerHTML = `<button type="button" class="indicator-item-btn" aria-label="${label}" aria-controls="${this._sliderId}"></button>`;
arrLi.push(li);
ul.append(li);
});
this.el.append(ul);
this._indicators = arrLi;
2022-08-04 19:50:18 -05:00
}
}
_removeIndicators() {
this.el.querySelector('ul.indicators').remove(); //find('ul.indicators').remove();
}
set(index) {
// Wrap around indices.
if (index >= this._slides.length)
index = 0;
else if (index < 0)
index = this._slides.length - 1;
// Only do if index changes
if (this.activeIndex === index)
return;
this._activeSlide = this._slides[this.activeIndex];
const _caption = this._activeSlide.querySelector('.caption');
this._activeSlide.classList.remove('active');
// Enables every slide
this._slides.forEach(slide => slide.style.visibility = 'visible');
//--- Hide active Slide + Caption
this._activeSlide.style.opacity = '0';
setTimeout(() => {
this._slides.forEach(slide => {
if (slide.classList.contains('active'))
return;
slide.style.opacity = '0';
slide.style.transform = 'translate(0, 0)';
// Disables invisible slides (for assistive technologies)
slide.style.visibility = 'hidden';
});
}, this.options.duration);
// Hide active Caption
//this._animateCaptionIn(_caption, this.options.duration);
_caption.style.opacity = '0';
// Update indicators
if (this.options.indicators) {
const activeIndicator = this._indicators[this.activeIndex].children[0];
const nextIndicator = this._indicators[index].children[0];
activeIndicator.classList.remove('active');
nextIndicator.classList.add('active');
if (typeof this.options.indicatorLabelFunc === "function") {
activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, this.activeIndex, false);
nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
}
2022-08-04 19:50:18 -05:00
}
//--- Show new Slide + Caption
this._animateSlide(this._slides[index], true);
this._slides[index].classList.add('active');
this.activeIndex = index;
// Reset interval, if allowed. This check prevents autostart
// when slider is paused, since it can be changed though indicators.
if (this.interval != null) {
this.start();
2022-08-04 19:50:18 -05:00
}
}
_pause(fromEvent) {
clearInterval(this.interval);
this.eventPause = fromEvent;
this.interval = null;
}
}
exports.Slider = Slider;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/tabs.ts":
/*!*********************!*\
!*** ./src/tabs.ts ***!
\*********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Tabs = void 0;
const carousel_1 = __webpack_require__(/*! ./carousel */ "./src/carousel.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
let _defaults = {
duration: 300,
onShow: null,
swipeable: false,
responsiveThreshold: Infinity // breakpoint for swipeable
};
class Tabs extends component_1.Component {
constructor(el, options) {
super(el, options, Tabs);
this._handleWindowResize = () => {
this._setTabsAndTabWidth();
if (this._tabWidth !== 0 && this._tabsWidth !== 0) {
this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px';
this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px';
}
2022-08-04 19:50:18 -05:00
};
this._handleTabClick = (e) => {
const tabLink = e.target;
const tab = tabLink.parentElement;
// Handle click on tab link only
if (!tabLink || !tab.classList.contains('tab'))
return;
// is disabled?
if (tab.classList.contains('disabled')) {
e.preventDefault();
return;
}
// Act as regular link if target attribute is specified.
if (tabLink.hasAttribute('target'))
return;
// Make the old tab inactive.
this._activeTabLink.classList.remove('active');
const _oldContent = this._content;
// Update the variables with the new link and content
this._activeTabLink = tabLink;
if (tabLink.hash)
this._content = document.querySelector(tabLink.hash);
this._tabLinks = this.el.querySelectorAll('li.tab > a');
// Make the tab active
this._activeTabLink.classList.add('active');
const prevIndex = this._index;
this._index = Math.max(Array.from(this._tabLinks).indexOf(tabLink), 0);
// Swap content
if (this.options.swipeable) {
if (this._tabsCarousel) {
this._tabsCarousel.set(this._index, () => {
if (typeof this.options.onShow === 'function')
this.options.onShow.call(this, this._content);
});
}
}
else {
if (this._content) {
this._content.style.display = 'block';
this._content.classList.add('active');
if (typeof this.options.onShow === 'function')
this.options.onShow.call(this, this._content);
if (_oldContent && _oldContent !== this._content) {
_oldContent.style.display = 'none';
_oldContent.classList.remove('active');
}
}
}
// Update widths after content is swapped (scrollbar bugfix)
this._setTabsAndTabWidth();
this._animateIndicator(prevIndex);
e.preventDefault();
};
this.el.M_Tabs = this;
this.options = Object.assign(Object.assign({}, Tabs.defaults), options);
this._tabLinks = this.el.querySelectorAll('li.tab > a');
this._index = 0;
this._setupActiveTabLink();
if (this.options.swipeable) {
this._setupSwipeableTabs();
2022-08-04 19:50:18 -05:00
}
else {
this._setupNormalTabs();
2022-08-04 19:50:18 -05:00
}
// Setup tabs indicator after content to ensure accurate widths
this._setTabsAndTabWidth();
this._createIndicator();
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Tabs.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Tabs);
}
static getInstance(el) {
return el.M_Tabs;
}
destroy() {
this._removeEventHandlers();
this._indicator.parentNode.removeChild(this._indicator);
if (this.options.swipeable) {
this._teardownSwipeableTabs();
2022-08-04 19:50:18 -05:00
}
else {
this._teardownNormalTabs();
2022-08-04 19:50:18 -05:00
}
this.el.M_Tabs = undefined;
}
/**
* The index of tab that is currently shown.
*/
get index() { return this._index; }
_setupEventHandlers() {
window.addEventListener('resize', this._handleWindowResize);
this.el.addEventListener('click', this._handleTabClick);
}
_removeEventHandlers() {
window.removeEventListener('resize', this._handleWindowResize);
this.el.removeEventListener('click', this._handleTabClick);
}
_createIndicator() {
const indicator = document.createElement('li');
indicator.classList.add('indicator');
this.el.appendChild(indicator);
this._indicator = indicator;
this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px';
this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px';
}
_setupActiveTabLink() {
// If the location.hash matches one of the links, use that as the active tab.
this._activeTabLink = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === location.hash);
// If no match is found, use the first link or any with class 'active' as the initial active tab.
if (!this._activeTabLink) {
this._activeTabLink = this.el.querySelector('li.tab a.active');
2022-08-04 19:50:18 -05:00
}
if (this._activeTabLink.length === 0) {
this._activeTabLink = this.el.querySelector('li.tab a');
2022-08-04 19:50:18 -05:00
}
Array.from(this._tabLinks).forEach((a) => a.classList.remove('active'));
this._activeTabLink.classList.add('active');
this._index = Math.max(Array.from(this._tabLinks).indexOf(this._activeTabLink), 0);
if (this._activeTabLink && this._activeTabLink.hash) {
this._content = document.querySelector(this._activeTabLink.hash);
if (this._content)
this._content.classList.add('active');
2022-08-04 19:50:18 -05:00
}
}
_setupSwipeableTabs() {
// Change swipeable according to responsive threshold
if (window.innerWidth > this.options.responsiveThreshold)
this.options.swipeable = false;
const tabsContent = [];
this._tabLinks.forEach(a => {
if (a.hash) {
const currContent = document.querySelector(a.hash);
currContent.classList.add('carousel-item');
tabsContent.push(currContent);
}
});
// Create Carousel-Wrapper around Tab-Contents
const tabsWrapper = document.createElement('div');
tabsWrapper.classList.add('tabs-content', 'carousel', 'carousel-slider');
// Wrap around
tabsContent[0].parentElement.insertBefore(tabsWrapper, tabsContent[0]);
tabsContent.forEach(tabContent => {
tabsWrapper.appendChild(tabContent);
tabContent.style.display = '';
});
// Keep active tab index to set initial carousel slide
const tab = this._activeTabLink.parentElement;
const activeTabIndex = Array.from(tab.parentNode.children).indexOf(tab);
this._tabsCarousel = carousel_1.Carousel.init(tabsWrapper, {
fullWidth: true,
noWrap: true,
onCycleTo: (item) => {
const prevIndex = this._index;
this._index = Array.from(item.parentNode.children).indexOf(item);
this._activeTabLink.classList.remove('active');
this._activeTabLink = Array.from(this._tabLinks)[this._index];
this._activeTabLink.classList.add('active');
this._animateIndicator(prevIndex);
if (typeof this.options.onShow === 'function')
this.options.onShow.call(this, this._content);
}
});
// Set initial carousel slide to active tab
this._tabsCarousel.set(activeTabIndex);
}
_teardownSwipeableTabs() {
const tabsWrapper = this._tabsCarousel.el;
this._tabsCarousel.destroy();
// Unwrap
tabsWrapper.after(tabsWrapper.children);
tabsWrapper.remove();
}
_setupNormalTabs() {
// Hide Tabs Content
Array.from(this._tabLinks).forEach((a) => {
if (a === this._activeTabLink)
return;
if (a.hash) {
const currContent = document.querySelector(a.hash);
if (currContent)
currContent.style.display = 'none';
}
});
}
_teardownNormalTabs() {
// show Tabs Content
this._tabLinks.forEach((a) => {
if (a.hash) {
const currContent = document.querySelector(a.hash);
if (currContent)
currContent.style.display = '';
}
});
}
_setTabsAndTabWidth() {
this._tabsWidth = this.el.getBoundingClientRect().width;
this._tabWidth = Math.max(this._tabsWidth, this.el.scrollWidth) / this._tabLinks.length;
}
_calcRightPos(el) {
return Math.ceil(this._tabsWidth - el.offsetLeft - el.getBoundingClientRect().width);
}
_calcLeftPos(el) {
return Math.floor(el.offsetLeft);
}
/**
* Recalculate tab indicator position. This is useful when
* the indicator position is not correct.
*/
updateTabIndicator() {
this._setTabsAndTabWidth();
this._animateIndicator(this._index);
}
_animateIndicator(prevIndex) {
let leftDelay = 0, rightDelay = 0;
const isMovingLeftOrStaying = (this._index - prevIndex >= 0);
if (isMovingLeftOrStaying)
leftDelay = 90;
else
rightDelay = 90;
// in v1: easeOutQuad
this._indicator.style.transition = `
left ${this.options.duration}ms ease-out ${leftDelay}ms,
right ${this.options.duration}ms ease-out ${rightDelay}ms`;
this._indicator.style.left = this._calcLeftPos(this._activeTabLink) + 'px';
this._indicator.style.right = this._calcRightPos(this._activeTabLink) + 'px';
}
/**
* Show tab content that corresponds to the tab with the id.
* @param tabId The id of the tab that you want to switch to.
*/
select(tabId) {
const tab = Array.from(this._tabLinks).find((a) => a.getAttribute('href') === '#' + tabId);
if (tab)
tab.click();
}
}
exports.Tabs = Tabs;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/tapTarget.ts":
/*!**************************!*\
!*** ./src/tapTarget.ts ***!
\**************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TapTarget = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
;
let _defaults = {
onOpen: null,
onClose: null
};
class TapTarget extends component_1.Component {
constructor(el, options) {
super(el, options, TapTarget);
this._handleThrottledResize = utils_1.Utils.throttle(function () { this._handleResize(); }, 200).bind(this);
this._handleTargetClick = () => {
this.open();
};
this._handleOriginClick = () => {
this.close();
};
this._handleResize = () => {
this._calculatePositioning();
};
this._handleDocumentClick = (e) => {
if (!e.target.closest('.tap-target-wrapper')) {
this.close();
e.preventDefault();
e.stopPropagation();
}
};
/**
* Open Tap Target.
*/
this.open = () => {
if (this.isOpen)
return;
// onOpen callback
if (typeof this.options.onOpen === 'function') {
this.options.onOpen.call(this, this._origin);
}
this.isOpen = true;
this.wrapper.classList.add('open');
document.body.addEventListener('click', this._handleDocumentClick, true);
document.body.addEventListener('touchend', this._handleDocumentClick);
};
/**
* Close Tap Target.
*/
this.close = () => {
if (!this.isOpen)
return;
// onClose callback
if (typeof this.options.onClose === 'function') {
this.options.onClose.call(this, this._origin);
}
this.isOpen = false;
this.wrapper.classList.remove('open');
document.body.removeEventListener('click', this._handleDocumentClick, true);
document.body.removeEventListener('touchend', this._handleDocumentClick);
};
this.el.M_TapTarget = this;
this.options = Object.assign(Object.assign({}, TapTarget.defaults), options);
2022-08-04 19:50:18 -05:00
this.isOpen = false;
// setup
this._origin = document.querySelector(`#${el.dataset.target}`);
this._setup();
this._calculatePositioning();
this._setupEventHandlers();
}
static get defaults() {
2022-08-04 19:50:18 -05:00
return _defaults;
}
/**
* Initializes instances of TapTarget.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, TapTarget);
}
static getInstance(el) {
return el.M_TapTarget;
}
destroy() {
this._removeEventHandlers();
this.el.TapTarget = undefined;
}
_setupEventHandlers() {
this.el.addEventListener('click', this._handleTargetClick);
this.originEl.addEventListener('click', this._handleOriginClick);
// Resize
window.addEventListener('resize', this._handleThrottledResize);
}
_removeEventHandlers() {
this.el.removeEventListener('click', this._handleTargetClick);
this.originEl.removeEventListener('click', this._handleOriginClick);
window.removeEventListener('resize', this._handleThrottledResize);
}
_setup() {
// Creating tap target
this.wrapper = this.el.parentElement;
this.waveEl = this.wrapper.querySelector('.tap-target-wave');
this.originEl = this.wrapper.querySelector('.tap-target-origin');
this.contentEl = this.el.querySelector('.tap-target-content');
// Creating wrapper
if (!this.wrapper.classList.contains('.tap-target-wrapper')) {
this.wrapper = document.createElement('div');
this.wrapper.classList.add('tap-target-wrapper');
this.el.before(this.wrapper);
this.wrapper.append(this.el);
}
// Creating content
if (!this.contentEl) {
this.contentEl = document.createElement('div');
this.contentEl.classList.add('tap-target-content');
this.el.append(this.contentEl);
}
// Creating foreground wave
if (!this.waveEl) {
this.waveEl = document.createElement('div');
this.waveEl.classList.add('tap-target-wave');
// Creating origin
if (!this.originEl) {
this.originEl = this._origin.cloneNode(true); // .clone(true, true);
this.originEl.classList.add('tap-target-origin');
this.originEl.removeAttribute('id');
this.originEl.removeAttribute('style');
this.waveEl.append(this.originEl);
}
this.wrapper.append(this.waveEl);
}
}
_offset(el) {
const box = el.getBoundingClientRect();
const docElem = document.documentElement;
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
_calculatePositioning() {
// Element or parent is fixed position?
let isFixed = getComputedStyle(this._origin).position === 'fixed';
if (!isFixed) {
let currentElem = this._origin;
const parents = [];
while ((currentElem = currentElem.parentNode) && currentElem !== document)
parents.push(currentElem);
for (let i = 0; i < parents.length; i++) {
isFixed = getComputedStyle(parents[i]).position === 'fixed';
if (isFixed)
break;
}
}
// Calculating origin
const originWidth = this._origin.offsetWidth;
const originHeight = this._origin.offsetHeight;
const originTop = isFixed ? this._offset(this._origin).top - utils_1.Utils.getDocumentScrollTop() : this._offset(this._origin).top;
const originLeft = isFixed ? this._offset(this._origin).left - utils_1.Utils.getDocumentScrollLeft() : this._offset(this._origin).left;
// Calculating screen
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
const scrollBarWidth = windowWidth - document.documentElement.clientWidth;
const centerX = windowWidth / 2;
const centerY = windowHeight / 2;
const isLeft = originLeft <= centerX;
const isRight = originLeft > centerX;
const isTop = originTop <= centerY;
const isBottom = originTop > centerY;
const isCenterX = originLeft >= windowWidth * 0.25 && originLeft <= windowWidth * 0.75;
// Calculating tap target
const tapTargetWidth = this.el.offsetWidth;
const tapTargetHeight = this.el.offsetHeight;
const tapTargetTop = originTop + originHeight / 2 - tapTargetHeight / 2;
const tapTargetLeft = originLeft + originWidth / 2 - tapTargetWidth / 2;
const tapTargetPosition = isFixed ? 'fixed' : 'absolute';
// Calculating content
const tapTargetTextWidth = isCenterX ? tapTargetWidth : tapTargetWidth / 2 + originWidth;
const tapTargetTextHeight = tapTargetHeight / 2;
const tapTargetTextTop = isTop ? tapTargetHeight / 2 : 0;
const tapTargetTextBottom = 0;
const tapTargetTextLeft = isLeft && !isCenterX ? tapTargetWidth / 2 - originWidth : 0;
const tapTargetTextRight = 0;
const tapTargetTextPadding = originWidth;
const tapTargetTextAlign = isBottom ? 'bottom' : 'top';
// Calculating wave
const tapTargetWaveWidth = originWidth > originHeight ? originWidth * 2 : originWidth * 2;
const tapTargetWaveHeight = tapTargetWaveWidth;
const tapTargetWaveTop = tapTargetHeight / 2 - tapTargetWaveHeight / 2;
const tapTargetWaveLeft = tapTargetWidth / 2 - tapTargetWaveWidth / 2;
// Setting tap target
this.wrapper.style.top = isTop ? tapTargetTop + 'px' : '';
this.wrapper.style.right = isRight ? windowWidth - tapTargetLeft - tapTargetWidth - scrollBarWidth + 'px' : '';
this.wrapper.style.bottom = isBottom ? windowHeight - tapTargetTop - tapTargetHeight + 'px' : '';
this.wrapper.style.left = isLeft ? tapTargetLeft + 'px' : '';
this.wrapper.style.position = tapTargetPosition;
// Setting content
this.contentEl.style.width = tapTargetTextWidth + 'px';
this.contentEl.style.height = tapTargetTextHeight + 'px';
this.contentEl.style.top = tapTargetTextTop + 'px';
this.contentEl.style.right = tapTargetTextRight + 'px';
this.contentEl.style.bottom = tapTargetTextBottom + 'px';
this.contentEl.style.left = tapTargetTextLeft + 'px';
this.contentEl.style.padding = tapTargetTextPadding + 'px';
this.contentEl.style.verticalAlign = tapTargetTextAlign;
// Setting wave
this.waveEl.style.top = tapTargetWaveTop + 'px';
this.waveEl.style.left = tapTargetWaveLeft + 'px';
this.waveEl.style.width = tapTargetWaveWidth + 'px';
this.waveEl.style.height = tapTargetWaveHeight + 'px';
}
}
exports.TapTarget = TapTarget;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/timepicker.ts":
/*!***************************!*\
!*** ./src/timepicker.ts ***!
\***************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Timepicker = void 0;
const modal_1 = __webpack_require__(/*! ./modal */ "./src/modal.ts");
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
let _defaults = {
2022-08-04 19:50:18 -05:00
dialRadius: 135,
outerRadius: 105,
innerRadius: 70,
tickRadius: 20,
duration: 350,
container: null,
defaultTime: 'now', // default time, 'now' or '13:14' e.g.
fromNow: 0, // Millisecond offset from the defaultTime
showClearBtn: false,
// internationalization
i18n: {
cancel: 'Cancel',
clear: 'Clear',
done: 'Ok'
2022-08-04 19:50:18 -05:00
},
autoClose: false, // auto close when minute is selected
twelveHour: true, // change to 12 hour AM/PM clock from 24 hour
vibrate: true, // vibrate the device when dragging clock hand
// Callbacks
onOpenStart: null,
onOpenEnd: null,
onCloseStart: null,
onCloseEnd: null,
onSelect: null
};
class Timepicker extends component_1.Component {
constructor(el, options) {
super(el, options, Timepicker);
this._handleInputClick = () => {
this.open();
};
this._handleInputKeydown = (e) => {
if (utils_1.Utils.keys.ENTER.includes(e.key)) {
e.preventDefault();
this.open();
}
};
this._handleTimeInputEnterKey = (e) => {
if (utils_1.Utils.keys.ENTER.includes(e.key)) {
e.preventDefault();
this._inputFromTextField();
}
};
this._handleClockClickStart = (e) => {
e.preventDefault();
let clockPlateBR = this.plate.getBoundingClientRect();
let offset = { x: clockPlateBR.left, y: clockPlateBR.top };
this.x0 = offset.x + this.options.dialRadius;
this.y0 = offset.y + this.options.dialRadius;
this.moved = false;
let clickPos = Timepicker._Pos(e);
this.dx = clickPos.x - this.x0;
this.dy = clickPos.y - this.y0;
// Set clock hands
this.setHand(this.dx, this.dy, false);
// Mousemove on document
document.addEventListener('mousemove', this._handleDocumentClickMove);
document.addEventListener('touchmove', this._handleDocumentClickMove);
// Mouseup on document
document.addEventListener('mouseup', this._handleDocumentClickEnd);
document.addEventListener('touchend', this._handleDocumentClickEnd);
};
this._handleDocumentClickMove = (e) => {
e.preventDefault();
let clickPos = Timepicker._Pos(e);
let x = clickPos.x - this.x0;
let y = clickPos.y - this.y0;
this.moved = true;
this.setHand(x, y, false);
};
this._handleDocumentClickEnd = (e) => {
e.preventDefault();
document.removeEventListener('mouseup', this._handleDocumentClickEnd);
document.removeEventListener('touchend', this._handleDocumentClickEnd);
let clickPos = Timepicker._Pos(e);
let x = clickPos.x - this.x0;
let y = clickPos.y - this.y0;
if (this.moved && x === this.dx && y === this.dy) {
this.setHand(x, y);
}
if (this.currentView === 'hours') {
this.showView('minutes', this.options.duration / 2);
}
else if (this.options.autoClose) {
this.minutesView.classList.add('timepicker-dial-out');
setTimeout(() => {
this.done();
}, this.options.duration / 2);
}
if (typeof this.options.onSelect === 'function') {
this.options.onSelect.call(this, this.hours, this.minutes);
}
// Unbind mousemove event
document.removeEventListener('mousemove', this._handleDocumentClickMove);
document.removeEventListener('touchmove', this._handleDocumentClickMove);
};
this._handleAmPmClick = (e) => {
const btnClicked = e.target;
this.amOrPm = btnClicked.classList.contains('am-btn') ? 'AM' : 'PM';
this._updateAmPmView();
};
/**
* Show hours or minutes view on timepicker.
* @param view The name of the view you want to switch to, 'hours' or 'minutes'.
*/
this.showView = (view, delay = null) => {
if (view === 'minutes' && getComputedStyle(this.hoursView).visibility === 'visible') {
// raiseCallback(this.options.beforeHourSelect);
}
let isHours = view === 'hours', nextView = isHours ? this.hoursView : this.minutesView, hideView = isHours ? this.minutesView : this.hoursView;
this.currentView = view;
if (isHours) {
this.inputHours.classList.add('text-primary');
this.inputMinutes.classList.remove('text-primary');
}
else {
this.inputHours.classList.remove('text-primary');
this.inputMinutes.classList.add('text-primary');
}
// Transition view
hideView.classList.add('timepicker-dial-out');
nextView.style.visibility = 'visible';
nextView.classList.remove('timepicker-dial-out');
// Reset clock hand
this.resetClock(delay);
// After transitions ended
clearTimeout(this.toggleViewTimer);
this.toggleViewTimer = setTimeout(() => {
hideView.style.visibility = 'hidden';
}, this.options.duration);
};
this._inputFromTextField = () => {
const isHours = this.currentView === 'hours';
if (isHours) {
const value = parseInt(this.inputHours.value);
if (value > 0 && value < 13) {
this.drawClockFromTimeInput(value, isHours);
this.showView('minutes', this.options.duration / 2);
this.hours = value;
this.inputMinutes.focus();
}
else {
const hour = new Date().getHours();
this.inputHours.value = (hour % 12).toString();
}
}
else {
const value = parseInt(this.inputMinutes.value);
if (value >= 0 && value < 60) {
this.inputMinutes.value = Timepicker._addLeadingZero(value);
this.drawClockFromTimeInput(value, isHours);
this.minutes = value;
this.modalEl.querySelector('.confirmation-btns :nth-child(2)').focus();
}
else {
const minutes = new Date().getMinutes();
this.inputMinutes.value = Timepicker._addLeadingZero(minutes);
}
}
};
/**
* Open timepicker.
*/
this.open = () => {
if (this.isOpen)
return;
this.isOpen = true;
this._updateTimeFromInput();
this.showView('hours');
this.modal.open(undefined);
};
/**
* Close timepicker.
*/
this.close = () => {
if (!this.isOpen)
return;
this.isOpen = false;
this.modal.close();
};
this.done = (e = null, clearValue = null) => {
// Set input value
let last = this.el.value;
let value = clearValue
? ''
: Timepicker._addLeadingZero(this.hours) + ':' + Timepicker._addLeadingZero(this.minutes);
this.time = value;
if (!clearValue && this.options.twelveHour) {
value = `${value} ${this.amOrPm}`;
}
this.el.value = value;
// Trigger change event
if (value !== last) {
this.el.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true }));
}
this.close();
this.el.focus();
};
this.clear = () => {
this.done(null, true);
};
this.el.M_Timepicker = this;
this.options = Object.assign(Object.assign({}, Timepicker.defaults), options);
this.id = utils_1.Utils.guid();
this._insertHTMLIntoDOM();
this._setupModal();
this._setupVariables();
this._setupEventHandlers();
this._clockSetup();
this._pickerSetup();
2022-08-04 19:50:18 -05:00
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Timepicker.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Timepicker);
}
static _addLeadingZero(num) {
return (num < 10 ? '0' : '') + num;
}
static _createSVGEl(name) {
let svgNS = 'http://www.w3.org/2000/svg';
return document.createElementNS(svgNS, name);
}
static _Pos(e) {
if (e.type.startsWith("touch") && e.targetTouches.length >= 1) {
return { x: e.targetTouches[0].clientX, y: e.targetTouches[0].clientY };
}
// mouse event
return { x: e.clientX, y: e.clientY };
}
static getInstance(el) {
return el.M_Timepicker;
}
destroy() {
2022-08-04 19:50:18 -05:00
this._removeEventHandlers();
this.modal.destroy();
this.modalEl.remove();
2022-08-04 19:50:18 -05:00
this.el.M_Timepicker = undefined;
}
_setupEventHandlers() {
this.el.addEventListener('click', this._handleInputClick);
this.el.addEventListener('keydown', this._handleInputKeydown);
this.plate.addEventListener('mousedown', this._handleClockClickStart);
this.plate.addEventListener('touchstart', this._handleClockClickStart);
this.digitalClock.addEventListener('keyup', this._inputFromTextField);
this.inputHours.addEventListener('click', () => this.showView('hours'));
this.inputMinutes.addEventListener('click', () => this.showView('minutes'));
}
_removeEventHandlers() {
this.el.removeEventListener('click', this._handleInputClick);
this.el.removeEventListener('keydown', this._handleInputKeydown);
}
_insertHTMLIntoDOM() {
const template = document.createElement('template');
template.innerHTML = Timepicker._template.trim();
this.modalEl = template.content.firstChild;
2022-08-04 19:50:18 -05:00
this.modalEl.id = 'modal-' + this.id;
// Append popover to input by default
const optEl = this.options.container;
const containerEl = optEl instanceof HTMLElement ? optEl : document.querySelector(optEl);
2022-08-04 19:50:18 -05:00
if (this.options.container && !!containerEl) {
containerEl.append(this.modalEl);
}
else {
this.el.parentElement.appendChild(this.modalEl);
}
}
_setupModal() {
this.modal = modal_1.Modal.init(this.modalEl, {
onOpenStart: this.options.onOpenStart,
onOpenEnd: this.options.onOpenEnd,
onCloseStart: this.options.onCloseStart,
onCloseEnd: () => {
if (typeof this.options.onCloseEnd === 'function') {
this.options.onCloseEnd.call(this);
}
this.isOpen = false;
}
2022-08-04 19:50:18 -05:00
});
}
_setupVariables() {
2022-08-04 19:50:18 -05:00
this.currentView = 'hours';
this.vibrate = navigator.vibrate
? 'vibrate'
: navigator.webkitVibrate
? 'webkitVibrate'
: null;
2022-08-04 19:50:18 -05:00
this._canvas = this.modalEl.querySelector('.timepicker-canvas');
this.plate = this.modalEl.querySelector('.timepicker-plate');
this.digitalClock = this.modalEl.querySelector('.timepicker-display-column');
2022-08-04 19:50:18 -05:00
this.hoursView = this.modalEl.querySelector('.timepicker-hours');
this.minutesView = this.modalEl.querySelector('.timepicker-minutes');
this.inputHours = this.modalEl.querySelector('.timepicker-input-hours');
this.inputMinutes = this.modalEl.querySelector('.timepicker-input-minutes');
2022-08-04 19:50:18 -05:00
this.spanAmPm = this.modalEl.querySelector('.timepicker-span-am-pm');
this.footer = this.modalEl.querySelector('.timepicker-footer');
this.amOrPm = 'PM';
}
_createButton(text, visibility) {
const button = document.createElement('button');
button.classList.add('btn-flat', 'waves-effect');
button.style.visibility = visibility;
button.type = 'button';
button.tabIndex = this.options.twelveHour ? 3 : 1;
button.innerText = text;
return button;
}
_pickerSetup() {
const clearButton = this._createButton(this.options.i18n.clear, this.options.showClearBtn ? '' : 'hidden');
clearButton.classList.add('timepicker-clear');
clearButton.addEventListener('click', this.clear);
this.footer.appendChild(clearButton);
const confirmationBtnsContainer = document.createElement('div');
confirmationBtnsContainer.classList.add('confirmation-btns');
this.footer.append(confirmationBtnsContainer);
const cancelButton = this._createButton(this.options.i18n.cancel, '');
cancelButton.classList.add('timepicker-close');
cancelButton.addEventListener('click', this.close);
confirmationBtnsContainer.appendChild(cancelButton);
const doneButton = this._createButton(this.options.i18n.done, '');
doneButton.classList.add('timepicker-close');
doneButton.addEventListener('click', this.done);
confirmationBtnsContainer.appendChild(doneButton);
}
_clockSetup() {
2022-08-04 19:50:18 -05:00
if (this.options.twelveHour) {
// AM Button
this._amBtn = document.createElement('div');
this._amBtn.classList.add('am-btn');
this._amBtn.innerText = 'AM';
this._amBtn.addEventListener('click', this._handleAmPmClick);
this.spanAmPm.appendChild(this._amBtn);
// PM Button
this._pmBtn = document.createElement('div');
this._pmBtn.classList.add('pm-btn');
this._pmBtn.innerText = 'PM';
this._pmBtn.addEventListener('click', this._handleAmPmClick);
this.spanAmPm.appendChild(this._pmBtn);
2022-08-04 19:50:18 -05:00
}
this._buildHoursView();
this._buildMinutesView();
this._buildSVGClock();
}
_buildSVGClock() {
2022-08-04 19:50:18 -05:00
// Draw clock hands and others
let dialRadius = this.options.dialRadius;
let tickRadius = this.options.tickRadius;
let diameter = dialRadius * 2;
let svg = Timepicker._createSVGEl('svg');
2022-08-04 19:50:18 -05:00
svg.setAttribute('class', 'timepicker-svg');
svg.setAttribute('width', diameter.toString());
svg.setAttribute('height', diameter.toString());
let g = Timepicker._createSVGEl('g');
2022-08-04 19:50:18 -05:00
g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')');
let bearing = Timepicker._createSVGEl('circle');
2022-08-04 19:50:18 -05:00
bearing.setAttribute('class', 'timepicker-canvas-bearing');
bearing.setAttribute('cx', '0');
bearing.setAttribute('cy', '0');
bearing.setAttribute('r', '4');
let hand = Timepicker._createSVGEl('line');
hand.setAttribute('x1', '0');
hand.setAttribute('y1', '0');
let bg = Timepicker._createSVGEl('circle');
2022-08-04 19:50:18 -05:00
bg.setAttribute('class', 'timepicker-canvas-bg');
bg.setAttribute('r', tickRadius.toString());
2022-08-04 19:50:18 -05:00
g.appendChild(hand);
g.appendChild(bg);
g.appendChild(bearing);
svg.appendChild(g);
this._canvas.appendChild(svg);
this.hand = hand;
this.bg = bg;
this.bearing = bearing;
this.g = g;
}
_buildHoursView() {
const $tick = document.createElement('div');
$tick.classList.add('timepicker-tick');
// Hours view
if (this.options.twelveHour) {
for (let i = 1; i < 13; i += 1) {
const tick = $tick.cloneNode(true);
const radian = (i / 6) * Math.PI;
const radius = this.options.outerRadius;
tick.style.left = this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px';
tick.style.top = this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px';
tick.innerHTML = i === 0 ? '00' : i.toString();
this.hoursView.appendChild(tick);
// tick.on(mousedownEvent, mousedown);
}
2022-08-04 19:50:18 -05:00
}
else {
for (let i = 0; i < 24; i += 1) {
const tick = $tick.cloneNode(true);
const radian = (i / 6) * Math.PI;
const inner = i > 0 && i < 13;
const radius = inner ? this.options.innerRadius : this.options.outerRadius;
tick.style.left = this.options.dialRadius + Math.sin(radian) * radius - this.options.tickRadius + 'px';
tick.style.top = this.options.dialRadius - Math.cos(radian) * radius - this.options.tickRadius + 'px';
tick.innerHTML = i === 0 ? '00' : i.toString();
this.hoursView.appendChild(tick);
// tick.on(mousedownEvent, mousedown);
}
2022-08-04 19:50:18 -05:00
}
}
_buildMinutesView() {
const _tick = document.createElement('div');
_tick.classList.add('timepicker-tick');
// Minutes view
for (let i = 0; i < 60; i += 5) {
const tick = _tick.cloneNode(true);
const radian = (i / 30) * Math.PI;
tick.style.left =
this.options.dialRadius +
Math.sin(radian) * this.options.outerRadius -
this.options.tickRadius +
'px';
tick.style.top =
this.options.dialRadius -
Math.cos(radian) * this.options.outerRadius -
this.options.tickRadius +
'px';
tick.innerHTML = Timepicker._addLeadingZero(i);
this.minutesView.appendChild(tick);
2022-08-04 19:50:18 -05:00
}
}
_updateAmPmView() {
if (this.options.twelveHour) {
if (this.amOrPm === 'PM') {
this._amBtn.classList.remove('text-primary');
this._pmBtn.classList.add('text-primary');
2022-08-04 19:50:18 -05:00
}
else if (this.amOrPm === 'AM') {
this._amBtn.classList.add('text-primary');
this._pmBtn.classList.remove('text-primary');
2022-08-04 19:50:18 -05:00
}
}
}
_updateTimeFromInput() {
// Get the time
let value = ((this.el.value || this.options.defaultTime || '') + '').split(':');
if (this.options.twelveHour && !(typeof value[1] === 'undefined')) {
if (value[1].toUpperCase().indexOf('AM') > 0) {
this.amOrPm = 'AM';
}
else {
this.amOrPm = 'PM';
}
value[1] = value[1].replace('AM', '').replace('PM', '');
2022-08-04 19:50:18 -05:00
}
if (value[0] === 'now') {
let now = new Date(+new Date() + this.options.fromNow);
value = [now.getHours().toString(), now.getMinutes().toString()];
if (this.options.twelveHour) {
this.amOrPm = parseInt(value[0]) >= 12 && parseInt(value[0]) < 24 ? 'PM' : 'AM';
}
2022-08-04 19:50:18 -05:00
}
this.hours = +value[0] || 0;
this.minutes = +value[1] || 0;
this.inputHours.value = this.hours;
this.inputMinutes.value = Timepicker._addLeadingZero(this.minutes);
this._updateAmPmView();
}
resetClock(delay) {
var _a;
let view = this.currentView, value = this[view], isHours = view === 'hours', unit = Math.PI / (isHours ? 6 : 30), radian = value * unit, radius = isHours && value > 0 && value < 13 ? this.options.innerRadius : this.options.outerRadius, x = Math.sin(radian) * radius, y = -Math.cos(radian) * radius, self = this;
if (delay) {
(_a = this.canvas) === null || _a === void 0 ? void 0 : _a.classList.add('timepicker-canvas-out');
setTimeout(() => {
var _a;
(_a = self.canvas) === null || _a === void 0 ? void 0 : _a.classList.remove('timepicker-canvas-out');
self.setHand(x, y);
}, delay);
2022-08-04 19:50:18 -05:00
}
else {
this.setHand(x, y);
2022-08-04 19:50:18 -05:00
}
}
drawClockFromTimeInput(value, isHours) {
const unit = Math.PI / (isHours ? 6 : 30);
const radian = value * unit;
let radius;
if (this.options.twelveHour) {
radius = this.options.outerRadius;
2022-08-04 19:50:18 -05:00
}
let cx1 = Math.sin(radian) * (radius - this.options.tickRadius), cy1 = -Math.cos(radian) * (radius - this.options.tickRadius), cx2 = Math.sin(radian) * radius, cy2 = -Math.cos(radian) * radius;
this.hand.setAttribute('x2', cx1.toString());
this.hand.setAttribute('y2', cy1.toString());
this.bg.setAttribute('cx', cx2.toString());
this.bg.setAttribute('cy', cy2.toString());
}
setHand(x, y, roundBy5 = false) {
let radian = Math.atan2(x, -y), isHours = this.currentView === 'hours', unit = Math.PI / (isHours || roundBy5 ? 6 : 30), z = Math.sqrt(x * x + y * y), inner = isHours && z < (this.options.outerRadius + this.options.innerRadius) / 2, radius = inner ? this.options.innerRadius : this.options.outerRadius;
if (this.options.twelveHour) {
radius = this.options.outerRadius;
2022-08-04 19:50:18 -05:00
}
// Radian should in range [0, 2PI]
if (radian < 0) {
radian = Math.PI * 2 + radian;
2022-08-04 19:50:18 -05:00
}
// Get the round value
let value = Math.round(radian / unit);
// Get the round radian
radian = value * unit;
// Correct the hours or minutes
if (this.options.twelveHour) {
if (isHours) {
if (value === 0)
value = 12;
}
else {
if (roundBy5)
value *= 5;
if (value === 60)
value = 0;
2022-08-04 19:50:18 -05:00
}
}
else {
if (isHours) {
if (value === 12) {
value = 0;
}
value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12;
}
else {
if (roundBy5) {
value *= 5;
}
if (value === 60) {
value = 0;
}
}
2022-08-04 19:50:18 -05:00
}
// Once hours or minutes changed, vibrate the device
if (this[this.currentView] !== value) {
if (this.vibrate && this.options.vibrate) {
// Do not vibrate too frequently
if (!this.vibrateTimer) {
navigator[this.vibrate](10);
this.vibrateTimer = setTimeout(() => {
this.vibrateTimer = null;
}, 100);
}
}
2022-08-04 19:50:18 -05:00
}
this[this.currentView] = value;
if (isHours) {
this.inputHours.value = value.toString();
2022-08-04 19:50:18 -05:00
}
else {
this.inputMinutes.value = Timepicker._addLeadingZero(value);
2022-08-04 19:50:18 -05:00
}
// Set clock hand and others' position
let cx1 = Math.sin(radian) * (radius - this.options.tickRadius), cy1 = -Math.cos(radian) * (radius - this.options.tickRadius), cx2 = Math.sin(radian) * radius, cy2 = -Math.cos(radian) * radius;
this.hand.setAttribute('x2', cx1.toString());
this.hand.setAttribute('y2', cy1.toString());
this.bg.setAttribute('cx', cx2.toString());
this.bg.setAttribute('cy', cy2.toString());
}
}
exports.Timepicker = Timepicker;
(() => {
Timepicker._template = `
<div class="modal timepicker-modal">
<div class="modal-content timepicker-container">
<div class="timepicker-digital-display">
<div class="timepicker-text-container">
<div class="timepicker-display-column">
<input type="text" maxlength="2" autofocus class="timepicker-input-hours text-primary" />
:
<input type="text" maxlength="2" class="timepicker-input-minutes" />
</div>
<div class="timepicker-display-column timepicker-display-am-pm">
<div class="timepicker-span-am-pm"></div>
</div>
</div>
</div>
<div class="timepicker-analog-display">
<div class="timepicker-plate">
<div class="timepicker-canvas"></div>
<div class="timepicker-dial timepicker-hours"></div>
<div class="timepicker-dial timepicker-minutes timepicker-dial-out"></div>
</div>
<div class="timepicker-footer"></div>
</div>
</div>
</div`;
})();
/***/ }),
/***/ "./src/toasts.ts":
/*!***********************!*\
!*** ./src/toasts.ts ***!
\***********************/
/***/ (function(__unused_webpack_module, exports) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Toast = void 0;
let _defaults = {
text: '',
displayLength: 4000,
inDuration: 300,
outDuration: 375,
2022-08-04 19:50:18 -05:00
classes: '',
completeCallback: null,
activationPercent: 0.8
};
class Toast {
constructor(options) {
this.options = Object.assign(Object.assign({}, Toast.defaults), options);
this.message = this.options.text;
this.panning = false;
this.timeRemaining = this.options.displayLength;
if (Toast._toasts.length === 0) {
Toast._createContainer();
}
// Create new toast
Toast._toasts.push(this);
let toastElement = this._createToast();
toastElement.M_Toast = this;
this.el = toastElement;
this._animateIn();
this._setTimer();
2022-08-04 19:50:18 -05:00
}
static get defaults() {
return _defaults;
}
static getInstance(el) {
return el.M_Toast;
}
static _createContainer() {
const container = document.createElement('div');
container.setAttribute('id', 'toast-container');
// Add event handler
container.addEventListener('touchstart', Toast._onDragStart);
container.addEventListener('touchmove', Toast._onDragMove);
container.addEventListener('touchend', Toast._onDragEnd);
container.addEventListener('mousedown', Toast._onDragStart);
document.addEventListener('mousemove', Toast._onDragMove);
document.addEventListener('mouseup', Toast._onDragEnd);
document.body.appendChild(container);
Toast._container = container;
}
static _removeContainer() {
document.removeEventListener('mousemove', Toast._onDragMove);
document.removeEventListener('mouseup', Toast._onDragEnd);
Toast._container.remove();
Toast._container = null;
}
static _onDragStart(e) {
if (e.target && e.target.closest('.toast')) {
const toastElem = e.target.closest('.toast');
const toast = toastElem.M_Toast;
toast.panning = true;
Toast._draggedToast = toast;
toast.el.classList.add('panning');
toast.el.style.transition = '';
toast.startingXPos = Toast._xPos(e);
toast.time = Date.now();
toast.xPos = Toast._xPos(e);
2022-08-04 19:50:18 -05:00
}
}
static _onDragMove(e) {
if (!!Toast._draggedToast) {
e.preventDefault();
const toast = Toast._draggedToast;
toast.deltaX = Math.abs(toast.xPos - Toast._xPos(e));
toast.xPos = Toast._xPos(e);
toast.velocityX = toast.deltaX / (Date.now() - toast.time);
toast.time = Date.now();
const totalDeltaX = toast.xPos - toast.startingXPos;
const activationDistance = toast.el.offsetWidth * toast.options.activationPercent;
toast.el.style.transform = `translateX(${totalDeltaX}px)`;
toast.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();
2022-08-04 19:50:18 -05:00
}
}
static _onDragEnd() {
if (!!Toast._draggedToast) {
let toast = Toast._draggedToast;
toast.panning = false;
toast.el.classList.remove('panning');
let totalDeltaX = toast.xPos - toast.startingXPos;
let activationDistance = toast.el.offsetWidth * toast.options.activationPercent;
let shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || toast.velocityX > 1;
// Remove toast
if (shouldBeDismissed) {
toast.wasSwiped = true;
toast.dismiss();
// Animate toast back to original position
}
else {
toast.el.style.transition = 'transform .2s, opacity .2s';
toast.el.style.transform = '';
toast.el.style.opacity = '';
}
Toast._draggedToast = null;
}
}
static _xPos(e) {
if (e.type.startsWith("touch") && e.targetTouches.length >= 1) {
return e.targetTouches[0].clientX;
}
// mouse event
return e.clientX;
}
/**
* dismiss all toasts.
*/
static dismissAll() {
for (let toastIndex in Toast._toasts) {
Toast._toasts[toastIndex].dismiss();
2022-08-04 19:50:18 -05:00
}
}
_createToast() {
let toast = this.options.toastId
? document.getElementById(this.options.toastId)
: document.createElement('div');
if (toast instanceof HTMLTemplateElement) {
const node = toast.content.cloneNode(true);
toast = node.firstElementChild;
2022-08-04 19:50:18 -05:00
}
toast.classList.add('toast');
toast.setAttribute('role', 'alert');
toast.setAttribute('aria-live', 'assertive');
toast.setAttribute('aria-atomic', 'true');
// Add custom classes onto toast
if (this.options.classes.length > 0) {
toast.classList.add(...this.options.classes.split(' '));
2022-08-04 19:50:18 -05:00
}
if (this.message)
toast.innerText = this.message;
Toast._container.appendChild(toast);
return toast;
}
_animateIn() {
// Animate toast in
this.el.style.display = "";
this.el.style.opacity = '0';
// easeOutCubic
this.el.style.transition = `
top ${this.options.inDuration}ms ease,
opacity ${this.options.inDuration}ms ease
`;
setTimeout(() => {
this.el.style.top = '0';
this.el.style.opacity = '1';
}, 1);
}
/**
* Create setInterval which automatically removes toast when timeRemaining >= 0
* has been reached.
*/
_setTimer() {
if (this.timeRemaining !== Infinity) {
this.counterInterval = setInterval(() => {
// If toast is not being dragged, decrease its time remaining
if (!this.panning) {
this.timeRemaining -= 20;
}
// Animate toast out
if (this.timeRemaining <= 0) {
this.dismiss();
}
}, 20);
2022-08-04 19:50:18 -05:00
}
}
/**
* Dismiss toast with animation.
*/
dismiss() {
window.clearInterval(this.counterInterval);
let activationDistance = this.el.offsetWidth * this.options.activationPercent;
if (this.wasSwiped) {
this.el.style.transition = 'transform .05s, opacity .05s';
this.el.style.transform = `translateX(${activationDistance}px)`;
this.el.style.opacity = '0';
}
// easeOutExpo
this.el.style.transition = `
margin ${this.options.outDuration}ms ease,
opacity ${this.options.outDuration}ms ease`;
setTimeout(() => {
this.el.style.opacity = '0';
this.el.style.marginTop = '-40px';
}, 1);
setTimeout(() => {
// Call the optional callback
if (typeof this.options.completeCallback === 'function') {
this.options.completeCallback();
}
// Remove toast from DOM
if (this.el.id != this.options.toastId) {
this.el.remove();
Toast._toasts.splice(Toast._toasts.indexOf(this), 1);
if (Toast._toasts.length === 0) {
Toast._removeContainer();
}
}
}, this.options.outDuration);
}
}
exports.Toast = Toast;
(() => {
Toast._toasts = [];
Toast._container = null;
Toast._draggedToast = null;
})();
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/tooltip.ts":
/*!************************!*\
!*** ./src/tooltip.ts ***!
\************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Tooltip = void 0;
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
const component_1 = __webpack_require__(/*! ./component */ "./src/component.ts");
const _defaults = {
exitDelay: 200,
enterDelay: 0,
text: '',
margin: 5,
inDuration: 250,
outDuration: 200,
position: 'bottom',
transitionMovement: 10,
opacity: 1
};
class Tooltip extends component_1.Component {
constructor(el, options) {
super(el, options, Tooltip);
/**
* Show tooltip.
*/
this.open = (isManual) => {
if (this.isOpen)
return;
isManual = isManual === undefined ? true : undefined; // Default value true
this.isOpen = true;
// Update tooltip content with HTML attribute options
this.options = Object.assign(Object.assign({}, this.options), this._getAttributeOptions());
this._updateTooltipContent();
this._setEnterDelayTimeout(isManual);
};
/**
* Hide tooltip.
*/
this.close = () => {
if (!this.isOpen)
return;
this.isHovered = false;
this.isFocused = false;
this.isOpen = false;
this._setExitDelayTimeout();
};
this._handleMouseEnter = () => {
this.isHovered = true;
this.isFocused = false; // Allows close of tooltip when opened by focus.
this.open(false);
};
this._handleMouseLeave = () => {
this.isHovered = false;
this.isFocused = false; // Allows close of tooltip when opened by focus.
this.close();
};
this._handleFocus = () => {
if (utils_1.Utils.tabPressed) {
this.isFocused = true;
this.open(false);
2022-08-04 19:50:18 -05:00
}
};
this._handleBlur = () => {
this.isFocused = false;
this.close();
};
this.el.M_Tooltip = this;
this.options = Object.assign(Object.assign(Object.assign({}, Tooltip.defaults), this._getAttributeOptions()), options);
this.isOpen = false;
this.isHovered = false;
this.isFocused = false;
this._appendTooltipEl();
this._setupEventHandlers();
}
static get defaults() {
return _defaults;
}
/**
* Initializes instances of Tooltip.
* @param els HTML elements.
* @param options Component options.
*/
static init(els, options = {}) {
return super.init(els, options, Tooltip);
}
static getInstance(el) {
return el.M_Tooltip;
}
destroy() {
this.tooltipEl.remove();
this._removeEventHandlers();
this.el.M_Tooltip = undefined;
}
_appendTooltipEl() {
this.tooltipEl = document.createElement('div');
this.tooltipEl.classList.add('material-tooltip');
const tooltipContentEl = this.options.tooltipId
? document.getElementById(this.options.tooltipId)
: document.createElement('div');
this.tooltipEl.append(tooltipContentEl);
tooltipContentEl.style.display = "";
tooltipContentEl.classList.add('tooltip-content');
this._setTooltipContent(tooltipContentEl);
this.tooltipEl.appendChild(tooltipContentEl);
document.body.appendChild(this.tooltipEl);
}
_setTooltipContent(tooltipContentEl) {
if (this.options.tooltipId)
return;
tooltipContentEl.innerText = this.options.text;
}
_updateTooltipContent() {
this._setTooltipContent(this.tooltipEl.querySelector('.tooltip-content'));
}
_setupEventHandlers() {
this.el.addEventListener('mouseenter', this._handleMouseEnter);
this.el.addEventListener('mouseleave', this._handleMouseLeave);
this.el.addEventListener('focus', this._handleFocus, true);
this.el.addEventListener('blur', this._handleBlur, true);
}
_removeEventHandlers() {
this.el.removeEventListener('mouseenter', this._handleMouseEnter);
this.el.removeEventListener('mouseleave', this._handleMouseLeave);
this.el.removeEventListener('focus', this._handleFocus, true);
this.el.removeEventListener('blur', this._handleBlur, true);
}
_setExitDelayTimeout() {
clearTimeout(this._exitDelayTimeout);
this._exitDelayTimeout = setTimeout(() => {
if (this.isHovered || this.isFocused)
return;
this._animateOut();
}, this.options.exitDelay);
}
_setEnterDelayTimeout(isManual) {
clearTimeout(this._enterDelayTimeout);
this._enterDelayTimeout = setTimeout(() => {
if (!this.isHovered && !this.isFocused && !isManual)
return;
this._animateIn();
}, this.options.enterDelay);
}
_positionTooltip() {
const tooltip = this.tooltipEl;
const origin = this.el, originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, tooltipHeight = tooltip.offsetHeight, tooltipWidth = tooltip.offsetWidth, margin = this.options.margin;
(this.xMovement = 0), (this.yMovement = 0);
let targetTop = origin.getBoundingClientRect().top + utils_1.Utils.getDocumentScrollTop();
let targetLeft = origin.getBoundingClientRect().left + utils_1.Utils.getDocumentScrollLeft();
if (this.options.position === 'top') {
targetTop += -tooltipHeight - margin;
targetLeft += originWidth / 2 - tooltipWidth / 2;
this.yMovement = -this.options.transitionMovement;
}
else if (this.options.position === 'right') {
targetTop += originHeight / 2 - tooltipHeight / 2;
targetLeft += originWidth + margin;
this.xMovement = this.options.transitionMovement;
}
else if (this.options.position === 'left') {
targetTop += originHeight / 2 - tooltipHeight / 2;
targetLeft += -tooltipWidth - margin;
this.xMovement = -this.options.transitionMovement;
}
else {
targetTop += originHeight + margin;
targetLeft += originWidth / 2 - tooltipWidth / 2;
this.yMovement = this.options.transitionMovement;
}
const newCoordinates = this._repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight);
tooltip.style.top = newCoordinates.y + 'px';
tooltip.style.left = newCoordinates.x + 'px';
}
_repositionWithinScreen(x, y, width, height) {
const scrollLeft = utils_1.Utils.getDocumentScrollLeft();
const scrollTop = utils_1.Utils.getDocumentScrollTop();
let newX = x - scrollLeft;
let newY = y - scrollTop;
const bounding = {
left: newX,
top: newY,
width: width,
height: height
};
const offset = this.options.margin + this.options.transitionMovement;
const edges = utils_1.Utils.checkWithinContainer(document.body, bounding, offset);
if (edges.left) {
newX = offset;
2022-08-04 19:50:18 -05:00
}
else if (edges.right) {
newX -= newX + width - window.innerWidth;
}
if (edges.top) {
newY = offset;
}
else if (edges.bottom) {
newY -= newY + height - window.innerHeight;
}
return {
x: newX + scrollLeft,
y: newY + scrollTop
};
}
_animateIn() {
this._positionTooltip();
this.tooltipEl.style.visibility = 'visible';
const duration = this.options.inDuration;
// easeOutCubic
this.tooltipEl.style.transition = `
transform ${duration}ms ease-out,
opacity ${duration}ms ease-out`;
setTimeout(() => {
this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`;
this.tooltipEl.style.opacity = (this.options.opacity || 1).toString();
}, 1);
}
_animateOut() {
const duration = this.options.outDuration;
// easeOutCubic
this.tooltipEl.style.transition = `
transform ${duration}ms ease-out,
opacity ${duration}ms ease-out`;
setTimeout(() => {
this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`;
this.tooltipEl.style.opacity = '0';
}, 1);
/*
anim.remove(this.tooltipEl);
anim({
targets: this.tooltipEl,
opacity: 0,
translateX: 0,
translateY: 0,
duration: this.options.outDuration,
easing: 'easeOutCubic'
2022-08-04 19:50:18 -05:00
});
*/
}
_getAttributeOptions() {
let attributeOptions = {};
const tooltipTextOption = this.el.getAttribute('data-tooltip');
const tooltipId = this.el.getAttribute('data-tooltip-id');
const positionOption = this.el.getAttribute('data-position');
if (tooltipTextOption) {
attributeOptions.text = tooltipTextOption;
2022-08-04 19:50:18 -05:00
}
if (positionOption) {
attributeOptions.position = positionOption;
2022-08-04 19:50:18 -05:00
}
if (tooltipId) {
attributeOptions.tooltipId = tooltipId;
}
return attributeOptions;
}
}
exports.Tooltip = Tooltip;
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/utils.ts":
/*!**********************!*\
!*** ./src/utils.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Utils = void 0;
/**
* Class with utilitary functions for global usage.
*/
class Utils {
2022-08-04 19:50:18 -05:00
/**
* Detects when a key is pressed.
* @param e Event instance.
2022-08-04 19:50:18 -05:00
*/
static docHandleKeydown(e) {
Utils.keyDown = true;
if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) {
Utils.tabPressed = true;
}
2022-08-04 19:50:18 -05:00
}
/**
* Detects when a key is released.
* @param e Event instance.
*/
static docHandleKeyup(e) {
Utils.keyDown = false;
if ([...Utils.keys.TAB, ...Utils.keys.ARROW_DOWN, ...Utils.keys.ARROW_UP].includes(e.key)) {
Utils.tabPressed = false;
2022-08-04 19:50:18 -05:00
}
}
/**
* Detects when document is focused.
* @param e Event instance.
*/
static docHandleFocus(e) {
if (Utils.keyDown) {
document.body.classList.add('keyboard-focused');
2022-08-04 19:50:18 -05:00
}
}
/**
* Detects when document is not focused.
* @param e Event instance.
*/
static docHandleBlur(e) {
document.body.classList.remove('keyboard-focused');
}
/**
* Generates a unique string identifier.
*/
static guid() {
const s4 = () => {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
/**
* Checks for exceeded edges
* @param container Container element.
* @param bounding Bounding rect.
* @param offset Element offset.
*/
static checkWithinContainer(container, bounding, offset) {
let edges = {
top: false,
right: false,
bottom: false,
left: false
};
let containerRect = container.getBoundingClientRect();
// If body element is smaller than viewport, use viewport height instead.
let containerBottom = container === document.body
? Math.max(containerRect.bottom, window.innerHeight)
: containerRect.bottom;
let scrollLeft = container.scrollLeft;
let scrollTop = container.scrollTop;
let scrolledX = bounding.left - scrollLeft;
let scrolledY = bounding.top - scrollTop;
// Check for container and viewport for each edge
if (scrolledX < containerRect.left + offset || scrolledX < offset) {
edges.left = true;
}
if (scrolledX + bounding.width > containerRect.right - offset ||
scrolledX + bounding.width > window.innerWidth - offset) {
edges.right = true;
}
if (scrolledY < containerRect.top + offset || scrolledY < offset) {
edges.top = true;
}
if (scrolledY + bounding.height > containerBottom - offset ||
scrolledY + bounding.height > window.innerHeight - offset) {
edges.bottom = true;
}
return edges;
}
/**
* Checks if element can be aligned in multiple directions.
* @param el Element to be inspected.
* @param container Container element.
* @param bounding Bounding rect.
* @param offset Element offset.
*/
static checkPossibleAlignments(el, container, bounding, offset) {
let canAlign = {
top: true,
right: true,
bottom: true,
left: true,
spaceOnTop: null,
spaceOnRight: null,
spaceOnBottom: null,
spaceOnLeft: null
};
let containerAllowsOverflow = getComputedStyle(container).overflow === 'visible';
let containerRect = container.getBoundingClientRect();
let containerHeight = Math.min(containerRect.height, window.innerHeight);
let containerWidth = Math.min(containerRect.width, window.innerWidth);
let elOffsetRect = el.getBoundingClientRect();
let scrollLeft = container.scrollLeft;
let scrollTop = container.scrollTop;
let scrolledX = bounding.left - scrollLeft;
let scrolledYTopEdge = bounding.top - scrollTop;
let scrolledYBottomEdge = bounding.top + elOffsetRect.height - scrollTop;
// Check for container and viewport for left
canAlign.spaceOnRight = !containerAllowsOverflow
? containerWidth - (scrolledX + bounding.width)
: window.innerWidth - (elOffsetRect.left + bounding.width);
if (canAlign.spaceOnRight < 0) {
canAlign.left = false;
}
// Check for container and viewport for Right
canAlign.spaceOnLeft = !containerAllowsOverflow
? scrolledX - bounding.width + elOffsetRect.width
: elOffsetRect.right - bounding.width;
if (canAlign.spaceOnLeft < 0) {
canAlign.right = false;
}
// Check for container and viewport for Top
canAlign.spaceOnBottom = !containerAllowsOverflow
? containerHeight - (scrolledYTopEdge + bounding.height + offset)
: window.innerHeight - (elOffsetRect.top + bounding.height + offset);
if (canAlign.spaceOnBottom < 0) {
canAlign.top = false;
}
// Check for container and viewport for Bottom
canAlign.spaceOnTop = !containerAllowsOverflow
? scrolledYBottomEdge - (bounding.height - offset)
: elOffsetRect.bottom - (bounding.height + offset);
if (canAlign.spaceOnTop < 0) {
canAlign.bottom = false;
}
return canAlign;
}
/**
* Retrieves target element id from trigger.
* @param trigger Trigger element.
*/
static getIdFromTrigger(trigger) {
let id = trigger.dataset.target;
if (!id) {
id = trigger.getAttribute('href');
return id ? id.slice(1) : '';
2022-08-04 19:50:18 -05:00
}
return id;
}
/**
* Retrieves document scroll postion from top.
*/
static getDocumentScrollTop() {
return window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0;
}
;
/**
* Retrieves document scroll postion from left.
*/
static getDocumentScrollLeft() {
return window.scrollX || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
}
/**
* Fires the given function after a certain ammount of time.
* @param func Function to be fired.
* @param wait Wait time.
* @param options Additional options.
*/
static throttle(func, wait, options = null) {
let context, args, result;
let timeout = null;
let previous = 0;
options || (options = {});
let later = function () {
previous = options.leading === false ? 0 : new Date().getTime();
timeout = null;
result = func.apply(context, args);
context = args = null;
};
return function () {
let now = new Date().getTime();
if (!previous && options.leading === false)
previous = now;
let remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
context = args = null;
}
else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
}
}
exports.Utils = Utils;
/** Specifies wether tab is pressed or not. */
Utils.tabPressed = false;
/** Specifies wether there is a key pressed. */
Utils.keyDown = false;
/**
* Key maps.
*/
Utils.keys = {
TAB: ['Tab'],
ENTER: ['Enter'],
ESC: ['Escape', 'Esc'],
BACKSPACE: ['Backspace'],
ARROW_UP: ['ArrowUp', 'Up'],
ARROW_DOWN: ['ArrowDown', 'Down'],
ARROW_LEFT: ['ArrowLeft', 'Left'],
ARROW_RIGHT: ['ArrowRight', 'Right'],
DELETE: ['Delete', 'Del'],
};
2022-08-04 19:50:18 -05:00
/***/ }),
2022-08-04 19:50:18 -05:00
/***/ "./src/waves.ts":
/*!**********************!*\
!*** ./src/waves.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports) {
2022-08-04 19:50:18 -05:00
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Waves = void 0;
class Waves {
static _offset(el) {
const box = el.getBoundingClientRect();
const docElem = document.documentElement;
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
// https://phoenix-dx.com/css-techniques-for-material-ripple-effect/
static renderWaveEffect(targetElement, position = null, color = null) {
const isCentered = position === null;
const duration = 500;
let animationFrame, animationStart;
const animationStep = function (timestamp) {
if (!animationStart) {
animationStart = timestamp;
}
const frame = timestamp - animationStart;
if (frame < duration) {
const easing = (frame / duration) * (2 - (frame / duration));
const circle = isCentered ? 'circle at 50% 50%' : `circle at ${position.x}px ${position.y}px`;
const waveColor = `rgba(${(color === null || color === void 0 ? void 0 : color.r) || 0}, ${(color === null || color === void 0 ? void 0 : color.g) || 0}, ${(color === null || color === void 0 ? void 0 : color.b) || 0}, ${0.3 * (1 - easing)})`;
const stop = 90 * easing + "%";
targetElement.style.backgroundImage = "radial-gradient(" + circle + ", " + waveColor + " " + stop + ", transparent " + stop + ")";
animationFrame = window.requestAnimationFrame(animationStep);
}
else {
targetElement.style.backgroundImage = 'none';
window.cancelAnimationFrame(animationFrame);
}
};
animationFrame = window.requestAnimationFrame(animationStep);
}
static Init() {
document.addEventListener("DOMContentLoaded", () => {
document.body.addEventListener('click', e => {
const trigger = e.target;
const el = trigger.closest('.waves-effect');
if (el && el.contains(trigger)) {
const isCircular = el.classList.contains('waves-circle');
const x = e.pageX - Waves._offset(el).left;
const y = e.pageY - Waves._offset(el).top;
let color = null;
if (el.classList.contains('waves-light'))
color = { r: 255, g: 255, b: 255 };
Waves.renderWaveEffect(el, isCircular ? null : { x, y }, color);
}
2022-08-04 19:50:18 -05:00
});
});
}
}
exports.Waves = Waves;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
!function() {
var exports = __webpack_exports__;
/*!***********************!*\
!*** ./src/global.ts ***!
\***********************/
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.M = void 0;
const autocomplete_1 = __webpack_require__(/*! ./autocomplete */ "./src/autocomplete.ts");
const buttons_1 = __webpack_require__(/*! ./buttons */ "./src/buttons.ts");
const cards_1 = __webpack_require__(/*! ./cards */ "./src/cards.ts");
const carousel_1 = __webpack_require__(/*! ./carousel */ "./src/carousel.ts");
const characterCounter_1 = __webpack_require__(/*! ./characterCounter */ "./src/characterCounter.ts");
const chips_1 = __webpack_require__(/*! ./chips */ "./src/chips.ts");
const collapsible_1 = __webpack_require__(/*! ./collapsible */ "./src/collapsible.ts");
const datepicker_1 = __webpack_require__(/*! ./datepicker */ "./src/datepicker.ts");
const dropdown_1 = __webpack_require__(/*! ./dropdown */ "./src/dropdown.ts");
const forms_1 = __webpack_require__(/*! ./forms */ "./src/forms.ts");
const materialbox_1 = __webpack_require__(/*! ./materialbox */ "./src/materialbox.ts");
const modal_1 = __webpack_require__(/*! ./modal */ "./src/modal.ts");
const parallax_1 = __webpack_require__(/*! ./parallax */ "./src/parallax.ts");
const pushpin_1 = __webpack_require__(/*! ./pushpin */ "./src/pushpin.ts");
const scrollspy_1 = __webpack_require__(/*! ./scrollspy */ "./src/scrollspy.ts");
const select_1 = __webpack_require__(/*! ./select */ "./src/select.ts");
const sidenav_1 = __webpack_require__(/*! ./sidenav */ "./src/sidenav.ts");
const slider_1 = __webpack_require__(/*! ./slider */ "./src/slider.ts");
const tabs_1 = __webpack_require__(/*! ./tabs */ "./src/tabs.ts");
const tapTarget_1 = __webpack_require__(/*! ./tapTarget */ "./src/tapTarget.ts");
const timepicker_1 = __webpack_require__(/*! ./timepicker */ "./src/timepicker.ts");
const toasts_1 = __webpack_require__(/*! ./toasts */ "./src/toasts.ts");
const tooltip_1 = __webpack_require__(/*! ./tooltip */ "./src/tooltip.ts");
const waves_1 = __webpack_require__(/*! ./waves */ "./src/waves.ts");
const range_1 = __webpack_require__(/*! ./range */ "./src/range.ts");
const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
class M {
/**
* Automatically initialize components.
* @param context Root element to initialize. Defaults to `document.body`.
*/
static AutoInit(context = document.body) {
let registry = {
Autocomplete: context.querySelectorAll('.autocomplete:not(.no-autoinit)'),
Carousel: context.querySelectorAll('.carousel:not(.no-autoinit)'),
Chips: context.querySelectorAll('.chips:not(.no-autoinit)'),
Collapsible: context.querySelectorAll('.collapsible:not(.no-autoinit)'),
Datepicker: context.querySelectorAll('.datepicker:not(.no-autoinit)'),
Dropdown: context.querySelectorAll('.dropdown-trigger:not(.no-autoinit)'),
Materialbox: context.querySelectorAll('.materialboxed:not(.no-autoinit)'),
Modal: context.querySelectorAll('.modal:not(.no-autoinit)'),
Parallax: context.querySelectorAll('.parallax:not(.no-autoinit)'),
Pushpin: context.querySelectorAll('.pushpin:not(.no-autoinit)'),
ScrollSpy: context.querySelectorAll('.scrollspy:not(.no-autoinit)'),
FormSelect: context.querySelectorAll('select:not(.no-autoinit)'),
Sidenav: context.querySelectorAll('.sidenav:not(.no-autoinit)'),
Tabs: context.querySelectorAll('.tabs:not(.no-autoinit)'),
TapTarget: context.querySelectorAll('.tap-target:not(.no-autoinit)'),
Timepicker: context.querySelectorAll('.timepicker:not(.no-autoinit)'),
Tooltip: context.querySelectorAll('.tooltipped:not(.no-autoinit)'),
FloatingActionButton: context.querySelectorAll('.fixed-action-btn:not(.no-autoinit)'),
};
M.Autocomplete.init(registry.Autocomplete, {});
M.Carousel.init(registry.Carousel, {});
M.Chips.init(registry.Chips, {});
M.Collapsible.init(registry.Collapsible, {});
M.Datepicker.init(registry.Datepicker, {});
M.Dropdown.init(registry.Dropdown, {});
M.Materialbox.init(registry.Materialbox, {});
M.Modal.init(registry.Modal, {});
M.Parallax.init(registry.Parallax, {});
M.Pushpin.init(registry.Pushpin, {});
M.ScrollSpy.init(registry.ScrollSpy, {});
M.FormSelect.init(registry.FormSelect, {});
M.Sidenav.init(registry.Sidenav, {});
M.Tabs.init(registry.Tabs, {});
M.TapTarget.init(registry.TapTarget, {});
M.Timepicker.init(registry.Timepicker, {});
M.Tooltip.init(registry.Tooltip, {});
M.FloatingActionButton.init(registry.FloatingActionButton, {});
}
}
exports.M = M;
M.version = '2.1.0';
M.Autocomplete = autocomplete_1.Autocomplete;
M.Tabs = tabs_1.Tabs;
M.Carousel = carousel_1.Carousel;
M.Dropdown = dropdown_1.Dropdown;
M.FloatingActionButton = buttons_1.FloatingActionButton;
M.Chips = chips_1.Chips;
M.Collapsible = collapsible_1.Collapsible;
M.Datepicker = datepicker_1.Datepicker;
M.CharacterCounter = characterCounter_1.CharacterCounter;
M.Forms = forms_1.Forms;
M.FormSelect = select_1.FormSelect;
M.Modal = modal_1.Modal;
M.Pushpin = pushpin_1.Pushpin;
M.Materialbox = materialbox_1.Materialbox;
M.Parallax = parallax_1.Parallax;
M.Slider = slider_1.Slider;
M.Timepicker = timepicker_1.Timepicker;
/** Creates a toast. */
M.toast = (opt) => new toasts_1.Toast(opt);
M.Tooltip = tooltip_1.Tooltip;
M.Sidenav = sidenav_1.Sidenav;
M.TapTarget = tapTarget_1.TapTarget;
M.ScrollSpy = scrollspy_1.ScrollSpy;
M.Range = range_1.Range;
M.Waves = waves_1.Waves;
M.Utils = utils_1.Utils;
(() => {
document.addEventListener('keydown', utils_1.Utils.docHandleKeydown, true);
document.addEventListener('keyup', utils_1.Utils.docHandleKeyup, true);
document.addEventListener('focus', utils_1.Utils.docHandleFocus, true);
document.addEventListener('blur', utils_1.Utils.docHandleBlur, true);
cards_1.Cards.Init();
forms_1.Forms.Init();
chips_1.Chips.Init();
waves_1.Waves.Init();
range_1.Range.Init();
})();
2022-08-04 19:50:18 -05:00
}();
/******/ return __webpack_exports__;
/******/ })()
;
});