├── .DS_Store ├── License.pdf ├── README.md ├── awesome.html ├── basic.html ├── collapsible.html ├── colorful.html ├── css ├── bootstrap-chat.dark.min.css ├── bootstrap-chat.dark.rtl.min.css ├── bootstrap-chat.min.css ├── bootstrap-chat.rtl.min.css ├── mdb.dark.min.css.map ├── mdb.dark.rtl.min.css.map ├── mdb.min.css.map └── mdb.rtl.min.css.map ├── gradient.html ├── img └── mdb-favicon.ico ├── js ├── mdb.min.js └── mdb.min.js.map ├── package.json ├── simple.html ├── src ├── js │ ├── bootstrap │ │ ├── dist │ │ │ ├── alert.js │ │ │ ├── alert.js.map │ │ │ ├── base-component.js │ │ │ ├── base-component.js.map │ │ │ ├── button.js │ │ │ ├── button.js.map │ │ │ ├── carousel.js │ │ │ ├── carousel.js.map │ │ │ ├── collapse.js │ │ │ ├── collapse.js.map │ │ │ ├── dom │ │ │ │ ├── data.js │ │ │ │ ├── data.js.map │ │ │ │ ├── event-handler.js │ │ │ │ ├── event-handler.js.map │ │ │ │ ├── manipulator.js │ │ │ │ ├── manipulator.js.map │ │ │ │ ├── selector-engine.js │ │ │ │ └── selector-engine.js.map │ │ │ ├── dropdown.js │ │ │ ├── dropdown.js.map │ │ │ ├── modal.js │ │ │ ├── modal.js.map │ │ │ ├── offcanvas.js │ │ │ ├── offcanvas.js.map │ │ │ ├── popover.js │ │ │ ├── popover.js.map │ │ │ ├── scrollspy.js │ │ │ ├── scrollspy.js.map │ │ │ ├── tab.js │ │ │ ├── tab.js.map │ │ │ ├── toast.js │ │ │ ├── toast.js.map │ │ │ ├── tooltip.js │ │ │ └── tooltip.js.map │ │ ├── mdb-prefix │ │ │ ├── alert.js │ │ │ ├── base-component.js │ │ │ ├── button.js │ │ │ ├── carousel.js │ │ │ ├── collapse.js │ │ │ ├── dom │ │ │ │ ├── data.js │ │ │ │ ├── event-handler.js │ │ │ │ ├── manipulator.js │ │ │ │ └── selector-engine.js │ │ │ ├── dropdown.js │ │ │ ├── modal.js │ │ │ ├── offcanvas.js │ │ │ ├── popover.js │ │ │ ├── scrollspy.js │ │ │ ├── tab.js │ │ │ ├── toast.js │ │ │ ├── tooltip.js │ │ │ └── util │ │ │ │ ├── backdrop.js │ │ │ │ ├── component-functions.js │ │ │ │ ├── focustrap.js │ │ │ │ ├── index.js │ │ │ │ ├── sanitizer.js │ │ │ │ └── scrollbar.js │ │ └── src │ │ │ ├── alert.js │ │ │ ├── base-component.js │ │ │ ├── button.js │ │ │ ├── carousel.js │ │ │ ├── collapse.js │ │ │ ├── dom │ │ │ ├── data.js │ │ │ ├── event-handler.js │ │ │ ├── manipulator.js │ │ │ └── selector-engine.js │ │ │ ├── dropdown.js │ │ │ ├── modal.js │ │ │ ├── offcanvas.js │ │ │ ├── popover.js │ │ │ ├── scrollspy.js │ │ │ ├── tab.js │ │ │ ├── toast.js │ │ │ ├── tooltip.js │ │ │ └── util │ │ │ ├── backdrop.js │ │ │ ├── component-functions.js │ │ │ ├── focustrap.js │ │ │ ├── index.js │ │ │ ├── sanitizer.js │ │ │ └── scrollbar.js │ ├── free │ │ ├── alert.js │ │ ├── button.js │ │ ├── carousel.js │ │ ├── dropdown.js │ │ ├── input.js │ │ ├── modal.js │ │ ├── popover.js │ │ ├── range.js │ │ ├── ripple.js │ │ ├── scrollspy.js │ │ ├── tab.js │ │ ├── toast.js │ │ └── tooltip.js │ ├── mdb.free.js │ └── mdb │ │ ├── dom │ │ ├── data.js │ │ ├── event-handler.js │ │ ├── manipulator.js │ │ └── selector-engine.js │ │ ├── perfect-scrollbar │ │ ├── handlers │ │ │ ├── click-rail.js │ │ │ ├── drag-thumb.js │ │ │ ├── keyboard.js │ │ │ ├── mouse-wheel.js │ │ │ └── touch.js │ │ ├── index.js │ │ ├── lib │ │ │ ├── class-names.js │ │ │ ├── css.js │ │ │ ├── dom.js │ │ │ ├── event-manager.js │ │ │ └── util.js │ │ ├── process-scroll-diff.js │ │ └── update-geometry.js │ │ └── util │ │ ├── focusTrap.js │ │ ├── index.js │ │ ├── keycodes.js │ │ ├── sanitizer.js │ │ ├── scrollbar.js │ │ ├── stack.js │ │ └── touch │ │ ├── index.js │ │ ├── swipe.js │ │ └── touchUtil.js └── scss │ ├── bootstrap-rtl-fix │ ├── _accordion.scss │ ├── _alert.scss │ ├── _badge.scss │ ├── _breadcrumb.scss │ ├── _button-group.scss │ ├── _buttons.scss │ ├── _card.scss │ ├── _carousel.scss │ ├── _close.scss │ ├── _containers.scss │ ├── _dropdown.scss │ ├── _forms.scss │ ├── _functions.scss │ ├── _grid.scss │ ├── _helpers.scss │ ├── _images.scss │ ├── _list-group.scss │ ├── _mixins.scss │ ├── _modal.scss │ ├── _nav.scss │ ├── _navbar.scss │ ├── _offcanvas.scss │ ├── _pagination.scss │ ├── _placeholders.scss │ ├── _popover.scss │ ├── _progress.scss │ ├── _reboot.scss │ ├── _root.scss │ ├── _spinners.scss │ ├── _tables.scss │ ├── _toasts.scss │ ├── _tooltip.scss │ ├── _transitions.scss │ ├── _type.scss │ ├── _utilities.scss │ ├── _variables.scss │ ├── bootstrap-grid.scss │ ├── bootstrap-reboot.scss │ ├── bootstrap-utilities.scss │ ├── bootstrap.scss │ ├── forms │ │ ├── _floating-labels.scss │ │ ├── _form-check.scss │ │ ├── _form-control.scss │ │ ├── _form-range.scss │ │ ├── _form-select.scss │ │ ├── _form-text.scss │ │ ├── _input-group.scss │ │ ├── _labels.scss │ │ └── _validation.scss │ ├── helpers │ │ ├── _clearfix.scss │ │ ├── _colored-links.scss │ │ ├── _position.scss │ │ ├── _ratio.scss │ │ ├── _stacks.scss │ │ ├── _stretched-link.scss │ │ ├── _text-truncation.scss │ │ ├── _visually-hidden.scss │ │ └── _vr.scss │ ├── mixins │ │ ├── _alert.scss │ │ ├── _backdrop.scss │ │ ├── _border-radius.scss │ │ ├── _box-shadow.scss │ │ ├── _breakpoints.scss │ │ ├── _buttons.scss │ │ ├── _caret.scss │ │ ├── _clearfix.scss │ │ ├── _color-scheme.scss │ │ ├── _container.scss │ │ ├── _deprecate.scss │ │ ├── _forms.scss │ │ ├── _gradients.scss │ │ ├── _grid.scss │ │ ├── _image.scss │ │ ├── _list-group.scss │ │ ├── _lists.scss │ │ ├── _pagination.scss │ │ ├── _reset-text.scss │ │ ├── _resize.scss │ │ ├── _table-variants.scss │ │ ├── _text-truncate.scss │ │ ├── _transition.scss │ │ ├── _utilities.scss │ │ └── _visually-hidden.scss │ ├── utilities │ │ └── _api.scss │ └── vendor │ │ └── _rfs.scss │ ├── bootstrap │ ├── _accordion.scss │ ├── _alert.scss │ ├── _badge.scss │ ├── _breadcrumb.scss │ ├── _button-group.scss │ ├── _buttons.scss │ ├── _card.scss │ ├── _carousel.scss │ ├── _close.scss │ ├── _containers.scss │ ├── _dropdown.scss │ ├── _forms.scss │ ├── _functions.scss │ ├── _grid.scss │ ├── _helpers.scss │ ├── _images.scss │ ├── _list-group.scss │ ├── _mixins.scss │ ├── _modal.scss │ ├── _nav.scss │ ├── _navbar.scss │ ├── _offcanvas.scss │ ├── _pagination.scss │ ├── _placeholders.scss │ ├── _popover.scss │ ├── _progress.scss │ ├── _reboot.scss │ ├── _root.scss │ ├── _spinners.scss │ ├── _tables.scss │ ├── _toasts.scss │ ├── _tooltip.scss │ ├── _transitions.scss │ ├── _type.scss │ ├── _utilities.scss │ ├── _variables.scss │ ├── bootstrap-grid.scss │ ├── bootstrap-reboot.scss │ ├── bootstrap-utilities.scss │ ├── bootstrap.scss │ ├── forms │ │ ├── _floating-labels.scss │ │ ├── _form-check.scss │ │ ├── _form-control.scss │ │ ├── _form-range.scss │ │ ├── _form-select.scss │ │ ├── _form-text.scss │ │ ├── _input-group.scss │ │ ├── _labels.scss │ │ └── _validation.scss │ ├── helpers │ │ ├── _clearfix.scss │ │ ├── _colored-links.scss │ │ ├── _position.scss │ │ ├── _ratio.scss │ │ ├── _stacks.scss │ │ ├── _stretched-link.scss │ │ ├── _text-truncation.scss │ │ ├── _visually-hidden.scss │ │ └── _vr.scss │ ├── mixins │ │ ├── _alert.scss │ │ ├── _backdrop.scss │ │ ├── _border-radius.scss │ │ ├── _box-shadow.scss │ │ ├── _breakpoints.scss │ │ ├── _buttons.scss │ │ ├── _caret.scss │ │ ├── _clearfix.scss │ │ ├── _color-scheme.scss │ │ ├── _container.scss │ │ ├── _deprecate.scss │ │ ├── _forms.scss │ │ ├── _gradients.scss │ │ ├── _grid.scss │ │ ├── _image.scss │ │ ├── _list-group.scss │ │ ├── _lists.scss │ │ ├── _pagination.scss │ │ ├── _reset-text.scss │ │ ├── _resize.scss │ │ ├── _table-variants.scss │ │ ├── _text-truncate.scss │ │ ├── _transition.scss │ │ ├── _utilities.scss │ │ └── _visually-hidden.scss │ ├── utilities │ │ └── _api.scss │ └── vendor │ │ └── _rfs.scss │ ├── custom │ ├── _styles.scss │ └── _variables.scss │ ├── free │ ├── _accordion.scss │ ├── _alert.scss │ ├── _badge.scss │ ├── _breadcrumb.scss │ ├── _button-group.scss │ ├── _buttons.scss │ ├── _card.scss │ ├── _carousel.scss │ ├── _close.scss │ ├── _colors.scss │ ├── _deprecated.scss │ ├── _dropdown.scss │ ├── _flag.scss │ ├── _functions.scss │ ├── _images.scss │ ├── _list-group.scss │ ├── _mixins.scss │ ├── _modal.scss │ ├── _nav.scss │ ├── _navbar.scss │ ├── _pagination.scss │ ├── _popover.scss │ ├── _progress.scss │ ├── _range.scss │ ├── _reboot.scss │ ├── _ripple.scss │ ├── _root.scss │ ├── _scrollspy.scss │ ├── _shadows.scss │ ├── _tables.scss │ ├── _toasts.scss │ ├── _tooltip.scss │ ├── _type.scss │ ├── _utilities.scss │ ├── _variables.scss │ ├── forms │ │ ├── _form-check.scss │ │ ├── _form-control.scss │ │ ├── _form-file.scss │ │ ├── _form-range.scss │ │ ├── _form-select.scss │ │ ├── _input-group.scss │ │ └── _validation.scss │ └── mixins │ │ ├── _buttons.scss │ │ ├── _ripple.scss │ │ └── _table-variants.scss │ └── mdb.free.scss └── window.html /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdbootstrap/bootstrap-chat/1d8a4059cdbc8c592478efb8207757662b4f877b/.DS_Store -------------------------------------------------------------------------------- /License.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdbootstrap/bootstrap-chat/1d8a4059cdbc8c592478efb8207757662b4f877b/License.pdf -------------------------------------------------------------------------------- /img/mdb-favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdbootstrap/bootstrap-chat/1d8a4059cdbc8c592478efb8207757662b4f877b/img/mdb-favicon.ico -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mdbootstrap/bootstrap-chat", 3 | "version": "1.0.2", 4 | "description": "Responsive Chat built with Bootstrap 5. Many variants of the chat UI - mobile app, messages box, desktop widget and more.", 5 | "main": "basic.html", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/mdbootstrap/bootstrap-chat.git" 12 | }, 13 | "keywords": [ 14 | "bootstrap", 15 | "chat", 16 | "bootstrap5", 17 | "chat-window", 18 | "bootstrap-chat-aplication", 19 | "chat-message-box", 20 | "chat-with-gradient", 21 | "collapsible-chat" 22 | ], 23 | "author": "mdbootstrap", 24 | "license": "ISC", 25 | "bugs": { 26 | "url": "https://github.com/mdbootstrap/bootstrap-chat/issues" 27 | }, 28 | "homepage": "https://mdbootstrap.com/docs/standard/extended/chat/" 29 | } 30 | -------------------------------------------------------------------------------- /src/js/bootstrap/dist/dom/data.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap data.js v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' 8 | ? (module.exports = factory()) 9 | : typeof define === 'function' && define.amd 10 | ? define(factory) 11 | : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self), 12 | (global.Data = factory())); 13 | })(this, function () { 14 | 'use strict'; 15 | 16 | /** 17 | * -------------------------------------------------------------------------- 18 | * Bootstrap (v5.1.3): dom/data.js 19 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 20 | * -------------------------------------------------------------------------- 21 | */ 22 | 23 | /** 24 | * ------------------------------------------------------------------------ 25 | * Constants 26 | * ------------------------------------------------------------------------ 27 | */ 28 | const elementMap = new Map(); 29 | const data = { 30 | set(element, key, instance) { 31 | if (!elementMap.has(element)) { 32 | elementMap.set(element, new Map()); 33 | } 34 | 35 | const instanceMap = elementMap.get(element); // make it clear we only want one instance per element 36 | // can be removed later when multiple key/instances are fine to be used 37 | 38 | if (!instanceMap.has(key) && instanceMap.size !== 0) { 39 | // eslint-disable-next-line no-console 40 | console.error( 41 | `Bootstrap doesn't allow more than one instance per element. Bound instance: ${ 42 | Array.from(instanceMap.keys())[0] 43 | }.` 44 | ); 45 | return; 46 | } 47 | 48 | instanceMap.set(key, instance); 49 | }, 50 | 51 | get(element, key) { 52 | if (elementMap.has(element)) { 53 | return elementMap.get(element).get(key) || null; 54 | } 55 | 56 | return null; 57 | }, 58 | 59 | remove(element, key) { 60 | if (!elementMap.has(element)) { 61 | return; 62 | } 63 | 64 | const instanceMap = elementMap.get(element); 65 | instanceMap.delete(key); // free up element references if there are no instances left for an element 66 | 67 | if (instanceMap.size === 0) { 68 | elementMap.delete(element); 69 | } 70 | }, 71 | }; 72 | 73 | return data; 74 | }); 75 | //# sourceMappingURL=data.js.map 76 | -------------------------------------------------------------------------------- /src/js/bootstrap/dist/dom/manipulator.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap manipulator.js v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | (function (global, factory) { 7 | typeof exports === 'object' && typeof module !== 'undefined' 8 | ? (module.exports = factory()) 9 | : typeof define === 'function' && define.amd 10 | ? define(factory) 11 | : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self), 12 | (global.Manipulator = factory())); 13 | })(this, function () { 14 | 'use strict'; 15 | 16 | /** 17 | * -------------------------------------------------------------------------- 18 | * Bootstrap (v5.1.3): dom/manipulator.js 19 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 20 | * -------------------------------------------------------------------------- 21 | */ 22 | function normalizeData(val) { 23 | if (val === 'true') { 24 | return true; 25 | } 26 | 27 | if (val === 'false') { 28 | return false; 29 | } 30 | 31 | if (val === Number(val).toString()) { 32 | return Number(val); 33 | } 34 | 35 | if (val === '' || val === 'null') { 36 | return null; 37 | } 38 | 39 | return val; 40 | } 41 | 42 | function normalizeDataKey(key) { 43 | return key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`); 44 | } 45 | 46 | const Manipulator = { 47 | setDataAttribute(element, key, value) { 48 | element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 49 | }, 50 | 51 | removeDataAttribute(element, key) { 52 | element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 53 | }, 54 | 55 | getDataAttributes(element) { 56 | if (!element) { 57 | return {}; 58 | } 59 | 60 | const attributes = {}; 61 | Object.keys(element.dataset) 62 | .filter((key) => key.startsWith('bs')) 63 | .forEach((key) => { 64 | let pureKey = key.replace(/^bs/, ''); 65 | pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length); 66 | attributes[pureKey] = normalizeData(element.dataset[key]); 67 | }); 68 | return attributes; 69 | }, 70 | 71 | getDataAttribute(element, key) { 72 | return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 73 | }, 74 | 75 | offset(element) { 76 | const rect = element.getBoundingClientRect(); 77 | return { 78 | top: rect.top + window.pageYOffset, 79 | left: rect.left + window.pageXOffset, 80 | }; 81 | }, 82 | 83 | position(element) { 84 | return { 85 | top: element.offsetTop, 86 | left: element.offsetLeft, 87 | }; 88 | }, 89 | }; 90 | 91 | return Manipulator; 92 | }); 93 | //# sourceMappingURL=manipulator.js.map 94 | -------------------------------------------------------------------------------- /src/js/bootstrap/mdb-prefix/base-component.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): base-component.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import Data from './dom/data'; 9 | import { executeAfterTransition, getElement } from './util/index'; 10 | import EventHandler from './dom/event-handler'; 11 | 12 | /** 13 | * ------------------------------------------------------------------------ 14 | * Constants 15 | * ------------------------------------------------------------------------ 16 | */ 17 | 18 | const VERSION = '5.1.3'; 19 | 20 | class BaseComponent { 21 | constructor(element) { 22 | element = getElement(element); 23 | 24 | if (!element) { 25 | return; 26 | } 27 | 28 | this._element = element; 29 | Data.set(this._element, this.constructor.DATA_KEY, this); 30 | } 31 | 32 | dispose() { 33 | Data.remove(this._element, this.constructor.DATA_KEY); 34 | EventHandler.off(this._element, this.constructor.EVENT_KEY); 35 | 36 | Object.getOwnPropertyNames(this).forEach((propertyName) => { 37 | this[propertyName] = null; 38 | }); 39 | } 40 | 41 | _queueCallback(callback, element, isAnimated = true) { 42 | executeAfterTransition(callback, element, isAnimated); 43 | } 44 | 45 | /** Static */ 46 | 47 | static getInstance(element) { 48 | return Data.get(getElement(element), this.DATA_KEY); 49 | } 50 | 51 | static getOrCreateInstance(element, config = {}) { 52 | return ( 53 | this.getInstance(element) || new this(element, typeof config === 'object' ? config : null) 54 | ); 55 | } 56 | 57 | static get VERSION() { 58 | return VERSION; 59 | } 60 | 61 | static get NAME() { 62 | throw new Error('You have to implement the static method "NAME", for each component!'); 63 | } 64 | 65 | static get DATA_KEY() { 66 | return `bs.${this.NAME}`; 67 | } 68 | 69 | static get EVENT_KEY() { 70 | return `.${this.DATA_KEY}`; 71 | } 72 | } 73 | 74 | export default BaseComponent; 75 | -------------------------------------------------------------------------------- /src/js/bootstrap/mdb-prefix/button.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): button.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import { defineJQueryPlugin } from './util/index'; 9 | import EventHandler from './dom/event-handler'; 10 | import BaseComponent from './base-component'; 11 | 12 | /** 13 | * ------------------------------------------------------------------------ 14 | * Constants 15 | * ------------------------------------------------------------------------ 16 | */ 17 | 18 | const NAME = 'button'; 19 | const DATA_KEY = 'bs.button'; 20 | const EVENT_KEY = `.${DATA_KEY}`; 21 | const DATA_API_KEY = '.data-api'; 22 | 23 | const CLASS_NAME_ACTIVE = 'active'; 24 | 25 | const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="button"]'; 26 | 27 | const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; 28 | 29 | /** 30 | * ------------------------------------------------------------------------ 31 | * Class Definition 32 | * ------------------------------------------------------------------------ 33 | */ 34 | 35 | class Button extends BaseComponent { 36 | // Getters 37 | 38 | static get NAME() { 39 | return NAME; 40 | } 41 | 42 | // Public 43 | 44 | toggle() { 45 | // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method 46 | this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)); 47 | } 48 | 49 | // Static 50 | 51 | static jQueryInterface(config) { 52 | return this.each(function () { 53 | const data = Button.getOrCreateInstance(this); 54 | 55 | if (config === 'toggle') { 56 | data[config](); 57 | } 58 | }); 59 | } 60 | } 61 | 62 | /** 63 | * ------------------------------------------------------------------------ 64 | * Data Api implementation 65 | * ------------------------------------------------------------------------ 66 | */ 67 | 68 | EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, (event) => { 69 | event.preventDefault(); 70 | 71 | const button = event.target.closest(SELECTOR_DATA_TOGGLE); 72 | const data = Button.getOrCreateInstance(button); 73 | 74 | data.toggle(); 75 | }); 76 | 77 | /** 78 | * ------------------------------------------------------------------------ 79 | * jQuery 80 | * ------------------------------------------------------------------------ 81 | * add .Button to jQuery only if jQuery is present 82 | */ 83 | 84 | defineJQueryPlugin(Button); 85 | 86 | export default Button; 87 | -------------------------------------------------------------------------------- /src/js/bootstrap/mdb-prefix/dom/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): dom/data.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | /** 9 | * ------------------------------------------------------------------------ 10 | * Constants 11 | * ------------------------------------------------------------------------ 12 | */ 13 | 14 | const elementMap = new Map(); 15 | 16 | export default { 17 | set(element, key, instance) { 18 | if (!elementMap.has(element)) { 19 | elementMap.set(element, new Map()); 20 | } 21 | 22 | const instanceMap = elementMap.get(element); 23 | 24 | // make it clear we only want one instance per element 25 | // can be removed later when multiple key/instances are fine to be used 26 | if (!instanceMap.has(key) && instanceMap.size !== 0) { 27 | // eslint-disable-next-line no-console 28 | console.error( 29 | `Bootstrap doesn't allow more than one instance per element. Bound instance: ${ 30 | Array.from(instanceMap.keys())[0] 31 | }.` 32 | ); 33 | return; 34 | } 35 | 36 | instanceMap.set(key, instance); 37 | }, 38 | 39 | get(element, key) { 40 | if (elementMap.has(element)) { 41 | return elementMap.get(element).get(key) || null; 42 | } 43 | 44 | return null; 45 | }, 46 | 47 | remove(element, key) { 48 | if (!elementMap.has(element)) { 49 | return; 50 | } 51 | 52 | const instanceMap = elementMap.get(element); 53 | 54 | instanceMap.delete(key); 55 | 56 | // free up element references if there are no instances left for an element 57 | if (instanceMap.size === 0) { 58 | elementMap.delete(element); 59 | } 60 | }, 61 | }; 62 | -------------------------------------------------------------------------------- /src/js/bootstrap/mdb-prefix/dom/manipulator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): dom/manipulator.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | function normalizeData(val) { 9 | if (val === 'true') { 10 | return true; 11 | } 12 | 13 | if (val === 'false') { 14 | return false; 15 | } 16 | 17 | if (val === Number(val).toString()) { 18 | return Number(val); 19 | } 20 | 21 | if (val === '' || val === 'null') { 22 | return null; 23 | } 24 | 25 | return val; 26 | } 27 | 28 | function normalizeDataKey(key) { 29 | return key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`); 30 | } 31 | 32 | const Manipulator = { 33 | setDataAttribute(element, key, value) { 34 | element.setAttribute(`data-mdb-${normalizeDataKey(key)}`, value); 35 | }, 36 | 37 | removeDataAttribute(element, key) { 38 | element.removeAttribute(`data-mdb-${normalizeDataKey(key)}`); 39 | }, 40 | 41 | getDataAttributes(element) { 42 | if (!element) { 43 | return {}; 44 | } 45 | 46 | const attributes = {}; 47 | 48 | Object.keys(element.dataset) 49 | .filter((key) => key.startsWith('mdb')) 50 | .forEach((key) => { 51 | let pureKey = key.replace(/^mdb/, ''); 52 | pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length); 53 | attributes[pureKey] = normalizeData(element.dataset[key]); 54 | }); 55 | 56 | return attributes; 57 | }, 58 | 59 | getDataAttribute(element, key) { 60 | return normalizeData(element.getAttribute(`data-mdb-${normalizeDataKey(key)}`)); 61 | }, 62 | 63 | offset(element) { 64 | const rect = element.getBoundingClientRect(); 65 | 66 | return { 67 | top: rect.top + window.pageYOffset, 68 | left: rect.left + window.pageXOffset, 69 | }; 70 | }, 71 | 72 | position(element) { 73 | return { 74 | top: element.offsetTop, 75 | left: element.offsetLeft, 76 | }; 77 | }, 78 | }; 79 | 80 | export default Manipulator; 81 | -------------------------------------------------------------------------------- /src/js/bootstrap/mdb-prefix/dom/selector-engine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): dom/selector-engine.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | /** 9 | * ------------------------------------------------------------------------ 10 | * Constants 11 | * ------------------------------------------------------------------------ 12 | */ 13 | 14 | import { isDisabled, isVisible } from '../util/index'; 15 | 16 | const NODE_TEXT = 3; 17 | 18 | const SelectorEngine = { 19 | find(selector, element = document.documentElement) { 20 | return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 21 | }, 22 | 23 | findOne(selector, element = document.documentElement) { 24 | return Element.prototype.querySelector.call(element, selector); 25 | }, 26 | 27 | children(element, selector) { 28 | return [].concat(...element.children).filter((child) => child.matches(selector)); 29 | }, 30 | 31 | parents(element, selector) { 32 | const parents = []; 33 | 34 | let ancestor = element.parentNode; 35 | 36 | while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) { 37 | if (ancestor.matches(selector)) { 38 | parents.push(ancestor); 39 | } 40 | 41 | ancestor = ancestor.parentNode; 42 | } 43 | 44 | return parents; 45 | }, 46 | 47 | prev(element, selector) { 48 | let previous = element.previousElementSibling; 49 | 50 | while (previous) { 51 | if (previous.matches(selector)) { 52 | return [previous]; 53 | } 54 | 55 | previous = previous.previousElementSibling; 56 | } 57 | 58 | return []; 59 | }, 60 | 61 | next(element, selector) { 62 | let next = element.nextElementSibling; 63 | 64 | while (next) { 65 | if (next.matches(selector)) { 66 | return [next]; 67 | } 68 | 69 | next = next.nextElementSibling; 70 | } 71 | 72 | return []; 73 | }, 74 | 75 | focusableChildren(element) { 76 | const focusables = [ 77 | 'a', 78 | 'button', 79 | 'input', 80 | 'textarea', 81 | 'select', 82 | 'details', 83 | '[tabindex]', 84 | '[contenteditable="true"]', 85 | ] 86 | .map((selector) => `${selector}:not([tabindex^="-"])`) 87 | .join(', '); 88 | 89 | return this.find(focusables, element).filter((el) => !isDisabled(el) && isVisible(el)); 90 | }, 91 | }; 92 | 93 | export default SelectorEngine; 94 | -------------------------------------------------------------------------------- /src/js/bootstrap/mdb-prefix/util/component-functions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): util/component-functions.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import EventHandler from '../dom/event-handler'; 9 | import { getElementFromSelector, isDisabled } from './index'; 10 | 11 | const enableDismissTrigger = (component, method = 'hide') => { 12 | const clickEvent = `click.dismiss${component.EVENT_KEY}`; 13 | const name = component.NAME; 14 | 15 | EventHandler.on(document, clickEvent, `[data-mdb-dismiss="${name}"]`, function (event) { 16 | if (['A', 'AREA'].includes(this.tagName)) { 17 | event.preventDefault(); 18 | } 19 | 20 | if (isDisabled(this)) { 21 | return; 22 | } 23 | 24 | const target = getElementFromSelector(this) || this.closest(`.${name}`); 25 | const instance = component.getOrCreateInstance(target); 26 | 27 | // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 28 | instance[method](); 29 | }); 30 | }; 31 | 32 | export { enableDismissTrigger }; 33 | -------------------------------------------------------------------------------- /src/js/bootstrap/src/base-component.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): base-component.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import Data from './dom/data'; 9 | import { executeAfterTransition, getElement } from './util/index'; 10 | import EventHandler from './dom/event-handler'; 11 | 12 | /** 13 | * ------------------------------------------------------------------------ 14 | * Constants 15 | * ------------------------------------------------------------------------ 16 | */ 17 | 18 | const VERSION = '5.1.3'; 19 | 20 | class BaseComponent { 21 | constructor(element) { 22 | element = getElement(element); 23 | 24 | if (!element) { 25 | return; 26 | } 27 | 28 | this._element = element; 29 | Data.set(this._element, this.constructor.DATA_KEY, this); 30 | } 31 | 32 | dispose() { 33 | Data.remove(this._element, this.constructor.DATA_KEY); 34 | EventHandler.off(this._element, this.constructor.EVENT_KEY); 35 | 36 | Object.getOwnPropertyNames(this).forEach((propertyName) => { 37 | this[propertyName] = null; 38 | }); 39 | } 40 | 41 | _queueCallback(callback, element, isAnimated = true) { 42 | executeAfterTransition(callback, element, isAnimated); 43 | } 44 | 45 | /** Static */ 46 | 47 | static getInstance(element) { 48 | return Data.get(getElement(element), this.DATA_KEY); 49 | } 50 | 51 | static getOrCreateInstance(element, config = {}) { 52 | return ( 53 | this.getInstance(element) || new this(element, typeof config === 'object' ? config : null) 54 | ); 55 | } 56 | 57 | static get VERSION() { 58 | return VERSION; 59 | } 60 | 61 | static get NAME() { 62 | throw new Error('You have to implement the static method "NAME", for each component!'); 63 | } 64 | 65 | static get DATA_KEY() { 66 | return `bs.${this.NAME}`; 67 | } 68 | 69 | static get EVENT_KEY() { 70 | return `.${this.DATA_KEY}`; 71 | } 72 | } 73 | 74 | export default BaseComponent; 75 | -------------------------------------------------------------------------------- /src/js/bootstrap/src/button.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): button.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import { defineJQueryPlugin } from './util/index'; 9 | import EventHandler from './dom/event-handler'; 10 | import BaseComponent from './base-component'; 11 | 12 | /** 13 | * ------------------------------------------------------------------------ 14 | * Constants 15 | * ------------------------------------------------------------------------ 16 | */ 17 | 18 | const NAME = 'button'; 19 | const DATA_KEY = 'bs.button'; 20 | const EVENT_KEY = `.${DATA_KEY}`; 21 | const DATA_API_KEY = '.data-api'; 22 | 23 | const CLASS_NAME_ACTIVE = 'active'; 24 | 25 | const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]'; 26 | 27 | const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; 28 | 29 | /** 30 | * ------------------------------------------------------------------------ 31 | * Class Definition 32 | * ------------------------------------------------------------------------ 33 | */ 34 | 35 | class Button extends BaseComponent { 36 | // Getters 37 | 38 | static get NAME() { 39 | return NAME; 40 | } 41 | 42 | // Public 43 | 44 | toggle() { 45 | // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method 46 | this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)); 47 | } 48 | 49 | // Static 50 | 51 | static jQueryInterface(config) { 52 | return this.each(function () { 53 | const data = Button.getOrCreateInstance(this); 54 | 55 | if (config === 'toggle') { 56 | data[config](); 57 | } 58 | }); 59 | } 60 | } 61 | 62 | /** 63 | * ------------------------------------------------------------------------ 64 | * Data Api implementation 65 | * ------------------------------------------------------------------------ 66 | */ 67 | 68 | EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, (event) => { 69 | event.preventDefault(); 70 | 71 | const button = event.target.closest(SELECTOR_DATA_TOGGLE); 72 | const data = Button.getOrCreateInstance(button); 73 | 74 | data.toggle(); 75 | }); 76 | 77 | /** 78 | * ------------------------------------------------------------------------ 79 | * jQuery 80 | * ------------------------------------------------------------------------ 81 | * add .Button to jQuery only if jQuery is present 82 | */ 83 | 84 | defineJQueryPlugin(Button); 85 | 86 | export default Button; 87 | -------------------------------------------------------------------------------- /src/js/bootstrap/src/dom/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): dom/data.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | /** 9 | * ------------------------------------------------------------------------ 10 | * Constants 11 | * ------------------------------------------------------------------------ 12 | */ 13 | 14 | const elementMap = new Map(); 15 | 16 | export default { 17 | set(element, key, instance) { 18 | if (!elementMap.has(element)) { 19 | elementMap.set(element, new Map()); 20 | } 21 | 22 | const instanceMap = elementMap.get(element); 23 | 24 | // make it clear we only want one instance per element 25 | // can be removed later when multiple key/instances are fine to be used 26 | if (!instanceMap.has(key) && instanceMap.size !== 0) { 27 | // eslint-disable-next-line no-console 28 | console.error( 29 | `Bootstrap doesn't allow more than one instance per element. Bound instance: ${ 30 | Array.from(instanceMap.keys())[0] 31 | }.` 32 | ); 33 | return; 34 | } 35 | 36 | instanceMap.set(key, instance); 37 | }, 38 | 39 | get(element, key) { 40 | if (elementMap.has(element)) { 41 | return elementMap.get(element).get(key) || null; 42 | } 43 | 44 | return null; 45 | }, 46 | 47 | remove(element, key) { 48 | if (!elementMap.has(element)) { 49 | return; 50 | } 51 | 52 | const instanceMap = elementMap.get(element); 53 | 54 | instanceMap.delete(key); 55 | 56 | // free up element references if there are no instances left for an element 57 | if (instanceMap.size === 0) { 58 | elementMap.delete(element); 59 | } 60 | }, 61 | }; 62 | -------------------------------------------------------------------------------- /src/js/bootstrap/src/dom/manipulator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): dom/manipulator.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | function normalizeData(val) { 9 | if (val === 'true') { 10 | return true; 11 | } 12 | 13 | if (val === 'false') { 14 | return false; 15 | } 16 | 17 | if (val === Number(val).toString()) { 18 | return Number(val); 19 | } 20 | 21 | if (val === '' || val === 'null') { 22 | return null; 23 | } 24 | 25 | return val; 26 | } 27 | 28 | function normalizeDataKey(key) { 29 | return key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`); 30 | } 31 | 32 | const Manipulator = { 33 | setDataAttribute(element, key, value) { 34 | element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 35 | }, 36 | 37 | removeDataAttribute(element, key) { 38 | element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 39 | }, 40 | 41 | getDataAttributes(element) { 42 | if (!element) { 43 | return {}; 44 | } 45 | 46 | const attributes = {}; 47 | 48 | Object.keys(element.dataset) 49 | .filter((key) => key.startsWith('bs')) 50 | .forEach((key) => { 51 | let pureKey = key.replace(/^bs/, ''); 52 | pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length); 53 | attributes[pureKey] = normalizeData(element.dataset[key]); 54 | }); 55 | 56 | return attributes; 57 | }, 58 | 59 | getDataAttribute(element, key) { 60 | return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 61 | }, 62 | 63 | offset(element) { 64 | const rect = element.getBoundingClientRect(); 65 | 66 | return { 67 | top: rect.top + window.pageYOffset, 68 | left: rect.left + window.pageXOffset, 69 | }; 70 | }, 71 | 72 | position(element) { 73 | return { 74 | top: element.offsetTop, 75 | left: element.offsetLeft, 76 | }; 77 | }, 78 | }; 79 | 80 | export default Manipulator; 81 | -------------------------------------------------------------------------------- /src/js/bootstrap/src/dom/selector-engine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): dom/selector-engine.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | /** 9 | * ------------------------------------------------------------------------ 10 | * Constants 11 | * ------------------------------------------------------------------------ 12 | */ 13 | 14 | import { isDisabled, isVisible } from '../util/index'; 15 | 16 | const NODE_TEXT = 3; 17 | 18 | const SelectorEngine = { 19 | find(selector, element = document.documentElement) { 20 | return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 21 | }, 22 | 23 | findOne(selector, element = document.documentElement) { 24 | return Element.prototype.querySelector.call(element, selector); 25 | }, 26 | 27 | children(element, selector) { 28 | return [].concat(...element.children).filter((child) => child.matches(selector)); 29 | }, 30 | 31 | parents(element, selector) { 32 | const parents = []; 33 | 34 | let ancestor = element.parentNode; 35 | 36 | while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) { 37 | if (ancestor.matches(selector)) { 38 | parents.push(ancestor); 39 | } 40 | 41 | ancestor = ancestor.parentNode; 42 | } 43 | 44 | return parents; 45 | }, 46 | 47 | prev(element, selector) { 48 | let previous = element.previousElementSibling; 49 | 50 | while (previous) { 51 | if (previous.matches(selector)) { 52 | return [previous]; 53 | } 54 | 55 | previous = previous.previousElementSibling; 56 | } 57 | 58 | return []; 59 | }, 60 | 61 | next(element, selector) { 62 | let next = element.nextElementSibling; 63 | 64 | while (next) { 65 | if (next.matches(selector)) { 66 | return [next]; 67 | } 68 | 69 | next = next.nextElementSibling; 70 | } 71 | 72 | return []; 73 | }, 74 | 75 | focusableChildren(element) { 76 | const focusables = [ 77 | 'a', 78 | 'button', 79 | 'input', 80 | 'textarea', 81 | 'select', 82 | 'details', 83 | '[tabindex]', 84 | '[contenteditable="true"]', 85 | ] 86 | .map((selector) => `${selector}:not([tabindex^="-"])`) 87 | .join(', '); 88 | 89 | return this.find(focusables, element).filter((el) => !isDisabled(el) && isVisible(el)); 90 | }, 91 | }; 92 | 93 | export default SelectorEngine; 94 | -------------------------------------------------------------------------------- /src/js/bootstrap/src/util/component-functions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.1.3): util/component-functions.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | import EventHandler from '../dom/event-handler'; 9 | import { getElementFromSelector, isDisabled } from './index'; 10 | 11 | const enableDismissTrigger = (component, method = 'hide') => { 12 | const clickEvent = `click.dismiss${component.EVENT_KEY}`; 13 | const name = component.NAME; 14 | 15 | EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 16 | if (['A', 'AREA'].includes(this.tagName)) { 17 | event.preventDefault(); 18 | } 19 | 20 | if (isDisabled(this)) { 21 | return; 22 | } 23 | 24 | const target = getElementFromSelector(this) || this.closest(`.${name}`); 25 | const instance = component.getOrCreateInstance(target); 26 | 27 | // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 28 | instance[method](); 29 | }); 30 | }; 31 | 32 | export { enableDismissTrigger }; 33 | -------------------------------------------------------------------------------- /src/js/free/alert.js: -------------------------------------------------------------------------------- 1 | import { getjQuery, onDOMContentLoaded } from '../mdb/util/index'; 2 | import EventHandler from '../mdb/dom/event-handler'; 3 | import SelectorEngine from '../mdb/dom/selector-engine'; 4 | import BSAlert from '../bootstrap/mdb-prefix/alert'; 5 | 6 | /** 7 | * ------------------------------------------------------------------------ 8 | * Constants 9 | * ------------------------------------------------------------------------ 10 | */ 11 | 12 | const NAME = 'alert'; 13 | const DATA_KEY = `mdb.${NAME}`; 14 | const EVENT_KEY = `.${DATA_KEY}`; 15 | 16 | const EVENT_CLOSE_BS = 'close.bs.alert'; 17 | const EVENT_CLOSED_BS = 'closed.bs.alert'; 18 | 19 | const EVENT_CLOSE = `close${EVENT_KEY}`; 20 | const EVENT_CLOSED = `closed${EVENT_KEY}`; 21 | 22 | const SELECTOR_ALERT = '.alert'; 23 | 24 | class Alert extends BSAlert { 25 | constructor(element, data = {}) { 26 | super(element, data); 27 | 28 | this._init(); 29 | } 30 | 31 | dispose() { 32 | EventHandler.off(this._element, EVENT_CLOSE_BS); 33 | EventHandler.off(this._element, EVENT_CLOSED_BS); 34 | 35 | super.dispose(); 36 | } 37 | 38 | // Getters 39 | static get NAME() { 40 | return NAME; 41 | } 42 | 43 | // Private 44 | _init() { 45 | this._bindCloseEvent(); 46 | this._bindClosedEvent(); 47 | } 48 | 49 | _bindCloseEvent() { 50 | EventHandler.on(this._element, EVENT_CLOSE_BS, () => { 51 | EventHandler.trigger(this._element, EVENT_CLOSE); 52 | }); 53 | } 54 | 55 | _bindClosedEvent() { 56 | EventHandler.on(this._element, EVENT_CLOSED_BS, () => { 57 | EventHandler.trigger(this._element, EVENT_CLOSED); 58 | }); 59 | } 60 | } 61 | 62 | /** 63 | * ------------------------------------------------------------------------ 64 | * Data Api implementation - auto initialization 65 | * ------------------------------------------------------------------------ 66 | */ 67 | 68 | SelectorEngine.find(SELECTOR_ALERT).forEach((el) => { 69 | let instance = Alert.getInstance(el); 70 | if (!instance) { 71 | instance = new Alert(el); 72 | } 73 | }); 74 | 75 | /** 76 | * ------------------------------------------------------------------------ 77 | * jQuery 78 | * ------------------------------------------------------------------------ 79 | * add .rating to jQuery only if jQuery is present 80 | */ 81 | onDOMContentLoaded(() => { 82 | const $ = getjQuery(); 83 | 84 | if ($) { 85 | const JQUERY_NO_CONFLICT = $.fn[NAME]; 86 | $.fn[NAME] = Alert.jQueryInterface; 87 | $.fn[NAME].Constructor = Alert; 88 | $.fn[NAME].noConflict = () => { 89 | $.fn[NAME] = JQUERY_NO_CONFLICT; 90 | return Alert.jQueryInterface; 91 | }; 92 | } 93 | }); 94 | 95 | export default Alert; 96 | -------------------------------------------------------------------------------- /src/js/mdb.free.js: -------------------------------------------------------------------------------- 1 | // BOOTSTRAP CORE COMPONENTS 2 | import Button from './free/button'; 3 | import Collapse from './bootstrap/mdb-prefix/collapse'; 4 | import Offcanvas from './bootstrap/mdb-prefix/offcanvas'; 5 | import Alert from './free/alert'; 6 | import Carousel from './free/carousel'; 7 | import Modal from './free/modal'; 8 | import Popover from './free/popover'; 9 | import ScrollSpy from './free/scrollspy'; 10 | import Tab from './free/tab'; 11 | import Tooltip from './free/tooltip'; 12 | import Toast from './free/toast'; 13 | 14 | // MDB FREE COMPONENTS 15 | import Input from './free/input'; 16 | import Dropdown from './free/dropdown'; 17 | import Ripple from './free/ripple'; 18 | import Range from './free/range'; 19 | 20 | export { 21 | Alert, 22 | Button, 23 | Carousel, 24 | Collapse, 25 | Offcanvas, 26 | Dropdown, 27 | Input, 28 | Modal, 29 | Popover, 30 | Ripple, 31 | ScrollSpy, 32 | Tab, 33 | Toast, 34 | Tooltip, 35 | Range, 36 | }; 37 | -------------------------------------------------------------------------------- /src/js/mdb/dom/data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.0.0-beta2): dom/data.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | /** 9 | * ------------------------------------------------------------------------ 10 | * Constants 11 | * ------------------------------------------------------------------------ 12 | */ 13 | 14 | const mapData = (() => { 15 | const storeData = {}; 16 | let id = 1; 17 | return { 18 | set(element, key, data) { 19 | if (typeof element[key] === 'undefined') { 20 | element[key] = { 21 | key, 22 | id, 23 | }; 24 | id++; 25 | } 26 | 27 | storeData[element[key].id] = data; 28 | }, 29 | get(element, key) { 30 | if (!element || typeof element[key] === 'undefined') { 31 | return null; 32 | } 33 | 34 | const keyProperties = element[key]; 35 | if (keyProperties.key === key) { 36 | return storeData[keyProperties.id]; 37 | } 38 | 39 | return null; 40 | }, 41 | delete(element, key) { 42 | if (typeof element[key] === 'undefined') { 43 | return; 44 | } 45 | 46 | const keyProperties = element[key]; 47 | if (keyProperties.key === key) { 48 | delete storeData[keyProperties.id]; 49 | delete element[key]; 50 | } 51 | }, 52 | }; 53 | })(); 54 | 55 | const Data = { 56 | setData(instance, key, data) { 57 | mapData.set(instance, key, data); 58 | }, 59 | getData(instance, key) { 60 | return mapData.get(instance, key); 61 | }, 62 | removeData(instance, key) { 63 | mapData.delete(instance, key); 64 | }, 65 | }; 66 | 67 | export default Data; 68 | -------------------------------------------------------------------------------- /src/js/mdb/dom/selector-engine.js: -------------------------------------------------------------------------------- 1 | /** 2 | * -------------------------------------------------------------------------- 3 | * Bootstrap (v5.0.0-beta2): dom/selector-engine.js 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | * -------------------------------------------------------------------------- 6 | */ 7 | 8 | /** 9 | * ------------------------------------------------------------------------ 10 | * Constants 11 | * ------------------------------------------------------------------------ 12 | */ 13 | 14 | const NODE_TEXT = 3; 15 | 16 | const SelectorEngine = { 17 | closest(element, selector) { 18 | return element.closest(selector); 19 | }, 20 | 21 | matches(element, selector) { 22 | return element.matches(selector); 23 | }, 24 | 25 | find(selector, element = document.documentElement) { 26 | return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 27 | }, 28 | 29 | findOne(selector, element = document.documentElement) { 30 | return Element.prototype.querySelector.call(element, selector); 31 | }, 32 | 33 | children(element, selector) { 34 | const children = [].concat(...element.children); 35 | 36 | return children.filter((child) => child.matches(selector)); 37 | }, 38 | 39 | parents(element, selector) { 40 | const parents = []; 41 | 42 | let ancestor = element.parentNode; 43 | 44 | while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) { 45 | if (this.matches(ancestor, selector)) { 46 | parents.push(ancestor); 47 | } 48 | 49 | ancestor = ancestor.parentNode; 50 | } 51 | 52 | return parents; 53 | }, 54 | 55 | prev(element, selector) { 56 | let previous = element.previousElementSibling; 57 | 58 | while (previous) { 59 | if (previous.matches(selector)) { 60 | return [previous]; 61 | } 62 | 63 | previous = previous.previousElementSibling; 64 | } 65 | 66 | return []; 67 | }, 68 | 69 | next(element, selector) { 70 | let next = element.nextElementSibling; 71 | 72 | while (next) { 73 | if (this.matches(next, selector)) { 74 | return [next]; 75 | } 76 | 77 | next = next.nextElementSibling; 78 | } 79 | 80 | return []; 81 | }, 82 | }; 83 | 84 | export default SelectorEngine; 85 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/handlers/click-rail.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import updateGeometry from '../update-geometry'; 4 | 5 | export default function (i) { 6 | // const element = i.element; 7 | 8 | i.event.bind(i.scrollbarY, 'mousedown', (e) => e.stopPropagation()); 9 | i.event.bind(i.scrollbarYRail, 'mousedown', (e) => { 10 | const positionTop = e.pageY - window.pageYOffset - i.scrollbarYRail.getBoundingClientRect().top; 11 | const direction = positionTop > i.scrollbarYTop ? 1 : -1; 12 | 13 | i.element.scrollTop += direction * i.containerHeight; 14 | updateGeometry(i); 15 | 16 | e.stopPropagation(); 17 | }); 18 | 19 | i.event.bind(i.scrollbarX, 'mousedown', (e) => e.stopPropagation()); 20 | i.event.bind(i.scrollbarXRail, 'mousedown', (e) => { 21 | const positionLeft = 22 | e.pageX - window.pageXOffset - i.scrollbarXRail.getBoundingClientRect().left; 23 | const direction = positionLeft > i.scrollbarXLeft ? 1 : -1; 24 | 25 | i.element.scrollLeft += direction * i.containerWidth; 26 | updateGeometry(i); 27 | 28 | e.stopPropagation(); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/handlers/drag-thumb.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import * as CSS from '../lib/css'; 4 | import * as DOM from '../lib/dom'; 5 | import cls, { addScrollingClass, removeScrollingClass } from '../lib/class-names'; 6 | import updateGeometry from '../update-geometry'; 7 | import { toInt } from '../lib/util'; 8 | 9 | export default function (i) { 10 | bindMouseScrollHandler(i, [ 11 | 'containerWidth', 12 | 'contentWidth', 13 | 'pageX', 14 | 'railXWidth', 15 | 'scrollbarX', 16 | 'scrollbarXWidth', 17 | 'scrollLeft', 18 | 'x', 19 | 'scrollbarXRail', 20 | ]); 21 | bindMouseScrollHandler(i, [ 22 | 'containerHeight', 23 | 'contentHeight', 24 | 'pageY', 25 | 'railYHeight', 26 | 'scrollbarY', 27 | 'scrollbarYHeight', 28 | 'scrollTop', 29 | 'y', 30 | 'scrollbarYRail', 31 | ]); 32 | } 33 | 34 | function bindMouseScrollHandler( 35 | i, 36 | [ 37 | containerHeight, 38 | contentHeight, 39 | pageY, 40 | railYHeight, 41 | scrollbarY, 42 | scrollbarYHeight, 43 | scrollTop, 44 | y, 45 | scrollbarYRail, 46 | ] 47 | ) { 48 | const element = i.element; 49 | 50 | let startingScrollTop = null; 51 | let startingMousePageY = null; 52 | let scrollBy = null; 53 | 54 | function mouseMoveHandler(e) { 55 | if (e.touches && e.touches[0]) { 56 | e[pageY] = e.touches[0].pageY; 57 | } 58 | element[scrollTop] = startingScrollTop + scrollBy * (e[pageY] - startingMousePageY); 59 | addScrollingClass(i, y); 60 | updateGeometry(i); 61 | 62 | e.stopPropagation(); 63 | e.preventDefault(); 64 | } 65 | 66 | function mouseUpHandler() { 67 | removeScrollingClass(i, y); 68 | i[scrollbarYRail].classList.remove(cls.state.clicking); 69 | i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler); 70 | } 71 | 72 | function bindMoves(e, touchMode) { 73 | startingScrollTop = element[scrollTop]; 74 | if (touchMode && e.touches) { 75 | e[pageY] = e.touches[0].pageY; 76 | } 77 | startingMousePageY = e[pageY]; 78 | scrollBy = (i[contentHeight] - i[containerHeight]) / (i[railYHeight] - i[scrollbarYHeight]); 79 | if (!touchMode) { 80 | i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); 81 | i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler); 82 | e.preventDefault(); 83 | } else { 84 | i.event.bind(i.ownerDocument, 'touchmove', mouseMoveHandler); 85 | } 86 | 87 | i[scrollbarYRail].classList.add(cls.state.clicking); 88 | 89 | e.stopPropagation(); 90 | } 91 | 92 | i.event.bind(i[scrollbarY], 'mousedown', (e) => { 93 | bindMoves(e); 94 | }); 95 | i.event.bind(i[scrollbarY], 'touchstart', (e) => { 96 | bindMoves(e, true); 97 | }); 98 | } 99 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/lib/class-names.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | const cls = { 4 | main: 'ps', 5 | rtl: 'ps__rtl', 6 | element: { 7 | thumb: (x) => `ps__thumb-${x}`, 8 | rail: (x) => `ps__rail-${x}`, 9 | consuming: 'ps__child--consume', 10 | }, 11 | state: { 12 | focus: 'ps--focus', 13 | clicking: 'ps--clicking', 14 | active: (x) => `ps--active-${x}`, 15 | scrolling: (x) => `ps--scrolling-${x}`, 16 | }, 17 | }; 18 | 19 | export default cls; 20 | 21 | /* 22 | * Helper methods 23 | */ 24 | const scrollingClassTimeout = { x: null, y: null }; 25 | 26 | export function addScrollingClass(i, x) { 27 | const classList = i.element.classList; 28 | const className = cls.state.scrolling(x); 29 | 30 | if (classList.contains(className)) { 31 | clearTimeout(scrollingClassTimeout[x]); 32 | } else { 33 | classList.add(className); 34 | } 35 | } 36 | 37 | export function removeScrollingClass(i, x) { 38 | scrollingClassTimeout[x] = setTimeout( 39 | () => i.isAlive && i.element.classList.remove(cls.state.scrolling(x)), 40 | i.settings.scrollingThreshold 41 | ); 42 | } 43 | 44 | export function setScrollingClassInstantly(i, x) { 45 | addScrollingClass(i, x); 46 | removeScrollingClass(i, x); 47 | } 48 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/lib/css.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | export function get(element) { 4 | return getComputedStyle(element); 5 | } 6 | 7 | export function set(element, obj) { 8 | for (const key in obj) { 9 | let val = obj[key]; 10 | if (typeof val === 'number') { 11 | val = `${val}px`; 12 | } 13 | element.style[key] = val; 14 | } 15 | return element; 16 | } 17 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/lib/dom.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | export function div(className) { 4 | const div = document.createElement('div'); 5 | div.className = className; 6 | return div; 7 | } 8 | 9 | const elMatches = 10 | typeof Element !== 'undefined' && 11 | (Element.prototype.matches || 12 | Element.prototype.webkitMatchesSelector || 13 | Element.prototype.mozMatchesSelector || 14 | Element.prototype.msMatchesSelector); 15 | 16 | export function matches(element, query) { 17 | if (!elMatches) { 18 | throw new Error('No element matching method supported'); 19 | } 20 | 21 | return elMatches.call(element, query); 22 | } 23 | 24 | export function remove(element) { 25 | if (element.remove) { 26 | element.remove(); 27 | } else { 28 | if (element.parentNode) { 29 | element.parentNode.removeChild(element); 30 | } 31 | } 32 | } 33 | 34 | export function queryChildren(element, selector) { 35 | return Array.prototype.filter.call(element.children, (child) => matches(child, selector)); 36 | } 37 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/lib/event-manager.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | class EventElement { 3 | constructor(element) { 4 | this.element = element; 5 | this.handlers = {}; 6 | } 7 | 8 | bind(eventName, handler) { 9 | if (typeof this.handlers[eventName] === 'undefined') { 10 | this.handlers[eventName] = []; 11 | } 12 | this.handlers[eventName].push(handler); 13 | this.element.addEventListener(eventName, handler, false); 14 | } 15 | 16 | unbind(eventName, target) { 17 | this.handlers[eventName] = this.handlers[eventName].filter((handler) => { 18 | if (target && handler !== target) { 19 | return true; 20 | } 21 | this.element.removeEventListener(eventName, handler, false); 22 | return false; 23 | }); 24 | } 25 | 26 | unbindAll() { 27 | for (const name in this.handlers) { 28 | this.unbind(name); 29 | } 30 | } 31 | 32 | get isEmpty() { 33 | return Object.keys(this.handlers).every((key) => this.handlers[key].length === 0); 34 | } 35 | } 36 | 37 | export default class EventManager { 38 | constructor() { 39 | this.eventElements = []; 40 | } 41 | 42 | eventElement(element) { 43 | let ee = this.eventElements.filter((ee) => ee.element === element)[0]; 44 | if (!ee) { 45 | ee = new EventElement(element); 46 | this.eventElements.push(ee); 47 | } 48 | return ee; 49 | } 50 | 51 | bind(element, eventName, handler) { 52 | this.eventElement(element).bind(eventName, handler); 53 | } 54 | 55 | unbind(element, eventName, handler) { 56 | const ee = this.eventElement(element); 57 | ee.unbind(eventName, handler); 58 | 59 | if (ee.isEmpty) { 60 | // remove 61 | this.eventElements.splice(this.eventElements.indexOf(ee), 1); 62 | } 63 | } 64 | 65 | unbindAll() { 66 | this.eventElements.forEach((e) => e.unbindAll()); 67 | this.eventElements = []; 68 | } 69 | 70 | once(element, eventName, handler) { 71 | const ee = this.eventElement(element); 72 | const onceHandler = (evt) => { 73 | ee.unbind(eventName, onceHandler); 74 | handler(evt); 75 | }; 76 | ee.bind(eventName, onceHandler); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/lib/util.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import * as CSS from './css'; 4 | import * as DOM from './dom'; 5 | 6 | export function toInt(x) { 7 | return parseInt(x, 10) || 0; 8 | } 9 | 10 | export function isEditable(el) { 11 | return ( 12 | DOM.matches(el, 'input,[contenteditable]') || 13 | DOM.matches(el, 'select,[contenteditable]') || 14 | DOM.matches(el, 'textarea,[contenteditable]') || 15 | DOM.matches(el, 'button,[contenteditable]') 16 | ); 17 | } 18 | 19 | export function outerWidth(element) { 20 | const styles = CSS.get(element); 21 | return ( 22 | toInt(styles.width) + 23 | toInt(styles.paddingLeft) + 24 | toInt(styles.paddingRight) + 25 | toInt(styles.borderLeftWidth) + 26 | toInt(styles.borderRightWidth) 27 | ); 28 | } 29 | 30 | export const env = { 31 | isWebKit: typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style, 32 | supportsTouch: 33 | typeof window !== 'undefined' && 34 | ('ontouchstart' in window || 35 | ('maxTouchPoints' in window.navigator && window.navigator.maxTouchPoints > 0) || 36 | (window.DocumentTouch && document instanceof window.DocumentTouch)), 37 | supportsIePointer: typeof navigator !== 'undefined' && navigator.msMaxTouchPoints, 38 | isChrome: typeof navigator !== 'undefined' && /Chrome/i.test(navigator && navigator.userAgent), 39 | }; 40 | -------------------------------------------------------------------------------- /src/js/mdb/perfect-scrollbar/process-scroll-diff.js: -------------------------------------------------------------------------------- 1 | import { setScrollingClassInstantly } from './lib/class-names'; 2 | 3 | function createEvent(name) { 4 | if (typeof window.CustomEvent === 'function') { 5 | return new CustomEvent(name); 6 | } 7 | 8 | const evt = document.createEvent('CustomEvent'); 9 | evt.initCustomEvent(name, false, false, undefined); 10 | return evt; 11 | } 12 | 13 | export default function (i, axis, diff, useScrollingClass = true, forceFireReachEvent = false) { 14 | let fields; 15 | if (axis === 'top') { 16 | fields = ['contentHeight', 'containerHeight', 'scrollTop', 'y', 'up', 'down']; 17 | } else if (axis === 'left') { 18 | fields = ['contentWidth', 'containerWidth', 'scrollLeft', 'x', 'left', 'right']; 19 | } else { 20 | throw new Error('A proper axis should be provided'); 21 | } 22 | 23 | processScrollDiff(i, diff, fields, useScrollingClass, forceFireReachEvent); 24 | } 25 | 26 | function processScrollDiff( 27 | i, 28 | diff, 29 | [contentHeight, containerHeight, scrollTop, y, up, down], 30 | useScrollingClass = true, 31 | forceFireReachEvent = false 32 | ) { 33 | const element = i.element; 34 | 35 | // reset reach 36 | i.reach[y] = null; 37 | 38 | // 1 for subpixel rounding 39 | if (element[scrollTop] < 1) { 40 | i.reach[y] = 'start'; 41 | } 42 | 43 | // 1 for subpixel rounding 44 | if (element[scrollTop] > i[contentHeight] - i[containerHeight] - 1) { 45 | i.reach[y] = 'end'; 46 | } 47 | 48 | if (diff) { 49 | element.dispatchEvent(createEvent(`ps-scroll-${y}`)); 50 | 51 | if (diff < 0) { 52 | element.dispatchEvent(createEvent(`ps-scroll-${up}`)); 53 | } else if (diff > 0) { 54 | element.dispatchEvent(createEvent(`ps-scroll-${down}`)); 55 | } 56 | 57 | if (useScrollingClass) { 58 | setScrollingClassInstantly(i, y); 59 | } 60 | } 61 | 62 | if (i.reach[y] && (diff || forceFireReachEvent)) { 63 | element.dispatchEvent(createEvent(`ps-${y}-reach-${i.reach[y]}`)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/js/mdb/util/focusTrap.js: -------------------------------------------------------------------------------- 1 | import SelectorEngine from '../dom/selector-engine'; 2 | import { isVisible } from './index'; 3 | 4 | class FocusTrap { 5 | constructor(element, options = {}, toggler) { 6 | this._element = element; 7 | this._toggler = toggler; 8 | this._event = options.event || 'blur'; 9 | this._condition = options.condition || (() => true); 10 | this._selector = 11 | options.selector || 'button, a, input, select, textarea, [tabindex]:not([tabindex="-1"])'; 12 | this._onlyVisible = options.onlyVisible || false; 13 | this._focusableElements = []; 14 | this._firstElement = null; 15 | this._lastElement = null; 16 | 17 | this.handler = (e) => { 18 | if (this._condition(e) && e.target === this._lastElement) { 19 | e.preventDefault(); 20 | this._firstElement.focus(); 21 | } 22 | }; 23 | } 24 | 25 | trap() { 26 | this._setElements(); 27 | this._init(); 28 | this._setFocusTrap(); 29 | } 30 | 31 | disable() { 32 | this._focusableElements.forEach((element) => { 33 | element.removeEventListener(this._event, this.handler); 34 | }); 35 | 36 | if (this._toggler) { 37 | this._toggler.focus(); 38 | } 39 | } 40 | 41 | update() { 42 | this._setElements(); 43 | this._setFocusTrap(); 44 | } 45 | 46 | _init() { 47 | const handler = (e) => { 48 | if (!this._firstElement || e.key !== 'Tab' || this._focusableElements.includes(e.target)) { 49 | return; 50 | } 51 | 52 | e.preventDefault(); 53 | this._firstElement.focus(); 54 | 55 | window.removeEventListener('keydown', handler); 56 | }; 57 | 58 | window.addEventListener('keydown', handler); 59 | } 60 | 61 | _filterVisible(elements) { 62 | return elements.filter((el) => { 63 | if (!isVisible(el)) return false; 64 | 65 | const ancestors = SelectorEngine.parents(el, '*'); 66 | 67 | for (let i = 0; i < ancestors.length; i++) { 68 | const style = window.getComputedStyle(ancestors[i]); 69 | if (style && (style.display === 'none' || style.visibility === 'hidden')) return false; 70 | } 71 | return true; 72 | }); 73 | } 74 | 75 | _setElements() { 76 | this._focusableElements = SelectorEngine.find(this._selector, this._element); 77 | 78 | if (this._onlyVisible) { 79 | this._focusableElements = this._filterVisible(this._focusableElements); 80 | } 81 | 82 | this._firstElement = this._focusableElements[0]; 83 | this._lastElement = this._focusableElements[this._focusableElements.length - 1]; 84 | } 85 | 86 | _setFocusTrap() { 87 | this._focusableElements.forEach((element, i) => { 88 | if (i === this._focusableElements.length - 1) { 89 | element.addEventListener(this._event, this.handler); 90 | } else { 91 | element.removeEventListener(this._event, this.handler); 92 | } 93 | }); 94 | } 95 | } 96 | 97 | export default FocusTrap; 98 | -------------------------------------------------------------------------------- /src/js/mdb/util/keycodes.js: -------------------------------------------------------------------------------- 1 | export const LEFT_ARROW = 37; 2 | export const UP_ARROW = 38; 3 | export const RIGHT_ARROW = 39; 4 | export const DOWN_ARROW = 40; 5 | export const HOME = 36; 6 | export const END = 35; 7 | export const PAGE_UP = 33; 8 | export const PAGE_DOWN = 34; 9 | export const ENTER = 13; 10 | export const SPACE = 32; 11 | export const ESCAPE = 27; 12 | export const TAB = 9; 13 | export const BACKSPACE = 8; 14 | export const DELETE = 46; 15 | export const A = 65; 16 | export const B = 66; 17 | export const C = 67; 18 | export const D = 68; 19 | export const E = 69; 20 | export const F = 70; 21 | export const G = 71; 22 | export const H = 72; 23 | export const I = 73; 24 | export const J = 74; 25 | export const K = 75; 26 | export const L = 76; 27 | export const M = 77; 28 | export const N = 78; 29 | export const O = 79; 30 | export const P = 80; 31 | export const Q = 81; 32 | export const R = 82; 33 | export const S = 83; 34 | export const T = 84; 35 | export const U = 85; 36 | export const V = 86; 37 | export const W = 87; 38 | export const X = 88; 39 | export const Y = 89; 40 | export const Z = 90; 41 | -------------------------------------------------------------------------------- /src/js/mdb/util/touch/index.js: -------------------------------------------------------------------------------- 1 | import Swipe from './swipe'; 2 | 3 | class Touch { 4 | constructor(element, event = 'swipe', options = {}) { 5 | this._element = element; 6 | this._event = event; 7 | 8 | // events 9 | 10 | this.swipe = new Swipe(element, options); 11 | 12 | // handlers 13 | 14 | this._touchStartHandler = this._handleTouchStart.bind(this); 15 | this._touchMoveHandler = this._handleTouchMove.bind(this); 16 | this._touchEndHandler = this._handleTouchEnd.bind(this); 17 | } 18 | 19 | dispose() { 20 | this._element.removeEventListener('touchstart', this._touchStartHandler); 21 | this._element.removeEventListener('touchmove', this._touchMoveHandler); 22 | window.removeEventListener('touchend', this._touchEndHandler); 23 | } 24 | 25 | init() { 26 | // istanbul ignore next 27 | this._element.addEventListener('touchstart', (e) => this._handleTouchStart(e)); 28 | // istanbul ignore next 29 | this._element.addEventListener('touchmove', (e) => this._handleTouchMove(e)); 30 | // istanbul ignore next 31 | window.addEventListener('touchend', (e) => this._handleTouchEnd(e)); 32 | } 33 | 34 | _handleTouchStart(e) { 35 | this[this._event].handleTouchStart(e); 36 | } 37 | 38 | _handleTouchMove(e) { 39 | this[this._event].handleTouchMove(e); 40 | } 41 | 42 | _handleTouchEnd(e) { 43 | this[this._event].handleTouchEnd(e); 44 | } 45 | } 46 | 47 | export default Touch; 48 | -------------------------------------------------------------------------------- /src/js/mdb/util/touch/swipe.js: -------------------------------------------------------------------------------- 1 | import EventHandler from '../../dom/event-handler'; 2 | 3 | const DEFAULT_OPTIONS = { 4 | threshold: 10, 5 | direction: 'all', 6 | }; 7 | 8 | class Swipe { 9 | constructor(element, options) { 10 | this._element = element; 11 | this._startPosition = null; 12 | this._options = { 13 | ...DEFAULT_OPTIONS, 14 | ...options, 15 | }; 16 | } 17 | 18 | handleTouchStart(e) { 19 | this._startPosition = this._getCoordinates(e); 20 | } 21 | 22 | handleTouchMove(e) { 23 | if (!this._startPosition) return; 24 | 25 | const position = this._getCoordinates(e); 26 | const displacement = { 27 | x: position.x - this._startPosition.x, 28 | y: position.y - this._startPosition.y, 29 | }; 30 | 31 | const swipe = this._getDirection(displacement); 32 | 33 | if (this._options.direction === 'all') { 34 | if (swipe.y.value < this._options.threshold && swipe.x.value < this._options.threshold) { 35 | return; 36 | } 37 | const direction = swipe.y.value > swipe.x.value ? swipe.y.direction : swipe.x.direction; 38 | EventHandler.trigger(this._element, `swipe${direction}`); 39 | EventHandler.trigger(this._element, 'swipe', { direction }); 40 | this._startPosition = null; 41 | return; 42 | } 43 | 44 | const axis = this._options.direction === 'left' || this._options === 'right' ? 'x' : 'y'; 45 | 46 | if ( 47 | swipe[axis].direction === this._options.direction && 48 | swipe[axis].value > this._options.threshold 49 | ) { 50 | EventHandler.trigger(this._element, `swipe${swipe[axis].direction}`); 51 | this._startPosition = null; 52 | } 53 | } 54 | 55 | handleTouchEnd() { 56 | this._startPosition = null; 57 | } 58 | 59 | _getCoordinates(e) { 60 | const [touch] = e.touches; 61 | return { 62 | x: touch.clientX, 63 | y: touch.clientY, 64 | }; 65 | } 66 | 67 | _getDirection(displacement) { 68 | return { 69 | x: { 70 | direction: displacement.x < 0 ? 'left' : 'right', 71 | value: Math.abs(displacement.x), 72 | }, 73 | y: { 74 | direction: displacement.y < 0 ? 'up' : 'down', 75 | value: Math.abs(displacement.y), 76 | }, 77 | }; 78 | } 79 | } 80 | 81 | export default Swipe; 82 | -------------------------------------------------------------------------------- /src/js/mdb/util/touch/touchUtil.js: -------------------------------------------------------------------------------- 1 | class TouchUtil { 2 | _getCoordinates(e) { 3 | const [touch] = e.touches; 4 | return { 5 | x: touch.clientX, 6 | y: touch.clientY, 7 | }; 8 | } 9 | 10 | _getDirection(displacement) { 11 | return { 12 | x: { 13 | direction: displacement.x < 0 ? 'left' : 'right', 14 | value: Math.abs(displacement.x), 15 | }, 16 | y: { 17 | direction: displacement.y < 0 ? 'up' : 'down', 18 | value: Math.abs(displacement.y), 19 | }, 20 | }; 21 | } 22 | } 23 | 24 | export default TouchUtil; 25 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | position: relative; 7 | padding: $alert-padding-y $alert-padding-x; 8 | margin-bottom: $alert-margin-bottom; 9 | border: $alert-border-width solid transparent; 10 | @include border-radius($alert-border-radius); 11 | } 12 | 13 | // Headings for larger alerts 14 | .alert-heading { 15 | // Specified to prevent conflicts of changing $headings-color 16 | color: inherit; 17 | } 18 | 19 | // Provide class for links that match alerts 20 | .alert-link { 21 | font-weight: $alert-link-font-weight; 22 | } 23 | 24 | // Dismissible alerts 25 | // 26 | // Expand the right padding and account for the close button's positioning. 27 | 28 | .alert-dismissible { 29 | padding-right: $alert-dismissible-padding-r; 30 | 31 | // Adjust close link position 32 | .btn-close { 33 | position: absolute; 34 | top: 0; 35 | right: 0; 36 | z-index: $stretched-link-z-index + 1; 37 | padding: $alert-padding-y * 1.25 $alert-padding-x; 38 | } 39 | } 40 | 41 | // scss-docs-start alert-modifiers 42 | // Generate contextual modifier classes for colorizing the alert. 43 | 44 | @each $state, $value in $theme-colors { 45 | $alert-background: shift-color($value, $alert-bg-scale); 46 | $alert-border: shift-color($value, $alert-border-scale); 47 | $alert-color: shift-color($value, $alert-color-scale); 48 | @if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) { 49 | $alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale)); 50 | } 51 | .alert-#{$state} { 52 | @include alert-variant($alert-background, $alert-border, $alert-color); 53 | } 54 | } 55 | // scss-docs-end alert-modifiers 56 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | display: inline-block; 8 | padding: $badge-padding-y $badge-padding-x; 9 | @include font-size($badge-font-size); 10 | font-weight: $badge-font-weight; 11 | line-height: 1; 12 | color: $badge-color; 13 | text-align: center; 14 | white-space: nowrap; 15 | vertical-align: baseline; 16 | @include border-radius($badge-border-radius); 17 | @include gradient-bg(); 18 | 19 | // Empty badges collapse automatically 20 | &:empty { 21 | display: none; 22 | } 23 | } 24 | 25 | // Quick fix for badges in buttons 26 | .btn .badge { 27 | position: relative; 28 | top: -1px; 29 | } 30 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: $breadcrumb-padding-y $breadcrumb-padding-x; 5 | margin-bottom: $breadcrumb-margin-bottom; 6 | @include font-size($breadcrumb-font-size); 7 | list-style: none; 8 | background-color: $breadcrumb-bg; 9 | @include border-radius($breadcrumb-border-radius); 10 | } 11 | 12 | .breadcrumb-item { 13 | // The separator between breadcrumbs (by default, a forward-slash: "/") 14 | + .breadcrumb-item { 15 | padding-left: $breadcrumb-item-padding-x; 16 | 17 | &::before { 18 | float: left; // Suppress inline spacings and underlining of the separator 19 | padding-right: $breadcrumb-item-padding-x; 20 | color: $breadcrumb-divider-color; 21 | content: var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{'/*!rtl:'} 22 | var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{'*/'}; 23 | } 24 | } 25 | 26 | &.active { 27 | color: $breadcrumb-active-color; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_buttons.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .btn { 6 | display: inline-block; 7 | font-family: $btn-font-family; 8 | font-weight: $btn-font-weight; 9 | line-height: $btn-line-height; 10 | color: $body-color; 11 | text-align: center; 12 | text-decoration: if($link-decoration == none, null, none); 13 | white-space: $btn-white-space; 14 | vertical-align: middle; 15 | cursor: if($enable-button-pointers, pointer, null); 16 | user-select: none; 17 | background-color: transparent; 18 | border: $btn-border-width solid transparent; 19 | @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius); 20 | @include transition($btn-transition); 21 | 22 | &:hover { 23 | color: $body-color; 24 | text-decoration: if($link-hover-decoration == underline, none, null); 25 | } 26 | 27 | .btn-check:focus + &, 28 | &:focus { 29 | outline: 0; 30 | box-shadow: $btn-focus-box-shadow; 31 | } 32 | 33 | .btn-check:checked + &, 34 | .btn-check:active + &, 35 | &:active, 36 | &.active { 37 | @include box-shadow($btn-active-box-shadow); 38 | 39 | &:focus { 40 | @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow); 41 | } 42 | } 43 | 44 | &:disabled, 45 | &.disabled, 46 | fieldset:disabled & { 47 | pointer-events: none; 48 | opacity: $btn-disabled-opacity; 49 | @include box-shadow(none); 50 | } 51 | } 52 | 53 | // 54 | // Alternate buttons 55 | // 56 | 57 | // scss-docs-start btn-variant-loops 58 | @each $color, $value in $theme-colors { 59 | .btn-#{$color} { 60 | @include button-variant($value, $value); 61 | } 62 | } 63 | 64 | @each $color, $value in $theme-colors { 65 | .btn-outline-#{$color} { 66 | @include button-outline-variant($value); 67 | } 68 | } 69 | // scss-docs-end btn-variant-loops 70 | 71 | // 72 | // Link buttons 73 | // 74 | 75 | // Make a button look and behave like a link 76 | .btn-link { 77 | font-weight: $font-weight-normal; 78 | color: $btn-link-color; 79 | text-decoration: $link-decoration; 80 | 81 | &:hover { 82 | color: $btn-link-hover-color; 83 | text-decoration: $link-hover-decoration; 84 | } 85 | 86 | &:focus { 87 | text-decoration: $link-hover-decoration; 88 | } 89 | 90 | &:disabled, 91 | &.disabled { 92 | color: $btn-link-disabled-color; 93 | } 94 | 95 | // No need for an active state here 96 | } 97 | 98 | // 99 | // Button Sizes 100 | // 101 | 102 | .btn-lg { 103 | @include button-size( 104 | $btn-padding-y-lg, 105 | $btn-padding-x-lg, 106 | $btn-font-size-lg, 107 | $btn-border-radius-lg 108 | ); 109 | } 110 | 111 | .btn-sm { 112 | @include button-size( 113 | $btn-padding-y-sm, 114 | $btn-padding-x-sm, 115 | $btn-font-size-sm, 116 | $btn-border-radius-sm 117 | ); 118 | } 119 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_close.scss: -------------------------------------------------------------------------------- 1 | // transparent background and border properties included for button version. 2 | // iOS requires the button element instead of an anchor tag. 3 | // If you want the anchor version, it requires `href="#"`. 4 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 5 | 6 | .btn-close { 7 | box-sizing: content-box; 8 | width: $btn-close-width; 9 | height: $btn-close-height; 10 | padding: $btn-close-padding-y $btn-close-padding-x; 11 | color: $btn-close-color; 12 | background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements 13 | border: 0; // for button elements 14 | @include border-radius(); 15 | opacity: $btn-close-opacity; 16 | 17 | // Override 's hover style 18 | &:hover { 19 | color: $btn-close-color; 20 | text-decoration: none; 21 | opacity: $btn-close-hover-opacity; 22 | } 23 | 24 | &:focus { 25 | outline: 0; 26 | box-shadow: $btn-close-focus-shadow; 27 | opacity: $btn-close-focus-opacity; 28 | } 29 | 30 | &:disabled, 31 | &.disabled { 32 | pointer-events: none; 33 | user-select: none; 34 | opacity: $btn-close-disabled-opacity; 35 | } 36 | } 37 | 38 | .btn-close-white { 39 | filter: $btn-close-white-filter; 40 | } 41 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_containers.scss: -------------------------------------------------------------------------------- 1 | // Container widths 2 | // 3 | // Set the container width, and override it for fixed navbars in media queries. 4 | 5 | @if $enable-grid-classes { 6 | // Single container class with breakpoint max-widths 7 | .container, 8 | // 100% wide container at all breakpoints 9 | .container-fluid { 10 | @include make-container(); 11 | } 12 | 13 | // Responsive containers that are 100% wide until a breakpoint 14 | @each $breakpoint, $container-max-width in $container-max-widths { 15 | .container-#{$breakpoint} { 16 | @extend .container-fluid; 17 | } 18 | 19 | @include media-breakpoint-up($breakpoint, $grid-breakpoints) { 20 | %responsive-container-#{$breakpoint} { 21 | max-width: $container-max-width; 22 | } 23 | 24 | // Extend each breakpoint which is smaller or equal to the current breakpoint 25 | $extend-breakpoint: true; 26 | 27 | @each $name, $width in $grid-breakpoints { 28 | @if ($extend-breakpoint) { 29 | .container#{breakpoint-infix($name, $grid-breakpoints)} { 30 | @extend %responsive-container-#{$breakpoint}; 31 | } 32 | 33 | // Once the current breakpoint is reached, stop extending 34 | @if ($breakpoint == $name) { 35 | $extend-breakpoint: false; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_forms.scss: -------------------------------------------------------------------------------- 1 | @import 'forms/labels'; 2 | @import 'forms/form-text'; 3 | @import 'forms/form-control'; 4 | @import 'forms/form-select'; 5 | @import 'forms/form-check'; 6 | @import 'forms/form-range'; 7 | @import 'forms/floating-labels'; 8 | @import 'forms/input-group'; 9 | @import 'forms/validation'; 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_grid.scss: -------------------------------------------------------------------------------- 1 | // Row 2 | // 3 | // Rows contain your columns. 4 | 5 | @if $enable-grid-classes { 6 | .row { 7 | @include make-row(); 8 | 9 | > * { 10 | @include make-col-ready(); 11 | } 12 | } 13 | } 14 | 15 | @if $enable-cssgrid { 16 | .grid { 17 | display: grid; 18 | grid-template-rows: repeat(var(--#{$variable-prefix}rows, 1), 1fr); 19 | grid-template-columns: repeat(var(--#{$variable-prefix}columns, #{$grid-columns}), 1fr); 20 | gap: var(--#{$variable-prefix}gap, #{$grid-gutter-width}); 21 | 22 | @include make-cssgrid(); 23 | } 24 | } 25 | 26 | // Columns 27 | // 28 | // Common styles for small and large grid columns 29 | 30 | @if $enable-grid-classes { 31 | @include make-grid-columns(); 32 | } 33 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_helpers.scss: -------------------------------------------------------------------------------- 1 | @import 'helpers/clearfix'; 2 | @import 'helpers/colored-links'; 3 | @import 'helpers/ratio'; 4 | @import 'helpers/position'; 5 | @import 'helpers/stacks'; 6 | @import 'helpers/visually-hidden'; 7 | @import 'helpers/stretched-link'; 8 | @import 'helpers/text-truncation'; 9 | @import 'helpers/vr'; 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_images.scss: -------------------------------------------------------------------------------- 1 | // Responsive images (ensure images don't scale beyond their parents) 2 | // 3 | // This is purposefully opt-in via an explicit class rather than being the default for all ``s. 4 | // We previously tried the "images are responsive by default" approach in Bootstrap v2, 5 | // and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps) 6 | // which weren't expecting the images within themselves to be involuntarily resized. 7 | // See also https://github.com/twbs/bootstrap/issues/18178 8 | .img-fluid { 9 | @include img-fluid(); 10 | } 11 | 12 | // Image thumbnails 13 | .img-thumbnail { 14 | padding: $thumbnail-padding; 15 | background-color: $thumbnail-bg; 16 | border: $thumbnail-border-width solid $thumbnail-border-color; 17 | @include border-radius($thumbnail-border-radius); 18 | @include box-shadow($thumbnail-box-shadow); 19 | 20 | // Keep them at most 100% wide 21 | @include img-fluid(); 22 | } 23 | 24 | // 25 | // Figures 26 | // 27 | 28 | .figure { 29 | // Ensures the caption's text aligns with the image. 30 | display: inline-block; 31 | } 32 | 33 | .figure-img { 34 | margin-bottom: $spacer * 0.5; 35 | line-height: 1; 36 | } 37 | 38 | .figure-caption { 39 | @include font-size($figure-caption-font-size); 40 | color: $figure-caption-color; 41 | } 42 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Vendor 6 | @import 'vendor/rfs'; 7 | 8 | // Deprecate 9 | @import 'mixins/deprecate'; 10 | 11 | // Helpers 12 | @import 'mixins/breakpoints'; 13 | @import 'mixins/color-scheme'; 14 | @import 'mixins/image'; 15 | @import 'mixins/resize'; 16 | @import 'mixins/visually-hidden'; 17 | @import 'mixins/reset-text'; 18 | @import 'mixins/text-truncate'; 19 | 20 | // Utilities 21 | @import 'mixins/utilities'; 22 | 23 | // Components 24 | @import 'mixins/alert'; 25 | @import 'mixins/backdrop'; 26 | @import 'mixins/buttons'; 27 | @import 'mixins/caret'; 28 | @import 'mixins/pagination'; 29 | @import 'mixins/lists'; 30 | @import 'mixins/list-group'; 31 | @import 'mixins/forms'; 32 | @import 'mixins/table-variants'; 33 | 34 | // Skins 35 | @import 'mixins/border-radius'; 36 | @import 'mixins/box-shadow'; 37 | @import 'mixins/gradients'; 38 | @import 'mixins/transition'; 39 | 40 | // Layout 41 | @import 'mixins/clearfix'; 42 | @import 'mixins/container'; 43 | @import 'mixins/grid'; 44 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_offcanvas.scss: -------------------------------------------------------------------------------- 1 | .offcanvas { 2 | position: fixed; 3 | bottom: 0; 4 | z-index: $zindex-offcanvas; 5 | display: flex; 6 | flex-direction: column; 7 | max-width: 100%; 8 | color: $offcanvas-color; 9 | visibility: hidden; 10 | background-color: $offcanvas-bg-color; 11 | background-clip: padding-box; 12 | outline: 0; 13 | @include box-shadow($offcanvas-box-shadow); 14 | @include transition(transform $offcanvas-transition-duration ease-in-out); 15 | } 16 | 17 | .offcanvas-backdrop { 18 | @include overlay-backdrop( 19 | $zindex-offcanvas-backdrop, 20 | $offcanvas-backdrop-bg, 21 | $offcanvas-backdrop-opacity 22 | ); 23 | } 24 | 25 | .offcanvas-header { 26 | display: flex; 27 | align-items: center; 28 | justify-content: space-between; 29 | padding: $offcanvas-padding-y $offcanvas-padding-x; 30 | 31 | .btn-close { 32 | padding: ($offcanvas-padding-y * 0.5) ($offcanvas-padding-x * 0.5); 33 | margin-top: $offcanvas-padding-y * -0.5; 34 | margin-right: $offcanvas-padding-x * -0.5; 35 | margin-bottom: $offcanvas-padding-y * -0.5; 36 | } 37 | } 38 | 39 | .offcanvas-title { 40 | margin-bottom: 0; 41 | line-height: $offcanvas-title-line-height; 42 | } 43 | 44 | .offcanvas-body { 45 | flex-grow: 1; 46 | padding: $offcanvas-padding-y $offcanvas-padding-x; 47 | overflow-y: auto; 48 | } 49 | 50 | .offcanvas-start { 51 | top: 0; 52 | left: 0; 53 | width: $offcanvas-horizontal-width; 54 | border-right: $offcanvas-border-width solid $offcanvas-border-color; 55 | transform: translateX(-100%); 56 | } 57 | 58 | .offcanvas-end { 59 | top: 0; 60 | right: 0; 61 | width: $offcanvas-horizontal-width; 62 | border-left: $offcanvas-border-width solid $offcanvas-border-color; 63 | transform: translateX(100%); 64 | } 65 | 66 | .offcanvas-top { 67 | top: 0; 68 | right: 0; 69 | left: 0; 70 | height: $offcanvas-vertical-height; 71 | max-height: 100%; 72 | border-bottom: $offcanvas-border-width solid $offcanvas-border-color; 73 | transform: translateY(-100%); 74 | } 75 | 76 | .offcanvas-bottom { 77 | right: 0; 78 | left: 0; 79 | height: $offcanvas-vertical-height; 80 | max-height: 100%; 81 | border-top: $offcanvas-border-width solid $offcanvas-border-color; 82 | transform: translateY(100%); 83 | } 84 | 85 | .offcanvas.show { 86 | transform: none; 87 | } 88 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_pagination.scss: -------------------------------------------------------------------------------- 1 | .pagination { 2 | display: flex; 3 | @include list-unstyled(); 4 | } 5 | 6 | .page-link { 7 | position: relative; 8 | display: block; 9 | color: $pagination-color; 10 | text-decoration: if($link-decoration == none, null, none); 11 | background-color: $pagination-bg; 12 | border: $pagination-border-width solid $pagination-border-color; 13 | @include transition($pagination-transition); 14 | 15 | &:hover { 16 | z-index: 2; 17 | color: $pagination-hover-color; 18 | text-decoration: if($link-hover-decoration == underline, none, null); 19 | background-color: $pagination-hover-bg; 20 | border-color: $pagination-hover-border-color; 21 | } 22 | 23 | &:focus { 24 | z-index: 3; 25 | color: $pagination-focus-color; 26 | background-color: $pagination-focus-bg; 27 | outline: $pagination-focus-outline; 28 | box-shadow: $pagination-focus-box-shadow; 29 | } 30 | } 31 | 32 | .page-item { 33 | &:not(:first-child) .page-link { 34 | margin-left: $pagination-margin-start; 35 | } 36 | 37 | &.active .page-link { 38 | z-index: 3; 39 | color: $pagination-active-color; 40 | @include gradient-bg($pagination-active-bg); 41 | border-color: $pagination-active-border-color; 42 | } 43 | 44 | &.disabled .page-link { 45 | color: $pagination-disabled-color; 46 | pointer-events: none; 47 | background-color: $pagination-disabled-bg; 48 | border-color: $pagination-disabled-border-color; 49 | } 50 | } 51 | 52 | // 53 | // Sizing 54 | // 55 | @include pagination-size( 56 | $pagination-padding-y, 57 | $pagination-padding-x, 58 | null, 59 | $pagination-border-radius 60 | ); 61 | 62 | .pagination-lg { 63 | @include pagination-size( 64 | $pagination-padding-y-lg, 65 | $pagination-padding-x-lg, 66 | $font-size-lg, 67 | $pagination-border-radius-lg 68 | ); 69 | } 70 | 71 | .pagination-sm { 72 | @include pagination-size( 73 | $pagination-padding-y-sm, 74 | $pagination-padding-x-sm, 75 | $font-size-sm, 76 | $pagination-border-radius-sm 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_placeholders.scss: -------------------------------------------------------------------------------- 1 | .placeholder { 2 | display: inline-block; 3 | min-height: 1em; 4 | vertical-align: middle; 5 | cursor: wait; 6 | background-color: currentColor; 7 | opacity: $placeholder-opacity-max; 8 | 9 | &.btn::before { 10 | display: inline-block; 11 | content: ''; 12 | } 13 | } 14 | 15 | // Sizing 16 | .placeholder-xs { 17 | min-height: 0.6em; 18 | } 19 | 20 | .placeholder-sm { 21 | min-height: 0.8em; 22 | } 23 | 24 | .placeholder-lg { 25 | min-height: 1.2em; 26 | } 27 | 28 | // Animation 29 | .placeholder-glow { 30 | .placeholder { 31 | animation: placeholder-glow 2s ease-in-out infinite; 32 | } 33 | } 34 | 35 | @keyframes placeholder-glow { 36 | 50% { 37 | opacity: $placeholder-opacity-min; 38 | } 39 | } 40 | 41 | .placeholder-wave { 42 | mask-image: linear-gradient( 43 | 130deg, 44 | $black 55%, 45 | rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, 46 | $black 95% 47 | ); 48 | mask-size: 200% 100%; 49 | animation: placeholder-wave 2s linear infinite; 50 | } 51 | 52 | @keyframes placeholder-wave { 53 | 100% { 54 | mask-position: -200% 0%; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_progress.scss: -------------------------------------------------------------------------------- 1 | // Disable animation if transitions are disabled 2 | 3 | // scss-docs-start progress-keyframes 4 | @if $enable-transitions { 5 | @keyframes progress-bar-stripes { 6 | 0% { 7 | background-position-x: $progress-height; 8 | } 9 | } 10 | } 11 | // scss-docs-end progress-keyframes 12 | 13 | .progress { 14 | display: flex; 15 | height: $progress-height; 16 | overflow: hidden; // force rounded corners by cropping it 17 | @include font-size($progress-font-size); 18 | background-color: $progress-bg; 19 | @include border-radius($progress-border-radius); 20 | @include box-shadow($progress-box-shadow); 21 | } 22 | 23 | .progress-bar { 24 | display: flex; 25 | flex-direction: column; 26 | justify-content: center; 27 | overflow: hidden; 28 | color: $progress-bar-color; 29 | text-align: center; 30 | white-space: nowrap; 31 | background-color: $progress-bar-bg; 32 | @include transition($progress-bar-transition); 33 | } 34 | 35 | .progress-bar-striped { 36 | @include gradient-striped(); 37 | background-size: $progress-height $progress-height; 38 | } 39 | 40 | @if $enable-transitions { 41 | .progress-bar-animated { 42 | animation: $progress-bar-animation-timing progress-bar-stripes; 43 | 44 | @if $enable-reduced-motion { 45 | @media (prefers-reduced-motion: reduce) { 46 | animation: none; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | // Note: Custom variable values only support SassScript inside `#{}`. 3 | 4 | // Colors 5 | // 6 | // Generate palettes for full colors, grays, and theme colors. 7 | 8 | @each $color, $value in $colors { 9 | --#{$variable-prefix}#{$color}: #{$value}; 10 | } 11 | 12 | @each $color, $value in $grays { 13 | --#{$variable-prefix}gray-#{$color}: #{$value}; 14 | } 15 | 16 | @each $color, $value in $theme-colors { 17 | --#{$variable-prefix}#{$color}: #{$value}; 18 | } 19 | 20 | @each $color, $value in $theme-colors-rgb { 21 | --#{$variable-prefix}#{$color}-rgb: #{$value}; 22 | } 23 | 24 | --#{$variable-prefix}white-rgb: #{to-rgb($white)}; 25 | --#{$variable-prefix}black-rgb: #{to-rgb($black)}; 26 | --#{$variable-prefix}body-color-rgb: #{to-rgb($body-color)}; 27 | --#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)}; 28 | 29 | // Fonts 30 | 31 | // Note: Use `inspect` for lists so that quoted items keep the quotes. 32 | // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 33 | --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)}; 34 | --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)}; 35 | --#{$variable-prefix}gradient: #{$gradient}; 36 | 37 | // Root and body 38 | // stylelint-disable custom-property-empty-line-before 39 | // scss-docs-start root-body-variables 40 | @if $font-size-root != null { 41 | --#{$variable-prefix}root-font-size: #{$font-size-root}; 42 | } 43 | --#{$variable-prefix}body-font-family: #{$font-family-base}; 44 | --#{$variable-prefix}body-font-size: #{$font-size-base}; 45 | --#{$variable-prefix}body-font-weight: #{$font-weight-base}; 46 | --#{$variable-prefix}body-line-height: #{$line-height-base}; 47 | --#{$variable-prefix}body-color: #{$body-color}; 48 | @if $body-text-align != null { 49 | --#{$variable-prefix}body-text-align: #{$body-text-align}; 50 | } 51 | --#{$variable-prefix}body-bg: #{$body-bg}; 52 | // scss-docs-end root-body-variables 53 | // stylelint-enable custom-property-empty-line-before 54 | } 55 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_spinners.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Rotating border 3 | // 4 | 5 | // scss-docs-start spinner-border-keyframes 6 | @keyframes spinner-border { 7 | /*!rtl:ignore*/ 8 | to { 9 | transform: rotate(360deg); 10 | } 11 | } 12 | 13 | // scss-docs-end spinner-border-keyframes 14 | 15 | .spinner-border { 16 | display: inline-block; 17 | width: $spinner-width; 18 | height: $spinner-height; 19 | vertical-align: $spinner-vertical-align; 20 | border: $spinner-border-width solid currentColor; 21 | border-right-color: transparent; 22 | // stylelint-disable-next-line property-disallowed-list 23 | border-radius: 50%; 24 | animation: $spinner-animation-speed linear infinite spinner-border; 25 | } 26 | 27 | .spinner-border-sm { 28 | width: $spinner-width-sm; 29 | height: $spinner-height-sm; 30 | border-width: $spinner-border-width-sm; 31 | } 32 | 33 | // 34 | // Growing circle 35 | // 36 | 37 | // scss-docs-start spinner-grow-keyframes 38 | @keyframes spinner-grow { 39 | 0% { 40 | transform: scale(0); 41 | } 42 | 43 | 50% { 44 | opacity: 1; 45 | transform: none; 46 | } 47 | } 48 | 49 | // scss-docs-end spinner-grow-keyframes 50 | 51 | .spinner-grow { 52 | display: inline-block; 53 | width: $spinner-width; 54 | height: $spinner-height; 55 | vertical-align: $spinner-vertical-align; 56 | background-color: currentColor; 57 | // stylelint-disable-next-line property-disallowed-list 58 | border-radius: 50%; 59 | opacity: 0; 60 | animation: $spinner-animation-speed linear infinite spinner-grow; 61 | } 62 | 63 | .spinner-grow-sm { 64 | width: $spinner-width-sm; 65 | height: $spinner-height-sm; 66 | } 67 | 68 | @if $enable-reduced-motion { 69 | @media (prefers-reduced-motion: reduce) { 70 | .spinner-border, 71 | .spinner-grow { 72 | animation-duration: $spinner-animation-speed * 2; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_toasts.scss: -------------------------------------------------------------------------------- 1 | .toast { 2 | width: $toast-max-width; 3 | max-width: 100%; 4 | @include font-size($toast-font-size); 5 | color: $toast-color; 6 | pointer-events: auto; 7 | background-color: $toast-background-color; 8 | background-clip: padding-box; 9 | border: $toast-border-width solid $toast-border-color; 10 | box-shadow: $toast-box-shadow; 11 | @include border-radius($toast-border-radius); 12 | 13 | &.showing { 14 | opacity: 0; 15 | } 16 | 17 | &:not(.show) { 18 | display: none; 19 | } 20 | } 21 | 22 | .toast-container { 23 | width: max-content; 24 | max-width: 100%; 25 | pointer-events: none; 26 | 27 | > :not(:last-child) { 28 | margin-bottom: $toast-spacing; 29 | } 30 | } 31 | 32 | .toast-header { 33 | display: flex; 34 | align-items: center; 35 | padding: $toast-padding-y $toast-padding-x; 36 | color: $toast-header-color; 37 | background-color: $toast-header-background-color; 38 | background-clip: padding-box; 39 | border-bottom: $toast-border-width solid $toast-header-border-color; 40 | @include border-top-radius(subtract($toast-border-radius, $toast-border-width)); 41 | 42 | .btn-close { 43 | margin-right: $toast-padding-x * -0.5; 44 | margin-left: $toast-padding-x; 45 | } 46 | } 47 | 48 | .toast-body { 49 | padding: $toast-padding-x; // apply to both vertical and horizontal 50 | word-wrap: break-word; 51 | } 52 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_transitions.scss: -------------------------------------------------------------------------------- 1 | .fade { 2 | @include transition($transition-fade); 3 | 4 | &:not(.show) { 5 | opacity: 0; 6 | } 7 | } 8 | 9 | // scss-docs-start collapse-classes 10 | .collapse { 11 | &:not(.show) { 12 | display: none; 13 | } 14 | } 15 | 16 | .collapsing { 17 | height: 0; 18 | overflow: hidden; 19 | @include transition($transition-collapse); 20 | 21 | &.collapse-horizontal { 22 | width: 0; 23 | height: auto; 24 | @include transition($transition-collapse-width); 25 | } 26 | } 27 | // scss-docs-end collapse-classes 28 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/_type.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Headings 3 | // 4 | .h1 { 5 | @extend h1; 6 | } 7 | 8 | .h2 { 9 | @extend h2; 10 | } 11 | 12 | .h3 { 13 | @extend h3; 14 | } 15 | 16 | .h4 { 17 | @extend h4; 18 | } 19 | 20 | .h5 { 21 | @extend h5; 22 | } 23 | 24 | .h6 { 25 | @extend h6; 26 | } 27 | 28 | .lead { 29 | @include font-size($lead-font-size); 30 | font-weight: $lead-font-weight; 31 | } 32 | 33 | // Type display classes 34 | @each $display, $font-size in $display-font-sizes { 35 | .display-#{$display} { 36 | @include font-size($font-size); 37 | font-weight: $display-font-weight; 38 | line-height: $display-line-height; 39 | } 40 | } 41 | 42 | // 43 | // Emphasis 44 | // 45 | .small { 46 | @extend small; 47 | } 48 | 49 | .mark { 50 | @extend mark; 51 | } 52 | 53 | // 54 | // Lists 55 | // 56 | 57 | .list-unstyled { 58 | @include list-unstyled(); 59 | } 60 | 61 | // Inline turns list items into inline-block 62 | .list-inline { 63 | @include list-unstyled(); 64 | } 65 | .list-inline-item { 66 | display: inline-block; 67 | 68 | &:not(:last-child) { 69 | margin-right: $list-inline-padding; 70 | } 71 | } 72 | 73 | // 74 | // Misc 75 | // 76 | 77 | // Builds on `abbr` 78 | .initialism { 79 | @include font-size($initialism-font-size); 80 | text-transform: uppercase; 81 | } 82 | 83 | // Blockquotes 84 | .blockquote { 85 | margin-bottom: $blockquote-margin-y; 86 | @include font-size($blockquote-font-size); 87 | 88 | > :last-child { 89 | margin-bottom: 0; 90 | } 91 | } 92 | 93 | .blockquote-footer { 94 | margin-top: -$blockquote-margin-y; 95 | margin-bottom: $blockquote-margin-y; 96 | @include font-size($blockquote-footer-font-size); 97 | color: $blockquote-footer-color; 98 | 99 | &::before { 100 | content: '\2014\00A0'; // em dash, nbsp 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/bootstrap-grid.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | 8 | $include-column-box-sizing: true !default; 9 | 10 | @import 'functions'; 11 | @import 'variables'; 12 | 13 | @import 'mixins/lists'; 14 | @import 'mixins/breakpoints'; 15 | @import 'mixins/container'; 16 | @import 'mixins/grid'; 17 | @import 'mixins/utilities'; 18 | 19 | @import 'vendor/rfs'; 20 | 21 | @import 'root'; 22 | 23 | @import 'containers'; 24 | @import 'grid'; 25 | 26 | @import 'utilities'; 27 | // Only use the utilities we need 28 | // stylelint-disable-next-line scss/dollar-variable-default 29 | $utilities: map-get-multiple( 30 | $utilities, 31 | ( 32 | 'display', 33 | 'order', 34 | 'flex', 35 | 'flex-direction', 36 | 'flex-grow', 37 | 'flex-shrink', 38 | 'flex-wrap', 39 | 'justify-content', 40 | 'align-items', 41 | 'align-content', 42 | 'align-self', 43 | 'margin', 44 | 'margin-x', 45 | 'margin-y', 46 | 'margin-top', 47 | 'margin-end', 48 | 'margin-bottom', 49 | 'margin-start', 50 | 'negative-margin', 51 | 'negative-margin-x', 52 | 'negative-margin-y', 53 | 'negative-margin-top', 54 | 'negative-margin-end', 55 | 'negative-margin-bottom', 56 | 'negative-margin-start', 57 | 'padding', 58 | 'padding-x', 59 | 'padding-y', 60 | 'padding-top', 61 | 'padding-end', 62 | 'padding-bottom', 63 | 'padding-start' 64 | ) 65 | ); 66 | 67 | @import 'utilities/api'; 68 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/bootstrap-reboot.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */ 8 | 9 | @import 'functions'; 10 | @import 'variables'; 11 | @import 'mixins'; 12 | @import 'root'; 13 | @import 'reboot'; 14 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/bootstrap-utilities.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Utilities v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | 8 | // Configuration 9 | @import 'functions'; 10 | @import 'variables'; 11 | @import 'mixins'; 12 | @import 'utilities'; 13 | 14 | // Helpers 15 | @import 'helpers'; 16 | 17 | // Utilities 18 | @import 'utilities/api'; 19 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/bootstrap.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | 8 | // scss-docs-start import-stack 9 | // Configuration 10 | @import 'functions'; 11 | @import 'variables'; 12 | @import 'mixins'; 13 | @import 'utilities'; 14 | 15 | // Layout & components 16 | @import 'root'; 17 | @import 'reboot'; 18 | @import 'type'; 19 | @import 'images'; 20 | @import 'containers'; 21 | @import 'grid'; 22 | @import 'tables'; 23 | @import 'forms'; 24 | @import 'buttons'; 25 | @import 'transitions'; 26 | @import 'dropdown'; 27 | @import 'button-group'; 28 | @import 'nav'; 29 | @import 'navbar'; 30 | @import 'card'; 31 | @import 'accordion'; 32 | @import 'breadcrumb'; 33 | @import 'pagination'; 34 | @import 'badge'; 35 | @import 'alert'; 36 | @import 'progress'; 37 | @import 'list-group'; 38 | @import 'close'; 39 | @import 'toasts'; 40 | @import 'modal'; 41 | @import 'tooltip'; 42 | @import 'popover'; 43 | @import 'carousel'; 44 | @import 'spinners'; 45 | @import 'offcanvas'; 46 | @import 'placeholders'; 47 | 48 | // Helpers 49 | @import 'helpers'; 50 | 51 | // Utilities 52 | @import 'utilities/api'; 53 | // scss-docs-end import-stack 54 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/forms/_floating-labels.scss: -------------------------------------------------------------------------------- 1 | .form-floating { 2 | position: relative; 3 | 4 | > .form-control, 5 | > .form-select { 6 | height: $form-floating-height; 7 | line-height: $form-floating-line-height; 8 | } 9 | 10 | > label { 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | height: 100%; // allow textareas 15 | padding: $form-floating-padding-y $form-floating-padding-x; 16 | pointer-events: none; 17 | border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model 18 | transform-origin: 0 0; 19 | @include transition($form-floating-transition); 20 | } 21 | 22 | // stylelint-disable no-duplicate-selectors 23 | > .form-control { 24 | padding: $form-floating-padding-y $form-floating-padding-x; 25 | 26 | &::placeholder { 27 | color: transparent; 28 | } 29 | 30 | &:focus, 31 | &:not(:placeholder-shown) { 32 | padding-top: $form-floating-input-padding-t; 33 | padding-bottom: $form-floating-input-padding-b; 34 | } 35 | // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped 36 | &:-webkit-autofill { 37 | padding-top: $form-floating-input-padding-t; 38 | padding-bottom: $form-floating-input-padding-b; 39 | } 40 | } 41 | 42 | > .form-select { 43 | padding-top: $form-floating-input-padding-t; 44 | padding-bottom: $form-floating-input-padding-b; 45 | } 46 | 47 | > .form-control:focus, 48 | > .form-control:not(:placeholder-shown), 49 | > .form-select { 50 | ~ label { 51 | opacity: $form-floating-label-opacity; 52 | transform: $form-floating-label-transform; 53 | } 54 | } 55 | // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped 56 | > .form-control:-webkit-autofill { 57 | ~ label { 58 | opacity: $form-floating-label-opacity; 59 | transform: $form-floating-label-transform; 60 | } 61 | } 62 | // stylelint-enable no-duplicate-selectors 63 | } 64 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/forms/_form-select.scss: -------------------------------------------------------------------------------- 1 | // Select 2 | // 3 | // Replaces the browser default select with a custom one, mostly pulled from 4 | // https://primer.github.io/. 5 | 6 | .form-select { 7 | display: block; 8 | width: 100%; 9 | padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y 10 | $form-select-padding-x; 11 | // stylelint-disable-next-line property-no-vendor-prefix 12 | -moz-padding-start: subtract( 13 | $form-select-padding-x, 14 | 3px 15 | ); // See https://github.com/twbs/bootstrap/issues/32636 16 | font-family: $form-select-font-family; 17 | @include font-size($form-select-font-size); 18 | font-weight: $form-select-font-weight; 19 | line-height: $form-select-line-height; 20 | color: $form-select-color; 21 | background-color: $form-select-bg; 22 | background-image: escape-svg($form-select-indicator); 23 | background-repeat: no-repeat; 24 | background-position: $form-select-bg-position; 25 | background-size: $form-select-bg-size; 26 | border: $form-select-border-width solid $form-select-border-color; 27 | @include border-radius($form-select-border-radius, 0); 28 | @include box-shadow($form-select-box-shadow); 29 | @include transition($form-select-transition); 30 | appearance: none; 31 | 32 | &:focus { 33 | border-color: $form-select-focus-border-color; 34 | outline: 0; 35 | @if $enable-shadows { 36 | @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow); 37 | } @else { 38 | // Avoid using mixin so we can pass custom focus shadow properly 39 | box-shadow: $form-select-focus-box-shadow; 40 | } 41 | } 42 | 43 | &[multiple], 44 | &[size]:not([size='1']) { 45 | padding-right: $form-select-padding-x; 46 | background-image: none; 47 | } 48 | 49 | &:disabled { 50 | color: $form-select-disabled-color; 51 | background-color: $form-select-disabled-bg; 52 | border-color: $form-select-disabled-border-color; 53 | } 54 | 55 | // Remove outline from select box in FF 56 | &:-moz-focusring { 57 | color: transparent; 58 | text-shadow: 0 0 0 $form-select-color; 59 | } 60 | } 61 | 62 | .form-select-sm { 63 | padding-top: $form-select-padding-y-sm; 64 | padding-bottom: $form-select-padding-y-sm; 65 | padding-left: $form-select-padding-x-sm; 66 | @include font-size($form-select-font-size-sm); 67 | @include border-radius($form-select-border-radius-sm); 68 | } 69 | 70 | .form-select-lg { 71 | padding-top: $form-select-padding-y-lg; 72 | padding-bottom: $form-select-padding-y-lg; 73 | padding-left: $form-select-padding-x-lg; 74 | @include font-size($form-select-font-size-lg); 75 | @include border-radius($form-select-border-radius-lg); 76 | } 77 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/forms/_form-text.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Form text 3 | // 4 | 5 | .form-text { 6 | margin-top: $form-text-margin-top; 7 | @include font-size($form-text-font-size); 8 | font-style: $form-text-font-style; 9 | font-weight: $form-text-font-weight; 10 | color: $form-text-color; 11 | } 12 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/forms/_labels.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // 4 | 5 | .form-label { 6 | margin-bottom: $form-label-margin-bottom; 7 | @include font-size($form-label-font-size); 8 | font-style: $form-label-font-style; 9 | font-weight: $form-label-font-weight; 10 | color: $form-label-color; 11 | } 12 | 13 | // For use with horizontal and inline forms, when you need the label (or legend) 14 | // text to align with the form controls. 15 | .col-form-label { 16 | padding-top: add($input-padding-y, $input-border-width); 17 | padding-bottom: add($input-padding-y, $input-border-width); 18 | margin-bottom: 0; // Override the `` default 19 | @include font-size(inherit); // Override the `` default 20 | font-style: $form-label-font-style; 21 | font-weight: $form-label-font-weight; 22 | line-height: $input-line-height; 23 | color: $form-label-color; 24 | } 25 | 26 | .col-form-label-lg { 27 | padding-top: add($input-padding-y-lg, $input-border-width); 28 | padding-bottom: add($input-padding-y-lg, $input-border-width); 29 | @include font-size($input-font-size-lg); 30 | } 31 | 32 | .col-form-label-sm { 33 | padding-top: add($input-padding-y-sm, $input-border-width); 34 | padding-bottom: add($input-padding-y-sm, $input-border-width); 35 | @include font-size($input-font-size-sm); 36 | } 37 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/forms/_validation.scss: -------------------------------------------------------------------------------- 1 | // Form validation 2 | // 3 | // Provide feedback to users when form field values are valid or invalid. Works 4 | // primarily for client-side validation via scoped `:invalid` and `:valid` 5 | // pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for 6 | // server-side validation. 7 | 8 | // scss-docs-start form-validation-states-loop 9 | @each $state, $data in $form-validation-states { 10 | @include form-validation-state($state, $data...); 11 | } 12 | // scss-docs-end form-validation-states-loop 13 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_colored-links.scss: -------------------------------------------------------------------------------- 1 | @each $color, $value in $theme-colors { 2 | .link-#{$color} { 3 | color: $value; 4 | 5 | @if $link-shade-percentage != 0 { 6 | &:hover, 7 | &:focus { 8 | color: if( 9 | color-contrast($value) == $color-contrast-light, 10 | shade-color($value, $link-shade-percentage), 11 | tint-color($value, $link-shade-percentage) 12 | ); 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_position.scss: -------------------------------------------------------------------------------- 1 | // Shorthand 2 | 3 | .fixed-top { 4 | position: fixed; 5 | top: 0; 6 | right: 0; 7 | left: 0; 8 | z-index: $zindex-fixed; 9 | } 10 | 11 | .fixed-bottom { 12 | position: fixed; 13 | right: 0; 14 | bottom: 0; 15 | left: 0; 16 | z-index: $zindex-fixed; 17 | } 18 | 19 | // Responsive sticky top 20 | @each $breakpoint in map-keys($grid-breakpoints) { 21 | @include media-breakpoint-up($breakpoint) { 22 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 23 | 24 | .sticky#{$infix}-top { 25 | position: sticky; 26 | top: 0; 27 | z-index: $zindex-sticky; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_ratio.scss: -------------------------------------------------------------------------------- 1 | // Credit: Nicolas Gallagher and SUIT CSS. 2 | 3 | .ratio { 4 | position: relative; 5 | width: 100%; 6 | 7 | &::before { 8 | display: block; 9 | padding-top: var(--#{$variable-prefix}aspect-ratio); 10 | content: ''; 11 | } 12 | 13 | > * { 14 | position: absolute; 15 | top: 0; 16 | left: 0; 17 | width: 100%; 18 | height: 100%; 19 | } 20 | } 21 | 22 | @each $key, $ratio in $aspect-ratios { 23 | .ratio-#{$key} { 24 | --#{$variable-prefix}aspect-ratio: #{$ratio}; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_stacks.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start stacks 2 | .hstack { 3 | display: flex; 4 | flex-direction: row; 5 | align-items: center; 6 | align-self: stretch; 7 | } 8 | 9 | .vstack { 10 | display: flex; 11 | flex: 1 1 auto; 12 | flex-direction: column; 13 | align-self: stretch; 14 | } 15 | // scss-docs-end stacks 16 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_stretched-link.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Stretched link 3 | // 4 | 5 | .stretched-link { 6 | &::#{$stretched-link-pseudo-element} { 7 | position: absolute; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: $stretched-link-z-index; 13 | content: ''; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_text-truncation.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Text truncation 3 | // 4 | 5 | .text-truncate { 6 | @include text-truncate(); 7 | } 8 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Visually hidden 3 | // 4 | 5 | .visually-hidden, 6 | .visually-hidden-focusable:not(:focus):not(:focus-within) { 7 | @include visually-hidden(); 8 | } 9 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/helpers/_vr.scss: -------------------------------------------------------------------------------- 1 | .vr { 2 | display: inline-block; 3 | align-self: stretch; 4 | width: 1px; 5 | min-height: 1em; 6 | background-color: currentColor; 7 | opacity: $hr-opacity; 8 | } 9 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start alert-variant-mixin 2 | @mixin alert-variant($background, $border, $color) { 3 | color: $color; 4 | @include gradient-bg($background); 5 | border-color: $border; 6 | 7 | .alert-link { 8 | color: shade-color($color, 20%); 9 | } 10 | } 11 | // scss-docs-end alert-variant-mixin 12 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_backdrop.scss: -------------------------------------------------------------------------------- 1 | // Shared between modals and offcanvases 2 | @mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) { 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | z-index: $zindex; 7 | width: 100vw; 8 | height: 100vh; 9 | background-color: $backdrop-bg; 10 | 11 | // Fade for backdrop 12 | &.fade { 13 | opacity: 0; 14 | } 15 | &.show { 16 | opacity: $backdrop-opacity; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_border-radius.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-disallowed-list 2 | // Single side border-radius 3 | 4 | // Helper function to replace negative values with 0 5 | @function valid-radius($radius) { 6 | $return: (); 7 | @each $value in $radius { 8 | @if type-of($value) == number { 9 | $return: append($return, max($value, 0)); 10 | } @else { 11 | $return: append($return, $value); 12 | } 13 | } 14 | @return $return; 15 | } 16 | 17 | // scss-docs-start border-radius-mixins 18 | @mixin border-radius($radius: $border-radius, $fallback-border-radius: false) { 19 | @if $enable-rounded { 20 | border-radius: valid-radius($radius); 21 | } @else if $fallback-border-radius != false { 22 | border-radius: $fallback-border-radius; 23 | } 24 | } 25 | 26 | @mixin border-top-radius($radius: $border-radius) { 27 | @if $enable-rounded { 28 | border-top-left-radius: valid-radius($radius); 29 | border-top-right-radius: valid-radius($radius); 30 | } 31 | } 32 | 33 | @mixin border-end-radius($radius: $border-radius) { 34 | @if $enable-rounded { 35 | border-top-right-radius: valid-radius($radius); 36 | border-bottom-right-radius: valid-radius($radius); 37 | } 38 | } 39 | 40 | @mixin border-bottom-radius($radius: $border-radius) { 41 | @if $enable-rounded { 42 | border-bottom-right-radius: valid-radius($radius); 43 | border-bottom-left-radius: valid-radius($radius); 44 | } 45 | } 46 | 47 | @mixin border-start-radius($radius: $border-radius) { 48 | @if $enable-rounded { 49 | border-top-left-radius: valid-radius($radius); 50 | border-bottom-left-radius: valid-radius($radius); 51 | } 52 | } 53 | 54 | @mixin border-top-start-radius($radius: $border-radius) { 55 | @if $enable-rounded { 56 | border-top-left-radius: valid-radius($radius); 57 | } 58 | } 59 | 60 | @mixin border-top-end-radius($radius: $border-radius) { 61 | @if $enable-rounded { 62 | border-top-right-radius: valid-radius($radius); 63 | } 64 | } 65 | 66 | @mixin border-bottom-end-radius($radius: $border-radius) { 67 | @if $enable-rounded { 68 | border-bottom-right-radius: valid-radius($radius); 69 | } 70 | } 71 | 72 | @mixin border-bottom-start-radius($radius: $border-radius) { 73 | @if $enable-rounded { 74 | border-bottom-left-radius: valid-radius($radius); 75 | } 76 | } 77 | // scss-docs-end border-radius-mixins 78 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow($shadow...) { 2 | @if $enable-shadows { 3 | $result: (); 4 | 5 | @each $value in $shadow { 6 | @if $value != null { 7 | $result: append($result, $value, 'comma'); 8 | } 9 | @if $value == none and length($shadow) > 1 { 10 | @warn "The keyword 'none' must be used as a single argument."; 11 | } 12 | } 13 | 14 | @if (length($result) > 0) { 15 | box-shadow: $result; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_caret.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start caret-mixins 2 | @mixin caret-down { 3 | border-top: $caret-width solid; 4 | border-right: $caret-width solid transparent; 5 | border-bottom: 0; 6 | border-left: $caret-width solid transparent; 7 | } 8 | 9 | @mixin caret-up { 10 | border-top: 0; 11 | border-right: $caret-width solid transparent; 12 | border-bottom: $caret-width solid; 13 | border-left: $caret-width solid transparent; 14 | } 15 | 16 | @mixin caret-end { 17 | border-top: $caret-width solid transparent; 18 | border-right: 0; 19 | border-bottom: $caret-width solid transparent; 20 | border-left: $caret-width solid; 21 | } 22 | 23 | @mixin caret-start { 24 | border-top: $caret-width solid transparent; 25 | border-right: $caret-width solid; 26 | border-bottom: $caret-width solid transparent; 27 | } 28 | 29 | @mixin caret($direction: down) { 30 | @if $enable-caret { 31 | &::after { 32 | display: inline-block; 33 | margin-left: $caret-spacing; 34 | vertical-align: $caret-vertical-align; 35 | content: ''; 36 | @if $direction == down { 37 | @include caret-down(); 38 | } @else if $direction == up { 39 | @include caret-up(); 40 | } @else if $direction == end { 41 | @include caret-end(); 42 | } 43 | } 44 | 45 | @if $direction == start { 46 | &::after { 47 | display: none; 48 | } 49 | 50 | &::before { 51 | display: inline-block; 52 | margin-right: $caret-spacing; 53 | vertical-align: $caret-vertical-align; 54 | content: ''; 55 | @include caret-start(); 56 | } 57 | } 58 | 59 | &:empty::after { 60 | margin-left: 0; 61 | } 62 | } 63 | } 64 | // scss-docs-end caret-mixins 65 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start clearfix 2 | @mixin clearfix() { 3 | &::after { 4 | display: block; 5 | clear: both; 6 | content: ''; 7 | } 8 | } 9 | // scss-docs-end clearfix 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_color-scheme.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start mixin-color-scheme 2 | @mixin color-scheme($name) { 3 | @media (prefers-color-scheme: #{$name}) { 4 | @content; 5 | } 6 | } 7 | // scss-docs-end mixin-color-scheme 8 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_container.scss: -------------------------------------------------------------------------------- 1 | // Container mixins 2 | 3 | @mixin make-container($gutter: $container-padding-x) { 4 | width: 100%; 5 | padding-right: var(--#{$variable-prefix}gutter-x, #{$gutter}); 6 | padding-left: var(--#{$variable-prefix}gutter-x, #{$gutter}); 7 | margin-right: auto; 8 | margin-left: auto; 9 | } 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_deprecate.scss: -------------------------------------------------------------------------------- 1 | // Deprecate mixin 2 | // 3 | // This mixin can be used to deprecate mixins or functions. 4 | // `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to 5 | // some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap) 6 | @mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) { 7 | @if ($enable-deprecation-messages != false and $ignore-warning != true) { 8 | @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}."; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_gradients.scss: -------------------------------------------------------------------------------- 1 | // Gradients 2 | 3 | // scss-docs-start gradient-bg-mixin 4 | @mixin gradient-bg($color: null) { 5 | background-color: $color; 6 | 7 | @if $enable-gradients { 8 | background-image: var(--#{$variable-prefix}gradient); 9 | } 10 | } 11 | // scss-docs-end gradient-bg-mixin 12 | 13 | // scss-docs-start gradient-mixins 14 | // Horizontal gradient, from left to right 15 | // 16 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 17 | @mixin gradient-x( 18 | $start-color: $gray-700, 19 | $end-color: $gray-800, 20 | $start-percent: 0%, 21 | $end-percent: 100% 22 | ) { 23 | background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); 24 | } 25 | 26 | // Vertical gradient, from top to bottom 27 | // 28 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 29 | @mixin gradient-y( 30 | $start-color: $gray-700, 31 | $end-color: $gray-800, 32 | $start-percent: null, 33 | $end-percent: null 34 | ) { 35 | background-image: linear-gradient( 36 | to bottom, 37 | $start-color $start-percent, 38 | $end-color $end-percent 39 | ); 40 | } 41 | 42 | @mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) { 43 | background-image: linear-gradient($deg, $start-color, $end-color); 44 | } 45 | 46 | @mixin gradient-x-three-colors( 47 | $start-color: $blue, 48 | $mid-color: $purple, 49 | $color-stop: 50%, 50 | $end-color: $red 51 | ) { 52 | background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); 53 | } 54 | 55 | @mixin gradient-y-three-colors( 56 | $start-color: $blue, 57 | $mid-color: $purple, 58 | $color-stop: 50%, 59 | $end-color: $red 60 | ) { 61 | background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); 62 | } 63 | 64 | @mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) { 65 | background-image: radial-gradient(circle, $inner-color, $outer-color); 66 | } 67 | 68 | @mixin gradient-striped($color: rgba($white, 0.15), $angle: 45deg) { 69 | background-image: linear-gradient( 70 | $angle, 71 | $color 25%, 72 | transparent 25%, 73 | transparent 50%, 74 | $color 50%, 75 | $color 75%, 76 | transparent 75%, 77 | transparent 78 | ); 79 | } 80 | // scss-docs-end gradient-mixins 81 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | // Responsive image 6 | // 7 | // Keep images from scaling beyond the width of their parents. 8 | 9 | @mixin img-fluid { 10 | // Part 1: Set a maximum relative to the parent 11 | max-width: 100%; 12 | // Part 2: Override the height to auto, otherwise images will be stretched 13 | // when setting a width and height attribute on the img element. 14 | height: auto; 15 | } 16 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | // scss-docs-start list-group-mixin 4 | @mixin list-group-item-variant($state, $background, $color) { 5 | .list-group-item-#{$state} { 6 | color: $color; 7 | background-color: $background; 8 | 9 | &.list-group-item-action { 10 | &:hover, 11 | &:focus { 12 | color: $color; 13 | background-color: shade-color($background, 10%); 14 | } 15 | 16 | &.active { 17 | color: $white; 18 | background-color: $color; 19 | border-color: $color; 20 | } 21 | } 22 | } 23 | } 24 | // scss-docs-end list-group-mixin 25 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_lists.scss: -------------------------------------------------------------------------------- 1 | // Lists 2 | 3 | // Unstyled keeps list items block level, just removes default browser padding and list-style 4 | @mixin list-unstyled { 5 | padding-left: 0; 6 | list-style: none; 7 | } 8 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | // scss-docs-start pagination-mixin 4 | @mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { 5 | .page-link { 6 | padding: $padding-y $padding-x; 7 | @include font-size($font-size); 8 | } 9 | 10 | .page-item { 11 | @if $pagination-margin-start == (-$pagination-border-width) { 12 | &:first-child { 13 | .page-link { 14 | @include border-start-radius($border-radius); 15 | } 16 | } 17 | 18 | &:last-child { 19 | .page-link { 20 | @include border-end-radius($border-radius); 21 | } 22 | } 23 | } @else { 24 | //Add border-radius to all pageLinks in case they have left margin 25 | .page-link { 26 | @include border-radius($border-radius); 27 | } 28 | } 29 | } 30 | } 31 | // scss-docs-end pagination-mixin 32 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size or overflow-wrap / word-wrap. 4 | font-style: normal; 5 | font-weight: $font-weight-normal; 6 | line-height: $line-height-base; 7 | text-align: left; // Fallback for where `start` is not supported 8 | text-align: start; 9 | text-decoration: none; 10 | text-shadow: none; 11 | text-transform: none; 12 | letter-spacing: normal; 13 | word-break: normal; 14 | word-spacing: normal; 15 | white-space: normal; 16 | line-break: auto; 17 | } 18 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 5 | resize: $direction; // Options: horizontal, vertical, both 6 | } 7 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_table-variants.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start table-variant 2 | @mixin table-variant($state, $background) { 3 | .table-#{$state} { 4 | $color: color-contrast(opaque($body-bg, $background)); 5 | $hover-bg: mix($color, $background, percentage($table-hover-bg-factor)); 6 | $striped-bg: mix($color, $background, percentage($table-striped-bg-factor)); 7 | $active-bg: mix($color, $background, percentage($table-active-bg-factor)); 8 | 9 | --#{$variable-prefix}table-bg: #{$background}; 10 | --#{$variable-prefix}table-striped-bg: #{$striped-bg}; 11 | --#{$variable-prefix}table-striped-color: #{color-contrast($striped-bg)}; 12 | --#{$variable-prefix}table-active-bg: #{$active-bg}; 13 | --#{$variable-prefix}table-active-color: #{color-contrast($active-bg)}; 14 | --#{$variable-prefix}table-hover-bg: #{$hover-bg}; 15 | --#{$variable-prefix}table-hover-color: #{color-contrast($hover-bg)}; 16 | 17 | color: $color; 18 | border-color: mix($color, $background, percentage($table-border-factor)); 19 | } 20 | } 21 | // scss-docs-end table-variant 22 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_text-truncate.scss: -------------------------------------------------------------------------------- 1 | // Text truncate 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-truncate() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_transition.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-disallowed-list 2 | @mixin transition($transition...) { 3 | @if length($transition) == 0 { 4 | $transition: $transition-base; 5 | } 6 | 7 | @if length($transition) > 1 { 8 | @each $value in $transition { 9 | @if $value == null or $value == none { 10 | @warn "The keyword 'none' or 'null' must be used as a single argument."; 11 | } 12 | } 13 | } 14 | 15 | @if $enable-transitions { 16 | @if nth($transition, 1) != null { 17 | transition: $transition; 18 | } 19 | 20 | @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none { 21 | @media (prefers-reduced-motion: reduce) { 22 | transition: none; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/mixins/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Hide content visually while keeping it accessible to assistive technologies 4 | // 5 | // See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/ 6 | // See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/ 7 | 8 | @mixin visually-hidden() { 9 | position: absolute !important; 10 | width: 1px !important; 11 | height: 1px !important; 12 | padding: 0 !important; 13 | margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686 14 | overflow: hidden !important; 15 | clip: rect(0, 0, 0, 0) !important; 16 | white-space: nowrap !important; 17 | border: 0 !important; 18 | } 19 | 20 | // Use to only display content when it's focused, or one of its child elements is focused 21 | // (i.e. when focus is within the element/container that the class was applied to) 22 | // 23 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 24 | 25 | @mixin visually-hidden-focusable() { 26 | &:not(:focus):not(:focus-within) { 27 | @include visually-hidden(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/scss/bootstrap-rtl-fix/utilities/_api.scss: -------------------------------------------------------------------------------- 1 | // Loop over each breakpoint 2 | @each $breakpoint in map-keys($grid-breakpoints) { 3 | // Generate media query if needed 4 | @include media-breakpoint-up($breakpoint) { 5 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 6 | 7 | // Loop over each utility property 8 | @each $key, $utility in $utilities { 9 | // The utility can be disabled with `false`, thus check if the utility is a map first 10 | // Only proceed if responsive media queries are enabled or if it's the base media query 11 | @if type-of($utility) == 'map' and (map-get($utility, responsive) or $infix == '') { 12 | @include generate-utility($utility, $infix); 13 | } 14 | } 15 | } 16 | } 17 | 18 | // RFS rescaling 19 | @media (min-width: $rfs-mq-value) { 20 | @each $breakpoint in map-keys($grid-breakpoints) { 21 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 22 | 23 | @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) { 24 | // Loop over each utility property 25 | @each $key, $utility in $utilities { 26 | // The utility can be disabled with `false`, thus check if the utility is a map first 27 | // Only proceed if responsive media queries are enabled or if it's the base media query 28 | @if type-of($utility) == 29 | 'map' and 30 | map-get($utility, rfs) and 31 | (map-get($utility, responsive) or $infix == '') 32 | { 33 | @include generate-utility($utility, $infix, true); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | // Print utilities 41 | @media print { 42 | @each $key, $utility in $utilities { 43 | // The utility can be disabled with `false`, thus check if the utility is a map first 44 | // Then check if the utility needs print styles 45 | @if type-of($utility) == 'map' and map-get($utility, print) == true { 46 | @include generate-utility($utility, '-print'); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_alert.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .alert { 6 | position: relative; 7 | padding: $alert-padding-y $alert-padding-x; 8 | margin-bottom: $alert-margin-bottom; 9 | border: $alert-border-width solid transparent; 10 | @include border-radius($alert-border-radius); 11 | } 12 | 13 | // Headings for larger alerts 14 | .alert-heading { 15 | // Specified to prevent conflicts of changing $headings-color 16 | color: inherit; 17 | } 18 | 19 | // Provide class for links that match alerts 20 | .alert-link { 21 | font-weight: $alert-link-font-weight; 22 | } 23 | 24 | // Dismissible alerts 25 | // 26 | // Expand the right padding and account for the close button's positioning. 27 | 28 | .alert-dismissible { 29 | padding-right: $alert-dismissible-padding-r; 30 | 31 | // Adjust close link position 32 | .btn-close { 33 | position: absolute; 34 | top: 0; 35 | right: 0; 36 | z-index: $stretched-link-z-index + 1; 37 | padding: $alert-padding-y * 1.25 $alert-padding-x; 38 | } 39 | } 40 | 41 | // scss-docs-start alert-modifiers 42 | // Generate contextual modifier classes for colorizing the alert. 43 | 44 | @each $state, $value in $theme-colors { 45 | $alert-background: shift-color($value, $alert-bg-scale); 46 | $alert-border: shift-color($value, $alert-border-scale); 47 | $alert-color: shift-color($value, $alert-color-scale); 48 | @if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) { 49 | $alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale)); 50 | } 51 | .alert-#{$state} { 52 | @include alert-variant($alert-background, $alert-border, $alert-color); 53 | } 54 | } 55 | // scss-docs-end alert-modifiers 56 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_badge.scss: -------------------------------------------------------------------------------- 1 | // Base class 2 | // 3 | // Requires one of the contextual, color modifier classes for `color` and 4 | // `background-color`. 5 | 6 | .badge { 7 | display: inline-block; 8 | padding: $badge-padding-y $badge-padding-x; 9 | @include font-size($badge-font-size); 10 | font-weight: $badge-font-weight; 11 | line-height: 1; 12 | color: $badge-color; 13 | text-align: center; 14 | white-space: nowrap; 15 | vertical-align: baseline; 16 | @include border-radius($badge-border-radius); 17 | @include gradient-bg(); 18 | 19 | // Empty badges collapse automatically 20 | &:empty { 21 | display: none; 22 | } 23 | } 24 | 25 | // Quick fix for badges in buttons 26 | .btn .badge { 27 | position: relative; 28 | top: -1px; 29 | } 30 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | display: flex; 3 | flex-wrap: wrap; 4 | padding: $breadcrumb-padding-y $breadcrumb-padding-x; 5 | margin-bottom: $breadcrumb-margin-bottom; 6 | @include font-size($breadcrumb-font-size); 7 | list-style: none; 8 | background-color: $breadcrumb-bg; 9 | @include border-radius($breadcrumb-border-radius); 10 | } 11 | 12 | .breadcrumb-item { 13 | // The separator between breadcrumbs (by default, a forward-slash: "/") 14 | + .breadcrumb-item { 15 | padding-left: $breadcrumb-item-padding-x; 16 | 17 | &::before { 18 | float: left; // Suppress inline spacings and underlining of the separator 19 | padding-right: $breadcrumb-item-padding-x; 20 | color: $breadcrumb-divider-color; 21 | content: var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{'/* rtl:'} 22 | var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{'*/'}; 23 | } 24 | } 25 | 26 | &.active { 27 | color: $breadcrumb-active-color; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_buttons.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Base styles 3 | // 4 | 5 | .btn { 6 | display: inline-block; 7 | font-family: $btn-font-family; 8 | font-weight: $btn-font-weight; 9 | line-height: $btn-line-height; 10 | color: $body-color; 11 | text-align: center; 12 | text-decoration: if($link-decoration == none, null, none); 13 | white-space: $btn-white-space; 14 | vertical-align: middle; 15 | cursor: if($enable-button-pointers, pointer, null); 16 | user-select: none; 17 | background-color: transparent; 18 | border: $btn-border-width solid transparent; 19 | @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius); 20 | @include transition($btn-transition); 21 | 22 | &:hover { 23 | color: $body-color; 24 | text-decoration: if($link-hover-decoration == underline, none, null); 25 | } 26 | 27 | .btn-check:focus + &, 28 | &:focus { 29 | outline: 0; 30 | box-shadow: $btn-focus-box-shadow; 31 | } 32 | 33 | .btn-check:checked + &, 34 | .btn-check:active + &, 35 | &:active, 36 | &.active { 37 | @include box-shadow($btn-active-box-shadow); 38 | 39 | &:focus { 40 | @include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow); 41 | } 42 | } 43 | 44 | &:disabled, 45 | &.disabled, 46 | fieldset:disabled & { 47 | pointer-events: none; 48 | opacity: $btn-disabled-opacity; 49 | @include box-shadow(none); 50 | } 51 | } 52 | 53 | // 54 | // Alternate buttons 55 | // 56 | 57 | // scss-docs-start btn-variant-loops 58 | @each $color, $value in $theme-colors { 59 | .btn-#{$color} { 60 | @include button-variant($value, $value); 61 | } 62 | } 63 | 64 | @each $color, $value in $theme-colors { 65 | .btn-outline-#{$color} { 66 | @include button-outline-variant($value); 67 | } 68 | } 69 | // scss-docs-end btn-variant-loops 70 | 71 | // 72 | // Link buttons 73 | // 74 | 75 | // Make a button look and behave like a link 76 | .btn-link { 77 | font-weight: $font-weight-normal; 78 | color: $btn-link-color; 79 | text-decoration: $link-decoration; 80 | 81 | &:hover { 82 | color: $btn-link-hover-color; 83 | text-decoration: $link-hover-decoration; 84 | } 85 | 86 | &:focus { 87 | text-decoration: $link-hover-decoration; 88 | } 89 | 90 | &:disabled, 91 | &.disabled { 92 | color: $btn-link-disabled-color; 93 | } 94 | 95 | // No need for an active state here 96 | } 97 | 98 | // 99 | // Button Sizes 100 | // 101 | 102 | .btn-lg { 103 | @include button-size( 104 | $btn-padding-y-lg, 105 | $btn-padding-x-lg, 106 | $btn-font-size-lg, 107 | $btn-border-radius-lg 108 | ); 109 | } 110 | 111 | .btn-sm { 112 | @include button-size( 113 | $btn-padding-y-sm, 114 | $btn-padding-x-sm, 115 | $btn-font-size-sm, 116 | $btn-border-radius-sm 117 | ); 118 | } 119 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_close.scss: -------------------------------------------------------------------------------- 1 | // transparent background and border properties included for button version. 2 | // iOS requires the button element instead of an anchor tag. 3 | // If you want the anchor version, it requires `href="#"`. 4 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 5 | 6 | .btn-close { 7 | box-sizing: content-box; 8 | width: $btn-close-width; 9 | height: $btn-close-height; 10 | padding: $btn-close-padding-y $btn-close-padding-x; 11 | color: $btn-close-color; 12 | background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements 13 | border: 0; // for button elements 14 | @include border-radius(); 15 | opacity: $btn-close-opacity; 16 | 17 | // Override 's hover style 18 | &:hover { 19 | color: $btn-close-color; 20 | text-decoration: none; 21 | opacity: $btn-close-hover-opacity; 22 | } 23 | 24 | &:focus { 25 | outline: 0; 26 | box-shadow: $btn-close-focus-shadow; 27 | opacity: $btn-close-focus-opacity; 28 | } 29 | 30 | &:disabled, 31 | &.disabled { 32 | pointer-events: none; 33 | user-select: none; 34 | opacity: $btn-close-disabled-opacity; 35 | } 36 | } 37 | 38 | .btn-close-white { 39 | filter: $btn-close-white-filter; 40 | } 41 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_containers.scss: -------------------------------------------------------------------------------- 1 | // Container widths 2 | // 3 | // Set the container width, and override it for fixed navbars in media queries. 4 | 5 | @if $enable-grid-classes { 6 | // Single container class with breakpoint max-widths 7 | .container, 8 | // 100% wide container at all breakpoints 9 | .container-fluid { 10 | @include make-container(); 11 | } 12 | 13 | // Responsive containers that are 100% wide until a breakpoint 14 | @each $breakpoint, $container-max-width in $container-max-widths { 15 | .container-#{$breakpoint} { 16 | @extend .container-fluid; 17 | } 18 | 19 | @include media-breakpoint-up($breakpoint, $grid-breakpoints) { 20 | %responsive-container-#{$breakpoint} { 21 | max-width: $container-max-width; 22 | } 23 | 24 | // Extend each breakpoint which is smaller or equal to the current breakpoint 25 | $extend-breakpoint: true; 26 | 27 | @each $name, $width in $grid-breakpoints { 28 | @if ($extend-breakpoint) { 29 | .container#{breakpoint-infix($name, $grid-breakpoints)} { 30 | @extend %responsive-container-#{$breakpoint}; 31 | } 32 | 33 | // Once the current breakpoint is reached, stop extending 34 | @if ($breakpoint == $name) { 35 | $extend-breakpoint: false; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_forms.scss: -------------------------------------------------------------------------------- 1 | @import 'forms/labels'; 2 | @import 'forms/form-text'; 3 | @import 'forms/form-control'; 4 | @import 'forms/form-select'; 5 | @import 'forms/form-check'; 6 | @import 'forms/form-range'; 7 | @import 'forms/floating-labels'; 8 | @import 'forms/input-group'; 9 | @import 'forms/validation'; 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_grid.scss: -------------------------------------------------------------------------------- 1 | // Row 2 | // 3 | // Rows contain your columns. 4 | 5 | @if $enable-grid-classes { 6 | .row { 7 | @include make-row(); 8 | 9 | > * { 10 | @include make-col-ready(); 11 | } 12 | } 13 | } 14 | 15 | @if $enable-cssgrid { 16 | .grid { 17 | display: grid; 18 | grid-template-rows: repeat(var(--#{$variable-prefix}rows, 1), 1fr); 19 | grid-template-columns: repeat(var(--#{$variable-prefix}columns, #{$grid-columns}), 1fr); 20 | gap: var(--#{$variable-prefix}gap, #{$grid-gutter-width}); 21 | 22 | @include make-cssgrid(); 23 | } 24 | } 25 | 26 | // Columns 27 | // 28 | // Common styles for small and large grid columns 29 | 30 | @if $enable-grid-classes { 31 | @include make-grid-columns(); 32 | } 33 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_helpers.scss: -------------------------------------------------------------------------------- 1 | @import 'helpers/clearfix'; 2 | @import 'helpers/colored-links'; 3 | @import 'helpers/ratio'; 4 | @import 'helpers/position'; 5 | @import 'helpers/stacks'; 6 | @import 'helpers/visually-hidden'; 7 | @import 'helpers/stretched-link'; 8 | @import 'helpers/text-truncation'; 9 | @import 'helpers/vr'; 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_images.scss: -------------------------------------------------------------------------------- 1 | // Responsive images (ensure images don't scale beyond their parents) 2 | // 3 | // This is purposefully opt-in via an explicit class rather than being the default for all ``s. 4 | // We previously tried the "images are responsive by default" approach in Bootstrap v2, 5 | // and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps) 6 | // which weren't expecting the images within themselves to be involuntarily resized. 7 | // See also https://github.com/twbs/bootstrap/issues/18178 8 | .img-fluid { 9 | @include img-fluid(); 10 | } 11 | 12 | // Image thumbnails 13 | .img-thumbnail { 14 | padding: $thumbnail-padding; 15 | background-color: $thumbnail-bg; 16 | border: $thumbnail-border-width solid $thumbnail-border-color; 17 | @include border-radius($thumbnail-border-radius); 18 | @include box-shadow($thumbnail-box-shadow); 19 | 20 | // Keep them at most 100% wide 21 | @include img-fluid(); 22 | } 23 | 24 | // 25 | // Figures 26 | // 27 | 28 | .figure { 29 | // Ensures the caption's text aligns with the image. 30 | display: inline-block; 31 | } 32 | 33 | .figure-img { 34 | margin-bottom: $spacer * 0.5; 35 | line-height: 1; 36 | } 37 | 38 | .figure-caption { 39 | @include font-size($figure-caption-font-size); 40 | color: $figure-caption-color; 41 | } 42 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Vendor 6 | @import 'vendor/rfs'; 7 | 8 | // Deprecate 9 | @import 'mixins/deprecate'; 10 | 11 | // Helpers 12 | @import 'mixins/breakpoints'; 13 | @import 'mixins/color-scheme'; 14 | @import 'mixins/image'; 15 | @import 'mixins/resize'; 16 | @import 'mixins/visually-hidden'; 17 | @import 'mixins/reset-text'; 18 | @import 'mixins/text-truncate'; 19 | 20 | // Utilities 21 | @import 'mixins/utilities'; 22 | 23 | // Components 24 | @import 'mixins/alert'; 25 | @import 'mixins/backdrop'; 26 | @import 'mixins/buttons'; 27 | @import 'mixins/caret'; 28 | @import 'mixins/pagination'; 29 | @import 'mixins/lists'; 30 | @import 'mixins/list-group'; 31 | @import 'mixins/forms'; 32 | @import 'mixins/table-variants'; 33 | 34 | // Skins 35 | @import 'mixins/border-radius'; 36 | @import 'mixins/box-shadow'; 37 | @import 'mixins/gradients'; 38 | @import 'mixins/transition'; 39 | 40 | // Layout 41 | @import 'mixins/clearfix'; 42 | @import 'mixins/container'; 43 | @import 'mixins/grid'; 44 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_offcanvas.scss: -------------------------------------------------------------------------------- 1 | .offcanvas { 2 | position: fixed; 3 | bottom: 0; 4 | z-index: $zindex-offcanvas; 5 | display: flex; 6 | flex-direction: column; 7 | max-width: 100%; 8 | color: $offcanvas-color; 9 | visibility: hidden; 10 | background-color: $offcanvas-bg-color; 11 | background-clip: padding-box; 12 | outline: 0; 13 | @include box-shadow($offcanvas-box-shadow); 14 | @include transition(transform $offcanvas-transition-duration ease-in-out); 15 | } 16 | 17 | .offcanvas-backdrop { 18 | @include overlay-backdrop( 19 | $zindex-offcanvas-backdrop, 20 | $offcanvas-backdrop-bg, 21 | $offcanvas-backdrop-opacity 22 | ); 23 | } 24 | 25 | .offcanvas-header { 26 | display: flex; 27 | align-items: center; 28 | justify-content: space-between; 29 | padding: $offcanvas-padding-y $offcanvas-padding-x; 30 | 31 | .btn-close { 32 | padding: ($offcanvas-padding-y * 0.5) ($offcanvas-padding-x * 0.5); 33 | margin-top: $offcanvas-padding-y * -0.5; 34 | margin-right: $offcanvas-padding-x * -0.5; 35 | margin-bottom: $offcanvas-padding-y * -0.5; 36 | } 37 | } 38 | 39 | .offcanvas-title { 40 | margin-bottom: 0; 41 | line-height: $offcanvas-title-line-height; 42 | } 43 | 44 | .offcanvas-body { 45 | flex-grow: 1; 46 | padding: $offcanvas-padding-y $offcanvas-padding-x; 47 | overflow-y: auto; 48 | } 49 | 50 | .offcanvas-start { 51 | top: 0; 52 | left: 0; 53 | width: $offcanvas-horizontal-width; 54 | border-right: $offcanvas-border-width solid $offcanvas-border-color; 55 | transform: translateX(-100%); 56 | } 57 | 58 | .offcanvas-end { 59 | top: 0; 60 | right: 0; 61 | width: $offcanvas-horizontal-width; 62 | border-left: $offcanvas-border-width solid $offcanvas-border-color; 63 | transform: translateX(100%); 64 | } 65 | 66 | .offcanvas-top { 67 | top: 0; 68 | right: 0; 69 | left: 0; 70 | height: $offcanvas-vertical-height; 71 | max-height: 100%; 72 | border-bottom: $offcanvas-border-width solid $offcanvas-border-color; 73 | transform: translateY(-100%); 74 | } 75 | 76 | .offcanvas-bottom { 77 | right: 0; 78 | left: 0; 79 | height: $offcanvas-vertical-height; 80 | max-height: 100%; 81 | border-top: $offcanvas-border-width solid $offcanvas-border-color; 82 | transform: translateY(100%); 83 | } 84 | 85 | .offcanvas.show { 86 | transform: none; 87 | } 88 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_pagination.scss: -------------------------------------------------------------------------------- 1 | .pagination { 2 | display: flex; 3 | @include list-unstyled(); 4 | } 5 | 6 | .page-link { 7 | position: relative; 8 | display: block; 9 | color: $pagination-color; 10 | text-decoration: if($link-decoration == none, null, none); 11 | background-color: $pagination-bg; 12 | border: $pagination-border-width solid $pagination-border-color; 13 | @include transition($pagination-transition); 14 | 15 | &:hover { 16 | z-index: 2; 17 | color: $pagination-hover-color; 18 | text-decoration: if($link-hover-decoration == underline, none, null); 19 | background-color: $pagination-hover-bg; 20 | border-color: $pagination-hover-border-color; 21 | } 22 | 23 | &:focus { 24 | z-index: 3; 25 | color: $pagination-focus-color; 26 | background-color: $pagination-focus-bg; 27 | outline: $pagination-focus-outline; 28 | box-shadow: $pagination-focus-box-shadow; 29 | } 30 | } 31 | 32 | .page-item { 33 | &:not(:first-child) .page-link { 34 | margin-left: $pagination-margin-start; 35 | } 36 | 37 | &.active .page-link { 38 | z-index: 3; 39 | color: $pagination-active-color; 40 | @include gradient-bg($pagination-active-bg); 41 | border-color: $pagination-active-border-color; 42 | } 43 | 44 | &.disabled .page-link { 45 | color: $pagination-disabled-color; 46 | pointer-events: none; 47 | background-color: $pagination-disabled-bg; 48 | border-color: $pagination-disabled-border-color; 49 | } 50 | } 51 | 52 | // 53 | // Sizing 54 | // 55 | @include pagination-size( 56 | $pagination-padding-y, 57 | $pagination-padding-x, 58 | null, 59 | $pagination-border-radius 60 | ); 61 | 62 | .pagination-lg { 63 | @include pagination-size( 64 | $pagination-padding-y-lg, 65 | $pagination-padding-x-lg, 66 | $font-size-lg, 67 | $pagination-border-radius-lg 68 | ); 69 | } 70 | 71 | .pagination-sm { 72 | @include pagination-size( 73 | $pagination-padding-y-sm, 74 | $pagination-padding-x-sm, 75 | $font-size-sm, 76 | $pagination-border-radius-sm 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_placeholders.scss: -------------------------------------------------------------------------------- 1 | .placeholder { 2 | display: inline-block; 3 | min-height: 1em; 4 | vertical-align: middle; 5 | cursor: wait; 6 | background-color: currentColor; 7 | opacity: $placeholder-opacity-max; 8 | 9 | &.btn::before { 10 | display: inline-block; 11 | content: ''; 12 | } 13 | } 14 | 15 | // Sizing 16 | .placeholder-xs { 17 | min-height: 0.6em; 18 | } 19 | 20 | .placeholder-sm { 21 | min-height: 0.8em; 22 | } 23 | 24 | .placeholder-lg { 25 | min-height: 1.2em; 26 | } 27 | 28 | // Animation 29 | .placeholder-glow { 30 | .placeholder { 31 | animation: placeholder-glow 2s ease-in-out infinite; 32 | } 33 | } 34 | 35 | @keyframes placeholder-glow { 36 | 50% { 37 | opacity: $placeholder-opacity-min; 38 | } 39 | } 40 | 41 | .placeholder-wave { 42 | mask-image: linear-gradient( 43 | 130deg, 44 | $black 55%, 45 | rgba(0, 0, 0, (1 - $placeholder-opacity-min)) 75%, 46 | $black 95% 47 | ); 48 | mask-size: 200% 100%; 49 | animation: placeholder-wave 2s linear infinite; 50 | } 51 | 52 | @keyframes placeholder-wave { 53 | 100% { 54 | mask-position: -200% 0%; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_progress.scss: -------------------------------------------------------------------------------- 1 | // Disable animation if transitions are disabled 2 | 3 | // scss-docs-start progress-keyframes 4 | @if $enable-transitions { 5 | @keyframes progress-bar-stripes { 6 | 0% { 7 | background-position-x: $progress-height; 8 | } 9 | } 10 | } 11 | // scss-docs-end progress-keyframes 12 | 13 | .progress { 14 | display: flex; 15 | height: $progress-height; 16 | overflow: hidden; // force rounded corners by cropping it 17 | @include font-size($progress-font-size); 18 | background-color: $progress-bg; 19 | @include border-radius($progress-border-radius); 20 | @include box-shadow($progress-box-shadow); 21 | } 22 | 23 | .progress-bar { 24 | display: flex; 25 | flex-direction: column; 26 | justify-content: center; 27 | overflow: hidden; 28 | color: $progress-bar-color; 29 | text-align: center; 30 | white-space: nowrap; 31 | background-color: $progress-bar-bg; 32 | @include transition($progress-bar-transition); 33 | } 34 | 35 | .progress-bar-striped { 36 | @include gradient-striped(); 37 | background-size: $progress-height $progress-height; 38 | } 39 | 40 | @if $enable-transitions { 41 | .progress-bar-animated { 42 | animation: $progress-bar-animation-timing progress-bar-stripes; 43 | 44 | @if $enable-reduced-motion { 45 | @media (prefers-reduced-motion: reduce) { 46 | animation: none; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | // Note: Custom variable values only support SassScript inside `#{}`. 3 | 4 | // Colors 5 | // 6 | // Generate palettes for full colors, grays, and theme colors. 7 | 8 | @each $color, $value in $colors { 9 | --#{$variable-prefix}#{$color}: #{$value}; 10 | } 11 | 12 | @each $color, $value in $grays { 13 | --#{$variable-prefix}gray-#{$color}: #{$value}; 14 | } 15 | 16 | @each $color, $value in $theme-colors { 17 | --#{$variable-prefix}#{$color}: #{$value}; 18 | } 19 | 20 | @each $color, $value in $theme-colors-rgb { 21 | --#{$variable-prefix}#{$color}-rgb: #{$value}; 22 | } 23 | 24 | --#{$variable-prefix}white-rgb: #{to-rgb($white)}; 25 | --#{$variable-prefix}black-rgb: #{to-rgb($black)}; 26 | --#{$variable-prefix}body-color-rgb: #{to-rgb($body-color)}; 27 | --#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)}; 28 | 29 | // Fonts 30 | 31 | // Note: Use `inspect` for lists so that quoted items keep the quotes. 32 | // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 33 | --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)}; 34 | --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)}; 35 | --#{$variable-prefix}gradient: #{$gradient}; 36 | 37 | // Root and body 38 | // stylelint-disable custom-property-empty-line-before 39 | // scss-docs-start root-body-variables 40 | @if $font-size-root != null { 41 | --#{$variable-prefix}root-font-size: #{$font-size-root}; 42 | } 43 | --#{$variable-prefix}body-font-family: #{$font-family-base}; 44 | --#{$variable-prefix}body-font-size: #{$font-size-base}; 45 | --#{$variable-prefix}body-font-weight: #{$font-weight-base}; 46 | --#{$variable-prefix}body-line-height: #{$line-height-base}; 47 | --#{$variable-prefix}body-color: #{$body-color}; 48 | @if $body-text-align != null { 49 | --#{$variable-prefix}body-text-align: #{$body-text-align}; 50 | } 51 | --#{$variable-prefix}body-bg: #{$body-bg}; 52 | // scss-docs-end root-body-variables 53 | // stylelint-enable custom-property-empty-line-before 54 | } 55 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_spinners.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Rotating border 3 | // 4 | 5 | // scss-docs-start spinner-border-keyframes 6 | @keyframes spinner-border { 7 | to { 8 | transform: rotate(360deg) #{'/* rtl:ignore */'}; 9 | } 10 | } 11 | // scss-docs-end spinner-border-keyframes 12 | 13 | .spinner-border { 14 | display: inline-block; 15 | width: $spinner-width; 16 | height: $spinner-height; 17 | vertical-align: $spinner-vertical-align; 18 | border: $spinner-border-width solid currentColor; 19 | border-right-color: transparent; 20 | // stylelint-disable-next-line property-disallowed-list 21 | border-radius: 50%; 22 | animation: $spinner-animation-speed linear infinite spinner-border; 23 | } 24 | 25 | .spinner-border-sm { 26 | width: $spinner-width-sm; 27 | height: $spinner-height-sm; 28 | border-width: $spinner-border-width-sm; 29 | } 30 | 31 | // 32 | // Growing circle 33 | // 34 | 35 | // scss-docs-start spinner-grow-keyframes 36 | @keyframes spinner-grow { 37 | 0% { 38 | transform: scale(0); 39 | } 40 | 50% { 41 | opacity: 1; 42 | transform: none; 43 | } 44 | } 45 | // scss-docs-end spinner-grow-keyframes 46 | 47 | .spinner-grow { 48 | display: inline-block; 49 | width: $spinner-width; 50 | height: $spinner-height; 51 | vertical-align: $spinner-vertical-align; 52 | background-color: currentColor; 53 | // stylelint-disable-next-line property-disallowed-list 54 | border-radius: 50%; 55 | opacity: 0; 56 | animation: $spinner-animation-speed linear infinite spinner-grow; 57 | } 58 | 59 | .spinner-grow-sm { 60 | width: $spinner-width-sm; 61 | height: $spinner-height-sm; 62 | } 63 | 64 | @if $enable-reduced-motion { 65 | @media (prefers-reduced-motion: reduce) { 66 | .spinner-border, 67 | .spinner-grow { 68 | animation-duration: $spinner-animation-speed * 2; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_toasts.scss: -------------------------------------------------------------------------------- 1 | .toast { 2 | width: $toast-max-width; 3 | max-width: 100%; 4 | @include font-size($toast-font-size); 5 | color: $toast-color; 6 | pointer-events: auto; 7 | background-color: $toast-background-color; 8 | background-clip: padding-box; 9 | border: $toast-border-width solid $toast-border-color; 10 | box-shadow: $toast-box-shadow; 11 | @include border-radius($toast-border-radius); 12 | 13 | &.showing { 14 | opacity: 0; 15 | } 16 | 17 | &:not(.show) { 18 | display: none; 19 | } 20 | } 21 | 22 | .toast-container { 23 | width: max-content; 24 | max-width: 100%; 25 | pointer-events: none; 26 | 27 | > :not(:last-child) { 28 | margin-bottom: $toast-spacing; 29 | } 30 | } 31 | 32 | .toast-header { 33 | display: flex; 34 | align-items: center; 35 | padding: $toast-padding-y $toast-padding-x; 36 | color: $toast-header-color; 37 | background-color: $toast-header-background-color; 38 | background-clip: padding-box; 39 | border-bottom: $toast-border-width solid $toast-header-border-color; 40 | @include border-top-radius(subtract($toast-border-radius, $toast-border-width)); 41 | 42 | .btn-close { 43 | margin-right: $toast-padding-x * -0.5; 44 | margin-left: $toast-padding-x; 45 | } 46 | } 47 | 48 | .toast-body { 49 | padding: $toast-padding-x; // apply to both vertical and horizontal 50 | word-wrap: break-word; 51 | } 52 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_transitions.scss: -------------------------------------------------------------------------------- 1 | .fade { 2 | @include transition($transition-fade); 3 | 4 | &:not(.show) { 5 | opacity: 0; 6 | } 7 | } 8 | 9 | // scss-docs-start collapse-classes 10 | .collapse { 11 | &:not(.show) { 12 | display: none; 13 | } 14 | } 15 | 16 | .collapsing { 17 | height: 0; 18 | overflow: hidden; 19 | @include transition($transition-collapse); 20 | 21 | &.collapse-horizontal { 22 | width: 0; 23 | height: auto; 24 | @include transition($transition-collapse-width); 25 | } 26 | } 27 | // scss-docs-end collapse-classes 28 | -------------------------------------------------------------------------------- /src/scss/bootstrap/_type.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Headings 3 | // 4 | .h1 { 5 | @extend h1; 6 | } 7 | 8 | .h2 { 9 | @extend h2; 10 | } 11 | 12 | .h3 { 13 | @extend h3; 14 | } 15 | 16 | .h4 { 17 | @extend h4; 18 | } 19 | 20 | .h5 { 21 | @extend h5; 22 | } 23 | 24 | .h6 { 25 | @extend h6; 26 | } 27 | 28 | .lead { 29 | @include font-size($lead-font-size); 30 | font-weight: $lead-font-weight; 31 | } 32 | 33 | // Type display classes 34 | @each $display, $font-size in $display-font-sizes { 35 | .display-#{$display} { 36 | @include font-size($font-size); 37 | font-weight: $display-font-weight; 38 | line-height: $display-line-height; 39 | } 40 | } 41 | 42 | // 43 | // Emphasis 44 | // 45 | .small { 46 | @extend small; 47 | } 48 | 49 | .mark { 50 | @extend mark; 51 | } 52 | 53 | // 54 | // Lists 55 | // 56 | 57 | .list-unstyled { 58 | @include list-unstyled(); 59 | } 60 | 61 | // Inline turns list items into inline-block 62 | .list-inline { 63 | @include list-unstyled(); 64 | } 65 | .list-inline-item { 66 | display: inline-block; 67 | 68 | &:not(:last-child) { 69 | margin-right: $list-inline-padding; 70 | } 71 | } 72 | 73 | // 74 | // Misc 75 | // 76 | 77 | // Builds on `abbr` 78 | .initialism { 79 | @include font-size($initialism-font-size); 80 | text-transform: uppercase; 81 | } 82 | 83 | // Blockquotes 84 | .blockquote { 85 | margin-bottom: $blockquote-margin-y; 86 | @include font-size($blockquote-font-size); 87 | 88 | > :last-child { 89 | margin-bottom: 0; 90 | } 91 | } 92 | 93 | .blockquote-footer { 94 | margin-top: -$blockquote-margin-y; 95 | margin-bottom: $blockquote-margin-y; 96 | @include font-size($blockquote-footer-font-size); 97 | color: $blockquote-footer-color; 98 | 99 | &::before { 100 | content: '\2014\00A0'; // em dash, nbsp 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/scss/bootstrap/bootstrap-grid.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | 8 | $include-column-box-sizing: true !default; 9 | 10 | @import 'functions'; 11 | @import 'variables'; 12 | 13 | @import 'mixins/lists'; 14 | @import 'mixins/breakpoints'; 15 | @import 'mixins/container'; 16 | @import 'mixins/grid'; 17 | @import 'mixins/utilities'; 18 | 19 | @import 'vendor/rfs'; 20 | 21 | @import 'root'; 22 | 23 | @import 'containers'; 24 | @import 'grid'; 25 | 26 | @import 'utilities'; 27 | // Only use the utilities we need 28 | // stylelint-disable-next-line scss/dollar-variable-default 29 | $utilities: map-get-multiple( 30 | $utilities, 31 | ( 32 | 'display', 33 | 'order', 34 | 'flex', 35 | 'flex-direction', 36 | 'flex-grow', 37 | 'flex-shrink', 38 | 'flex-wrap', 39 | 'justify-content', 40 | 'align-items', 41 | 'align-content', 42 | 'align-self', 43 | 'margin', 44 | 'margin-x', 45 | 'margin-y', 46 | 'margin-top', 47 | 'margin-end', 48 | 'margin-bottom', 49 | 'margin-start', 50 | 'negative-margin', 51 | 'negative-margin-x', 52 | 'negative-margin-y', 53 | 'negative-margin-top', 54 | 'negative-margin-end', 55 | 'negative-margin-bottom', 56 | 'negative-margin-start', 57 | 'padding', 58 | 'padding-x', 59 | 'padding-y', 60 | 'padding-top', 61 | 'padding-end', 62 | 'padding-bottom', 63 | 'padding-start' 64 | ) 65 | ); 66 | 67 | @import 'utilities/api'; 68 | -------------------------------------------------------------------------------- /src/scss/bootstrap/bootstrap-reboot.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */ 8 | 9 | @import 'functions'; 10 | @import 'variables'; 11 | @import 'mixins'; 12 | @import 'root'; 13 | @import 'reboot'; 14 | -------------------------------------------------------------------------------- /src/scss/bootstrap/bootstrap-utilities.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Utilities v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | 8 | // Configuration 9 | @import 'functions'; 10 | @import 'variables'; 11 | @import 'mixins'; 12 | @import 'utilities'; 13 | 14 | // Helpers 15 | @import 'helpers'; 16 | 17 | // Utilities 18 | @import 'utilities/api'; 19 | -------------------------------------------------------------------------------- /src/scss/bootstrap/bootstrap.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v5.1.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2021 The Bootstrap Authors 4 | * Copyright 2011-2021 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | */ 7 | 8 | // scss-docs-start import-stack 9 | // Configuration 10 | @import 'functions'; 11 | @import 'variables'; 12 | @import 'mixins'; 13 | @import 'utilities'; 14 | 15 | // Layout & components 16 | @import 'root'; 17 | @import 'reboot'; 18 | @import 'type'; 19 | @import 'images'; 20 | @import 'containers'; 21 | @import 'grid'; 22 | @import 'tables'; 23 | @import 'forms'; 24 | @import 'buttons'; 25 | @import 'transitions'; 26 | @import 'dropdown'; 27 | @import 'button-group'; 28 | @import 'nav'; 29 | @import 'navbar'; 30 | @import 'card'; 31 | @import 'accordion'; 32 | @import 'breadcrumb'; 33 | @import 'pagination'; 34 | @import 'badge'; 35 | @import 'alert'; 36 | @import 'progress'; 37 | @import 'list-group'; 38 | @import 'close'; 39 | @import 'toasts'; 40 | @import 'modal'; 41 | @import 'tooltip'; 42 | @import 'popover'; 43 | @import 'carousel'; 44 | @import 'spinners'; 45 | @import 'offcanvas'; 46 | @import 'placeholders'; 47 | 48 | // Helpers 49 | @import 'helpers'; 50 | 51 | // Utilities 52 | @import 'utilities/api'; 53 | // scss-docs-end import-stack 54 | -------------------------------------------------------------------------------- /src/scss/bootstrap/forms/_floating-labels.scss: -------------------------------------------------------------------------------- 1 | .form-floating { 2 | position: relative; 3 | 4 | > .form-control, 5 | > .form-select { 6 | height: $form-floating-height; 7 | line-height: $form-floating-line-height; 8 | } 9 | 10 | > label { 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | height: 100%; // allow textareas 15 | padding: $form-floating-padding-y $form-floating-padding-x; 16 | pointer-events: none; 17 | border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model 18 | transform-origin: 0 0; 19 | @include transition($form-floating-transition); 20 | } 21 | 22 | // stylelint-disable no-duplicate-selectors 23 | > .form-control { 24 | padding: $form-floating-padding-y $form-floating-padding-x; 25 | 26 | &::placeholder { 27 | color: transparent; 28 | } 29 | 30 | &:focus, 31 | &:not(:placeholder-shown) { 32 | padding-top: $form-floating-input-padding-t; 33 | padding-bottom: $form-floating-input-padding-b; 34 | } 35 | // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped 36 | &:-webkit-autofill { 37 | padding-top: $form-floating-input-padding-t; 38 | padding-bottom: $form-floating-input-padding-b; 39 | } 40 | } 41 | 42 | > .form-select { 43 | padding-top: $form-floating-input-padding-t; 44 | padding-bottom: $form-floating-input-padding-b; 45 | } 46 | 47 | > .form-control:focus, 48 | > .form-control:not(:placeholder-shown), 49 | > .form-select { 50 | ~ label { 51 | opacity: $form-floating-label-opacity; 52 | transform: $form-floating-label-transform; 53 | } 54 | } 55 | // Duplicated because `:-webkit-autofill` invalidates other selectors when grouped 56 | > .form-control:-webkit-autofill { 57 | ~ label { 58 | opacity: $form-floating-label-opacity; 59 | transform: $form-floating-label-transform; 60 | } 61 | } 62 | // stylelint-enable no-duplicate-selectors 63 | } 64 | -------------------------------------------------------------------------------- /src/scss/bootstrap/forms/_form-select.scss: -------------------------------------------------------------------------------- 1 | // Select 2 | // 3 | // Replaces the browser default select with a custom one, mostly pulled from 4 | // https://primer.github.io/. 5 | 6 | .form-select { 7 | display: block; 8 | width: 100%; 9 | padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y 10 | $form-select-padding-x; 11 | // stylelint-disable-next-line property-no-vendor-prefix 12 | -moz-padding-start: subtract( 13 | $form-select-padding-x, 14 | 3px 15 | ); // See https://github.com/twbs/bootstrap/issues/32636 16 | font-family: $form-select-font-family; 17 | @include font-size($form-select-font-size); 18 | font-weight: $form-select-font-weight; 19 | line-height: $form-select-line-height; 20 | color: $form-select-color; 21 | background-color: $form-select-bg; 22 | background-image: escape-svg($form-select-indicator); 23 | background-repeat: no-repeat; 24 | background-position: $form-select-bg-position; 25 | background-size: $form-select-bg-size; 26 | border: $form-select-border-width solid $form-select-border-color; 27 | @include border-radius($form-select-border-radius, 0); 28 | @include box-shadow($form-select-box-shadow); 29 | @include transition($form-select-transition); 30 | appearance: none; 31 | 32 | &:focus { 33 | border-color: $form-select-focus-border-color; 34 | outline: 0; 35 | @if $enable-shadows { 36 | @include box-shadow($form-select-box-shadow, $form-select-focus-box-shadow); 37 | } @else { 38 | // Avoid using mixin so we can pass custom focus shadow properly 39 | box-shadow: $form-select-focus-box-shadow; 40 | } 41 | } 42 | 43 | &[multiple], 44 | &[size]:not([size='1']) { 45 | padding-right: $form-select-padding-x; 46 | background-image: none; 47 | } 48 | 49 | &:disabled { 50 | color: $form-select-disabled-color; 51 | background-color: $form-select-disabled-bg; 52 | border-color: $form-select-disabled-border-color; 53 | } 54 | 55 | // Remove outline from select box in FF 56 | &:-moz-focusring { 57 | color: transparent; 58 | text-shadow: 0 0 0 $form-select-color; 59 | } 60 | } 61 | 62 | .form-select-sm { 63 | padding-top: $form-select-padding-y-sm; 64 | padding-bottom: $form-select-padding-y-sm; 65 | padding-left: $form-select-padding-x-sm; 66 | @include font-size($form-select-font-size-sm); 67 | @include border-radius($form-select-border-radius-sm); 68 | } 69 | 70 | .form-select-lg { 71 | padding-top: $form-select-padding-y-lg; 72 | padding-bottom: $form-select-padding-y-lg; 73 | padding-left: $form-select-padding-x-lg; 74 | @include font-size($form-select-font-size-lg); 75 | @include border-radius($form-select-border-radius-lg); 76 | } 77 | -------------------------------------------------------------------------------- /src/scss/bootstrap/forms/_form-text.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Form text 3 | // 4 | 5 | .form-text { 6 | margin-top: $form-text-margin-top; 7 | @include font-size($form-text-font-size); 8 | font-style: $form-text-font-style; 9 | font-weight: $form-text-font-weight; 10 | color: $form-text-color; 11 | } 12 | -------------------------------------------------------------------------------- /src/scss/bootstrap/forms/_labels.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // 4 | 5 | .form-label { 6 | margin-bottom: $form-label-margin-bottom; 7 | @include font-size($form-label-font-size); 8 | font-style: $form-label-font-style; 9 | font-weight: $form-label-font-weight; 10 | color: $form-label-color; 11 | } 12 | 13 | // For use with horizontal and inline forms, when you need the label (or legend) 14 | // text to align with the form controls. 15 | .col-form-label { 16 | padding-top: add($input-padding-y, $input-border-width); 17 | padding-bottom: add($input-padding-y, $input-border-width); 18 | margin-bottom: 0; // Override the `` default 19 | @include font-size(inherit); // Override the `` default 20 | font-style: $form-label-font-style; 21 | font-weight: $form-label-font-weight; 22 | line-height: $input-line-height; 23 | color: $form-label-color; 24 | } 25 | 26 | .col-form-label-lg { 27 | padding-top: add($input-padding-y-lg, $input-border-width); 28 | padding-bottom: add($input-padding-y-lg, $input-border-width); 29 | @include font-size($input-font-size-lg); 30 | } 31 | 32 | .col-form-label-sm { 33 | padding-top: add($input-padding-y-sm, $input-border-width); 34 | padding-bottom: add($input-padding-y-sm, $input-border-width); 35 | @include font-size($input-font-size-sm); 36 | } 37 | -------------------------------------------------------------------------------- /src/scss/bootstrap/forms/_validation.scss: -------------------------------------------------------------------------------- 1 | // Form validation 2 | // 3 | // Provide feedback to users when form field values are valid or invalid. Works 4 | // primarily for client-side validation via scoped `:invalid` and `:valid` 5 | // pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for 6 | // server-side validation. 7 | 8 | // scss-docs-start form-validation-states-loop 9 | @each $state, $data in $form-validation-states { 10 | @include form-validation-state($state, $data...); 11 | } 12 | // scss-docs-end form-validation-states-loop 13 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_colored-links.scss: -------------------------------------------------------------------------------- 1 | @each $color, $value in $theme-colors { 2 | .link-#{$color} { 3 | color: $value; 4 | 5 | @if $link-shade-percentage != 0 { 6 | &:hover, 7 | &:focus { 8 | color: if( 9 | color-contrast($value) == $color-contrast-light, 10 | shade-color($value, $link-shade-percentage), 11 | tint-color($value, $link-shade-percentage) 12 | ); 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_position.scss: -------------------------------------------------------------------------------- 1 | // Shorthand 2 | 3 | .fixed-top { 4 | position: fixed; 5 | top: 0; 6 | right: 0; 7 | left: 0; 8 | z-index: $zindex-fixed; 9 | } 10 | 11 | .fixed-bottom { 12 | position: fixed; 13 | right: 0; 14 | bottom: 0; 15 | left: 0; 16 | z-index: $zindex-fixed; 17 | } 18 | 19 | // Responsive sticky top 20 | @each $breakpoint in map-keys($grid-breakpoints) { 21 | @include media-breakpoint-up($breakpoint) { 22 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 23 | 24 | .sticky#{$infix}-top { 25 | position: sticky; 26 | top: 0; 27 | z-index: $zindex-sticky; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_ratio.scss: -------------------------------------------------------------------------------- 1 | // Credit: Nicolas Gallagher and SUIT CSS. 2 | 3 | .ratio { 4 | position: relative; 5 | width: 100%; 6 | 7 | &::before { 8 | display: block; 9 | padding-top: var(--#{$variable-prefix}aspect-ratio); 10 | content: ''; 11 | } 12 | 13 | > * { 14 | position: absolute; 15 | top: 0; 16 | left: 0; 17 | width: 100%; 18 | height: 100%; 19 | } 20 | } 21 | 22 | @each $key, $ratio in $aspect-ratios { 23 | .ratio-#{$key} { 24 | --#{$variable-prefix}aspect-ratio: #{$ratio}; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_stacks.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start stacks 2 | .hstack { 3 | display: flex; 4 | flex-direction: row; 5 | align-items: center; 6 | align-self: stretch; 7 | } 8 | 9 | .vstack { 10 | display: flex; 11 | flex: 1 1 auto; 12 | flex-direction: column; 13 | align-self: stretch; 14 | } 15 | // scss-docs-end stacks 16 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_stretched-link.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Stretched link 3 | // 4 | 5 | .stretched-link { 6 | &::#{$stretched-link-pseudo-element} { 7 | position: absolute; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: $stretched-link-z-index; 13 | content: ""; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_text-truncation.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Text truncation 3 | // 4 | 5 | .text-truncate { 6 | @include text-truncate(); 7 | } 8 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Visually hidden 3 | // 4 | 5 | .visually-hidden, 6 | .visually-hidden-focusable:not(:focus):not(:focus-within) { 7 | @include visually-hidden(); 8 | } 9 | -------------------------------------------------------------------------------- /src/scss/bootstrap/helpers/_vr.scss: -------------------------------------------------------------------------------- 1 | .vr { 2 | display: inline-block; 3 | align-self: stretch; 4 | width: 1px; 5 | min-height: 1em; 6 | background-color: currentColor; 7 | opacity: $hr-opacity; 8 | } 9 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start alert-variant-mixin 2 | @mixin alert-variant($background, $border, $color) { 3 | color: $color; 4 | @include gradient-bg($background); 5 | border-color: $border; 6 | 7 | .alert-link { 8 | color: shade-color($color, 20%); 9 | } 10 | } 11 | // scss-docs-end alert-variant-mixin 12 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_backdrop.scss: -------------------------------------------------------------------------------- 1 | // Shared between modals and offcanvases 2 | @mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) { 3 | position: fixed; 4 | top: 0; 5 | left: 0; 6 | z-index: $zindex; 7 | width: 100vw; 8 | height: 100vh; 9 | background-color: $backdrop-bg; 10 | 11 | // Fade for backdrop 12 | &.fade { 13 | opacity: 0; 14 | } 15 | &.show { 16 | opacity: $backdrop-opacity; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_border-radius.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-disallowed-list 2 | // Single side border-radius 3 | 4 | // Helper function to replace negative values with 0 5 | @function valid-radius($radius) { 6 | $return: (); 7 | @each $value in $radius { 8 | @if type-of($value) == number { 9 | $return: append($return, max($value, 0)); 10 | } @else { 11 | $return: append($return, $value); 12 | } 13 | } 14 | @return $return; 15 | } 16 | 17 | // scss-docs-start border-radius-mixins 18 | @mixin border-radius($radius: $border-radius, $fallback-border-radius: false) { 19 | @if $enable-rounded { 20 | border-radius: valid-radius($radius); 21 | } @else if $fallback-border-radius != false { 22 | border-radius: $fallback-border-radius; 23 | } 24 | } 25 | 26 | @mixin border-top-radius($radius: $border-radius) { 27 | @if $enable-rounded { 28 | border-top-left-radius: valid-radius($radius); 29 | border-top-right-radius: valid-radius($radius); 30 | } 31 | } 32 | 33 | @mixin border-end-radius($radius: $border-radius) { 34 | @if $enable-rounded { 35 | border-top-right-radius: valid-radius($radius); 36 | border-bottom-right-radius: valid-radius($radius); 37 | } 38 | } 39 | 40 | @mixin border-bottom-radius($radius: $border-radius) { 41 | @if $enable-rounded { 42 | border-bottom-right-radius: valid-radius($radius); 43 | border-bottom-left-radius: valid-radius($radius); 44 | } 45 | } 46 | 47 | @mixin border-start-radius($radius: $border-radius) { 48 | @if $enable-rounded { 49 | border-top-left-radius: valid-radius($radius); 50 | border-bottom-left-radius: valid-radius($radius); 51 | } 52 | } 53 | 54 | @mixin border-top-start-radius($radius: $border-radius) { 55 | @if $enable-rounded { 56 | border-top-left-radius: valid-radius($radius); 57 | } 58 | } 59 | 60 | @mixin border-top-end-radius($radius: $border-radius) { 61 | @if $enable-rounded { 62 | border-top-right-radius: valid-radius($radius); 63 | } 64 | } 65 | 66 | @mixin border-bottom-end-radius($radius: $border-radius) { 67 | @if $enable-rounded { 68 | border-bottom-right-radius: valid-radius($radius); 69 | } 70 | } 71 | 72 | @mixin border-bottom-start-radius($radius: $border-radius) { 73 | @if $enable-rounded { 74 | border-bottom-left-radius: valid-radius($radius); 75 | } 76 | } 77 | // scss-docs-end border-radius-mixins 78 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow($shadow...) { 2 | @if $enable-shadows { 3 | $result: (); 4 | 5 | @each $value in $shadow { 6 | @if $value != null { 7 | $result: append($result, $value, 'comma'); 8 | } 9 | @if $value == none and length($shadow) > 1 { 10 | @warn "The keyword 'none' must be used as a single argument."; 11 | } 12 | } 13 | 14 | @if (length($result) > 0) { 15 | box-shadow: $result; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_caret.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start caret-mixins 2 | @mixin caret-down { 3 | border-top: $caret-width solid; 4 | border-right: $caret-width solid transparent; 5 | border-bottom: 0; 6 | border-left: $caret-width solid transparent; 7 | } 8 | 9 | @mixin caret-up { 10 | border-top: 0; 11 | border-right: $caret-width solid transparent; 12 | border-bottom: $caret-width solid; 13 | border-left: $caret-width solid transparent; 14 | } 15 | 16 | @mixin caret-end { 17 | border-top: $caret-width solid transparent; 18 | border-right: 0; 19 | border-bottom: $caret-width solid transparent; 20 | border-left: $caret-width solid; 21 | } 22 | 23 | @mixin caret-start { 24 | border-top: $caret-width solid transparent; 25 | border-right: $caret-width solid; 26 | border-bottom: $caret-width solid transparent; 27 | } 28 | 29 | @mixin caret($direction: down) { 30 | @if $enable-caret { 31 | &::after { 32 | display: inline-block; 33 | margin-left: $caret-spacing; 34 | vertical-align: $caret-vertical-align; 35 | content: ''; 36 | @if $direction == down { 37 | @include caret-down(); 38 | } @else if $direction == up { 39 | @include caret-up(); 40 | } @else if $direction == end { 41 | @include caret-end(); 42 | } 43 | } 44 | 45 | @if $direction == start { 46 | &::after { 47 | display: none; 48 | } 49 | 50 | &::before { 51 | display: inline-block; 52 | margin-right: $caret-spacing; 53 | vertical-align: $caret-vertical-align; 54 | content: ''; 55 | @include caret-start(); 56 | } 57 | } 58 | 59 | &:empty::after { 60 | margin-left: 0; 61 | } 62 | } 63 | } 64 | // scss-docs-end caret-mixins 65 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start clearfix 2 | @mixin clearfix() { 3 | &::after { 4 | display: block; 5 | clear: both; 6 | content: ""; 7 | } 8 | } 9 | // scss-docs-end clearfix 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_color-scheme.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start mixin-color-scheme 2 | @mixin color-scheme($name) { 3 | @media (prefers-color-scheme: #{$name}) { 4 | @content; 5 | } 6 | } 7 | // scss-docs-end mixin-color-scheme 8 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_container.scss: -------------------------------------------------------------------------------- 1 | // Container mixins 2 | 3 | @mixin make-container($gutter: $container-padding-x) { 4 | width: 100%; 5 | padding-right: var(--#{$variable-prefix}gutter-x, #{$gutter}); 6 | padding-left: var(--#{$variable-prefix}gutter-x, #{$gutter}); 7 | margin-right: auto; 8 | margin-left: auto; 9 | } 10 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_deprecate.scss: -------------------------------------------------------------------------------- 1 | // Deprecate mixin 2 | // 3 | // This mixin can be used to deprecate mixins or functions. 4 | // `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to 5 | // some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap) 6 | @mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) { 7 | @if ($enable-deprecation-messages != false and $ignore-warning != true) { 8 | @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}."; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_gradients.scss: -------------------------------------------------------------------------------- 1 | // Gradients 2 | 3 | // scss-docs-start gradient-bg-mixin 4 | @mixin gradient-bg($color: null) { 5 | background-color: $color; 6 | 7 | @if $enable-gradients { 8 | background-image: var(--#{$variable-prefix}gradient); 9 | } 10 | } 11 | // scss-docs-end gradient-bg-mixin 12 | 13 | // scss-docs-start gradient-mixins 14 | // Horizontal gradient, from left to right 15 | // 16 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 17 | @mixin gradient-x( 18 | $start-color: $gray-700, 19 | $end-color: $gray-800, 20 | $start-percent: 0%, 21 | $end-percent: 100% 22 | ) { 23 | background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); 24 | } 25 | 26 | // Vertical gradient, from top to bottom 27 | // 28 | // Creates two color stops, start and end, by specifying a color and position for each color stop. 29 | @mixin gradient-y( 30 | $start-color: $gray-700, 31 | $end-color: $gray-800, 32 | $start-percent: null, 33 | $end-percent: null 34 | ) { 35 | background-image: linear-gradient( 36 | to bottom, 37 | $start-color $start-percent, 38 | $end-color $end-percent 39 | ); 40 | } 41 | 42 | @mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) { 43 | background-image: linear-gradient($deg, $start-color, $end-color); 44 | } 45 | 46 | @mixin gradient-x-three-colors( 47 | $start-color: $blue, 48 | $mid-color: $purple, 49 | $color-stop: 50%, 50 | $end-color: $red 51 | ) { 52 | background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color); 53 | } 54 | 55 | @mixin gradient-y-three-colors( 56 | $start-color: $blue, 57 | $mid-color: $purple, 58 | $color-stop: 50%, 59 | $end-color: $red 60 | ) { 61 | background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color); 62 | } 63 | 64 | @mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) { 65 | background-image: radial-gradient(circle, $inner-color, $outer-color); 66 | } 67 | 68 | @mixin gradient-striped($color: rgba($white, 0.15), $angle: 45deg) { 69 | background-image: linear-gradient( 70 | $angle, 71 | $color 25%, 72 | transparent 25%, 73 | transparent 50%, 74 | $color 50%, 75 | $color 75%, 76 | transparent 75%, 77 | transparent 78 | ); 79 | } 80 | // scss-docs-end gradient-mixins 81 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_image.scss: -------------------------------------------------------------------------------- 1 | // Image Mixins 2 | // - Responsive image 3 | // - Retina image 4 | 5 | 6 | // Responsive image 7 | // 8 | // Keep images from scaling beyond the width of their parents. 9 | 10 | @mixin img-fluid { 11 | // Part 1: Set a maximum relative to the parent 12 | max-width: 100%; 13 | // Part 2: Override the height to auto, otherwise images will be stretched 14 | // when setting a width and height attribute on the img element. 15 | height: auto; 16 | } 17 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | // scss-docs-start list-group-mixin 4 | @mixin list-group-item-variant($state, $background, $color) { 5 | .list-group-item-#{$state} { 6 | color: $color; 7 | background-color: $background; 8 | 9 | &.list-group-item-action { 10 | &:hover, 11 | &:focus { 12 | color: $color; 13 | background-color: shade-color($background, 10%); 14 | } 15 | 16 | &.active { 17 | color: $white; 18 | background-color: $color; 19 | border-color: $color; 20 | } 21 | } 22 | } 23 | } 24 | // scss-docs-end list-group-mixin 25 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_lists.scss: -------------------------------------------------------------------------------- 1 | // Lists 2 | 3 | // Unstyled keeps list items block level, just removes default browser padding and list-style 4 | @mixin list-unstyled { 5 | padding-left: 0; 6 | list-style: none; 7 | } 8 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | // scss-docs-start pagination-mixin 4 | @mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) { 5 | .page-link { 6 | padding: $padding-y $padding-x; 7 | @include font-size($font-size); 8 | } 9 | 10 | .page-item { 11 | @if $pagination-margin-start == (-$pagination-border-width) { 12 | &:first-child { 13 | .page-link { 14 | @include border-start-radius($border-radius); 15 | } 16 | } 17 | 18 | &:last-child { 19 | .page-link { 20 | @include border-end-radius($border-radius); 21 | } 22 | } 23 | } @else { 24 | //Add border-radius to all pageLinks in case they have left margin 25 | .page-link { 26 | @include border-radius($border-radius); 27 | } 28 | } 29 | } 30 | } 31 | // scss-docs-end pagination-mixin 32 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size or overflow-wrap / word-wrap. 4 | font-style: normal; 5 | font-weight: $font-weight-normal; 6 | line-height: $line-height-base; 7 | text-align: left; // Fallback for where `start` is not supported 8 | text-align: start; 9 | text-decoration: none; 10 | text-shadow: none; 11 | text-transform: none; 12 | letter-spacing: normal; 13 | word-break: normal; 14 | word-spacing: normal; 15 | white-space: normal; 16 | line-break: auto; 17 | } 18 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 5 | resize: $direction; // Options: horizontal, vertical, both 6 | } 7 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_table-variants.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start table-variant 2 | @mixin table-variant($state, $background) { 3 | .table-#{$state} { 4 | $color: color-contrast(opaque($body-bg, $background)); 5 | $hover-bg: mix($color, $background, percentage($table-hover-bg-factor)); 6 | $striped-bg: mix($color, $background, percentage($table-striped-bg-factor)); 7 | $active-bg: mix($color, $background, percentage($table-active-bg-factor)); 8 | 9 | --#{$variable-prefix}table-bg: #{$background}; 10 | --#{$variable-prefix}table-striped-bg: #{$striped-bg}; 11 | --#{$variable-prefix}table-striped-color: #{color-contrast($striped-bg)}; 12 | --#{$variable-prefix}table-active-bg: #{$active-bg}; 13 | --#{$variable-prefix}table-active-color: #{color-contrast($active-bg)}; 14 | --#{$variable-prefix}table-hover-bg: #{$hover-bg}; 15 | --#{$variable-prefix}table-hover-color: #{color-contrast($hover-bg)}; 16 | 17 | color: $color; 18 | border-color: mix($color, $background, percentage($table-border-factor)); 19 | } 20 | } 21 | // scss-docs-end table-variant 22 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_text-truncate.scss: -------------------------------------------------------------------------------- 1 | // Text truncate 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-truncate() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_transition.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-disallowed-list 2 | @mixin transition($transition...) { 3 | @if length($transition) == 0 { 4 | $transition: $transition-base; 5 | } 6 | 7 | @if length($transition) > 1 { 8 | @each $value in $transition { 9 | @if $value == null or $value == none { 10 | @warn "The keyword 'none' or 'null' must be used as a single argument."; 11 | } 12 | } 13 | } 14 | 15 | @if $enable-transitions { 16 | @if nth($transition, 1) != null { 17 | transition: $transition; 18 | } 19 | 20 | @if $enable-reduced-motion and nth($transition, 1) != null and nth($transition, 1) != none { 21 | @media (prefers-reduced-motion: reduce) { 22 | transition: none; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/scss/bootstrap/mixins/_visually-hidden.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Hide content visually while keeping it accessible to assistive technologies 4 | // 5 | // See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/ 6 | // See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/ 7 | 8 | @mixin visually-hidden() { 9 | position: absolute !important; 10 | width: 1px !important; 11 | height: 1px !important; 12 | padding: 0 !important; 13 | margin: -1px !important; // Fix for https://github.com/twbs/bootstrap/issues/25686 14 | overflow: hidden !important; 15 | clip: rect(0, 0, 0, 0) !important; 16 | white-space: nowrap !important; 17 | border: 0 !important; 18 | } 19 | 20 | // Use to only display content when it's focused, or one of its child elements is focused 21 | // (i.e. when focus is within the element/container that the class was applied to) 22 | // 23 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 24 | 25 | @mixin visually-hidden-focusable() { 26 | &:not(:focus):not(:focus-within) { 27 | @include visually-hidden(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/scss/bootstrap/utilities/_api.scss: -------------------------------------------------------------------------------- 1 | // Loop over each breakpoint 2 | @each $breakpoint in map-keys($grid-breakpoints) { 3 | // Generate media query if needed 4 | @include media-breakpoint-up($breakpoint) { 5 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 6 | 7 | // Loop over each utility property 8 | @each $key, $utility in $utilities { 9 | // The utility can be disabled with `false`, thus check if the utility is a map first 10 | // Only proceed if responsive media queries are enabled or if it's the base media query 11 | @if type-of($utility) == 'map' and (map-get($utility, responsive) or $infix == '') { 12 | @include generate-utility($utility, $infix); 13 | } 14 | } 15 | } 16 | } 17 | 18 | // RFS rescaling 19 | @media (min-width: $rfs-mq-value) { 20 | @each $breakpoint in map-keys($grid-breakpoints) { 21 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 22 | 23 | @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) { 24 | // Loop over each utility property 25 | @each $key, $utility in $utilities { 26 | // The utility can be disabled with `false`, thus check if the utility is a map first 27 | // Only proceed if responsive media queries are enabled or if it's the base media query 28 | @if type-of($utility) == 29 | 'map' and 30 | map-get($utility, rfs) and 31 | (map-get($utility, responsive) or $infix == '') 32 | { 33 | @include generate-utility($utility, $infix, true); 34 | } 35 | } 36 | } 37 | } 38 | } 39 | 40 | // Print utilities 41 | @media print { 42 | @each $key, $utility in $utilities { 43 | // The utility can be disabled with `false`, thus check if the utility is a map first 44 | // Then check if the utility needs print styles 45 | @if type-of($utility) == 'map' and map-get($utility, print) == true { 46 | @include generate-utility($utility, '-print'); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/scss/custom/_styles.scss: -------------------------------------------------------------------------------- 1 | // Your custom variables 2 | -------------------------------------------------------------------------------- /src/scss/custom/_variables.scss: -------------------------------------------------------------------------------- 1 | // Your custom variables 2 | -------------------------------------------------------------------------------- /src/scss/free/_accordion.scss: -------------------------------------------------------------------------------- 1 | // Accordion 2 | 3 | .accordion-button { 4 | &:not(.collapsed) { 5 | &:focus { 6 | box-shadow: $accordion-button-focus-box-shadow; 7 | } 8 | } 9 | 10 | &:focus { 11 | border-color: $accordion-button-focus-border-color; 12 | outline: 0; 13 | box-shadow: none; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/scss/free/_alert.scss: -------------------------------------------------------------------------------- 1 | // Alert 2 | 3 | .alert { 4 | border: 0; 5 | border-radius: $alert-border-radius; 6 | } 7 | 8 | .alert-absolute { 9 | position: absolute; 10 | } 11 | 12 | .alert-fixed { 13 | position: fixed; 14 | z-index: $zindex-alert; 15 | } 16 | 17 | .parent-alert-relative { 18 | position: relative; 19 | } 20 | -------------------------------------------------------------------------------- /src/scss/free/_badge.scss: -------------------------------------------------------------------------------- 1 | // Badge 2 | 3 | .badge { 4 | border-radius: $badge-border-radius; 5 | } 6 | 7 | .badge-dot { 8 | position: absolute; 9 | border-radius: $badge-dot-border-radius; 10 | height: $badge-dot-height; 11 | min-width: 0; 12 | padding: 0; 13 | width: $badge-dot-width; 14 | margin-left: $badge-dot-margin-left; 15 | &:empty { 16 | display: inline-block; 17 | } 18 | } 19 | 20 | .badge-notification { 21 | position: absolute; 22 | font-size: $badge-notification-font-size; 23 | margin-top: $badge-notification-margin-top; 24 | margin-left: $badge-notification-margin-left; 25 | padding: $badge-notification-padding-y $badge-notification-padding-x; 26 | } 27 | 28 | @each $name, $color in $badges { 29 | .badge-#{$name} { 30 | background-color: map-get($color, background-color); 31 | color: map-get($color, text-color); 32 | 33 | i { 34 | color: map-get($color, icon-color); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/scss/free/_breadcrumb.scss: -------------------------------------------------------------------------------- 1 | // Breadcrumb 2 | 3 | .navbar { 4 | .breadcrumb { 5 | background-color: transparent; 6 | margin-bottom: 0; 7 | 8 | .breadcrumb-item { 9 | a { 10 | color: $breadcrumb-item-color; 11 | transition: $breadcrumb-item-transition; 12 | &:hover, 13 | &:focus { 14 | color: $breadcrumb-item-hover-color; 15 | } 16 | } 17 | + .breadcrumb-item { 18 | &:before { 19 | color: $breadcrumb-item-before-color; 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/scss/free/_button-group.scss: -------------------------------------------------------------------------------- 1 | // Button group styles 2 | 3 | .btn-group, 4 | .btn-group-vertical { 5 | box-shadow: $btn-box-shadow; 6 | border-radius: $btn-group-border-radius; 7 | transition: $btn-group-transition; 8 | 9 | &:hover { 10 | box-shadow: $btn-hover-box-shadow; 11 | } 12 | 13 | &:focus, 14 | &.focus { 15 | box-shadow: $btn-focus-box-shadow; 16 | } 17 | 18 | &:active, 19 | &.active { 20 | box-shadow: $btn-hover-box-shadow; 21 | 22 | &:focus { 23 | box-shadow: $btn-hover-box-shadow; 24 | } 25 | } 26 | 27 | &:disabled, 28 | &.disabled, 29 | fieldset:disabled & { 30 | box-shadow: $btn-box-shadow; 31 | border: 0; 32 | } 33 | 34 | > .btn { 35 | box-shadow: none; 36 | } 37 | > .btn-group { 38 | box-shadow: none; 39 | } 40 | > .btn-link { 41 | &:first-child { 42 | border-top-left-radius: 0; 43 | border-bottom-left-radius: 0; 44 | } 45 | &:last-child { 46 | border-top-right-radius: 0; 47 | border-bottom-right-radius: 0; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/scss/free/_card.scss: -------------------------------------------------------------------------------- 1 | // Card 2 | 3 | .card { 4 | border: 0; 5 | box-shadow: $box-shadow-4; 6 | 7 | .bg-image { 8 | border-top-left-radius: $card-border-radius; 9 | border-top-right-radius: $card-border-radius; 10 | } 11 | } 12 | 13 | .card-header { 14 | background-color: $card-header-background-color; 15 | } 16 | 17 | .card-body { 18 | &[class*='bg-'] { 19 | border-bottom-left-radius: $card-border-radius; 20 | border-bottom-right-radius: $card-border-radius; 21 | } 22 | } 23 | 24 | .card-footer { 25 | background-color: $card-footer-background-color; 26 | } 27 | 28 | .card-img-left { 29 | border-top-left-radius: $card-border-radius; 30 | border-bottom-left-radius: $card-border-radius; 31 | } 32 | -------------------------------------------------------------------------------- /src/scss/free/_carousel.scss: -------------------------------------------------------------------------------- 1 | .carousel-control-prev-icon { 2 | &::after { 3 | content: '\f053'; 4 | font-weight: $font-weight-bold; 5 | font-family: 'Font Awesome 5 Pro', 'Font Awesome 5 Free'; 6 | font-size: 1.7rem; 7 | } 8 | } 9 | .carousel-control-next-icon { 10 | &::after { 11 | content: '\f054'; 12 | font-weight: $font-weight-bold; 13 | font-family: 'Font Awesome 5 Pro', 'Font Awesome 5 Free'; 14 | font-size: 1.7rem; 15 | } 16 | } 17 | .carousel-indicators { 18 | [data-mdb-target] { 19 | @extend [data-bs-target] !optional; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/scss/free/_close.scss: -------------------------------------------------------------------------------- 1 | // transparent background and border properties included for button version. 2 | // iOS requires the button element instead of an anchor tag. 3 | // If you want the anchor version, it requires `href="#"`. 4 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 5 | 6 | .btn-close { 7 | &:focus { 8 | box-shadow: none; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/scss/free/_colors.scss: -------------------------------------------------------------------------------- 1 | // Colors 2 | 3 | @each $color, $value in $theme-colors { 4 | .bg-#{$color} { 5 | background-color: rgba($value, var(--mdb-bg-opacity)) !important; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/scss/free/_dropdown.scss: -------------------------------------------------------------------------------- 1 | .dropdown-menu { 2 | color: $dropdown-color; 3 | margin: 0; 4 | padding-top: 0; 5 | padding-bottom: 0; 6 | border: 0; 7 | box-shadow: $dropdown-box-shadow; 8 | font-size: $dropdown-font-size; 9 | 10 | > li { 11 | border-radius: 0; 12 | &:first-child { 13 | border-top-left-radius: $dropdown-item-border-radius; 14 | border-top-right-radius: $dropdown-item-border-radius; 15 | border-bottom-left-radius: 0; 16 | border-bottom-right-radius: 0; 17 | .dropdown-item { 18 | border-top-left-radius: $dropdown-item-border-radius; 19 | border-top-right-radius: $dropdown-item-border-radius; 20 | border-bottom-left-radius: 0; 21 | border-bottom-right-radius: 0; 22 | } 23 | } 24 | 25 | &:not(:first-child):not(:last-child) { 26 | .dropdown-item { 27 | border-radius: 0; 28 | } 29 | } 30 | 31 | &:last-child { 32 | border-top-left-radius: 0; 33 | border-top-right-radius: 0; 34 | border-bottom-left-radius: $dropdown-item-border-radius; 35 | border-bottom-right-radius: $dropdown-item-border-radius; 36 | .dropdown-item { 37 | border-top-left-radius: 0; 38 | border-top-right-radius: 0; 39 | border-bottom-left-radius: $dropdown-item-border-radius; 40 | border-bottom-right-radius: $dropdown-item-border-radius; 41 | } 42 | } 43 | } 44 | 45 | &.animation { 46 | display: block; 47 | /* Speed up animations */ 48 | animation-duration: $dropdown-menu-animated-animation-duration; 49 | animation-timing-function: $dropdown-menu-animated-animation-timing-function; 50 | } 51 | } 52 | 53 | .dropdown-item { 54 | padding: $dropdown-item-padding-y $dropdown-item-padding-x; 55 | color: $dropdown-color; 56 | border-radius: 0; 57 | 58 | &:hover, 59 | &:focus { 60 | color: $dropdown-state-color; 61 | background-color: $dropdown-state-background-color; 62 | } 63 | 64 | &.active, 65 | &:active { 66 | color: $dropdown-state-color; 67 | background-color: $dropdown-state-background-color; 68 | } 69 | } 70 | 71 | .hidden-arrow { 72 | &.dropdown-toggle:after { 73 | display: none; 74 | } 75 | } 76 | 77 | .animation { 78 | animation-duration: 1s; 79 | animation-fill-mode: both; 80 | padding: auto; 81 | } 82 | 83 | @media (prefers-reduced-motion) { 84 | .animation { 85 | transition: none !important; 86 | animation: unset !important; 87 | } 88 | } 89 | 90 | @keyframes fade-in { 91 | from { 92 | opacity: 0; 93 | } 94 | 95 | to { 96 | opacity: 1; 97 | } 98 | } 99 | 100 | .fade-in { 101 | animation-name: fade-in; 102 | } 103 | 104 | @keyframes fade-out { 105 | from { 106 | opacity: 1; 107 | } 108 | 109 | to { 110 | opacity: 0; 111 | } 112 | } 113 | 114 | .fade-out { 115 | animation-name: fade-out; 116 | } 117 | -------------------------------------------------------------------------------- /src/scss/free/_functions.scss: -------------------------------------------------------------------------------- 1 | // Functions 2 | 3 | // Dynamically change text color based on background color 4 | 5 | @function set-notification-text-color($color) { 6 | @if (lightness($color) > 70) { 7 | @return $gray-800; 8 | } @else { 9 | @return $white; 10 | } 11 | } 12 | 13 | @function color-level($color: $primary, $level: 0) { 14 | $color-base: if($level > 0, $black, $white); 15 | $level: abs($level); 16 | 17 | @return mix($color-base, $color, $level); 18 | } 19 | -------------------------------------------------------------------------------- /src/scss/free/_images.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Images 3 | // 4 | 5 | .bg-image { 6 | position: relative; 7 | overflow: hidden; 8 | background-repeat: no-repeat; 9 | background-size: cover; 10 | background-position: center center; 11 | } 12 | 13 | .mask { 14 | position: absolute; 15 | top: 0; 16 | right: 0; 17 | bottom: 0; 18 | left: 0; 19 | width: 100%; 20 | height: 100%; 21 | overflow: hidden; 22 | background-attachment: fixed; 23 | } 24 | 25 | .hover-overlay { 26 | .mask { 27 | opacity: 0; 28 | transition: $image-hover-overlay-transition; 29 | &:hover { 30 | opacity: 1; 31 | } 32 | } 33 | } 34 | 35 | .hover-zoom { 36 | img, 37 | video { 38 | transition: $image-hover-zoom-transition; 39 | } 40 | &:hover { 41 | img, 42 | video { 43 | transform: $image-hover-zoom-transform; 44 | } 45 | } 46 | } 47 | 48 | .hover-shadow, 49 | .card.hover-shadow { 50 | box-shadow: none; 51 | transition: $image-hover-shadow-transition; 52 | &:hover { 53 | box-shadow: $image-hover-shadow-box-shadow; 54 | transition: $image-hover-shadow-transition; 55 | } 56 | } 57 | 58 | .bg-fixed { 59 | background-attachment: fixed; 60 | } 61 | 62 | .hover-shadow-soft, 63 | .card.hover-shadow-soft { 64 | box-shadow: none; 65 | transition: $image-hover-shadow-transition; 66 | &:hover { 67 | box-shadow: $image-hover-shadow-box-shadow-soft; 68 | transition: $image-hover-shadow-transition; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/scss/free/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List group 2 | 3 | .list-group-item-action { 4 | transition: 0.5s; 5 | 6 | // Hover state 7 | &:hover { 8 | transition: 0.5s; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/scss/free/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Toggles 2 | // 3 | // Used in conjunction with global variables to enable certain theme features. 4 | 5 | // Components 6 | @import './mixins/buttons'; 7 | @import './mixins/ripple'; 8 | @import './mixins/table-variants'; 9 | -------------------------------------------------------------------------------- /src/scss/free/_modal.scss: -------------------------------------------------------------------------------- 1 | // Modal 2 | .modal-content { 3 | border: 0; 4 | box-shadow: $modal-box-shadow; 5 | } 6 | -------------------------------------------------------------------------------- /src/scss/free/_nav.scss: -------------------------------------------------------------------------------- 1 | // Navs 2 | 3 | // 4 | // Tabs 5 | // 6 | 7 | .nav-tabs { 8 | border-bottom: 0; 9 | 10 | .nav-link { 11 | border-width: $nav-tabs-link-border-width; 12 | border-style: solid; 13 | border-color: transparent; 14 | border-radius: 0; 15 | text-transform: uppercase; 16 | line-height: 1; 17 | font-weight: $nav-tabs-link-font-weight; 18 | font-size: $nav-tabs-link-font-size; 19 | color: $nav-tabs-link-color; 20 | padding: $nav-tabs-link-padding-top $nav-tabs-link-padding-x $nav-tabs-link-padding-bottom 21 | $nav-tabs-link-padding-x; 22 | 23 | &:hover { 24 | background-color: $nav-tabs-link-hover-background-color; 25 | border-color: transparent; 26 | } 27 | 28 | &:focus { 29 | border-color: transparent; 30 | } 31 | } 32 | 33 | .nav-link.active, 34 | .nav-item.show .nav-link { 35 | color: $primary; 36 | border-color: $primary; 37 | } 38 | } 39 | 40 | // 41 | // Pills 42 | // 43 | 44 | .nav-pills { 45 | margin-left: -$nav-pills-margin; 46 | 47 | .nav-link { 48 | border-radius: $nav-pills-link-border-radius; 49 | font-size: $nav-pills-link-font-size; 50 | text-transform: uppercase; 51 | padding: $nav-pills-link-padding-top $nav-pills-link-padding-x $nav-pills-link-padding-bottom 52 | $nav-pills-link-padding-x; 53 | line-height: $nav-pills-link-line-height; 54 | background-color: $nav-pills-link-background-color; 55 | font-weight: $nav-pills-link-font-weight; 56 | color: $nav-pills-link-color; 57 | margin: $nav-pills-margin; 58 | } 59 | 60 | .nav-link.active, 61 | .show > .nav-link { 62 | color: $nav-pills-link-active-color; 63 | background-color: $nav-pills-link-active-bg; 64 | box-shadow: $btn-box-shadow; 65 | } 66 | } 67 | 68 | // Fix for keeping margins of pills 69 | .nav-fill, 70 | .nav-justified { 71 | .nav-item { 72 | .nav-link { 73 | width: auto; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/scss/free/_navbar.scss: -------------------------------------------------------------------------------- 1 | // Navbar 2 | 3 | .navbar { 4 | box-shadow: $navbar-box-shadow; 5 | padding-top: $navbar-padding-top; 6 | } 7 | 8 | .navbar-toggler { 9 | border: 0; 10 | 11 | &:focus { 12 | box-shadow: none; 13 | } 14 | } 15 | 16 | .navbar-dark .navbar-toggler, 17 | .navbar-light .navbar-toggler { 18 | border: 0; 19 | } 20 | 21 | .navbar-brand { 22 | display: flex; 23 | align-items: center; 24 | img { 25 | margin-right: $navbar-brand-img-margin-right; 26 | } 27 | } 28 | 29 | .navbar-nav .dropdown-menu { 30 | position: absolute; 31 | } 32 | 33 | .navbar-light { 34 | .navbar-toggler-icon { 35 | background-image: none; 36 | } 37 | } 38 | 39 | .navbar-dark { 40 | .navbar-toggler-icon { 41 | background-image: none; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/scss/free/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | .page-link { 4 | border: 0; 5 | font-size: $pagination-font-size; 6 | color: $pagination-color; 7 | background-color: transparent; 8 | border: 0; 9 | outline: 0; 10 | transition: $pagination-transition; 11 | border-radius: $pagination-border-radius; 12 | 13 | &:hover { 14 | color: $pagination-hover-color; 15 | } 16 | 17 | &:focus { 18 | box-shadow: none; 19 | } 20 | } 21 | 22 | .page-item { 23 | &.active .page-link { 24 | background-color: $pagination-active-bg; 25 | border: 0; 26 | box-shadow: $pagination-active-box-shadow; 27 | transition: $pagination-active-transition; 28 | } 29 | 30 | &:first-child { 31 | .page-link { 32 | border-top-left-radius: $pagination-border-radius; 33 | border-bottom-left-radius: $pagination-border-radius; 34 | } 35 | } 36 | 37 | &:last-child { 38 | .page-link { 39 | border-top-right-radius: $pagination-border-radius; 40 | border-bottom-right-radius: $pagination-border-radius; 41 | } 42 | } 43 | &:not(:first-child) { 44 | .page-link { 45 | margin-left: 0; 46 | } 47 | } 48 | } 49 | 50 | .pagination-lg, 51 | .pagination-sm { 52 | .page-item { 53 | &:first-child .page-link { 54 | border-top-left-radius: $pagination-border-radius; 55 | border-bottom-left-radius: $pagination-border-radius; 56 | } 57 | &:last-child .page-link { 58 | border-top-right-radius: $pagination-border-radius; 59 | border-bottom-right-radius: $pagination-border-radius; 60 | } 61 | } 62 | } 63 | 64 | .pagination-circle { 65 | .page-item { 66 | &:first-child { 67 | .page-link { 68 | border-radius: $pagination-circle-border-radius; 69 | } 70 | } 71 | 72 | &:last-child { 73 | .page-link { 74 | border-radius: $pagination-circle-border-radius; 75 | } 76 | } 77 | } 78 | .page-link { 79 | border-radius: $pagination-circle-border-radius; 80 | padding-left: $pagination-circle-padding-x; 81 | padding-right: $pagination-circle-padding-x; 82 | } 83 | 84 | &.pagination-lg { 85 | .page-link { 86 | padding-left: $pagination-circle-lg-padding-left; 87 | padding-right: $pagination-circle-lg-padding-right; 88 | } 89 | } 90 | &.pagination-sm { 91 | .page-link { 92 | padding-left: $pagination-circle-sm-padding-left; 93 | padding-right: $pagination-circle-sm-padding-right; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/scss/free/_popover.scss: -------------------------------------------------------------------------------- 1 | // Popover 2 | 3 | .popover { 4 | border: 0; 5 | box-shadow: $popover-box-shadow; 6 | 7 | .popover-arrow { 8 | display: none; 9 | } 10 | } 11 | 12 | .popover-header { 13 | background-color: $popover-background-color; 14 | } 15 | -------------------------------------------------------------------------------- /src/scss/free/_progress.scss: -------------------------------------------------------------------------------- 1 | // Progress 2 | 3 | .progress { 4 | border-radius: 0; 5 | } 6 | -------------------------------------------------------------------------------- /src/scss/free/_range.scss: -------------------------------------------------------------------------------- 1 | // range 2 | .range { 3 | position: relative; 4 | 5 | .thumb { 6 | position: absolute; 7 | display: block; 8 | height: 30px; 9 | width: 30px; 10 | top: -35px; 11 | margin-left: -15px; 12 | text-align: center; 13 | border-radius: 50% 50% 50% 0; 14 | transform: scale(0); 15 | transform-origin: bottom; 16 | transition: transform 0.2s ease-in-out; 17 | 18 | &:after { 19 | position: absolute; 20 | display: block; 21 | content: ''; 22 | transform: translateX(-50%); 23 | width: 100%; 24 | height: 100%; 25 | top: 0; 26 | border-radius: 50% 50% 50% 0; 27 | transform: rotate(-45deg); 28 | background: #1266f1; 29 | z-index: -1; 30 | } 31 | 32 | .thumb-value { 33 | display: block; 34 | font-size: 12px; 35 | line-height: 30px; 36 | color: rgb(255, 255, 255); 37 | font-weight: 500; 38 | z-index: 2; 39 | } 40 | 41 | &.thumb-active { 42 | transform: scale(1); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/scss/free/_reboot.scss: -------------------------------------------------------------------------------- 1 | // Reboot 2 | 3 | body { 4 | font-family: $font-family-base; 5 | line-height: $line-height-base; 6 | color: $body-color; 7 | } 8 | 9 | // Links 10 | 11 | a { 12 | text-decoration: none; 13 | } 14 | 15 | button:focus { 16 | outline: 0; 17 | } -------------------------------------------------------------------------------- /src/scss/free/_ripple.scss: -------------------------------------------------------------------------------- 1 | .ripple-surface { 2 | position: relative; 3 | overflow: hidden; 4 | display: inline-block; 5 | vertical-align: bottom; 6 | } 7 | 8 | .ripple-surface-unbound { 9 | overflow: visible; 10 | } 11 | 12 | .ripple-wave { 13 | @include ripple-variant(black); 14 | $cubicBezier: cubic-bezier(0, 0, 0.15, 1); 15 | border-radius: 50%; 16 | opacity: 0.5; 17 | pointer-events: none; 18 | position: absolute; 19 | touch-action: none; 20 | transform: scale(0); 21 | transition-property: transform, opacity; 22 | transition-timing-function: $cubicBezier, $cubicBezier; 23 | z-index: 999; 24 | &.active { 25 | transform: scale(1); 26 | opacity: 0; 27 | } 28 | } 29 | 30 | .btn .ripple-wave { 31 | @include ripple-variant(white); 32 | } 33 | 34 | @each $color, $value in $theme-colors { 35 | .ripple-surface-#{$color} { 36 | .ripple-wave { 37 | @include ripple-variant($value); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/scss/free/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --mdb-font-roboto: #{inspect($font-family-roboto)}; 3 | } -------------------------------------------------------------------------------- /src/scss/free/_scrollspy.scss: -------------------------------------------------------------------------------- 1 | // Scrollspy 2 | 3 | .nav-pills { 4 | &.menu-sidebar { 5 | .nav-link { 6 | font-size: $scrollspy-menu-sidebar-font-size; 7 | background-color: transparent; 8 | color: $scrollspy-menu-sidebar-color; 9 | line-height: $scrollspy-menu-sidebar-line-height; 10 | padding: 0 $scrollspy-menu-sidebar-padding-x; 11 | font-weight: $scrollspy-menu-sidebar-font-weight; 12 | transition: $scrollspy-menu-sidebar-transition; 13 | text-transform: initial; 14 | margin-top: $scrollspy-menu-sidebar-margin-y; 15 | margin-bottom: $scrollspy-menu-sidebar-margin-y; 16 | } 17 | 18 | .nav-link.active, 19 | .show > .nav-link { 20 | background-color: transparent; 21 | box-shadow: none; 22 | color: $scrollspy-menu-sidebar-active-color; 23 | font-weight: $scrollspy-menu-sidebar-active-font-weight; 24 | border-left: $scrollspy-menu-sidebar-active-border-width solid 25 | $scrollspy-menu-sidebar-active-border-color; 26 | border-radius: 0; 27 | } 28 | 29 | .collapsible-scrollspy ~ .nav { 30 | transition: height 0.5s ease; 31 | flex-wrap: nowrap; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/scss/free/_shadows.scss: -------------------------------------------------------------------------------- 1 | // Shadows 2 | // @each $shadow, $value in $shadows { 3 | // .shadow-#{$shadow} { 4 | // box-shadow: $value !important; 5 | // } 6 | // } 7 | 8 | // @each $shadow, $value in $shadows-soft { 9 | // .shadow-#{$shadow}-soft { 10 | // box-shadow: $value !important; 11 | // } 12 | // } 13 | 14 | // @each $shadow, $value in $shadows-strong { 15 | // .shadow-#{$shadow}-strong { 16 | // box-shadow: $value !important; 17 | // } 18 | // } 19 | -------------------------------------------------------------------------------- /src/scss/free/_tables.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Basic MDB table 3 | // 4 | 5 | .table { 6 | font-size: $table-font-size; 7 | 8 | > :not(caption) > * > * { 9 | padding: $table-cell-padding-y $table-cell-padding-x; 10 | } 11 | 12 | th { 13 | font-weight: 500; 14 | } 15 | 16 | tbody { 17 | font-weight: 300; 18 | } 19 | 20 | > :not(:last-child) > :last-child > * { 21 | border-bottom-color: $table-group-separator-color; 22 | } 23 | } 24 | 25 | .table-sm { 26 | > :not(caption) > * > * { 27 | padding: $table-cell-padding-y-sm $table-cell-padding-x-sm; 28 | } 29 | } 30 | 31 | @each $color, $value in $table-variants { 32 | @include table-variant-mdb($color, $value); 33 | } 34 | 35 | .table-hover { 36 | > tbody > tr { 37 | transition: $table-hover-transition; 38 | } 39 | > tbody > tr:hover { 40 | --#{$variable-prefix}table-accent-bg: transparent; 41 | color: var(--#{$variable-prefix}table-hover-color); 42 | background-color: var(--#{$variable-prefix}table-hover-bg); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/scss/free/_toasts.scss: -------------------------------------------------------------------------------- 1 | // Toasts 2 | 3 | .toast { 4 | background-color: $toast-background-color; 5 | border: 0; 6 | box-shadow: $toast-box-shadow; 7 | 8 | .btn-close { 9 | width: 1.3em; 10 | } 11 | } 12 | 13 | .toast-header { 14 | background-color: $toast-header-background-color; 15 | } 16 | 17 | .parent-toast-relative { 18 | position: relative; 19 | } 20 | 21 | .toast-absolute { 22 | position: absolute; 23 | } 24 | 25 | .toast-fixed { 26 | position: fixed; 27 | z-index: $zindex-toast; 28 | } 29 | -------------------------------------------------------------------------------- /src/scss/free/_tooltip.scss: -------------------------------------------------------------------------------- 1 | // Tooltip 2 | 3 | .tooltip { 4 | &.show { 5 | opacity: 1; 6 | } 7 | 8 | .tooltip-arrow { 9 | display: none; 10 | } 11 | } 12 | 13 | .tooltip-inner { 14 | color: $tooltip-inner-color; 15 | padding: $tooltip-inner-padding-y $tooltip-inner-padding-x; 16 | font-size: $tooltip-inner-font-size; 17 | background-color: $tooltip-inner-background-color; 18 | border-radius: $tooltip-inner-border-radius; 19 | } 20 | -------------------------------------------------------------------------------- /src/scss/free/_type.scss: -------------------------------------------------------------------------------- 1 | // Type 2 | .note { 3 | padding: $note-padding; 4 | border-left: $note-border-width solid; 5 | border-radius: $note-border-radius; 6 | strong { 7 | font-weight: $note-strong-font-weight; 8 | } 9 | p { 10 | font-weight: $note-paragraph-font-weight; 11 | } 12 | } 13 | 14 | @each $name, $color in $note { 15 | .note-#{$name} { 16 | background-color: map-get($color, bgc); 17 | border-color: map-get($color, border-color); 18 | } 19 | } 20 | 21 | .w-responsive { 22 | @media (min-width: 1199px) { 23 | width: 75%; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/scss/free/forms/_form-file.scss: -------------------------------------------------------------------------------- 1 | .form-control { 2 | &[type='file'] { 3 | &::-webkit-file-upload-button { 4 | background-color: transparent; 5 | } 6 | } 7 | &:hover { 8 | &:not(:disabled):not([readonly])::-webkit-file-upload-button { 9 | background-color: transparent; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/scss/free/forms/_form-range.scss: -------------------------------------------------------------------------------- 1 | // Range 2 | // 3 | // Style range inputs the same across browsers. Vendor-specific rules for pseudo 4 | // elements cannot be mixed. As such, there are no shared styles for focus or 5 | // active states on prefixed selectors. 6 | 7 | .form-range { 8 | &:focus { 9 | box-shadow: none; 10 | 11 | // Pseudo-elements must be split across multiple rulesets to have an effect. 12 | // No box-shadow() mixin for focus accessibility. 13 | &::-webkit-slider-thumb { 14 | box-shadow: none; 15 | } 16 | &::-moz-range-thumb { 17 | box-shadow: none; 18 | } 19 | &::-ms-thumb { 20 | box-shadow: none; 21 | } 22 | } 23 | 24 | &::-moz-focus-outer { 25 | border: 0; 26 | } 27 | 28 | &::-webkit-slider-thumb { 29 | margin-top: $form-range-webkit-slider-thumb-margin-top; // Webkit specific 30 | box-shadow: none; 31 | appearance: none; 32 | } 33 | 34 | &::-webkit-slider-runnable-track { 35 | height: $form-range-webkit-slider-runnable-track-height; 36 | border-radius: 0; 37 | } 38 | 39 | &::-moz-range-thumb { 40 | box-shadow: none; 41 | appearance: none; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/scss/free/forms/_form-select.scss: -------------------------------------------------------------------------------- 1 | // Select 2 | 3 | .select-input { 4 | &.form-control { 5 | &[readonly]:not([disabled]) { 6 | background-color: transparent; 7 | } 8 | } 9 | } 10 | 11 | .form-select { 12 | transition: $form-select-transition; 13 | } 14 | 15 | .form-select:focus { 16 | border-color: $form-select-focus-border-color; 17 | outline: 0; 18 | box-shadow: $form-select-focus-border-box-shadow; 19 | } 20 | -------------------------------------------------------------------------------- /src/scss/free/mixins/_buttons.scss: -------------------------------------------------------------------------------- 1 | // Button variant 2 | @mixin button-variant-mdb($background) { 3 | color: set-notification-text-color($background); 4 | background-color: $background; 5 | 6 | &:hover { 7 | color: set-notification-text-color($background); 8 | background-color: darken($background, 7.5%); 9 | } 10 | 11 | &:focus, 12 | &.focus { 13 | color: set-notification-text-color($background); 14 | background-color: darken($background, 7.5%); 15 | } 16 | 17 | .btn-check:checked + &, 18 | .btn-check:active + &, 19 | &:active, 20 | &.active, 21 | .show > &.dropdown-toggle { 22 | color: set-notification-text-color($background); 23 | background-color: darken($background, 20%); 24 | 25 | &:focus { 26 | box-shadow: $btn-focus-box-shadow; 27 | } 28 | } 29 | 30 | &:disabled, 31 | &.disabled { 32 | color: set-notification-text-color($background); 33 | background-color: $background; 34 | } 35 | } 36 | 37 | // Button variant outline 38 | @mixin button-outline-variant-mdb($color) { 39 | color: $color; 40 | border-color: $color; 41 | 42 | &:hover { 43 | color: $color; 44 | background-color: rgba(0, 0, 0, 0.02); 45 | } 46 | 47 | &:focus, 48 | &.focus { 49 | color: $color; 50 | background-color: transparent; 51 | } 52 | 53 | &:active, 54 | &.active, 55 | &.dropdown-toggle.show { 56 | color: $color; 57 | background-color: transparent; 58 | 59 | &:focus { 60 | box-shadow: none; 61 | } 62 | } 63 | 64 | &:disabled, 65 | &.disabled { 66 | color: $color; 67 | } 68 | } 69 | 70 | // Button sizes 71 | @mixin button-size-mdb( 72 | $padding-top, 73 | $padding-right, 74 | $padding-bottom, 75 | $padding-left, 76 | $font-size, 77 | $line-height 78 | ) { 79 | padding: $padding-top $padding-right $padding-bottom $padding-left; 80 | font-size: $font-size; 81 | line-height: $line-height; 82 | } 83 | 84 | // Button size variant outline 85 | @mixin button-outline-size-mdb($padding-top, $padding-right, $padding-bottom, $padding-left) { 86 | padding: $padding-top $padding-right $padding-bottom $padding-left; 87 | } 88 | -------------------------------------------------------------------------------- /src/scss/free/mixins/_ripple.scss: -------------------------------------------------------------------------------- 1 | @mixin ripple-variant($color_value) { 2 | $gradient: rgba( 3 | $color: $color_value, 4 | $alpha: 0.2, 5 | ) 6 | 0, 7 | rgba( 8 | $color: $color_value, 9 | $alpha: 0.3, 10 | ) 11 | 40%, 12 | rgba( 13 | $color: $color_value, 14 | $alpha: 0.4, 15 | ) 16 | 50%, 17 | rgba( 18 | $color: $color_value, 19 | $alpha: 0.5, 20 | ) 21 | 60%, 22 | rgba( 23 | $color: $color_value, 24 | $alpha: 0, 25 | ) 26 | 70%; 27 | background-image: radial-gradient(circle, $gradient); 28 | } 29 | -------------------------------------------------------------------------------- /src/scss/free/mixins/_table-variants.scss: -------------------------------------------------------------------------------- 1 | // scss-docs-start table-variant 2 | @mixin table-variant-mdb($state, $background) { 3 | .table-#{$state} { 4 | background-color: $background; 5 | } 6 | } 7 | // scss-docs-end table-variant 8 | --------------------------------------------------------------------------------