"use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var Theme = /*#__PURE__*/function () { function Theme() { var _this = this; _classCallCheck(this, Theme); // looper color scheme refer from our _variable-bs-overrides.scss this.colors = { black: '#14141F', brand: { blue: '#0179A8', indigo: '#346CB0', purple: '#5F4B8B', pink: '#B76BA3', red: '#EA6759', orange: '#EC935E', yellow: '#F7C46C', green: '#A7C796', teal: '#00A28A', cyan: '#3686A0' }, gray: { 100: '#f6f7f9', 200: '#e6e8ed', 300: '#d6d8e1', 400: '#c6c9d5', 500: '#a6abbd', 600: '#888c9b', 700: '#363642', 800: '#222230', 900: '#191927' }, white: '#ffffff' }; // list of supported skin this.skins = ['default', 'dark']; // current skin this.skin = localStorage.getItem('skin') || 'default'; // current aside menu mode this.hasCompactMenu = JSON.parse(localStorage.getItem('hasCompactMenu')) || false; // get auto initialize variable this.autoInit = localStorage.getItem('autoInit') || true; // initialized $(document).ready(function () { if (_this.autoInit) _this.init(); }); } _createClass(Theme, [{ key: "init", value: function init() { // handle polyfill // ============================================================= this.placeholderShown(); this.objectFitFallback(); // handle bootstrap components // ============================================================= this.tooltips(); this.popovers(); this.nestedDropdown(); this.inputClearable(); this.inputGroup(); this.inputNumber(); this.fileInputBehavior(); this.togglePasswordVisibility(); this.indeterminateCheckboxes(); this.formValidation(); this.cardExpansion(); this.modalScrollable(); this.autofocusInputBehaviour(); // handle theme skins (default, dark) // ============================================================= this.setSkin(this.skin); if (this.skin === 'dark') { this.invertGrays(); } // handle theme layouts // ============================================================= this.asideBackdrop(); this.toggleAside(); this.asideMenu(); this.handleAsideMenu(); this.sidebar(); this.pageExpander(); // handle theme components // ============================================================= this.hamburger(); this.publisher(); this.tasksStyle(); this.filterList(); this.radioList(); this.checkboxList(); this.smoothScroll(); // handle plugins initialization // ============================================================= this.perfectScrollbar(); this.masonry(); this.chartjs(); this.sparkline(); this.easypie(); this.knob(); this.sortable(); this.nestable(); this.plyr(); this.bootstrapSelect(); this.select2(); this.atwho(); this.tribute(); this.flatpickr(); this.colorpicker(); this.touchspin(); this.nouislider(); this.summernote(); this.quill(); this.simplemde(); this.maskInput(); this.headroom(); this.zxcvbn(); this.aos(); // handle events – how our components should react on events? // ============================================================= this.eventProps(); this.watchMQ(); this.watchIE(); // utilities // ============================================================= this.browserFlagging(); this.osFlagging(); // trigger the document $(document).trigger('theme:init', this); } // Polifyll // ============================================================= /** * Polyfill for Array.values() * returns an array of a given object's own enumerable property values, * in the same order as that provided */ }, { key: "objToArray", value: function objToArray(obj) { return Object.keys(obj).map(function (key) { return obj[key]; }); } /** * Polyfill for :placeholder-shown * used by floating label input */ }, { key: "placeholderShown", value: function placeholderShown() { $(document).on('focus blur keyup change', '.form-label-group > input', function () { this.classList[this.value ? 'remove' : 'add']('placeholder-shown'); }); // toggle .placeholder-shown onload $('.form-label-group > input').trigger('change'); } /** * object-fit fallbaack for ie and edge */ }, { key: "objectFitFallback", value: function objectFitFallback() { if (this.isIE() || this.isEdge()) { var selectors = ['.user-avatar img', '.tile > img', '.figure-attachment > img', '.page-cover > .cover-img', '.list-group-item-figure > img']; $(selectors.toString()).each(function () { var $img = $(this); var url = $img.prop('src'); var $container = $img.parent(); // .user-avatar with dropdown has deep markup if ($container.is('[data-toggle="dropdown"]')) { $container = $container.parent(); } if (url) { // copy img url then put as container bg $container.css({ backgroundImage: "url(".concat(url, ")"), backgroundSize: 'cover', backgroundPosition: 'center center' }); if ($container.hasClass('user-avatar') || $container.hasClass('user-avatar')) { $container.css('background-position', 'top center'); } // hide the image $img.css('opacity', 0); } }); } } // Bootstrap Components // ============================================================= /** * Init bootstrap tooltips */ }, { key: "tooltips", value: function tooltips() { // Turn off the transform placement on Popper Popper.Defaults.modifiers.computeStyle.gpuAcceleration = false; $('[data-toggle="tooltip"]').tooltip(); } /** * Init bootstrap popovers */ }, { key: "popovers", value: function popovers() { $('[data-toggle="popover"]').popover(); } /** * Init nested dropdown */ }, { key: "nestedDropdown", value: function nestedDropdown() { $('.dropdown-menu [data-toggle="dropdown"]').on('click', function (e) { e.preventDefault(); e.stopPropagation(); var $trigger = $(this); var $dropdown = $trigger.parent(); var $dropdownMenu = $trigger.next(); // close all dropdown menu $dropdown.siblings().find('.dropdown-menu').removeClass('show'); $dropdownMenu.toggleClass('show'); $trigger.parents('.nav-item').on('hidden.bs.dropdown', function () { return $dropdownMenu.removeClass('show'); }); }); } /** * Hide/show clearable button due to input value */ }, { key: "inputClearable", value: function inputClearable() { // hide/show due to input value var toggleClear = function toggleClear(input) { var isEmpty = !$(input).val(); var clearable = $(input).parent().children('.close'); clearable.toggleClass('show', !isEmpty); }; // give natural state onload // show close button when input has value $('.has-clearable > .form-control').each(function () { toggleClear(this); }); // handle input clearable events $(document).on('keyup', '.has-clearable > .form-control', function () { toggleClear(this); }).on('click', '.has-clearable > .close', function () { var $input = $(this).parent().children('.form-control'); $input.val('').focus(); toggleClear($input[0]); $input.trigger('keyup'); }); } /** * Toggle focus class in input-group when input is focused */ }, { key: "inputGroup", value: function inputGroup() { // handle input group events $(document).on('focusin focusout', '.input-group:not(.input-group-alt) .form-control', function (e) { var $parent = $(this).parent(); var hasInputGroup = $parent.has('.input-group'); var hasFocus = e.type === 'focusin'; if (hasInputGroup) { $parent.toggleClass('focus', hasFocus); } }); } /** * Toggle focus class in input-group when input is focused */ }, { key: "inputNumber", value: function inputNumber() { $('.custom-number').each(function () { var spinner = $(this); var input = spinner.children('.form-control[type="number"]'); var min = parseFloat(input.attr('min')); var max = parseFloat(input.attr('max')); var step = parseFloat(input.attr('step')) || 1; var newVal = 0; var controls = $('
'); var btnUp = $('
+
'); var btnDown = $('
-
'); controls.prepend(btnUp).append(btnDown); spinner.append(controls); btnUp.on('click', function () { var oldValue = parseFloat(input.val()) || 0; newVal = oldValue >= max ? oldValue : oldValue + step; input.val(newVal).trigger('change'); }); btnDown.on('click', function () { var oldValue = parseFloat(input.val()) || 0; newVal = oldValue <= min ? oldValue : oldValue - step; input.val(newVal).trigger('change'); }); }); } /** * Add text value to our custom file input */ }, { key: "fileInputBehavior", value: function fileInputBehavior() { // copy label text to data label which we'll use later $('.custom-file > .custom-file-label').each(function () { var label = $(this).text(); $(this).data('label', label); }); // update label text with current input value $(document).on('change', '.custom-file > .custom-file-input', function () { var files = this.files; var $fileLabel = $(this).next('.custom-file-label'); // use when no file chosen var $originLabel = $fileLabel.data('label'); // truncate text when user chose more than 2 files $fileLabel.text(files.length + ' files selected'); if (files.length <= 2) { var fileNames = []; for (var i = 0; i < files.length; i++) { fileNames.push(files[i].name); } $fileLabel.text(fileNames.join(', ')); } // reset label text if no file chosen if (!files.length) { $fileLabel.text($originLabel); } }); } /** * Toggle visibility password input value */ }, { key: "togglePasswordVisibility", value: function togglePasswordVisibility() { $(document).on('click', '[data-toggle="password"]', function (e) { e.preventDefault(); var target = $(this).attr('href'); var $input = $(target); var hasFa = $(this).has('.fa'); var isPassword = $input.is('[type="password"]'); var inputType = isPassword ? 'text' : 'password'; var triggerText = isPassword ? 'Hide' : 'Show'; // toggle icon $(this).children('.fa, .far').toggleClass('fa-eye fa-eye-slash', hasFa); // toggle trigger text $(this).children().last().text(triggerText); // toggle input type $input.prop('type', inputType); }); } /** * Add indeterminate state in custom checkbox */ }, { key: "indeterminateCheckboxes", value: function indeterminateCheckboxes() { $('input[type="checkbox"][indeterminate], input[type="checkbox"][data-indeterminate="true"]').prop('indeterminate', true); } /** * Validate form on submit */ }, { key: "formValidation", value: function formValidation() { $(window).on('load', function () { // Fetch all the forms we want to apply custom Bootstrap validation styles to var forms = $('.needs-validation'); // Loop over them and prevent submission forms.each(function (i, form) { $(form).on('submit', function (e) { if (form.checkValidity() === false) { e.preventDefault(); e.stopPropagation(); } $(form).addClass('was-validated'); }); }); }); } /** * Toggle card expansion like accordion */ }, { key: "cardExpansion", value: function cardExpansion() { $(document).on('show.bs.collapse hide.bs.collapse', '.card-expansion-item > .collapse', function (e) { var $item = $(this).parent(); var isShown = e.type === 'show'; $item.toggleClass('expanded', isShown); }); } /** * Toggle class scrollable when the modal body scroll reach the top/bottom */ }, { key: "modalScrollable", value: function modalScrollable() { $('.modal').on('shown.bs.modal', function () { $(this).addClass('has-shown').find('.modal-body').trigger('scroll'); }); $('.modal-dialog-scrollable .modal-body, .modal-drawer .modal-body').on('scroll', function () { var $elem = $(this); var elem = $elem[0]; var isTop = $elem.scrollTop() === 0; var isBottom = elem.scrollHeight - $elem.scrollTop() === $elem.outerHeight(); $elem.prev().toggleClass('modal-body-scrolled', isTop); $elem.next().toggleClass('modal-body-scrolled', isBottom); }); } /** * Make input with [autofocus] attribute in modal and dropdown work as native [autofocus] */ }, { key: "autofocusInputBehaviour", value: function autofocusInputBehaviour() { $(document).on('shown.bs.modal shown.bs.dropdown', '.modal, .dropdown', function (e) { var $modal = $(e.target); $modal.find('input[autofocus]:first, input[data-autofocus="true"]:first').focus(); }); } // Theme Skins // ============================================================= /** * Get gray colors from colors */ }, { key: "getColors", value: function getColors(color) { return this.colors[color]; } /** * Get muted colors based on active skin */ }, { key: "getMutedColor", value: function getMutedColor() { return this.skin === 'dark' ? this.colors.gray[400] : this.colors.gray[600]; } /** * Get light color based on active skin */ }, { key: "getLightColor", value: function getLightColor() { return this.colors.gray[100]; } /** * Get dark color based on active skin */ }, { key: "getDarkColor", value: function getDarkColor() { return this.colors.gray[900]; } /** * Set current skin to given value * We need to reload the browser when perform this method * to apply changes to all components */ }, { key: "setSkin", value: function setSkin(skin) { // reset to default when using un-appropriate value skin = this.skins.indexOf(skin) < 0 ? 'default' : skin; // inverse gray colors if (this.skin !== skin) { this.invertGrays(); } // flagging class $('body').removeClass('dark-skin default-skin').addClass("".concat(skin, "-skin")); localStorage.setItem('skin', skin); this.skin = skin; } /** * Invert gray colors due to active skin */ }, { key: "invertGrays", value: function invertGrays() { var _this2 = this; var self = this; var gray = this.getColors('gray'); // get gray colors in array that reserve it var reverseGray = this.objToArray(gray).reverse(); var x = 0; $.each(gray, function (i, v) { _this2.colors.gray[i] = reverseGray[x]; x++; }); } // Theme Layout // ============================================================= /** * Append aside-backdrop to .app */ }, { key: "asideBackdrop", value: function asideBackdrop() { $('.app').append('
'); } /** * Showing aside-backdrop */ }, { key: "showAsideBackdrop", value: function showAsideBackdrop() { $('.aside-backdrop').addClass('show'); return $('.aside-backdrop'); } /** * Hiding aside-backdrop */ }, { key: "hideAsideBackdrop", value: function hideAsideBackdrop() { $('.aside-backdrop').removeClass('show'); return $('.aside-backdrop'); } /** * Show aside */ }, { key: "showAside", value: function showAside() { var _this3 = this; // show aside-backdrop var backdrop = this.showAsideBackdrop(); // add .show class to aside $('.app-aside').addClass('show'); // add .active state to trigger button $('[data-toggle="aside"]').addClass('active'); backdrop.one('click', function () { _this3.hideAside(); }); } /** * Hide aside */ }, { key: "hideAside", value: function hideAside() { // hide aside-backdrop this.hideAsideBackdrop(); // remove .show class to aside $('.app-aside').removeClass('show'); // remove .active state to trigger button $('[data-toggle="aside"]').removeClass('active'); } /** * Handle show/hide aside */ }, { key: "toggleAside", value: function toggleAside() { var _this4 = this; var $trigger = $('[data-toggle="aside"]'); $trigger.on('click', function () { var isShown = $('.app-aside').hasClass('show'); $trigger.toggleClass('active', !isShown); if (isShown) _this4.hideAside();else _this4.showAside(); }); } /** * Get the appropriate StackedMenu options */ }, { key: "getMenuOptions", value: function getMenuOptions() { return { compact: this.hasCompactMenu, hoverable: this.hasCompactMenu }; } /** * Handle aside menu */ }, { key: "asideMenu", value: function asideMenu() { var ps; if (window.StackedMenu && this.isExists('#stacked-menu')) { // init stackedMenu this.stackedMenu = new StackedMenu(this.getMenuOptions()); $('.app').toggleClass('has-compact-menu', this.hasCompactMenu); // watch aside this.watchAside(); // update perfect scrollbar $(this.stackedMenu.selector).on('menu:open menu:close', function () { // wait until translation done setTimeout(function () { if (window.PerfectScrollbar) { ps.update(); } }, 300); }); // perfect scrollbar for aside menu if (window.PerfectScrollbar) { ps = new PerfectScrollbar('.aside-menu', { suppressScrollX: true }); } } } /** * Collapse aside menu to compact mode */ }, { key: "collapseAsideMenu", value: function collapseAsideMenu() { if (typeof this.stackedMenu !== 'undefined') { this.stackedMenu.compact(true).hoverable(true); // update aside mode this.hasCompactMenu = true; // as well as localStorage data localStorage.setItem('hasCompactMenu', true); // update flag class $('.app').addClass('has-compact-menu'); } // watch aside this.watchAside(); } /** * Expand aside menu to normal mode */ }, { key: "expandAsideMenu", value: function expandAsideMenu() { if (typeof this.stackedMenu !== 'undefined') { this.stackedMenu.compact(false).hoverable(false); // update aside mode this.hasCompactMenu = false; // as well as localStorage data localStorage.setItem('hasCompactMenu', false); // update flag class $('.app').removeClass('has-compact-menu'); } // watch aside this.watchAside(); } /** * Toggle aside menu mode */ }, { key: "toggleAsideMenu", value: function toggleAsideMenu() { if (this.hasCompactMenu == true) { this.expandAsideMenu(); } else { this.collapseAsideMenu(); } } /** * Watch aside on toggle screen */ }, { key: "watchAside", value: function watchAside() { var $appWrapper = $('.app'); if (typeof this.stackedMenu !== 'undefined') { if (!this.isToggleScreenUp() || $appWrapper.hasClass('has-fullwidth')) { this.stackedMenu.compact(false).hoverable(false); $appWrapper.removeClass('has-compact-menu'); } else { this.stackedMenu.compact(this.hasCompactMenu).hoverable(this.hasCompactMenu); $appWrapper.toggleClass('has-compact-menu', this.hasCompactMenu); } } } /** * handle aside compact */ }, { key: "handleAsideMenu", value: function handleAsideMenu() { var _this5 = this; $('body').on('click', '[data-toggle="aside-collapse"]', function (e) { e.preventDefault(); _this5.collapseAsideMenu(); }).on('click', '[data-toggle="aside-expand"]', function (e) { e.preventDefault(); _this5.expandAsideMenu(); }).on('click', '[data-toggle="aside-menu"]', function (e) { e.preventDefault(); _this5.toggleAsideMenu(); }); // remove any preparation classes here $('html').removeClass('preparing-compact-menu'); } /** * Showing sidebar */ }, { key: "showSidebar", value: function showSidebar(relatedTarget) { $('.has-sidebar').addClass('has-sidebar-open'); // trigger event $('.page-sidebar').trigger({ type: 'toggle.sidebar', isOpen: true, relatedTarget: relatedTarget }); } /** * Hiding sidebar */ }, { key: "hideSidebar", value: function hideSidebar(relatedTarget) { $('.has-sidebar').removeClass('has-sidebar-open'); // trigger event $('.page-sidebar').trigger({ type: 'toggle.sidebar', isOpen: false, relatedTarget: relatedTarget }); } /** * Toggle sidebar */ }, { key: "toggleSidebar", value: function toggleSidebar(relatedTarget) { var $target = $('.has-sidebar'); var isOpen = $target.hasClass('has-sidebar-open'); if (this.isExists('.has-sidebar') && isOpen) { this.hideSidebar(relatedTarget); } else if (this.isExists('.has-sidebar') && !isOpen) { this.showSidebar(relatedTarget); } } /** * Add sidebar backdrop to the .page */ }, { key: "sidebarBackdrop", value: function sidebarBackdrop() { // append backdrop only when .page has .sidebar component if (this.isExists('.has-sidebar')) { $('.page').prepend('