mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 00:32:03 +02:00
vanilla 19.0
This commit is contained in:
parent
991d2234ca
commit
d1963a3c3a
3066 changed files with 1651266 additions and 922560 deletions
|
|
@ -1,7 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2021 Twitter, Inc.
|
||||
Copyright (c) 2011-2021 The Bootstrap Authors
|
||||
Copyright (c) 2011-2024 The Bootstrap Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -1,155 +1,24 @@
|
|||
/*!
|
||||
* Bootstrap alert.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap alert.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/event-handler.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/event-handler', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.EventHandler, global.Base));
|
||||
})(this, (function (EventHandler, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/component-functions.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/component-functions', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Alert = factory(global.BaseComponent, global.EventHandler, global.ComponentFunctions, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, componentFunctions_js, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap alert.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getElementFromSelector = element => {
|
||||
const selector = getSelector(element);
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
};
|
||||
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/component-functions.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const enableDismissTrigger = (component, method = 'hide') => {
|
||||
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
||||
const name = component.NAME;
|
||||
EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
||||
if (['A', 'AREA'].includes(this.tagName)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (isDisabled(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = getElementFromSelector(this) || this.closest(`.${name}`);
|
||||
const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
||||
|
||||
instance[method]();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): alert.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'alert';
|
||||
|
|
@ -159,75 +28,61 @@
|
|||
const EVENT_CLOSED = `closed${EVENT_KEY}`;
|
||||
const CLASS_NAME_FADE = 'fade';
|
||||
const CLASS_NAME_SHOW = 'show';
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Alert extends BaseComponent__default.default {
|
||||
class Alert extends BaseComponent {
|
||||
// Getters
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
}
|
||||
|
||||
// Public
|
||||
close() {
|
||||
const closeEvent = EventHandler__default.default.trigger(this._element, EVENT_CLOSE);
|
||||
|
||||
const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
|
||||
if (closeEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_SHOW);
|
||||
|
||||
const isAnimated = this._element.classList.contains(CLASS_NAME_FADE);
|
||||
|
||||
this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
|
||||
} // Private
|
||||
|
||||
}
|
||||
|
||||
// Private
|
||||
_destroyElement() {
|
||||
this._element.remove();
|
||||
|
||||
EventHandler__default.default.trigger(this._element, EVENT_CLOSED);
|
||||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
||||
this.dispose();
|
||||
} // Static
|
||||
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Alert.getOrCreateInstance(this);
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
componentFunctions_js.enableDismissTrigger(Alert, 'close');
|
||||
|
||||
enableDismissTrigger(Alert, 'close');
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Alert to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Alert);
|
||||
index_js.defineJQueryPlugin(Alert);
|
||||
|
||||
return Alert;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,180 +1,81 @@
|
|||
/*!
|
||||
* Bootstrap base-component.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap base-component.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/data.js'), require('./dom/event-handler.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/data', './dom/event-handler'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Base = factory(global.Data, global.EventHandler));
|
||||
})(this, (function (Data, EventHandler) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const Data__default = /*#__PURE__*/_interopDefaultLegacy(Data);
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/data.js'), require('./dom/event-handler.js'), require('./util/config.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/data', './dom/event-handler', './util/config', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.BaseComponent = factory(global.Data, global.EventHandler, global.Config, global.Index));
|
||||
})(this, (function (Data, EventHandler, Config, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap base-component.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
||||
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
} // Get transition-duration of the element
|
||||
|
||||
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
|
||||
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
} // If multiple durations are defined, take the first
|
||||
|
||||
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
};
|
||||
|
||||
const getElement = obj => {
|
||||
if (isElement(obj)) {
|
||||
// it's a jQuery object or a node element
|
||||
return obj.jquery ? obj[0] : obj;
|
||||
}
|
||||
|
||||
if (typeof obj === 'string' && obj.length > 0) {
|
||||
return document.querySelector(obj);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const execute = callback => {
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): base-component.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const VERSION = '5.1.3';
|
||||
const VERSION = '5.3.3';
|
||||
|
||||
class BaseComponent {
|
||||
constructor(element) {
|
||||
element = getElement(element);
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class BaseComponent extends Config {
|
||||
constructor(element, config) {
|
||||
super();
|
||||
element = index_js.getElement(element);
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._element = element;
|
||||
Data__default.default.set(this._element, this.constructor.DATA_KEY, this);
|
||||
this._config = this._getConfig(config);
|
||||
Data.set(this._element, this.constructor.DATA_KEY, this);
|
||||
}
|
||||
|
||||
// Public
|
||||
dispose() {
|
||||
Data__default.default.remove(this._element, this.constructor.DATA_KEY);
|
||||
EventHandler__default.default.off(this._element, this.constructor.EVENT_KEY);
|
||||
Object.getOwnPropertyNames(this).forEach(propertyName => {
|
||||
Data.remove(this._element, this.constructor.DATA_KEY);
|
||||
EventHandler.off(this._element, this.constructor.EVENT_KEY);
|
||||
for (const propertyName of Object.getOwnPropertyNames(this)) {
|
||||
this[propertyName] = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_queueCallback(callback, element, isAnimated = true) {
|
||||
executeAfterTransition(callback, element, isAnimated);
|
||||
index_js.executeAfterTransition(callback, element, isAnimated);
|
||||
}
|
||||
_getConfig(config) {
|
||||
config = this._mergeConfigObj(config, this._element);
|
||||
config = this._configAfterMerge(config);
|
||||
this._typeCheckConfig(config);
|
||||
return config;
|
||||
}
|
||||
/** Static */
|
||||
|
||||
|
||||
// Static
|
||||
static getInstance(element) {
|
||||
return Data__default.default.get(getElement(element), this.DATA_KEY);
|
||||
return Data.get(index_js.getElement(element), this.DATA_KEY);
|
||||
}
|
||||
|
||||
static getOrCreateInstance(element, config = {}) {
|
||||
return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);
|
||||
}
|
||||
|
||||
static get VERSION() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
static get NAME() {
|
||||
throw new Error('You have to implement the static method "NAME", for each component!');
|
||||
}
|
||||
|
||||
static get DATA_KEY() {
|
||||
return `bs.${this.NAME}`;
|
||||
}
|
||||
|
||||
static get EVENT_KEY() {
|
||||
return `.${this.DATA_KEY}`;
|
||||
}
|
||||
|
||||
static eventName(name) {
|
||||
return `${name}${this.EVENT_KEY}`;
|
||||
}
|
||||
}
|
||||
|
||||
return BaseComponent;
|
||||
|
|
|
|||
|
|
@ -1,84 +1,24 @@
|
|||
/*!
|
||||
* Bootstrap button.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap button.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/event-handler.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/event-handler', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Button = factory(global.EventHandler, global.Base));
|
||||
})(this, (function (EventHandler, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Button = factory(global.BaseComponent, global.EventHandler, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap button.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): button.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'button';
|
||||
|
|
@ -88,57 +28,50 @@
|
|||
const CLASS_NAME_ACTIVE = 'active';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]';
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Button extends BaseComponent__default.default {
|
||||
class Button extends BaseComponent {
|
||||
// Getters
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
}
|
||||
|
||||
// Public
|
||||
toggle() {
|
||||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE));
|
||||
} // Static
|
||||
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Button.getOrCreateInstance(this);
|
||||
|
||||
if (config === 'toggle') {
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
|
||||
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {
|
||||
event.preventDefault();
|
||||
const button = event.target.closest(SELECTOR_DATA_TOGGLE);
|
||||
const data = Button.getOrCreateInstance(button);
|
||||
data.toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Button to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Button);
|
||||
index_js.defineJQueryPlugin(Button);
|
||||
|
||||
return Button;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,203 +1,24 @@
|
|||
/*!
|
||||
* Bootstrap carousel.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap carousel.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Carousel = factory(global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
|
||||
})(this, (function (EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
||||
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./util/index.js'), require('./util/swipe.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './util/index', './util/swipe'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Carousel = factory(global.BaseComponent, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Index, global.Swipe));
|
||||
})(this, (function (BaseComponent, EventHandler, Manipulator, SelectorEngine, index_js, Swipe) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap carousel.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
||||
|
||||
const toType = obj => {
|
||||
if (obj === null || obj === undefined) {
|
||||
return `${obj}`;
|
||||
}
|
||||
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getElementFromSelector = element => {
|
||||
const selector = getSelector(element);
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
};
|
||||
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
};
|
||||
|
||||
const typeCheckConfig = (componentName, config, configTypes) => {
|
||||
Object.keys(configTypes).forEach(property => {
|
||||
const expectedTypes = configTypes[property];
|
||||
const value = config[property];
|
||||
const valueType = value && isElement(value) ? 'element' : toType(value);
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
};
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
|
||||
|
||||
const reflow = element => {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
element.offsetHeight;
|
||||
};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
|
||||
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed
|
||||
|
||||
if (index === -1) {
|
||||
return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
|
||||
}
|
||||
|
||||
const listLength = list.length;
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): carousel.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'carousel';
|
||||
|
|
@ -208,41 +29,15 @@
|
|||
const ARROW_RIGHT_KEY = 'ArrowRight';
|
||||
const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
|
||||
|
||||
const SWIPE_THRESHOLD = 40;
|
||||
const Default = {
|
||||
interval: 5000,
|
||||
keyboard: true,
|
||||
slide: false,
|
||||
pause: 'hover',
|
||||
wrap: true,
|
||||
touch: true
|
||||
};
|
||||
const DefaultType = {
|
||||
interval: '(number|boolean)',
|
||||
keyboard: 'boolean',
|
||||
slide: '(boolean|string)',
|
||||
pause: '(string|boolean)',
|
||||
wrap: 'boolean',
|
||||
touch: 'boolean'
|
||||
};
|
||||
const ORDER_NEXT = 'next';
|
||||
const ORDER_PREV = 'prev';
|
||||
const DIRECTION_LEFT = 'left';
|
||||
const DIRECTION_RIGHT = 'right';
|
||||
const KEY_TO_DIRECTION = {
|
||||
[ARROW_LEFT_KEY]: DIRECTION_RIGHT,
|
||||
[ARROW_RIGHT_KEY]: DIRECTION_LEFT
|
||||
};
|
||||
const EVENT_SLIDE = `slide${EVENT_KEY}`;
|
||||
const EVENT_SLID = `slid${EVENT_KEY}`;
|
||||
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
|
||||
const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`;
|
||||
const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`;
|
||||
const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`;
|
||||
const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`;
|
||||
const EVENT_TOUCHEND = `touchend${EVENT_KEY}`;
|
||||
const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`;
|
||||
const EVENT_POINTERUP = `pointerup${EVENT_KEY}`;
|
||||
const EVENT_DRAG_START = `dragstart${EVENT_KEY}`;
|
||||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
||||
|
|
@ -253,489 +48,339 @@
|
|||
const CLASS_NAME_START = 'carousel-item-start';
|
||||
const CLASS_NAME_NEXT = 'carousel-item-next';
|
||||
const CLASS_NAME_PREV = 'carousel-item-prev';
|
||||
const CLASS_NAME_POINTER_EVENT = 'pointer-event';
|
||||
const SELECTOR_ACTIVE = '.active';
|
||||
const SELECTOR_ACTIVE_ITEM = '.active.carousel-item';
|
||||
const SELECTOR_ITEM = '.carousel-item';
|
||||
const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;
|
||||
const SELECTOR_ITEM_IMG = '.carousel-item img';
|
||||
const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';
|
||||
const SELECTOR_INDICATORS = '.carousel-indicators';
|
||||
const SELECTOR_INDICATOR = '[data-bs-target]';
|
||||
const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';
|
||||
const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]';
|
||||
const POINTER_TYPE_TOUCH = 'touch';
|
||||
const POINTER_TYPE_PEN = 'pen';
|
||||
const KEY_TO_DIRECTION = {
|
||||
[ARROW_LEFT_KEY]: DIRECTION_RIGHT,
|
||||
[ARROW_RIGHT_KEY]: DIRECTION_LEFT
|
||||
};
|
||||
const Default = {
|
||||
interval: 5000,
|
||||
keyboard: true,
|
||||
pause: 'hover',
|
||||
ride: false,
|
||||
touch: true,
|
||||
wrap: true
|
||||
};
|
||||
const DefaultType = {
|
||||
interval: '(number|boolean)',
|
||||
// TODO:v6 remove boolean support
|
||||
keyboard: 'boolean',
|
||||
pause: '(string|boolean)',
|
||||
ride: '(boolean|string)',
|
||||
touch: 'boolean',
|
||||
wrap: 'boolean'
|
||||
};
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Carousel extends BaseComponent__default.default {
|
||||
class Carousel extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
super(element);
|
||||
this._items = null;
|
||||
super(element, config);
|
||||
this._interval = null;
|
||||
this._activeElement = null;
|
||||
this._isPaused = false;
|
||||
this._isSliding = false;
|
||||
this.touchTimeout = null;
|
||||
this.touchStartX = 0;
|
||||
this.touchDeltaX = 0;
|
||||
this._config = this._getConfig(config);
|
||||
this._indicatorsElement = SelectorEngine__default.default.findOne(SELECTOR_INDICATORS, this._element);
|
||||
this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
|
||||
this._pointerEvent = Boolean(window.PointerEvent);
|
||||
|
||||
this._swipeHelper = null;
|
||||
this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);
|
||||
this._addEventListeners();
|
||||
} // Getters
|
||||
|
||||
if (this._config.ride === CLASS_NAME_CAROUSEL) {
|
||||
this.cycle();
|
||||
}
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
}
|
||||
|
||||
// Public
|
||||
next() {
|
||||
this._slide(ORDER_NEXT);
|
||||
}
|
||||
|
||||
nextWhenVisible() {
|
||||
// FIXME TODO use `document.visibilityState`
|
||||
// Don't call next when the page isn't visible
|
||||
// or the carousel or its parent isn't visible
|
||||
if (!document.hidden && isVisible(this._element)) {
|
||||
if (!document.hidden && index_js.isVisible(this._element)) {
|
||||
this.next();
|
||||
}
|
||||
}
|
||||
|
||||
prev() {
|
||||
this._slide(ORDER_PREV);
|
||||
}
|
||||
|
||||
pause(event) {
|
||||
if (!event) {
|
||||
this._isPaused = true;
|
||||
}
|
||||
|
||||
if (SelectorEngine__default.default.findOne(SELECTOR_NEXT_PREV, this._element)) {
|
||||
triggerTransitionEnd(this._element);
|
||||
this.cycle(true);
|
||||
}
|
||||
|
||||
clearInterval(this._interval);
|
||||
this._interval = null;
|
||||
}
|
||||
|
||||
cycle(event) {
|
||||
if (!event) {
|
||||
this._isPaused = false;
|
||||
}
|
||||
|
||||
if (this._interval) {
|
||||
clearInterval(this._interval);
|
||||
this._interval = null;
|
||||
}
|
||||
|
||||
if (this._config && this._config.interval && !this._isPaused) {
|
||||
this._updateInterval();
|
||||
|
||||
this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
|
||||
}
|
||||
}
|
||||
|
||||
to(index) {
|
||||
this._activeElement = SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM, this._element);
|
||||
|
||||
const activeIndex = this._getItemIndex(this._activeElement);
|
||||
|
||||
if (index > this._items.length - 1 || index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pause() {
|
||||
if (this._isSliding) {
|
||||
EventHandler__default.default.one(this._element, EVENT_SLID, () => this.to(index));
|
||||
index_js.triggerTransitionEnd(this._element);
|
||||
}
|
||||
this._clearInterval();
|
||||
}
|
||||
cycle() {
|
||||
this._clearInterval();
|
||||
this._updateInterval();
|
||||
this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);
|
||||
}
|
||||
_maybeEnableCycle() {
|
||||
if (!this._config.ride) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._isSliding) {
|
||||
EventHandler.one(this._element, EVENT_SLID, () => this.cycle());
|
||||
return;
|
||||
}
|
||||
this.cycle();
|
||||
}
|
||||
to(index) {
|
||||
const items = this._getItems();
|
||||
if (index > items.length - 1 || index < 0) {
|
||||
return;
|
||||
}
|
||||
if (this._isSliding) {
|
||||
EventHandler.one(this._element, EVENT_SLID, () => this.to(index));
|
||||
return;
|
||||
}
|
||||
const activeIndex = this._getItemIndex(this._getActive());
|
||||
if (activeIndex === index) {
|
||||
this.pause();
|
||||
this.cycle();
|
||||
return;
|
||||
}
|
||||
|
||||
const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;
|
||||
this._slide(order, items[index]);
|
||||
}
|
||||
dispose() {
|
||||
if (this._swipeHelper) {
|
||||
this._swipeHelper.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
this._slide(order, this._items[index]);
|
||||
} // Private
|
||||
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...Default,
|
||||
...Manipulator__default.default.getDataAttributes(this._element),
|
||||
...(typeof config === 'object' ? config : {})
|
||||
};
|
||||
typeCheckConfig(NAME, config, DefaultType);
|
||||
// Private
|
||||
_configAfterMerge(config) {
|
||||
config.defaultInterval = config.interval;
|
||||
return config;
|
||||
}
|
||||
|
||||
_handleSwipe() {
|
||||
const absDeltax = Math.abs(this.touchDeltaX);
|
||||
|
||||
if (absDeltax <= SWIPE_THRESHOLD) {
|
||||
return;
|
||||
}
|
||||
|
||||
const direction = absDeltax / this.touchDeltaX;
|
||||
this.touchDeltaX = 0;
|
||||
|
||||
if (!direction) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT);
|
||||
}
|
||||
|
||||
_addEventListeners() {
|
||||
if (this._config.keyboard) {
|
||||
EventHandler__default.default.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
|
||||
EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
|
||||
}
|
||||
|
||||
if (this._config.pause === 'hover') {
|
||||
EventHandler__default.default.on(this._element, EVENT_MOUSEENTER, event => this.pause(event));
|
||||
EventHandler__default.default.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event));
|
||||
EventHandler.on(this._element, EVENT_MOUSEENTER, () => this.pause());
|
||||
EventHandler.on(this._element, EVENT_MOUSELEAVE, () => this._maybeEnableCycle());
|
||||
}
|
||||
|
||||
if (this._config.touch && this._touchSupported) {
|
||||
if (this._config.touch && Swipe.isSupported()) {
|
||||
this._addTouchEventListeners();
|
||||
}
|
||||
}
|
||||
|
||||
_addTouchEventListeners() {
|
||||
const hasPointerPenTouch = event => {
|
||||
return this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);
|
||||
};
|
||||
|
||||
const start = event => {
|
||||
if (hasPointerPenTouch(event)) {
|
||||
this.touchStartX = event.clientX;
|
||||
} else if (!this._pointerEvent) {
|
||||
this.touchStartX = event.touches[0].clientX;
|
||||
}
|
||||
};
|
||||
|
||||
const move = event => {
|
||||
// ensure swiping with one touch and not pinching
|
||||
this.touchDeltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this.touchStartX;
|
||||
};
|
||||
|
||||
const end = event => {
|
||||
if (hasPointerPenTouch(event)) {
|
||||
this.touchDeltaX = event.clientX - this.touchStartX;
|
||||
}
|
||||
|
||||
this._handleSwipe();
|
||||
|
||||
if (this._config.pause === 'hover') {
|
||||
// If it's a touch-enabled device, mouseenter/leave are fired as
|
||||
// part of the mouse compatibility events on first tap - the carousel
|
||||
// would stop cycling until user tapped out of it;
|
||||
// here, we listen for touchend, explicitly pause the carousel
|
||||
// (as if it's the second time we tap on it, mouseenter compat event
|
||||
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
||||
// events to fire) we explicitly restart cycling
|
||||
this.pause();
|
||||
|
||||
if (this.touchTimeout) {
|
||||
clearTimeout(this.touchTimeout);
|
||||
}
|
||||
|
||||
this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval);
|
||||
}
|
||||
};
|
||||
|
||||
SelectorEngine__default.default.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {
|
||||
EventHandler__default.default.on(itemImg, EVENT_DRAG_START, event => event.preventDefault());
|
||||
});
|
||||
|
||||
if (this._pointerEvent) {
|
||||
EventHandler__default.default.on(this._element, EVENT_POINTERDOWN, event => start(event));
|
||||
EventHandler__default.default.on(this._element, EVENT_POINTERUP, event => end(event));
|
||||
|
||||
this._element.classList.add(CLASS_NAME_POINTER_EVENT);
|
||||
} else {
|
||||
EventHandler__default.default.on(this._element, EVENT_TOUCHSTART, event => start(event));
|
||||
EventHandler__default.default.on(this._element, EVENT_TOUCHMOVE, event => move(event));
|
||||
EventHandler__default.default.on(this._element, EVENT_TOUCHEND, event => end(event));
|
||||
for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {
|
||||
EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());
|
||||
}
|
||||
}
|
||||
const endCallBack = () => {
|
||||
if (this._config.pause !== 'hover') {
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's a touch-enabled device, mouseenter/leave are fired as
|
||||
// part of the mouse compatibility events on first tap - the carousel
|
||||
// would stop cycling until user tapped out of it;
|
||||
// here, we listen for touchend, explicitly pause the carousel
|
||||
// (as if it's the second time we tap on it, mouseenter compat event
|
||||
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
||||
// events to fire) we explicitly restart cycling
|
||||
|
||||
this.pause();
|
||||
if (this.touchTimeout) {
|
||||
clearTimeout(this.touchTimeout);
|
||||
}
|
||||
this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);
|
||||
};
|
||||
const swipeConfig = {
|
||||
leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),
|
||||
rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),
|
||||
endCallback: endCallBack
|
||||
};
|
||||
this._swipeHelper = new Swipe(this._element, swipeConfig);
|
||||
}
|
||||
_keydown(event) {
|
||||
if (/input|textarea/i.test(event.target.tagName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const direction = KEY_TO_DIRECTION[event.key];
|
||||
|
||||
if (direction) {
|
||||
event.preventDefault();
|
||||
|
||||
this._slide(direction);
|
||||
this._slide(this._directionToOrder(direction));
|
||||
}
|
||||
}
|
||||
|
||||
_getItemIndex(element) {
|
||||
this._items = element && element.parentNode ? SelectorEngine__default.default.find(SELECTOR_ITEM, element.parentNode) : [];
|
||||
return this._items.indexOf(element);
|
||||
return this._getItems().indexOf(element);
|
||||
}
|
||||
|
||||
_getItemByOrder(order, activeElement) {
|
||||
const isNext = order === ORDER_NEXT;
|
||||
return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);
|
||||
}
|
||||
|
||||
_triggerSlideEvent(relatedTarget, eventDirectionName) {
|
||||
const targetIndex = this._getItemIndex(relatedTarget);
|
||||
|
||||
const fromIndex = this._getItemIndex(SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM, this._element));
|
||||
|
||||
return EventHandler__default.default.trigger(this._element, EVENT_SLIDE, {
|
||||
relatedTarget,
|
||||
direction: eventDirectionName,
|
||||
from: fromIndex,
|
||||
to: targetIndex
|
||||
});
|
||||
}
|
||||
|
||||
_setActiveIndicatorElement(element) {
|
||||
if (this._indicatorsElement) {
|
||||
const activeIndicator = SelectorEngine__default.default.findOne(SELECTOR_ACTIVE, this._indicatorsElement);
|
||||
activeIndicator.classList.remove(CLASS_NAME_ACTIVE);
|
||||
activeIndicator.removeAttribute('aria-current');
|
||||
const indicators = SelectorEngine__default.default.find(SELECTOR_INDICATOR, this._indicatorsElement);
|
||||
|
||||
for (let i = 0; i < indicators.length; i++) {
|
||||
if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {
|
||||
indicators[i].classList.add(CLASS_NAME_ACTIVE);
|
||||
indicators[i].setAttribute('aria-current', 'true');
|
||||
break;
|
||||
}
|
||||
}
|
||||
_setActiveIndicatorElement(index) {
|
||||
if (!this._indicatorsElement) {
|
||||
return;
|
||||
}
|
||||
const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);
|
||||
activeIndicator.classList.remove(CLASS_NAME_ACTIVE);
|
||||
activeIndicator.removeAttribute('aria-current');
|
||||
const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement);
|
||||
if (newActiveIndicator) {
|
||||
newActiveIndicator.classList.add(CLASS_NAME_ACTIVE);
|
||||
newActiveIndicator.setAttribute('aria-current', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
_updateInterval() {
|
||||
const element = this._activeElement || SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM, this._element);
|
||||
|
||||
const element = this._activeElement || this._getActive();
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);
|
||||
|
||||
if (elementInterval) {
|
||||
this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
|
||||
this._config.interval = elementInterval;
|
||||
} else {
|
||||
this._config.interval = this._config.defaultInterval || this._config.interval;
|
||||
}
|
||||
this._config.interval = elementInterval || this._config.defaultInterval;
|
||||
}
|
||||
|
||||
_slide(directionOrOrder, element) {
|
||||
const order = this._directionToOrder(directionOrOrder);
|
||||
|
||||
const activeElement = SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM, this._element);
|
||||
|
||||
const activeElementIndex = this._getItemIndex(activeElement);
|
||||
|
||||
const nextElement = element || this._getItemByOrder(order, activeElement);
|
||||
|
||||
const nextElementIndex = this._getItemIndex(nextElement);
|
||||
|
||||
const isCycling = Boolean(this._interval);
|
||||
const isNext = order === ORDER_NEXT;
|
||||
const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
|
||||
const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
|
||||
|
||||
const eventDirectionName = this._orderToDirection(order);
|
||||
|
||||
if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) {
|
||||
this._isSliding = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_slide(order, element = null) {
|
||||
if (this._isSliding) {
|
||||
return;
|
||||
}
|
||||
|
||||
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
|
||||
|
||||
if (slideEvent.defaultPrevented) {
|
||||
const activeElement = this._getActive();
|
||||
const isNext = order === ORDER_NEXT;
|
||||
const nextElement = element || index_js.getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);
|
||||
if (nextElement === activeElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activeElement || !nextElement) {
|
||||
// Some weirdness is happening, so we bail
|
||||
return;
|
||||
}
|
||||
|
||||
this._isSliding = true;
|
||||
|
||||
if (isCycling) {
|
||||
this.pause();
|
||||
}
|
||||
|
||||
this._setActiveIndicatorElement(nextElement);
|
||||
|
||||
this._activeElement = nextElement;
|
||||
|
||||
const triggerSlidEvent = () => {
|
||||
EventHandler__default.default.trigger(this._element, EVENT_SLID, {
|
||||
const nextElementIndex = this._getItemIndex(nextElement);
|
||||
const triggerEvent = eventName => {
|
||||
return EventHandler.trigger(this._element, eventName, {
|
||||
relatedTarget: nextElement,
|
||||
direction: eventDirectionName,
|
||||
from: activeElementIndex,
|
||||
direction: this._orderToDirection(order),
|
||||
from: this._getItemIndex(activeElement),
|
||||
to: nextElementIndex
|
||||
});
|
||||
};
|
||||
|
||||
if (this._element.classList.contains(CLASS_NAME_SLIDE)) {
|
||||
nextElement.classList.add(orderClassName);
|
||||
reflow(nextElement);
|
||||
activeElement.classList.add(directionalClassName);
|
||||
nextElement.classList.add(directionalClassName);
|
||||
|
||||
const completeCallBack = () => {
|
||||
nextElement.classList.remove(directionalClassName, orderClassName);
|
||||
nextElement.classList.add(CLASS_NAME_ACTIVE);
|
||||
activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName);
|
||||
this._isSliding = false;
|
||||
setTimeout(triggerSlidEvent, 0);
|
||||
};
|
||||
|
||||
this._queueCallback(completeCallBack, activeElement, true);
|
||||
} else {
|
||||
activeElement.classList.remove(CLASS_NAME_ACTIVE);
|
||||
nextElement.classList.add(CLASS_NAME_ACTIVE);
|
||||
this._isSliding = false;
|
||||
triggerSlidEvent();
|
||||
const slideEvent = triggerEvent(EVENT_SLIDE);
|
||||
if (slideEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activeElement || !nextElement) {
|
||||
// Some weirdness is happening, so we bail
|
||||
// TODO: change tests that use empty divs to avoid this check
|
||||
return;
|
||||
}
|
||||
const isCycling = Boolean(this._interval);
|
||||
this.pause();
|
||||
this._isSliding = true;
|
||||
this._setActiveIndicatorElement(nextElementIndex);
|
||||
this._activeElement = nextElement;
|
||||
const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
|
||||
const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
|
||||
nextElement.classList.add(orderClassName);
|
||||
index_js.reflow(nextElement);
|
||||
activeElement.classList.add(directionalClassName);
|
||||
nextElement.classList.add(directionalClassName);
|
||||
const completeCallBack = () => {
|
||||
nextElement.classList.remove(directionalClassName, orderClassName);
|
||||
nextElement.classList.add(CLASS_NAME_ACTIVE);
|
||||
activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName);
|
||||
this._isSliding = false;
|
||||
triggerEvent(EVENT_SLID);
|
||||
};
|
||||
this._queueCallback(completeCallBack, activeElement, this._isAnimated());
|
||||
if (isCycling) {
|
||||
this.cycle();
|
||||
}
|
||||
}
|
||||
|
||||
_directionToOrder(direction) {
|
||||
if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {
|
||||
return direction;
|
||||
_isAnimated() {
|
||||
return this._element.classList.contains(CLASS_NAME_SLIDE);
|
||||
}
|
||||
_getActive() {
|
||||
return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
|
||||
}
|
||||
_getItems() {
|
||||
return SelectorEngine.find(SELECTOR_ITEM, this._element);
|
||||
}
|
||||
_clearInterval() {
|
||||
if (this._interval) {
|
||||
clearInterval(this._interval);
|
||||
this._interval = null;
|
||||
}
|
||||
|
||||
if (isRTL()) {
|
||||
}
|
||||
_directionToOrder(direction) {
|
||||
if (index_js.isRTL()) {
|
||||
return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
|
||||
}
|
||||
|
||||
return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
|
||||
}
|
||||
|
||||
_orderToDirection(order) {
|
||||
if (![ORDER_NEXT, ORDER_PREV].includes(order)) {
|
||||
return order;
|
||||
}
|
||||
|
||||
if (isRTL()) {
|
||||
if (index_js.isRTL()) {
|
||||
return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
|
||||
}
|
||||
|
||||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
||||
} // Static
|
||||
|
||||
|
||||
static carouselInterface(element, config) {
|
||||
const data = Carousel.getOrCreateInstance(element, config);
|
||||
let {
|
||||
_config
|
||||
} = data;
|
||||
|
||||
if (typeof config === 'object') {
|
||||
_config = { ..._config,
|
||||
...config
|
||||
};
|
||||
}
|
||||
|
||||
const action = typeof config === 'string' ? config : _config.slide;
|
||||
|
||||
if (typeof config === 'number') {
|
||||
data.to(config);
|
||||
} else if (typeof action === 'string') {
|
||||
if (typeof data[action] === 'undefined') {
|
||||
throw new TypeError(`No method named "${action}"`);
|
||||
}
|
||||
|
||||
data[action]();
|
||||
} else if (_config.interval && _config.ride) {
|
||||
data.pause();
|
||||
data.cycle();
|
||||
}
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
Carousel.carouselInterface(this, config);
|
||||
const data = Carousel.getOrCreateInstance(this, config);
|
||||
if (typeof config === 'number') {
|
||||
data.to(config);
|
||||
return;
|
||||
}
|
||||
if (typeof config === 'string') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static dataApiClickHandler(event) {
|
||||
const target = getElementFromSelector(this);
|
||||
|
||||
if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const config = { ...Manipulator__default.default.getDataAttributes(target),
|
||||
...Manipulator__default.default.getDataAttributes(this)
|
||||
};
|
||||
const slideIndex = this.getAttribute('data-bs-slide-to');
|
||||
|
||||
if (slideIndex) {
|
||||
config.interval = false;
|
||||
}
|
||||
|
||||
Carousel.carouselInterface(target, config);
|
||||
|
||||
if (slideIndex) {
|
||||
Carousel.getInstance(target).to(slideIndex);
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
|
||||
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler);
|
||||
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
const carousels = SelectorEngine__default.default.find(SELECTOR_DATA_RIDE);
|
||||
|
||||
for (let i = 0, len = carousels.length; i < len; i++) {
|
||||
Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, function (event) {
|
||||
const target = SelectorEngine.getElementFromSelector(this);
|
||||
if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
const carousel = Carousel.getOrCreateInstance(target);
|
||||
const slideIndex = this.getAttribute('data-bs-slide-to');
|
||||
if (slideIndex) {
|
||||
carousel.to(slideIndex);
|
||||
carousel._maybeEnableCycle();
|
||||
return;
|
||||
}
|
||||
if (Manipulator.getDataAttribute(this, 'slide') === 'next') {
|
||||
carousel.next();
|
||||
carousel._maybeEnableCycle();
|
||||
return;
|
||||
}
|
||||
carousel.prev();
|
||||
carousel._maybeEnableCycle();
|
||||
});
|
||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
|
||||
for (const carousel of carousels) {
|
||||
Carousel.getOrCreateInstance(carousel);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Carousel to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Carousel);
|
||||
index_js.defineJQueryPlugin(Carousel);
|
||||
|
||||
return Carousel;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,199 +1,30 @@
|
|||
/*!
|
||||
* Bootstrap collapse.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap collapse.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/data.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/data', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Collapse = factory(global.Data, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
|
||||
})(this, (function (Data, EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const Data__default = /*#__PURE__*/_interopDefaultLegacy(Data);
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
||||
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Collapse = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, SelectorEngine, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap collapse.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const toType = obj => {
|
||||
if (obj === null || obj === undefined) {
|
||||
return `${obj}`;
|
||||
}
|
||||
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getSelectorFromElement = element => {
|
||||
const selector = getSelector(element);
|
||||
|
||||
if (selector) {
|
||||
return document.querySelector(selector) ? selector : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const getElementFromSelector = element => {
|
||||
const selector = getSelector(element);
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
};
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
};
|
||||
|
||||
const getElement = obj => {
|
||||
if (isElement(obj)) {
|
||||
// it's a jQuery object or a node element
|
||||
return obj.jquery ? obj[0] : obj;
|
||||
}
|
||||
|
||||
if (typeof obj === 'string' && obj.length > 0) {
|
||||
return document.querySelector(obj);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const typeCheckConfig = (componentName, config, configTypes) => {
|
||||
Object.keys(configTypes).forEach(property => {
|
||||
const expectedTypes = configTypes[property];
|
||||
const value = config[property];
|
||||
const valueType = value && isElement(value) ? 'element' : toType(value);
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
|
||||
|
||||
const reflow = element => {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
element.offsetHeight;
|
||||
};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): collapse.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'collapse';
|
||||
const DATA_KEY = 'bs.collapse';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const DATA_API_KEY = '.data-api';
|
||||
const Default = {
|
||||
toggle: true,
|
||||
parent: null
|
||||
};
|
||||
const DefaultType = {
|
||||
toggle: 'boolean',
|
||||
parent: '(null|element)'
|
||||
};
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||||
|
|
@ -209,53 +40,53 @@
|
|||
const HEIGHT = 'height';
|
||||
const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]';
|
||||
const Default = {
|
||||
parent: null,
|
||||
toggle: true
|
||||
};
|
||||
const DefaultType = {
|
||||
parent: '(null|element)',
|
||||
toggle: 'boolean'
|
||||
};
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Collapse extends BaseComponent__default.default {
|
||||
class Collapse extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
super(element);
|
||||
super(element, config);
|
||||
this._isTransitioning = false;
|
||||
this._config = this._getConfig(config);
|
||||
this._triggerArray = [];
|
||||
const toggleList = SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE);
|
||||
|
||||
for (let i = 0, len = toggleList.length; i < len; i++) {
|
||||
const elem = toggleList[i];
|
||||
const selector = getSelectorFromElement(elem);
|
||||
const filterElement = SelectorEngine__default.default.find(selector).filter(foundElem => foundElem === this._element);
|
||||
|
||||
const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE);
|
||||
for (const elem of toggleList) {
|
||||
const selector = SelectorEngine.getSelectorFromElement(elem);
|
||||
const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);
|
||||
if (selector !== null && filterElement.length) {
|
||||
this._selector = selector;
|
||||
|
||||
this._triggerArray.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
this._initializeChildren();
|
||||
|
||||
if (!this._config.parent) {
|
||||
this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
|
||||
}
|
||||
|
||||
if (this._config.toggle) {
|
||||
this.toggle();
|
||||
}
|
||||
} // Getters
|
||||
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
}
|
||||
|
||||
// Public
|
||||
toggle() {
|
||||
if (this._isShown()) {
|
||||
this.hide();
|
||||
|
|
@ -263,231 +94,154 @@
|
|||
this.show();
|
||||
}
|
||||
}
|
||||
|
||||
show() {
|
||||
if (this._isTransitioning || this._isShown()) {
|
||||
return;
|
||||
}
|
||||
let activeChildren = [];
|
||||
|
||||
let actives = [];
|
||||
let activesData;
|
||||
|
||||
// find active children
|
||||
if (this._config.parent) {
|
||||
const children = SelectorEngine__default.default.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
|
||||
actives = SelectorEngine__default.default.find(SELECTOR_ACTIVES, this._config.parent).filter(elem => !children.includes(elem)); // remove children if greater depth
|
||||
activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {
|
||||
toggle: false
|
||||
}));
|
||||
}
|
||||
|
||||
const container = SelectorEngine__default.default.findOne(this._selector);
|
||||
|
||||
if (actives.length) {
|
||||
const tempActiveData = actives.find(elem => container !== elem);
|
||||
activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;
|
||||
|
||||
if (activesData && activesData._isTransitioning) {
|
||||
return;
|
||||
}
|
||||
if (activeChildren.length && activeChildren[0]._isTransitioning) {
|
||||
return;
|
||||
}
|
||||
|
||||
const startEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW);
|
||||
|
||||
const startEvent = EventHandler.trigger(this._element, EVENT_SHOW);
|
||||
if (startEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
actives.forEach(elemActive => {
|
||||
if (container !== elemActive) {
|
||||
Collapse.getOrCreateInstance(elemActive, {
|
||||
toggle: false
|
||||
}).hide();
|
||||
}
|
||||
|
||||
if (!activesData) {
|
||||
Data__default.default.set(elemActive, DATA_KEY, null);
|
||||
}
|
||||
});
|
||||
|
||||
for (const activeInstance of activeChildren) {
|
||||
activeInstance.hide();
|
||||
}
|
||||
const dimension = this._getDimension();
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_COLLAPSE);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_COLLAPSING);
|
||||
|
||||
this._element.style[dimension] = 0;
|
||||
|
||||
this._addAriaAndCollapsedClass(this._triggerArray, true);
|
||||
|
||||
this._isTransitioning = true;
|
||||
|
||||
const complete = () => {
|
||||
this._isTransitioning = false;
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_COLLAPSING);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
|
||||
|
||||
this._element.style[dimension] = '';
|
||||
EventHandler__default.default.trigger(this._element, EVENT_SHOWN);
|
||||
EventHandler.trigger(this._element, EVENT_SHOWN);
|
||||
};
|
||||
|
||||
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
|
||||
const scrollSize = `scroll${capitalizedDimension}`;
|
||||
|
||||
this._queueCallback(complete, this._element, true);
|
||||
|
||||
this._element.style[dimension] = `${this._element[scrollSize]}px`;
|
||||
}
|
||||
|
||||
hide() {
|
||||
if (this._isTransitioning || !this._isShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const startEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
|
||||
|
||||
const startEvent = EventHandler.trigger(this._element, EVENT_HIDE);
|
||||
if (startEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dimension = this._getDimension();
|
||||
|
||||
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;
|
||||
reflow(this._element);
|
||||
|
||||
index_js.reflow(this._element);
|
||||
this._element.classList.add(CLASS_NAME_COLLAPSING);
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
|
||||
|
||||
const triggerArrayLength = this._triggerArray.length;
|
||||
|
||||
for (let i = 0; i < triggerArrayLength; i++) {
|
||||
const trigger = this._triggerArray[i];
|
||||
const elem = getElementFromSelector(trigger);
|
||||
|
||||
if (elem && !this._isShown(elem)) {
|
||||
for (const trigger of this._triggerArray) {
|
||||
const element = SelectorEngine.getElementFromSelector(trigger);
|
||||
if (element && !this._isShown(element)) {
|
||||
this._addAriaAndCollapsedClass([trigger], false);
|
||||
}
|
||||
}
|
||||
|
||||
this._isTransitioning = true;
|
||||
|
||||
const complete = () => {
|
||||
this._isTransitioning = false;
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_COLLAPSING);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_COLLAPSE);
|
||||
|
||||
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
|
||||
EventHandler.trigger(this._element, EVENT_HIDDEN);
|
||||
};
|
||||
|
||||
this._element.style[dimension] = '';
|
||||
|
||||
this._queueCallback(complete, this._element, true);
|
||||
}
|
||||
|
||||
_isShown(element = this._element) {
|
||||
return element.classList.contains(CLASS_NAME_SHOW);
|
||||
} // Private
|
||||
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...Default,
|
||||
...Manipulator__default.default.getDataAttributes(this._element),
|
||||
...config
|
||||
};
|
||||
config.toggle = Boolean(config.toggle); // Coerce string values
|
||||
|
||||
config.parent = getElement(config.parent);
|
||||
typeCheckConfig(NAME, config, DefaultType);
|
||||
return config;
|
||||
}
|
||||
|
||||
// Private
|
||||
_configAfterMerge(config) {
|
||||
config.toggle = Boolean(config.toggle); // Coerce string values
|
||||
config.parent = index_js.getElement(config.parent);
|
||||
return config;
|
||||
}
|
||||
_getDimension() {
|
||||
return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
|
||||
}
|
||||
|
||||
_initializeChildren() {
|
||||
if (!this._config.parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const children = SelectorEngine__default.default.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
|
||||
SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE, this._config.parent).filter(elem => !children.includes(elem)).forEach(element => {
|
||||
const selected = getElementFromSelector(element);
|
||||
|
||||
const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE);
|
||||
for (const element of children) {
|
||||
const selected = SelectorEngine.getElementFromSelector(element);
|
||||
if (selected) {
|
||||
this._addAriaAndCollapsedClass([element], this._isShown(selected));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
_getFirstLevelChildren(selector) {
|
||||
const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
|
||||
// remove children if greater depth
|
||||
return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));
|
||||
}
|
||||
|
||||
_addAriaAndCollapsedClass(triggerArray, isOpen) {
|
||||
if (!triggerArray.length) {
|
||||
return;
|
||||
}
|
||||
for (const element of triggerArray) {
|
||||
element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);
|
||||
element.setAttribute('aria-expanded', isOpen);
|
||||
}
|
||||
}
|
||||
|
||||
triggerArray.forEach(elem => {
|
||||
if (isOpen) {
|
||||
elem.classList.remove(CLASS_NAME_COLLAPSED);
|
||||
} else {
|
||||
elem.classList.add(CLASS_NAME_COLLAPSED);
|
||||
}
|
||||
|
||||
elem.setAttribute('aria-expanded', isOpen);
|
||||
});
|
||||
} // Static
|
||||
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
const _config = {};
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
return this.each(function () {
|
||||
const _config = {};
|
||||
|
||||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||||
_config.toggle = false;
|
||||
}
|
||||
|
||||
const data = Collapse.getOrCreateInstance(this, _config);
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config]();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
|
||||
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
||||
if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
const selector = getSelectorFromElement(this);
|
||||
const selectorElements = SelectorEngine__default.default.find(selector);
|
||||
selectorElements.forEach(element => {
|
||||
for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {
|
||||
Collapse.getOrCreateInstance(element, {
|
||||
toggle: false
|
||||
}).toggle();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Collapse to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Collapse);
|
||||
index_js.defineJQueryPlugin(Collapse);
|
||||
|
||||
return Collapse;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*!
|
||||
* Bootstrap data.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap data.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
|
|
@ -11,56 +11,50 @@
|
|||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): dom/data.js
|
||||
* Bootstrap dom/data.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const elementMap = new Map();
|
||||
const data = {
|
||||
set(element, key, instance) {
|
||||
if (!elementMap.has(element)) {
|
||||
elementMap.set(element, new Map());
|
||||
}
|
||||
const instanceMap = elementMap.get(element);
|
||||
|
||||
const instanceMap = elementMap.get(element); // make it clear we only want one instance per element
|
||||
// make it clear we only want one instance per element
|
||||
// can be removed later when multiple key/instances are fine to be used
|
||||
|
||||
if (!instanceMap.has(key) && instanceMap.size !== 0) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
instanceMap.set(key, instance);
|
||||
},
|
||||
|
||||
get(element, key) {
|
||||
if (elementMap.has(element)) {
|
||||
return elementMap.get(element).get(key) || null;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
remove(element, key) {
|
||||
if (!elementMap.has(element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const instanceMap = elementMap.get(element);
|
||||
instanceMap.delete(key); // free up element references if there are no instances left for an element
|
||||
instanceMap.delete(key);
|
||||
|
||||
// free up element references if there are no instances left for an element
|
||||
if (instanceMap.size === 0) {
|
||||
elementMap.delete(element);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return data;
|
||||
|
|
|
|||
|
|
@ -1,274 +1,197 @@
|
|||
/*!
|
||||
* Bootstrap event-handler.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap event-handler.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventHandler = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventHandler = factory(global.Index));
|
||||
})(this, (function (index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap dom/event-handler.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): dom/event-handler.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
|
||||
const stripNameRegex = /\..*/;
|
||||
const stripUidRegex = /::\d+$/;
|
||||
const eventRegistry = {}; // Events storage
|
||||
|
||||
let uidEvent = 1;
|
||||
const customEvents = {
|
||||
mouseenter: 'mouseover',
|
||||
mouseleave: 'mouseout'
|
||||
};
|
||||
const customEventsRegex = /^(mouseenter|mouseleave)/i;
|
||||
const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Private methods
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
function getUidEvent(element, uid) {
|
||||
function makeEventUid(element, uid) {
|
||||
return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;
|
||||
}
|
||||
|
||||
function getEvent(element) {
|
||||
const uid = getUidEvent(element);
|
||||
function getElementEvents(element) {
|
||||
const uid = makeEventUid(element);
|
||||
element.uidEvent = uid;
|
||||
eventRegistry[uid] = eventRegistry[uid] || {};
|
||||
return eventRegistry[uid];
|
||||
}
|
||||
|
||||
function bootstrapHandler(element, fn) {
|
||||
return function handler(event) {
|
||||
event.delegateTarget = element;
|
||||
|
||||
hydrateObj(event, {
|
||||
delegateTarget: element
|
||||
});
|
||||
if (handler.oneOff) {
|
||||
EventHandler.off(element, event.type, fn);
|
||||
}
|
||||
|
||||
return fn.apply(element, [event]);
|
||||
};
|
||||
}
|
||||
|
||||
function bootstrapDelegationHandler(element, selector, fn) {
|
||||
return function handler(event) {
|
||||
const domElements = element.querySelectorAll(selector);
|
||||
|
||||
for (let {
|
||||
target
|
||||
} = event; target && target !== this; target = target.parentNode) {
|
||||
for (let i = domElements.length; i--;) {
|
||||
if (domElements[i] === target) {
|
||||
event.delegateTarget = target;
|
||||
|
||||
if (handler.oneOff) {
|
||||
EventHandler.off(element, event.type, selector, fn);
|
||||
}
|
||||
|
||||
return fn.apply(target, [event]);
|
||||
for (const domElement of domElements) {
|
||||
if (domElement !== target) {
|
||||
continue;
|
||||
}
|
||||
hydrateObj(event, {
|
||||
delegateTarget: target
|
||||
});
|
||||
if (handler.oneOff) {
|
||||
EventHandler.off(element, event.type, selector, fn);
|
||||
}
|
||||
return fn.apply(target, [event]);
|
||||
}
|
||||
} // To please ESLint
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function findHandler(events, handler, delegationSelector = null) {
|
||||
const uidEventList = Object.keys(events);
|
||||
|
||||
for (let i = 0, len = uidEventList.length; i < len; i++) {
|
||||
const event = events[uidEventList[i]];
|
||||
|
||||
if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
function findHandler(events, callable, delegationSelector = null) {
|
||||
return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);
|
||||
}
|
||||
|
||||
function normalizeParams(originalTypeEvent, handler, delegationFn) {
|
||||
const delegation = typeof handler === 'string';
|
||||
const originalHandler = delegation ? delegationFn : handler;
|
||||
function normalizeParameters(originalTypeEvent, handler, delegationFunction) {
|
||||
const isDelegated = typeof handler === 'string';
|
||||
// TODO: tooltip passes `false` instead of selector, so we need to check
|
||||
const callable = isDelegated ? delegationFunction : handler || delegationFunction;
|
||||
let typeEvent = getTypeEvent(originalTypeEvent);
|
||||
const isNative = nativeEvents.has(typeEvent);
|
||||
|
||||
if (!isNative) {
|
||||
if (!nativeEvents.has(typeEvent)) {
|
||||
typeEvent = originalTypeEvent;
|
||||
}
|
||||
|
||||
return [delegation, originalHandler, typeEvent];
|
||||
return [isDelegated, callable, typeEvent];
|
||||
}
|
||||
|
||||
function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {
|
||||
function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {
|
||||
if (typeof originalTypeEvent !== 'string' || !element) {
|
||||
return;
|
||||
}
|
||||
let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
|
||||
|
||||
if (!handler) {
|
||||
handler = delegationFn;
|
||||
delegationFn = null;
|
||||
} // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
|
||||
// in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
|
||||
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
|
||||
|
||||
|
||||
if (customEventsRegex.test(originalTypeEvent)) {
|
||||
const wrapFn = fn => {
|
||||
if (originalTypeEvent in customEvents) {
|
||||
const wrapFunction = fn => {
|
||||
return function (event) {
|
||||
if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {
|
||||
return fn.call(this, event);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if (delegationFn) {
|
||||
delegationFn = wrapFn(delegationFn);
|
||||
} else {
|
||||
handler = wrapFn(handler);
|
||||
}
|
||||
callable = wrapFunction(callable);
|
||||
}
|
||||
|
||||
const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);
|
||||
const events = getEvent(element);
|
||||
const events = getElementEvents(element);
|
||||
const handlers = events[typeEvent] || (events[typeEvent] = {});
|
||||
const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);
|
||||
|
||||
if (previousFn) {
|
||||
previousFn.oneOff = previousFn.oneOff && oneOff;
|
||||
const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);
|
||||
if (previousFunction) {
|
||||
previousFunction.oneOff = previousFunction.oneOff && oneOff;
|
||||
return;
|
||||
}
|
||||
|
||||
const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''));
|
||||
const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler);
|
||||
fn.delegationSelector = delegation ? handler : null;
|
||||
fn.originalHandler = originalHandler;
|
||||
const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));
|
||||
const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);
|
||||
fn.delegationSelector = isDelegated ? handler : null;
|
||||
fn.callable = callable;
|
||||
fn.oneOff = oneOff;
|
||||
fn.uidEvent = uid;
|
||||
handlers[uid] = fn;
|
||||
element.addEventListener(typeEvent, fn, delegation);
|
||||
element.addEventListener(typeEvent, fn, isDelegated);
|
||||
}
|
||||
|
||||
function removeHandler(element, events, typeEvent, handler, delegationSelector) {
|
||||
const fn = findHandler(events[typeEvent], handler, delegationSelector);
|
||||
|
||||
if (!fn) {
|
||||
return;
|
||||
}
|
||||
|
||||
element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
|
||||
delete events[typeEvent][fn.uidEvent];
|
||||
}
|
||||
|
||||
function removeNamespacedHandlers(element, events, typeEvent, namespace) {
|
||||
const storeElementEvent = events[typeEvent] || {};
|
||||
Object.keys(storeElementEvent).forEach(handlerKey => {
|
||||
for (const [handlerKey, event] of Object.entries(storeElementEvent)) {
|
||||
if (handlerKey.includes(namespace)) {
|
||||
const event = storeElementEvent[handlerKey];
|
||||
removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);
|
||||
removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeEvent(event) {
|
||||
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
|
||||
event = event.replace(stripNameRegex, '');
|
||||
return customEvents[event] || event;
|
||||
}
|
||||
|
||||
const EventHandler = {
|
||||
on(element, event, handler, delegationFn) {
|
||||
addHandler(element, event, handler, delegationFn, false);
|
||||
on(element, event, handler, delegationFunction) {
|
||||
addHandler(element, event, handler, delegationFunction, false);
|
||||
},
|
||||
|
||||
one(element, event, handler, delegationFn) {
|
||||
addHandler(element, event, handler, delegationFn, true);
|
||||
one(element, event, handler, delegationFunction) {
|
||||
addHandler(element, event, handler, delegationFunction, true);
|
||||
},
|
||||
|
||||
off(element, originalTypeEvent, handler, delegationFn) {
|
||||
off(element, originalTypeEvent, handler, delegationFunction) {
|
||||
if (typeof originalTypeEvent !== 'string' || !element) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);
|
||||
const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
|
||||
const inNamespace = typeEvent !== originalTypeEvent;
|
||||
const events = getEvent(element);
|
||||
const events = getElementEvents(element);
|
||||
const storeElementEvent = events[typeEvent] || {};
|
||||
const isNamespace = originalTypeEvent.startsWith('.');
|
||||
|
||||
if (typeof originalHandler !== 'undefined') {
|
||||
if (typeof callable !== 'undefined') {
|
||||
// Simplest case: handler is passed, remove that listener ONLY.
|
||||
if (!events || !events[typeEvent]) {
|
||||
if (!Object.keys(storeElementEvent).length) {
|
||||
return;
|
||||
}
|
||||
|
||||
removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null);
|
||||
removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNamespace) {
|
||||
Object.keys(events).forEach(elementEvent => {
|
||||
for (const elementEvent of Object.keys(events)) {
|
||||
removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
|
||||
});
|
||||
}
|
||||
|
||||
const storeElementEvent = events[typeEvent] || {};
|
||||
Object.keys(storeElementEvent).forEach(keyHandlers => {
|
||||
const handlerKey = keyHandlers.replace(stripUidRegex, '');
|
||||
|
||||
if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
|
||||
const event = storeElementEvent[keyHandlers];
|
||||
removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);
|
||||
}
|
||||
});
|
||||
}
|
||||
for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {
|
||||
const handlerKey = keyHandlers.replace(stripUidRegex, '');
|
||||
if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
|
||||
removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
trigger(element, event, args) {
|
||||
if (typeof event !== 'string' || !element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const $ = getjQuery();
|
||||
const $ = index_js.getjQuery();
|
||||
const typeEvent = getTypeEvent(event);
|
||||
const inNamespace = event !== typeEvent;
|
||||
const isNative = nativeEvents.has(typeEvent);
|
||||
let jQueryEvent;
|
||||
let jQueryEvent = null;
|
||||
let bubbles = true;
|
||||
let nativeDispatch = true;
|
||||
let defaultPrevented = false;
|
||||
let evt = null;
|
||||
|
||||
if (inNamespace && $) {
|
||||
jQueryEvent = $.Event(event, args);
|
||||
$(element).trigger(jQueryEvent);
|
||||
|
|
@ -276,45 +199,37 @@
|
|||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
||||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
||||
}
|
||||
|
||||
if (isNative) {
|
||||
evt = document.createEvent('HTMLEvents');
|
||||
evt.initEvent(typeEvent, bubbles, true);
|
||||
} else {
|
||||
evt = new CustomEvent(event, {
|
||||
bubbles,
|
||||
cancelable: true
|
||||
});
|
||||
} // merge custom information in our event
|
||||
|
||||
|
||||
if (typeof args !== 'undefined') {
|
||||
Object.keys(args).forEach(key => {
|
||||
Object.defineProperty(evt, key, {
|
||||
get() {
|
||||
return args[key];
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const evt = hydrateObj(new Event(event, {
|
||||
bubbles,
|
||||
cancelable: true
|
||||
}), args);
|
||||
if (defaultPrevented) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
|
||||
if (nativeDispatch) {
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {
|
||||
if (evt.defaultPrevented && jQueryEvent) {
|
||||
jQueryEvent.preventDefault();
|
||||
}
|
||||
|
||||
return evt;
|
||||
}
|
||||
|
||||
};
|
||||
function hydrateObj(obj, meta = {}) {
|
||||
for (const [key, value] of Object.entries(meta)) {
|
||||
try {
|
||||
obj[key] = value;
|
||||
} catch (_unused) {
|
||||
Object.defineProperty(obj, key, {
|
||||
configurable: true,
|
||||
get() {
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
return EventHandler;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*!
|
||||
* Bootstrap manipulator.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap manipulator.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
|
|
@ -11,76 +11,59 @@
|
|||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): dom/manipulator.js
|
||||
* Bootstrap dom/manipulator.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
function normalizeData(val) {
|
||||
if (val === 'true') {
|
||||
|
||||
function normalizeData(value) {
|
||||
if (value === 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (val === 'false') {
|
||||
if (value === 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val === Number(val).toString()) {
|
||||
return Number(val);
|
||||
if (value === Number(value).toString()) {
|
||||
return Number(value);
|
||||
}
|
||||
|
||||
if (val === '' || val === 'null') {
|
||||
if (value === '' || value === 'null') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return val;
|
||||
if (typeof value !== 'string') {
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
return JSON.parse(decodeURIComponent(value));
|
||||
} catch (_unused) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeDataKey(key) {
|
||||
return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);
|
||||
}
|
||||
|
||||
const Manipulator = {
|
||||
setDataAttribute(element, key, value) {
|
||||
element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);
|
||||
},
|
||||
|
||||
removeDataAttribute(element, key) {
|
||||
element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
|
||||
},
|
||||
|
||||
getDataAttributes(element) {
|
||||
if (!element) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const attributes = {};
|
||||
Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => {
|
||||
const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));
|
||||
for (const key of bsKeys) {
|
||||
let pureKey = key.replace(/^bs/, '');
|
||||
pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
|
||||
attributes[pureKey] = normalizeData(element.dataset[key]);
|
||||
});
|
||||
}
|
||||
return attributes;
|
||||
},
|
||||
|
||||
getDataAttribute(element, key) {
|
||||
return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));
|
||||
},
|
||||
|
||||
offset(element) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
return {
|
||||
top: rect.top + window.pageYOffset,
|
||||
left: rect.left + window.pageXOffset
|
||||
};
|
||||
},
|
||||
|
||||
position(element) {
|
||||
return {
|
||||
top: element.offsetTop,
|
||||
left: element.offsetLeft
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return Manipulator;
|
||||
|
|
|
|||
|
|
@ -1,125 +1,101 @@
|
|||
/*!
|
||||
* Bootstrap selector-engine.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap selector-engine.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.SelectorEngine = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.SelectorEngine = factory(global.Index));
|
||||
})(this, (function (index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap dom/selector-engine.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttribute = element.getAttribute('href');
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
// The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
// Just in case some CMS puts out a full URL with the anchor appended
|
||||
if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
|
||||
hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
|
||||
}
|
||||
selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;
|
||||
}
|
||||
return selector ? selector.split(',').map(sel => index_js.parseSelector(sel)).join(',') : null;
|
||||
};
|
||||
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
};
|
||||
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): dom/selector-engine.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
const NODE_TEXT = 3;
|
||||
const SelectorEngine = {
|
||||
find(selector, element = document.documentElement) {
|
||||
return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
|
||||
},
|
||||
|
||||
findOne(selector, element = document.documentElement) {
|
||||
return Element.prototype.querySelector.call(element, selector);
|
||||
},
|
||||
|
||||
children(element, selector) {
|
||||
return [].concat(...element.children).filter(child => child.matches(selector));
|
||||
},
|
||||
|
||||
parents(element, selector) {
|
||||
const parents = [];
|
||||
let ancestor = element.parentNode;
|
||||
|
||||
while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
|
||||
if (ancestor.matches(selector)) {
|
||||
parents.push(ancestor);
|
||||
}
|
||||
|
||||
ancestor = ancestor.parentNode;
|
||||
let ancestor = element.parentNode.closest(selector);
|
||||
while (ancestor) {
|
||||
parents.push(ancestor);
|
||||
ancestor = ancestor.parentNode.closest(selector);
|
||||
}
|
||||
|
||||
return parents;
|
||||
},
|
||||
|
||||
prev(element, selector) {
|
||||
let previous = element.previousElementSibling;
|
||||
|
||||
while (previous) {
|
||||
if (previous.matches(selector)) {
|
||||
return [previous];
|
||||
}
|
||||
|
||||
previous = previous.previousElementSibling;
|
||||
}
|
||||
|
||||
return [];
|
||||
},
|
||||
|
||||
// TODO: this is now unused; remove later along with prev()
|
||||
next(element, selector) {
|
||||
let next = element.nextElementSibling;
|
||||
|
||||
while (next) {
|
||||
if (next.matches(selector)) {
|
||||
return [next];
|
||||
}
|
||||
|
||||
next = next.nextElementSibling;
|
||||
}
|
||||
|
||||
return [];
|
||||
},
|
||||
|
||||
focusableChildren(element) {
|
||||
const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(', ');
|
||||
return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));
|
||||
const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(',');
|
||||
return this.find(focusables, element).filter(el => !index_js.isDisabled(el) && index_js.isVisible(el));
|
||||
},
|
||||
getSelectorFromElement(element) {
|
||||
const selector = getSelector(element);
|
||||
if (selector) {
|
||||
return SelectorEngine.findOne(selector) ? selector : null;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getElementFromSelector(element) {
|
||||
const selector = getSelector(element);
|
||||
return selector ? SelectorEngine.findOne(selector) : null;
|
||||
},
|
||||
getMultipleElementsFromSelector(element) {
|
||||
const selector = getSelector(element);
|
||||
return selector ? SelectorEngine.find(selector) : [];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return SelectorEngine;
|
||||
|
|
|
|||
|
|
@ -1,19 +1,16 @@
|
|||
/*!
|
||||
* Bootstrap dropdown.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap dropdown.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['@popperjs/core', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dropdown = factory(global.Popper, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
|
||||
})(this, (function (Popper, EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['@popperjs/core', './base-component', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dropdown = factory(global.Popper, global.BaseComponent, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Index));
|
||||
})(this, (function (Popper, BaseComponent, EventHandler, Manipulator, SelectorEngine, index_js) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
function _interopNamespace(e) {
|
||||
if (e && e.__esModule) return e;
|
||||
const n = Object.create(null);
|
||||
function _interopNamespaceDefault(e) {
|
||||
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
|
||||
if (e) {
|
||||
for (const k in e) {
|
||||
if (k !== 'default') {
|
||||
|
|
@ -29,206 +26,18 @@
|
|||
return Object.freeze(n);
|
||||
}
|
||||
|
||||
const Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
||||
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
const Popper__namespace = /*#__PURE__*/_interopNamespaceDefault(Popper);
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap dropdown.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const toType = obj => {
|
||||
if (obj === null || obj === undefined) {
|
||||
return `${obj}`;
|
||||
}
|
||||
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getElementFromSelector = element => {
|
||||
const selector = getSelector(element);
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
};
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
};
|
||||
|
||||
const getElement = obj => {
|
||||
if (isElement(obj)) {
|
||||
// it's a jQuery object or a node element
|
||||
return obj.jquery ? obj[0] : obj;
|
||||
}
|
||||
|
||||
if (typeof obj === 'string' && obj.length > 0) {
|
||||
return document.querySelector(obj);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const typeCheckConfig = (componentName, config, configTypes) => {
|
||||
Object.keys(configTypes).forEach(property => {
|
||||
const expectedTypes = configTypes[property];
|
||||
const value = config[property];
|
||||
const valueType = value && isElement(value) ? 'element' : toType(value);
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
};
|
||||
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
|
||||
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed
|
||||
|
||||
if (index === -1) {
|
||||
return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
|
||||
}
|
||||
|
||||
const listLength = list.length;
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): dropdown.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'dropdown';
|
||||
|
|
@ -236,13 +45,11 @@
|
|||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const DATA_API_KEY = '.data-api';
|
||||
const ESCAPE_KEY = 'Escape';
|
||||
const SPACE_KEY = 'Space';
|
||||
const TAB_KEY = 'Tab';
|
||||
const ARROW_UP_KEY = 'ArrowUp';
|
||||
const ARROW_DOWN_KEY = 'ArrowDown';
|
||||
const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
|
||||
|
||||
const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY}`);
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||||
|
|
@ -254,253 +61,205 @@
|
|||
const CLASS_NAME_DROPUP = 'dropup';
|
||||
const CLASS_NAME_DROPEND = 'dropend';
|
||||
const CLASS_NAME_DROPSTART = 'dropstart';
|
||||
const CLASS_NAME_NAVBAR = 'navbar';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]';
|
||||
const SELECTOR_MENU = '.dropdown-menu:not(.o-dropdown--menu)';
|
||||
const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
|
||||
const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
|
||||
const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`;
|
||||
const SELECTOR_MENU = '.dropdown-menu:not(.o-dropdown--menu)'; // Odoo fix task-2764821
|
||||
const SELECTOR_NAVBAR = '.navbar';
|
||||
const SELECTOR_MENU_NOT_SUB = '.dropdown-menu:not(.o-dropdown--menu):not(.o_wysiwyg_submenu)';
|
||||
const SELECTOR_NAVBAR_NAV = '.navbar-nav';
|
||||
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
|
||||
const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';
|
||||
const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';
|
||||
const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';
|
||||
const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';
|
||||
const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';
|
||||
const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';
|
||||
const PLACEMENT_TOP = index_js.isRTL() ? 'top-end' : 'top-start';
|
||||
const PLACEMENT_TOPEND = index_js.isRTL() ? 'top-start' : 'top-end';
|
||||
const PLACEMENT_BOTTOM = index_js.isRTL() ? 'bottom-end' : 'bottom-start';
|
||||
const PLACEMENT_BOTTOMEND = index_js.isRTL() ? 'bottom-start' : 'bottom-end';
|
||||
const PLACEMENT_RIGHT = index_js.isRTL() ? 'left-start' : 'right-start';
|
||||
const PLACEMENT_LEFT = index_js.isRTL() ? 'right-start' : 'left-start';
|
||||
const PLACEMENT_TOPCENTER = 'top';
|
||||
const PLACEMENT_BOTTOMCENTER = 'bottom';
|
||||
const Default = {
|
||||
offset: [0, 2],
|
||||
autoClose: true,
|
||||
boundary: 'clippingParents',
|
||||
reference: 'toggle',
|
||||
display: 'dynamic',
|
||||
offset: [0, 2],
|
||||
popperConfig: null,
|
||||
autoClose: true
|
||||
reference: 'toggle'
|
||||
};
|
||||
const DefaultType = {
|
||||
offset: '(array|string|function)',
|
||||
autoClose: '(boolean|string)',
|
||||
boundary: '(string|element)',
|
||||
reference: '(string|element|object)',
|
||||
display: 'string',
|
||||
offset: '(array|string|function)',
|
||||
popperConfig: '(null|object|function)',
|
||||
autoClose: '(boolean|string)'
|
||||
reference: '(string|element|object)'
|
||||
};
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Dropdown extends BaseComponent__default.default {
|
||||
class Dropdown extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
super(element);
|
||||
super(element, config);
|
||||
this._popper = null;
|
||||
this._config = this._getConfig(config);
|
||||
this._menu = this._getMenuElement();
|
||||
this._parent = this._element.parentNode; // dropdown wrapper
|
||||
// TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
|
||||
this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);
|
||||
this._inNavbar = this._detectNavbar();
|
||||
} // Getters
|
||||
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
}
|
||||
|
||||
// Public
|
||||
toggle() {
|
||||
return this._isShown() ? this.hide() : this.show();
|
||||
}
|
||||
|
||||
show() {
|
||||
if (isDisabled(this._element) || this._isShown(this._menu)) {
|
||||
if (index_js.isDisabled(this._element) || this._isShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const relatedTarget = {
|
||||
relatedTarget: this._element
|
||||
};
|
||||
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, relatedTarget);
|
||||
|
||||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, relatedTarget);
|
||||
if (showEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
this._createPopper();
|
||||
|
||||
const parent = Dropdown.getParentFromElement(this._element); // Totally disable Popper for Dropdowns in Navbar
|
||||
|
||||
if (this._inNavbar) {
|
||||
Manipulator__default.default.setDataAttribute(this._menu, 'popper', 'none');
|
||||
} else {
|
||||
this._createPopper(parent);
|
||||
} // If this is a touch-enabled device we add extra
|
||||
// If this is a touch-enabled device we add extra
|
||||
// empty mouseover listeners to the body's immediate children;
|
||||
// only needed because of broken event delegation on iOS
|
||||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||||
|
||||
|
||||
if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {
|
||||
[].concat(...document.body.children).forEach(elem => EventHandler__default.default.on(elem, 'mouseover', noop));
|
||||
if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
|
||||
for (const element of [].concat(...document.body.children)) {
|
||||
EventHandler.on(element, 'mouseover', index_js.noop);
|
||||
}
|
||||
}
|
||||
|
||||
this._element.focus();
|
||||
|
||||
this._element.setAttribute('aria-expanded', true);
|
||||
|
||||
this._menu.classList.add(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_SHOW);
|
||||
|
||||
EventHandler__default.default.trigger(this._element, EVENT_SHOWN, relatedTarget);
|
||||
EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget);
|
||||
}
|
||||
|
||||
hide() {
|
||||
if (isDisabled(this._element) || !this._isShown(this._menu)) {
|
||||
if (index_js.isDisabled(this._element) || !this._isShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const relatedTarget = {
|
||||
relatedTarget: this._element
|
||||
};
|
||||
|
||||
this._completeHide(relatedTarget);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
if (this._popper) {
|
||||
this._popper.destroy();
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
update() {
|
||||
this._inNavbar = this._detectNavbar();
|
||||
|
||||
if (this._popper) {
|
||||
this._popper.update();
|
||||
}
|
||||
} // Private
|
||||
|
||||
}
|
||||
|
||||
// Private
|
||||
_completeHide(relatedTarget) {
|
||||
const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE, relatedTarget);
|
||||
|
||||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget);
|
||||
if (hideEvent.defaultPrevented) {
|
||||
return;
|
||||
} // If this is a touch-enabled device we remove the extra
|
||||
// empty mouseover listeners we added for iOS support
|
||||
|
||||
|
||||
if ('ontouchstart' in document.documentElement) {
|
||||
[].concat(...document.body.children).forEach(elem => EventHandler__default.default.off(elem, 'mouseover', noop));
|
||||
}
|
||||
|
||||
// If this is a touch-enabled device we remove the extra
|
||||
// empty mouseover listeners we added for iOS support
|
||||
if ('ontouchstart' in document.documentElement) {
|
||||
for (const element of [].concat(...document.body.children)) {
|
||||
EventHandler.off(element, 'mouseover', index_js.noop);
|
||||
}
|
||||
}
|
||||
if (this._popper) {
|
||||
this._popper.destroy();
|
||||
}
|
||||
|
||||
this._menu.classList.remove(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.setAttribute('aria-expanded', 'false');
|
||||
|
||||
Manipulator__default.default.removeDataAttribute(this._menu, 'popper');
|
||||
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN, relatedTarget);
|
||||
Manipulator.removeDataAttribute(this._menu, 'popper');
|
||||
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget);
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...this.constructor.Default,
|
||||
...Manipulator__default.default.getDataAttributes(this._element),
|
||||
...config
|
||||
};
|
||||
typeCheckConfig(NAME, config, this.constructor.DefaultType);
|
||||
|
||||
if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
|
||||
config = super._getConfig(config);
|
||||
if (typeof config.reference === 'object' && !index_js.isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
|
||||
// Popper virtual elements require a getBoundingClientRect method
|
||||
throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
_createPopper(parent) {
|
||||
_createPopper() {
|
||||
if (typeof Popper__namespace === 'undefined') {
|
||||
throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
|
||||
}
|
||||
|
||||
let referenceElement = this._element;
|
||||
|
||||
if (this._config.reference === 'parent') {
|
||||
referenceElement = parent;
|
||||
} else if (isElement(this._config.reference)) {
|
||||
referenceElement = getElement(this._config.reference);
|
||||
referenceElement = this._parent;
|
||||
} else if (index_js.isElement(this._config.reference)) {
|
||||
referenceElement = index_js.getElement(this._config.reference);
|
||||
} else if (typeof this._config.reference === 'object') {
|
||||
referenceElement = this._config.reference;
|
||||
}
|
||||
|
||||
const popperConfig = this._getPopperConfig();
|
||||
|
||||
const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false);
|
||||
this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
|
||||
|
||||
if (isDisplayStatic) {
|
||||
Manipulator__default.default.setDataAttribute(this._menu, 'popper', 'static');
|
||||
}
|
||||
}
|
||||
|
||||
_isShown(element = this._element) {
|
||||
return element.classList.contains(CLASS_NAME_SHOW);
|
||||
_isShown() {
|
||||
return this._menu.classList.contains(CLASS_NAME_SHOW);
|
||||
}
|
||||
|
||||
_getMenuElement() {
|
||||
return SelectorEngine__default.default.next(this._element, SELECTOR_MENU)[0];
|
||||
}
|
||||
|
||||
_getPlacement() {
|
||||
const parentDropdown = this._element.parentNode;
|
||||
|
||||
const parentDropdown = this._parent;
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
|
||||
return PLACEMENT_RIGHT;
|
||||
}
|
||||
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
|
||||
return PLACEMENT_LEFT;
|
||||
} // We need to trim the value because custom properties can also include spaces
|
||||
|
||||
}
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
|
||||
return PLACEMENT_TOPCENTER;
|
||||
}
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
|
||||
return PLACEMENT_BOTTOMCENTER;
|
||||
}
|
||||
|
||||
// We need to trim the value because custom properties can also include spaces
|
||||
const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';
|
||||
|
||||
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
|
||||
return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;
|
||||
}
|
||||
|
||||
return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;
|
||||
}
|
||||
|
||||
_detectNavbar() {
|
||||
return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null;
|
||||
return this._element.closest(SELECTOR_NAVBAR) !== null;
|
||||
}
|
||||
|
||||
_getOffset() {
|
||||
const {
|
||||
offset
|
||||
} = this._config;
|
||||
|
||||
if (typeof offset === 'string') {
|
||||
return offset.split(',').map(val => Number.parseInt(val, 10));
|
||||
return offset.split(',').map(value => Number.parseInt(value, 10));
|
||||
}
|
||||
|
||||
if (typeof offset === 'function') {
|
||||
return popperData => offset(popperData, this._element);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
_getPopperConfig() {
|
||||
const defaultBsPopperConfig = {
|
||||
placement: this._getPlacement(),
|
||||
|
|
@ -515,172 +274,128 @@
|
|||
offset: this._getOffset()
|
||||
}
|
||||
}]
|
||||
}; // Disable Popper if we have a static display
|
||||
};
|
||||
|
||||
if (this._config.display === 'static') {
|
||||
// Disable Popper if we have a static display or Dropdown is in Navbar
|
||||
if (this._inNavbar || this._config.display === 'static') {
|
||||
Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove
|
||||
defaultBsPopperConfig.modifiers = [{
|
||||
name: 'applyStyles',
|
||||
enabled: false
|
||||
}];
|
||||
}
|
||||
|
||||
return { ...defaultBsPopperConfig,
|
||||
...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)
|
||||
return {
|
||||
...defaultBsPopperConfig,
|
||||
...index_js.execute(this._config.popperConfig, [defaultBsPopperConfig])
|
||||
};
|
||||
}
|
||||
|
||||
_selectMenuItem({
|
||||
key,
|
||||
target
|
||||
}) {
|
||||
const items = SelectorEngine__default.default.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);
|
||||
|
||||
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => index_js.isVisible(element));
|
||||
if (!items.length) {
|
||||
return;
|
||||
} // if target isn't included in items (e.g. when expanding the dropdown)
|
||||
}
|
||||
|
||||
// if target isn't included in items (e.g. when expanding the dropdown)
|
||||
// allow cycling to get the last item in case key equals ARROW_UP_KEY
|
||||
index_js.getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
|
||||
}
|
||||
|
||||
|
||||
getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
|
||||
} // Static
|
||||
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Dropdown.getOrCreateInstance(this, config);
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
|
||||
static clearMenus(event) {
|
||||
if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY)) {
|
||||
if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY) {
|
||||
return;
|
||||
}
|
||||
|
||||
const toggles = SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE);
|
||||
|
||||
for (let i = 0, len = toggles.length; i < len; i++) {
|
||||
const context = Dropdown.getInstance(toggles[i]);
|
||||
|
||||
const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);
|
||||
for (const toggle of openToggles) {
|
||||
const context = Dropdown.getInstance(toggle);
|
||||
if (!context || context._config.autoClose === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!context._isShown()) {
|
||||
const composedPath = event.composedPath();
|
||||
const isMenuTarget = composedPath.includes(context._menu);
|
||||
if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
|
||||
if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY || /input|select|option|textarea|form/i.test(event.target.tagName))) {
|
||||
continue;
|
||||
}
|
||||
const relatedTarget = {
|
||||
relatedTarget: context._element
|
||||
};
|
||||
|
||||
if (event) {
|
||||
const composedPath = event.composedPath();
|
||||
const isMenuTarget = composedPath.includes(context._menu);
|
||||
|
||||
if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
|
||||
continue;
|
||||
} // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
|
||||
|
||||
|
||||
if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY || /input|select|option|textarea|form/i.test(event.target.tagName))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (event.type === 'click') {
|
||||
relatedTarget.clickEvent = event;
|
||||
}
|
||||
if (event.type === 'click') {
|
||||
relatedTarget.clickEvent = event;
|
||||
}
|
||||
|
||||
context._completeHide(relatedTarget);
|
||||
}
|
||||
}
|
||||
|
||||
static getParentFromElement(element) {
|
||||
return getElementFromSelector(element) || element.parentNode;
|
||||
}
|
||||
|
||||
static dataApiKeydownHandler(event) {
|
||||
// If not input/textarea:
|
||||
// - And not a key in REGEXP_KEYDOWN => not a dropdown command
|
||||
// If input/textarea:
|
||||
// - If space key => not a dropdown command
|
||||
// - If key is other than escape
|
||||
// - If key is not up or down => not a dropdown command
|
||||
// - If trigger inside the menu => not a dropdown command
|
||||
if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) {
|
||||
// If not an UP | DOWN | ESCAPE key => not a dropdown command
|
||||
// If input/textarea && if key is other than ESCAPE => not a dropdown command
|
||||
|
||||
const isInput = /input|textarea/i.test(event.target.tagName);
|
||||
const isEscapeEvent = event.key === ESCAPE_KEY;
|
||||
const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key);
|
||||
if (!isUpOrDownEvent && !isEscapeEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isActive = this.classList.contains(CLASS_NAME_SHOW);
|
||||
|
||||
if (!isActive && event.key === ESCAPE_KEY) {
|
||||
if (isInput && !isEscapeEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (isDisabled(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine__default.default.prev(this, SELECTOR_DATA_TOGGLE)[0];
|
||||
// TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
|
||||
const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode);
|
||||
const instance = Dropdown.getOrCreateInstance(getToggleButton);
|
||||
|
||||
if (event.key === ESCAPE_KEY) {
|
||||
instance.hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {
|
||||
if (!isActive) {
|
||||
instance.show();
|
||||
}
|
||||
|
||||
if (isUpOrDownEvent) {
|
||||
event.stopPropagation();
|
||||
instance.show();
|
||||
instance._selectMenuItem(event);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isActive || event.key === SPACE_KEY) {
|
||||
Dropdown.clearMenus();
|
||||
if (instance._isShown()) {
|
||||
// else is escape and we check if it is shown
|
||||
event.stopPropagation();
|
||||
instance.hide();
|
||||
getToggleButton.focus();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
|
||||
EventHandler__default.default.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler);
|
||||
EventHandler__default.default.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU_NOT_SUB, Dropdown.dataApiKeydownHandler);
|
||||
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
|
||||
EventHandler__default.default.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
|
||||
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler);
|
||||
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU_NOT_SUB, Dropdown.dataApiKeydownHandler);
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
|
||||
EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
event.preventDefault();
|
||||
Dropdown.getOrCreateInstance(this).toggle();
|
||||
});
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Dropdown to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Dropdown);
|
||||
index_js.defineJQueryPlugin(Dropdown);
|
||||
|
||||
return Dropdown;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,620 +1,24 @@
|
|||
/*!
|
||||
* Bootstrap offcanvas.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap offcanvas.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/selector-engine.js'), require('./dom/manipulator.js'), require('./dom/event-handler.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/selector-engine', './dom/manipulator', './dom/event-handler', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Offcanvas = factory(global.SelectorEngine, global.Manipulator, global.EventHandler, global.Base));
|
||||
})(this, (function (SelectorEngine, Manipulator, EventHandler, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
||||
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/backdrop.js'), require('./util/component-functions.js'), require('./util/focustrap.js'), require('./util/index.js'), require('./util/scrollbar.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/backdrop', './util/component-functions', './util/focustrap', './util/index', './util/scrollbar'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Offcanvas = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Backdrop, global.ComponentFunctions, global.Focustrap, global.Index, global.Scrollbar));
|
||||
})(this, (function (BaseComponent, EventHandler, SelectorEngine, Backdrop, componentFunctions_js, FocusTrap, index_js, ScrollBarHelper) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
||||
|
||||
const toType = obj => {
|
||||
if (obj === null || obj === undefined) {
|
||||
return `${obj}`;
|
||||
}
|
||||
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getElementFromSelector = element => {
|
||||
const selector = getSelector(element);
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
};
|
||||
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
} // Get transition-duration of the element
|
||||
|
||||
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
|
||||
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
} // If multiple durations are defined, take the first
|
||||
|
||||
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
};
|
||||
|
||||
const getElement = obj => {
|
||||
if (isElement(obj)) {
|
||||
// it's a jQuery object or a node element
|
||||
return obj.jquery ? obj[0] : obj;
|
||||
}
|
||||
|
||||
if (typeof obj === 'string' && obj.length > 0) {
|
||||
return document.querySelector(obj);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const typeCheckConfig = (componentName, config, configTypes) => {
|
||||
Object.keys(configTypes).forEach(property => {
|
||||
const expectedTypes = configTypes[property];
|
||||
const value = config[property];
|
||||
const valueType = value && isElement(value) ? 'element' : toType(value);
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
};
|
||||
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
|
||||
|
||||
const reflow = element => {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
element.offsetHeight;
|
||||
};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const execute = callback => {
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/scrollBar.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
|
||||
const SELECTOR_STICKY_CONTENT = '.sticky-top';
|
||||
|
||||
class ScrollBarHelper {
|
||||
constructor() {
|
||||
this._element = document.body;
|
||||
}
|
||||
|
||||
getWidth() {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
|
||||
const documentWidth = document.documentElement.clientWidth;
|
||||
return Math.abs(window.innerWidth - documentWidth);
|
||||
}
|
||||
|
||||
hide() {
|
||||
const width = this.getWidth();
|
||||
|
||||
this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
|
||||
|
||||
|
||||
this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
|
||||
|
||||
|
||||
this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
|
||||
|
||||
this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
|
||||
}
|
||||
|
||||
_disableOverFlow() {
|
||||
this._saveInitialAttribute(this._element, 'overflow');
|
||||
|
||||
this._element.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
_setElementAttributes(selector, styleProp, callback) {
|
||||
const scrollbarWidth = this.getWidth();
|
||||
|
||||
const manipulationCallBack = element => {
|
||||
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._saveInitialAttribute(element, styleProp);
|
||||
|
||||
const calculatedValue = window.getComputedStyle(element)[styleProp];
|
||||
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
|
||||
};
|
||||
|
||||
this._applyManipulationCallback(selector, manipulationCallBack);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._resetElementAttributes(this._element, 'overflow');
|
||||
|
||||
this._resetElementAttributes(this._element, 'paddingRight');
|
||||
|
||||
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
|
||||
|
||||
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
|
||||
}
|
||||
|
||||
_saveInitialAttribute(element, styleProp) {
|
||||
const actualValue = element.style[styleProp];
|
||||
|
||||
if (actualValue) {
|
||||
Manipulator__default.default.setDataAttribute(element, styleProp, actualValue);
|
||||
}
|
||||
}
|
||||
|
||||
_resetElementAttributes(selector, styleProp) {
|
||||
const manipulationCallBack = element => {
|
||||
const value = Manipulator__default.default.getDataAttribute(element, styleProp);
|
||||
|
||||
if (typeof value === 'undefined') {
|
||||
element.style.removeProperty(styleProp);
|
||||
} else {
|
||||
Manipulator__default.default.removeDataAttribute(element, styleProp);
|
||||
element.style[styleProp] = value;
|
||||
}
|
||||
};
|
||||
|
||||
this._applyManipulationCallback(selector, manipulationCallBack);
|
||||
}
|
||||
|
||||
_applyManipulationCallback(selector, callBack) {
|
||||
if (isElement(selector)) {
|
||||
callBack(selector);
|
||||
} else {
|
||||
SelectorEngine__default.default.find(selector, this._element).forEach(callBack);
|
||||
}
|
||||
}
|
||||
|
||||
isOverflowing() {
|
||||
return this.getWidth() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/backdrop.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
const Default$2 = {
|
||||
className: 'modal-backdrop',
|
||||
isVisible: true,
|
||||
// if false, we use the backdrop helper without adding any element to the dom
|
||||
isAnimated: false,
|
||||
rootElement: 'body',
|
||||
// give the choice to place backdrop under different elements
|
||||
clickCallback: null
|
||||
};
|
||||
const DefaultType$2 = {
|
||||
className: 'string',
|
||||
isVisible: 'boolean',
|
||||
isAnimated: 'boolean',
|
||||
rootElement: '(element|string)',
|
||||
clickCallback: '(function|null)'
|
||||
};
|
||||
const NAME$2 = 'backdrop';
|
||||
const CLASS_NAME_FADE = 'fade';
|
||||
const CLASS_NAME_SHOW$1 = 'show';
|
||||
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$2}`;
|
||||
|
||||
class Backdrop {
|
||||
constructor(config) {
|
||||
this._config = this._getConfig(config);
|
||||
this._isAppended = false;
|
||||
this._element = null;
|
||||
}
|
||||
|
||||
show(callback) {
|
||||
if (!this._config.isVisible) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
this._append();
|
||||
|
||||
if (this._config.isAnimated) {
|
||||
reflow(this._getElement());
|
||||
}
|
||||
|
||||
this._getElement().classList.add(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._emulateAnimation(() => {
|
||||
execute(callback);
|
||||
});
|
||||
}
|
||||
|
||||
hide(callback) {
|
||||
if (!this._config.isVisible) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
|
||||
this._getElement().classList.remove(CLASS_NAME_SHOW$1);
|
||||
|
||||
this._emulateAnimation(() => {
|
||||
this.dispose();
|
||||
execute(callback);
|
||||
});
|
||||
} // Private
|
||||
|
||||
|
||||
_getElement() {
|
||||
if (!this._element) {
|
||||
const backdrop = document.createElement('div');
|
||||
backdrop.className = this._config.className;
|
||||
|
||||
if (this._config.isAnimated) {
|
||||
backdrop.classList.add(CLASS_NAME_FADE);
|
||||
}
|
||||
|
||||
this._element = backdrop;
|
||||
}
|
||||
|
||||
return this._element;
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...Default$2,
|
||||
...(typeof config === 'object' ? config : {})
|
||||
}; // use getElement() with the default "body" to get a fresh Element on each instantiation
|
||||
|
||||
config.rootElement = getElement(config.rootElement);
|
||||
typeCheckConfig(NAME$2, config, DefaultType$2);
|
||||
return config;
|
||||
}
|
||||
|
||||
_append() {
|
||||
if (this._isAppended) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._config.rootElement.append(this._getElement());
|
||||
|
||||
EventHandler__default.default.on(this._getElement(), EVENT_MOUSEDOWN, () => {
|
||||
execute(this._config.clickCallback);
|
||||
});
|
||||
this._isAppended = true;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
if (!this._isAppended) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN);
|
||||
|
||||
this._element.remove();
|
||||
|
||||
this._isAppended = false;
|
||||
}
|
||||
|
||||
_emulateAnimation(callback) {
|
||||
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/focustrap.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
const Default$1 = {
|
||||
trapElement: null,
|
||||
// The element to trap focus inside of
|
||||
autofocus: true
|
||||
};
|
||||
const DefaultType$1 = {
|
||||
trapElement: 'element',
|
||||
autofocus: 'boolean'
|
||||
};
|
||||
const NAME$1 = 'focustrap';
|
||||
const DATA_KEY$1 = 'bs.focustrap';
|
||||
const EVENT_KEY$1 = `.${DATA_KEY$1}`;
|
||||
const EVENT_FOCUSIN = `focusin${EVENT_KEY$1}`;
|
||||
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$1}`;
|
||||
const TAB_KEY = 'Tab';
|
||||
const TAB_NAV_FORWARD = 'forward';
|
||||
const TAB_NAV_BACKWARD = 'backward';
|
||||
|
||||
class FocusTrap {
|
||||
constructor(config) {
|
||||
this._config = this._getConfig(config);
|
||||
this._isActive = false;
|
||||
this._lastTabNavDirection = null;
|
||||
}
|
||||
|
||||
activate() {
|
||||
const {
|
||||
trapElement,
|
||||
autofocus
|
||||
} = this._config;
|
||||
|
||||
if (this._isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (autofocus) {
|
||||
trapElement.focus();
|
||||
}
|
||||
|
||||
EventHandler__default.default.off(document, EVENT_KEY$1); // guard against infinite focus loop
|
||||
|
||||
EventHandler__default.default.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
|
||||
EventHandler__default.default.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
|
||||
this._isActive = true;
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
if (!this._isActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isActive = false;
|
||||
EventHandler__default.default.off(document, EVENT_KEY$1);
|
||||
} // Private
|
||||
|
||||
|
||||
_handleFocusin(event) {
|
||||
const {
|
||||
target
|
||||
} = event;
|
||||
const {
|
||||
trapElement
|
||||
} = this._config;
|
||||
|
||||
if (target === document || target === trapElement || trapElement.contains(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elements = SelectorEngine__default.default.focusableChildren(trapElement);
|
||||
|
||||
if (elements.length === 0) {
|
||||
trapElement.focus();
|
||||
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
||||
elements[elements.length - 1].focus();
|
||||
} else {
|
||||
elements[0].focus();
|
||||
}
|
||||
}
|
||||
|
||||
_handleKeydown(event) {
|
||||
if (event.key !== TAB_KEY) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...Default$1,
|
||||
...(typeof config === 'object' ? config : {})
|
||||
};
|
||||
typeCheckConfig(NAME$1, config, DefaultType$1);
|
||||
return config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/component-functions.js
|
||||
* Bootstrap offcanvas.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const enableDismissTrigger = (component, method = 'hide') => {
|
||||
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
||||
const name = component.NAME;
|
||||
EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
||||
if (['A', 'AREA'].includes(this.tagName)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (isDisabled(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = getElementFromSelector(this) || this.closest(`.${name}`);
|
||||
const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
||||
|
||||
instance[method]();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): offcanvas.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'offcanvas';
|
||||
|
|
@ -623,243 +27,218 @@
|
|||
const DATA_API_KEY = '.data-api';
|
||||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const ESCAPE_KEY = 'Escape';
|
||||
const CLASS_NAME_SHOW = 'show';
|
||||
const CLASS_NAME_SHOWING = 'showing';
|
||||
const CLASS_NAME_HIDING = 'hiding';
|
||||
const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
|
||||
const OPEN_SELECTOR = '.offcanvas.show';
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||||
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`;
|
||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
||||
const EVENT_RESIZE = `resize${EVENT_KEY}`;
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]';
|
||||
const Default = {
|
||||
backdrop: true,
|
||||
keyboard: true,
|
||||
scroll: false
|
||||
};
|
||||
const DefaultType = {
|
||||
backdrop: 'boolean',
|
||||
backdrop: '(boolean|string)',
|
||||
keyboard: 'boolean',
|
||||
scroll: 'boolean'
|
||||
};
|
||||
const CLASS_NAME_SHOW = 'show';
|
||||
const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
|
||||
const OPEN_SELECTOR = '.offcanvas.show';
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]';
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Offcanvas extends BaseComponent__default.default {
|
||||
class Offcanvas extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
super(element);
|
||||
this._config = this._getConfig(config);
|
||||
super(element, config);
|
||||
this._isShown = false;
|
||||
this._backdrop = this._initializeBackDrop();
|
||||
this._focustrap = this._initializeFocusTrap();
|
||||
|
||||
this._addEventListeners();
|
||||
} // Getters
|
||||
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
static get Default() {
|
||||
return Default;
|
||||
} // Public
|
||||
|
||||
|
||||
// Public
|
||||
toggle(relatedTarget) {
|
||||
return this._isShown ? this.hide() : this.show(relatedTarget);
|
||||
}
|
||||
|
||||
show(relatedTarget) {
|
||||
if (this._isShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
|
||||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
|
||||
relatedTarget
|
||||
});
|
||||
|
||||
if (showEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isShown = true;
|
||||
this._element.style.visibility = 'visible';
|
||||
|
||||
this._backdrop.show();
|
||||
|
||||
if (!this._config.scroll) {
|
||||
new ScrollBarHelper().hide();
|
||||
}
|
||||
|
||||
this._element.removeAttribute('aria-hidden');
|
||||
|
||||
this._element.setAttribute('aria-modal', true);
|
||||
|
||||
this._element.setAttribute('role', 'dialog');
|
||||
|
||||
this._element.classList.add(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_SHOWING);
|
||||
const completeCallBack = () => {
|
||||
if (!this._config.scroll) {
|
||||
if (!this._config.scroll || this._config.backdrop) {
|
||||
this._focustrap.activate();
|
||||
}
|
||||
|
||||
EventHandler__default.default.trigger(this._element, EVENT_SHOWN, {
|
||||
this._element.classList.add(CLASS_NAME_SHOW);
|
||||
this._element.classList.remove(CLASS_NAME_SHOWING);
|
||||
EventHandler.trigger(this._element, EVENT_SHOWN, {
|
||||
relatedTarget
|
||||
});
|
||||
};
|
||||
|
||||
this._queueCallback(completeCallBack, this._element, true);
|
||||
}
|
||||
|
||||
hide() {
|
||||
if (!this._isShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
|
||||
|
||||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
|
||||
if (hideEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._focustrap.deactivate();
|
||||
|
||||
this._element.blur();
|
||||
|
||||
this._isShown = false;
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_HIDING);
|
||||
this._backdrop.hide();
|
||||
|
||||
const completeCallback = () => {
|
||||
this._element.setAttribute('aria-hidden', true);
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_SHOW, CLASS_NAME_HIDING);
|
||||
this._element.removeAttribute('aria-modal');
|
||||
|
||||
this._element.removeAttribute('role');
|
||||
|
||||
this._element.style.visibility = 'hidden';
|
||||
|
||||
if (!this._config.scroll) {
|
||||
new ScrollBarHelper().reset();
|
||||
}
|
||||
|
||||
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
|
||||
EventHandler.trigger(this._element, EVENT_HIDDEN);
|
||||
};
|
||||
|
||||
this._queueCallback(completeCallback, this._element, true);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._backdrop.dispose();
|
||||
|
||||
this._focustrap.deactivate();
|
||||
|
||||
super.dispose();
|
||||
} // Private
|
||||
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...Default,
|
||||
...Manipulator__default.default.getDataAttributes(this._element),
|
||||
...(typeof config === 'object' ? config : {})
|
||||
};
|
||||
typeCheckConfig(NAME, config, DefaultType);
|
||||
return config;
|
||||
}
|
||||
|
||||
// Private
|
||||
_initializeBackDrop() {
|
||||
const clickCallback = () => {
|
||||
if (this._config.backdrop === 'static') {
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||||
return;
|
||||
}
|
||||
this.hide();
|
||||
};
|
||||
|
||||
// 'static' option will be translated to true, and booleans will keep their value
|
||||
const isVisible = Boolean(this._config.backdrop);
|
||||
return new Backdrop({
|
||||
className: CLASS_NAME_BACKDROP,
|
||||
isVisible: this._config.backdrop,
|
||||
isVisible,
|
||||
isAnimated: true,
|
||||
rootElement: this._element.parentNode,
|
||||
clickCallback: () => this.hide()
|
||||
clickCallback: isVisible ? clickCallback : null
|
||||
});
|
||||
}
|
||||
|
||||
_initializeFocusTrap() {
|
||||
return new FocusTrap({
|
||||
trapElement: this._element
|
||||
});
|
||||
}
|
||||
|
||||
_addEventListeners() {
|
||||
EventHandler__default.default.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
|
||||
if (this._config.keyboard && event.key === ESCAPE_KEY) {
|
||||
this.hide();
|
||||
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
|
||||
if (event.key !== ESCAPE_KEY) {
|
||||
return;
|
||||
}
|
||||
if (this._config.keyboard) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||||
});
|
||||
} // Static
|
||||
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Offcanvas.getOrCreateInstance(this, config);
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config](this);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
|
||||
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
const target = getElementFromSelector(this);
|
||||
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
const target = SelectorEngine.getElementFromSelector(this);
|
||||
if (['A', 'AREA'].includes(this.tagName)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (isDisabled(this)) {
|
||||
if (index_js.isDisabled(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler__default.default.one(target, EVENT_HIDDEN, () => {
|
||||
EventHandler.one(target, EVENT_HIDDEN, () => {
|
||||
// focus on trigger when it is closed
|
||||
if (isVisible(this)) {
|
||||
if (index_js.isVisible(this)) {
|
||||
this.focus();
|
||||
}
|
||||
}); // avoid conflict when clicking a toggler of an offcanvas, while another is open
|
||||
});
|
||||
|
||||
const allReadyOpen = SelectorEngine__default.default.findOne(OPEN_SELECTOR);
|
||||
|
||||
if (allReadyOpen && allReadyOpen !== target) {
|
||||
Offcanvas.getInstance(allReadyOpen).hide();
|
||||
// avoid conflict when clicking a toggler of an offcanvas, while another is open
|
||||
const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
|
||||
if (alreadyOpen && alreadyOpen !== target) {
|
||||
Offcanvas.getInstance(alreadyOpen).hide();
|
||||
}
|
||||
|
||||
const data = Offcanvas.getOrCreateInstance(target);
|
||||
data.toggle(this);
|
||||
});
|
||||
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => SelectorEngine__default.default.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));
|
||||
enableDismissTrigger(Offcanvas);
|
||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {
|
||||
Offcanvas.getOrCreateInstance(selector).show();
|
||||
}
|
||||
});
|
||||
EventHandler.on(window, EVENT_RESIZE, () => {
|
||||
for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {
|
||||
if (getComputedStyle(element).position !== 'fixed') {
|
||||
Offcanvas.getOrCreateInstance(element).hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
componentFunctions_js.enableDismissTrigger(Offcanvas);
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Offcanvas);
|
||||
index_js.defineJQueryPlugin(Offcanvas);
|
||||
|
||||
return Offcanvas;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,182 +1,94 @@
|
|||
/*!
|
||||
* Bootstrap popover.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap popover.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./tooltip.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./tooltip'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Popover = factory(global.Tooltip));
|
||||
})(this, (function (Tooltip) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const Tooltip__default = /*#__PURE__*/_interopDefaultLegacy(Tooltip);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./tooltip.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./tooltip', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Popover = factory(global.Tooltip, global.Index));
|
||||
})(this, (function (Tooltip, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap popover.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): popover.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'popover';
|
||||
const DATA_KEY = 'bs.popover';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const CLASS_PREFIX = 'bs-popover';
|
||||
const Default = { ...Tooltip__default.default.Default,
|
||||
placement: 'right',
|
||||
offset: [0, 8],
|
||||
trigger: 'click',
|
||||
content: '',
|
||||
template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>'
|
||||
};
|
||||
const DefaultType = { ...Tooltip__default.default.DefaultType,
|
||||
content: '(string|element|function)'
|
||||
};
|
||||
const Event = {
|
||||
HIDE: `hide${EVENT_KEY}`,
|
||||
HIDDEN: `hidden${EVENT_KEY}`,
|
||||
SHOW: `show${EVENT_KEY}`,
|
||||
SHOWN: `shown${EVENT_KEY}`,
|
||||
INSERTED: `inserted${EVENT_KEY}`,
|
||||
CLICK: `click${EVENT_KEY}`,
|
||||
FOCUSIN: `focusin${EVENT_KEY}`,
|
||||
FOCUSOUT: `focusout${EVENT_KEY}`,
|
||||
MOUSEENTER: `mouseenter${EVENT_KEY}`,
|
||||
MOUSELEAVE: `mouseleave${EVENT_KEY}`
|
||||
};
|
||||
const SELECTOR_TITLE = '.popover-header';
|
||||
const SELECTOR_CONTENT = '.popover-body';
|
||||
const Default = {
|
||||
...Tooltip.Default,
|
||||
content: '',
|
||||
offset: [0, 8],
|
||||
placement: 'right',
|
||||
template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>',
|
||||
trigger: 'click'
|
||||
};
|
||||
const DefaultType = {
|
||||
...Tooltip.DefaultType,
|
||||
content: '(null|string|element|function)'
|
||||
};
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Popover extends Tooltip__default.default {
|
||||
class Popover extends Tooltip {
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
static get Event() {
|
||||
return Event;
|
||||
// Overrides
|
||||
_isWithContent() {
|
||||
return this._getTitle() || this._getContent();
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
} // Overrides
|
||||
|
||||
|
||||
isWithContent() {
|
||||
return this.getTitle() || this._getContent();
|
||||
// Private
|
||||
_getContentForTemplate() {
|
||||
return {
|
||||
[SELECTOR_TITLE]: this._getTitle(),
|
||||
[SELECTOR_CONTENT]: this._getContent()
|
||||
};
|
||||
}
|
||||
|
||||
setContent(tip) {
|
||||
this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);
|
||||
|
||||
this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);
|
||||
} // Private
|
||||
|
||||
|
||||
_getContent() {
|
||||
return this._resolvePossibleFunction(this._config.content);
|
||||
}
|
||||
|
||||
_getBasicClassPrefix() {
|
||||
return CLASS_PREFIX;
|
||||
} // Static
|
||||
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Popover.getOrCreateInstance(this, config);
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config]();
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Popover to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
|
||||
defineJQueryPlugin(Popover);
|
||||
index_js.defineJQueryPlugin(Popover);
|
||||
|
||||
return Popover;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,389 +1,273 @@
|
|||
/*!
|
||||
* Bootstrap scrollspy.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap scrollspy.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ScrollSpy = factory(global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
|
||||
})(this, (function (EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
||||
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ScrollSpy = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, SelectorEngine, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap scrollspy.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const toType = obj => {
|
||||
if (obj === null || obj === undefined) {
|
||||
return `${obj}`;
|
||||
}
|
||||
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getSelectorFromElement = element => {
|
||||
const selector = getSelector(element);
|
||||
|
||||
if (selector) {
|
||||
return document.querySelector(selector) ? selector : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
};
|
||||
|
||||
const getElement = obj => {
|
||||
if (isElement(obj)) {
|
||||
// it's a jQuery object or a node element
|
||||
return obj.jquery ? obj[0] : obj;
|
||||
}
|
||||
|
||||
if (typeof obj === 'string' && obj.length > 0) {
|
||||
return document.querySelector(obj);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const typeCheckConfig = (componentName, config, configTypes) => {
|
||||
Object.keys(configTypes).forEach(property => {
|
||||
const expectedTypes = configTypes[property];
|
||||
const value = config[property];
|
||||
const valueType = value && isElement(value) ? 'element' : toType(value);
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): scrollspy.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'scrollspy';
|
||||
const DATA_KEY = 'bs.scrollspy';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const DATA_API_KEY = '.data-api';
|
||||
const Default = {
|
||||
offset: 10,
|
||||
method: 'auto',
|
||||
target: ''
|
||||
};
|
||||
const DefaultType = {
|
||||
offset: 'number',
|
||||
method: 'string',
|
||||
target: '(string|element)'
|
||||
};
|
||||
const EVENT_ACTIVATE = `activate${EVENT_KEY}`;
|
||||
const EVENT_SCROLL = `scroll${EVENT_KEY}`;
|
||||
const EVENT_CLICK = `click${EVENT_KEY}`;
|
||||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
|
||||
const CLASS_NAME_ACTIVE = 'active';
|
||||
const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]';
|
||||
const SELECTOR_TARGET_LINKS = '[href]';
|
||||
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
|
||||
const SELECTOR_NAV_LINKS = '.nav-link';
|
||||
const SELECTOR_NAV_ITEMS = '.nav-item';
|
||||
const SELECTOR_LIST_ITEMS = '.list-group-item';
|
||||
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;
|
||||
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
|
||||
const SELECTOR_DROPDOWN = '.dropdown';
|
||||
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
|
||||
const METHOD_OFFSET = 'offset';
|
||||
const METHOD_POSITION = 'position';
|
||||
const Default = {
|
||||
offset: null,
|
||||
// TODO: v6 @deprecated, keep it for backwards compatibility reasons
|
||||
rootMargin: '0px 0px -25%',
|
||||
smoothScroll: false,
|
||||
target: null,
|
||||
threshold: [0.1, 0.5, 1]
|
||||
};
|
||||
const DefaultType = {
|
||||
offset: '(number|null)',
|
||||
// TODO v6 @deprecated, keep it for backwards compatibility reasons
|
||||
rootMargin: 'string',
|
||||
smoothScroll: 'boolean',
|
||||
target: 'element',
|
||||
threshold: 'array'
|
||||
};
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class ScrollSpy extends BaseComponent__default.default {
|
||||
class ScrollSpy extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
super(element);
|
||||
this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;
|
||||
this._config = this._getConfig(config);
|
||||
this._offsets = [];
|
||||
this._targets = [];
|
||||
super(element, config);
|
||||
|
||||
// this._element is the observablesContainer and config.target the menu links wrapper
|
||||
this._targetLinks = new Map();
|
||||
this._observableSections = new Map();
|
||||
this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
|
||||
this._activeTarget = null;
|
||||
this._scrollHeight = 0;
|
||||
EventHandler__default.default.on(this._scrollElement, EVENT_SCROLL, () => this._process());
|
||||
this.refresh();
|
||||
|
||||
this._process();
|
||||
} // Getters
|
||||
|
||||
this._observer = null;
|
||||
this._previousScrollData = {
|
||||
visibleEntryTop: 0,
|
||||
parentScrollTop: 0
|
||||
};
|
||||
this.refresh(); // initialize
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
|
||||
refresh() {
|
||||
const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
|
||||
const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
|
||||
const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
|
||||
this._offsets = [];
|
||||
this._targets = [];
|
||||
this._scrollHeight = this._getScrollHeight();
|
||||
const targets = SelectorEngine__default.default.find(SELECTOR_LINK_ITEMS, this._config.target);
|
||||
targets.map(element => {
|
||||
const targetSelector = getSelectorFromElement(element);
|
||||
const target = targetSelector ? SelectorEngine__default.default.findOne(targetSelector) : null;
|
||||
|
||||
if (target) {
|
||||
const targetBCR = target.getBoundingClientRect();
|
||||
|
||||
if (targetBCR.width || targetBCR.height) {
|
||||
return [Manipulator__default.default[offsetMethod](target).top + offsetBase, targetSelector];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {
|
||||
this._offsets.push(item[0]);
|
||||
|
||||
this._targets.push(item[1]);
|
||||
});
|
||||
}
|
||||
|
||||
// Public
|
||||
refresh() {
|
||||
this._initializeTargetsAndObservables();
|
||||
this._maybeEnableSmoothScroll();
|
||||
if (this._observer) {
|
||||
this._observer.disconnect();
|
||||
} else {
|
||||
this._observer = this._getNewObserver();
|
||||
}
|
||||
for (const section of this._observableSections.values()) {
|
||||
this._observer.observe(section);
|
||||
}
|
||||
}
|
||||
dispose() {
|
||||
EventHandler__default.default.off(this._scrollElement, EVENT_KEY);
|
||||
this._observer.disconnect();
|
||||
super.dispose();
|
||||
} // Private
|
||||
}
|
||||
|
||||
// Private
|
||||
_configAfterMerge(config) {
|
||||
// TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
|
||||
config.target = index_js.getElement(config.target) || document.body;
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...Default,
|
||||
...Manipulator__default.default.getDataAttributes(this._element),
|
||||
...(typeof config === 'object' && config ? config : {})
|
||||
};
|
||||
config.target = getElement(config.target) || document.documentElement;
|
||||
typeCheckConfig(NAME, config, DefaultType);
|
||||
// TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
|
||||
config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;
|
||||
if (typeof config.threshold === 'string') {
|
||||
config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
_getScrollTop() {
|
||||
return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
|
||||
}
|
||||
|
||||
_getScrollHeight() {
|
||||
return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
||||
}
|
||||
|
||||
_getOffsetHeight() {
|
||||
return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
|
||||
}
|
||||
|
||||
_process() {
|
||||
const scrollTop = this._getScrollTop() + this._config.offset;
|
||||
|
||||
const scrollHeight = this._getScrollHeight();
|
||||
|
||||
const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
|
||||
|
||||
if (this._scrollHeight !== scrollHeight) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
if (scrollTop >= maxScroll) {
|
||||
const target = this._targets[this._targets.length - 1];
|
||||
|
||||
if (this._activeTarget !== target) {
|
||||
this._activate(target);
|
||||
}
|
||||
|
||||
_maybeEnableSmoothScroll() {
|
||||
if (!this._config.smoothScroll) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
|
||||
this._activeTarget = null;
|
||||
// unregister any previous listeners
|
||||
EventHandler.off(this._config.target, EVENT_CLICK);
|
||||
EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
|
||||
const observableSection = this._observableSections.get(event.target.hash);
|
||||
if (observableSection) {
|
||||
event.preventDefault();
|
||||
const root = this._rootElement || window;
|
||||
const height = observableSection.offsetTop - this._element.offsetTop;
|
||||
if (root.scrollTo) {
|
||||
root.scrollTo({
|
||||
top: height,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this._clear();
|
||||
// Chrome 60 doesn't support `scrollTo`
|
||||
root.scrollTop = height;
|
||||
}
|
||||
});
|
||||
}
|
||||
_getNewObserver() {
|
||||
const options = {
|
||||
root: this._rootElement,
|
||||
threshold: this._config.threshold,
|
||||
rootMargin: this._config.rootMargin
|
||||
};
|
||||
return new IntersectionObserver(entries => this._observerCallback(entries), options);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// The logic of selection
|
||||
_observerCallback(entries) {
|
||||
const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
|
||||
const activate = entry => {
|
||||
this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
|
||||
this._process(targetElement(entry));
|
||||
};
|
||||
const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
|
||||
const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
|
||||
this._previousScrollData.parentScrollTop = parentScrollTop;
|
||||
for (const entry of entries) {
|
||||
if (!entry.isIntersecting) {
|
||||
this._activeTarget = null;
|
||||
this._clearActiveClass(targetElement(entry));
|
||||
continue;
|
||||
}
|
||||
const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;
|
||||
// if we are scrolling down, pick the bigger offsetTop
|
||||
if (userScrollsDown && entryIsLowerThanPrevious) {
|
||||
activate(entry);
|
||||
// if parent isn't scrolled, let's keep the first visible item, breaking the iteration
|
||||
if (!parentScrollTop) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let i = this._offsets.length; i--;) {
|
||||
const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
|
||||
|
||||
if (isActiveTarget) {
|
||||
this._activate(this._targets[i]);
|
||||
// if we are scrolling up, pick the smallest offsetTop
|
||||
if (!userScrollsDown && !entryIsLowerThanPrevious) {
|
||||
activate(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
_initializeTargetsAndObservables() {
|
||||
this._targetLinks = new Map();
|
||||
this._observableSections = new Map();
|
||||
const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);
|
||||
for (const anchor of targetLinks) {
|
||||
// ensure that the anchor has an id and is not disabled
|
||||
if (!anchor.hash || index_js.isDisabled(anchor)) {
|
||||
continue;
|
||||
}
|
||||
const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);
|
||||
|
||||
_activate(target) {
|
||||
// ensure that the observableSection exists & is visible
|
||||
if (index_js.isVisible(observableSection)) {
|
||||
this._targetLinks.set(decodeURI(anchor.hash), anchor);
|
||||
this._observableSections.set(anchor.hash, observableSection);
|
||||
}
|
||||
}
|
||||
}
|
||||
_process(target) {
|
||||
if (this._activeTarget === target) {
|
||||
return;
|
||||
}
|
||||
this._clearActiveClass(this._config.target);
|
||||
this._activeTarget = target;
|
||||
|
||||
this._clear();
|
||||
|
||||
const queries = SELECTOR_LINK_ITEMS.split(',').map(selector => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`);
|
||||
const link = SelectorEngine__default.default.findOne(queries.join(','), this._config.target);
|
||||
link.classList.add(CLASS_NAME_ACTIVE);
|
||||
|
||||
if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
|
||||
SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);
|
||||
} else {
|
||||
SelectorEngine__default.default.parents(link, SELECTOR_NAV_LIST_GROUP).forEach(listGroup => {
|
||||
// Set triggered links parents as active
|
||||
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
||||
SelectorEngine__default.default.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE)); // Handle special case when .nav-link is inside .nav-item
|
||||
|
||||
SelectorEngine__default.default.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {
|
||||
SelectorEngine__default.default.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
EventHandler__default.default.trigger(this._scrollElement, EVENT_ACTIVATE, {
|
||||
target.classList.add(CLASS_NAME_ACTIVE);
|
||||
this._activateParents(target);
|
||||
EventHandler.trigger(this._element, EVENT_ACTIVATE, {
|
||||
relatedTarget: target
|
||||
});
|
||||
}
|
||||
_activateParents(target) {
|
||||
// Activate dropdown parents
|
||||
if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
|
||||
SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);
|
||||
return;
|
||||
}
|
||||
for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {
|
||||
// Set triggered links parents as active
|
||||
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
||||
for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {
|
||||
item.classList.add(CLASS_NAME_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
_clearActiveClass(parent) {
|
||||
parent.classList.remove(CLASS_NAME_ACTIVE);
|
||||
const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent);
|
||||
for (const node of activeNodes) {
|
||||
node.classList.remove(CLASS_NAME_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
_clear() {
|
||||
SelectorEngine__default.default.find(SELECTOR_LINK_ITEMS, this._config.target).filter(node => node.classList.contains(CLASS_NAME_ACTIVE)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE));
|
||||
} // Static
|
||||
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = ScrollSpy.getOrCreateInstance(this, config);
|
||||
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof data[config] === 'undefined') {
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
|
||||
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
SelectorEngine__default.default.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy));
|
||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {
|
||||
ScrollSpy.getOrCreateInstance(spy);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .ScrollSpy to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(ScrollSpy);
|
||||
index_js.defineJQueryPlugin(ScrollSpy);
|
||||
|
||||
return ScrollSpy;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,331 +1,283 @@
|
|||
/*!
|
||||
* Bootstrap tab.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap tab.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/event-handler', './dom/selector-engine', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tab = factory(global.EventHandler, global.SelectorEngine, global.Base));
|
||||
})(this, (function (EventHandler, SelectorEngine, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Tab = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, SelectorEngine, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap tab.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getElementFromSelector = element => {
|
||||
const selector = getSelector(element);
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
};
|
||||
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
|
||||
|
||||
const reflow = element => {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
element.offsetHeight;
|
||||
};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): tab.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'tab';
|
||||
const DATA_KEY = 'bs.tab';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const DATA_API_KEY = '.data-api';
|
||||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
||||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
||||
const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';
|
||||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}`;
|
||||
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
|
||||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`;
|
||||
const ARROW_LEFT_KEY = 'ArrowLeft';
|
||||
const ARROW_RIGHT_KEY = 'ArrowRight';
|
||||
const ARROW_UP_KEY = 'ArrowUp';
|
||||
const ARROW_DOWN_KEY = 'ArrowDown';
|
||||
const HOME_KEY = 'Home';
|
||||
const END_KEY = 'End';
|
||||
const CLASS_NAME_ACTIVE = 'active';
|
||||
const CLASS_NAME_FADE = 'fade';
|
||||
const CLASS_NAME_SHOW = 'show';
|
||||
const SELECTOR_DROPDOWN = '.dropdown';
|
||||
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
|
||||
const SELECTOR_ACTIVE = '.active';
|
||||
const SELECTOR_ACTIVE_UL = ':scope > li > .active';
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]';
|
||||
const CLASS_DROPDOWN = 'dropdown';
|
||||
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
|
||||
const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active';
|
||||
const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
|
||||
const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`;
|
||||
const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
|
||||
const SELECTOR_OUTER = '.nav-item, .list-group-item';
|
||||
const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
|
||||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6
|
||||
const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
|
||||
const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`;
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Tab extends BaseComponent__default.default {
|
||||
class Tab extends BaseComponent {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this._parent = this._element.closest(SELECTOR_TAB_PANEL);
|
||||
if (!this._parent) {
|
||||
return;
|
||||
// TODO: should throw exception in v6
|
||||
// throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
|
||||
}
|
||||
|
||||
// Set up initial aria attributes
|
||||
this._setInitialAttributes(this._parent, this._getChildren());
|
||||
EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
|
||||
show() {
|
||||
if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.classList.contains(CLASS_NAME_ACTIVE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let previous;
|
||||
const target = getElementFromSelector(this._element);
|
||||
|
||||
const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP);
|
||||
|
||||
if (listElement) {
|
||||
const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;
|
||||
previous = SelectorEngine__default.default.find(itemSelector, listElement);
|
||||
previous = previous[previous.length - 1];
|
||||
}
|
||||
|
||||
const hideEvent = previous ? EventHandler__default.default.trigger(previous, EVENT_HIDE, {
|
||||
relatedTarget: this._element
|
||||
}) : null;
|
||||
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
|
||||
relatedTarget: previous
|
||||
});
|
||||
|
||||
if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._activate(this._element, listElement);
|
||||
|
||||
const complete = () => {
|
||||
EventHandler__default.default.trigger(previous, EVENT_HIDDEN, {
|
||||
relatedTarget: this._element
|
||||
});
|
||||
EventHandler__default.default.trigger(this._element, EVENT_SHOWN, {
|
||||
relatedTarget: previous
|
||||
});
|
||||
};
|
||||
|
||||
if (target) {
|
||||
this._activate(target, target.parentNode, complete);
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
} // Private
|
||||
|
||||
|
||||
_activate(element, container, callback) {
|
||||
const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine__default.default.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine__default.default.children(container, SELECTOR_ACTIVE);
|
||||
const active = activeElements[0];
|
||||
const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE);
|
||||
|
||||
const complete = () => this._transitionComplete(element, active, callback);
|
||||
|
||||
if (active && isTransitioning) {
|
||||
active.classList.remove(CLASS_NAME_SHOW);
|
||||
|
||||
this._queueCallback(complete, element, true);
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
}
|
||||
|
||||
_transitionComplete(element, active, callback) {
|
||||
if (active) {
|
||||
active.classList.remove(CLASS_NAME_ACTIVE);
|
||||
const dropdownChild = SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode);
|
||||
|
||||
if (dropdownChild) {
|
||||
dropdownChild.classList.remove(CLASS_NAME_ACTIVE);
|
||||
}
|
||||
|
||||
if (active.getAttribute('role') === 'tab') {
|
||||
active.setAttribute('aria-selected', false);
|
||||
}
|
||||
// Public
|
||||
show() {
|
||||
// Shows this elem and deactivate the active sibling if exists
|
||||
const innerElem = this._element;
|
||||
if (this._elemIsActive(innerElem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Search for active tab on same parent to deactivate it
|
||||
const active = this._getActiveElem();
|
||||
const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE, {
|
||||
relatedTarget: innerElem
|
||||
}) : null;
|
||||
const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW, {
|
||||
relatedTarget: active
|
||||
});
|
||||
if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
this._deactivate(active, innerElem);
|
||||
this._activate(innerElem, active);
|
||||
}
|
||||
|
||||
// Private
|
||||
_activate(element, relatedElem) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
element.classList.add(CLASS_NAME_ACTIVE);
|
||||
this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section
|
||||
|
||||
if (element.getAttribute('role') === 'tab') {
|
||||
element.setAttribute('aria-selected', true);
|
||||
}
|
||||
|
||||
reflow(element);
|
||||
|
||||
if (element.classList.contains(CLASS_NAME_FADE)) {
|
||||
element.classList.add(CLASS_NAME_SHOW);
|
||||
}
|
||||
|
||||
let parent = element.parentNode;
|
||||
|
||||
if (parent && parent.nodeName === 'LI') {
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
|
||||
const dropdownElement = element.closest(SELECTOR_DROPDOWN);
|
||||
|
||||
if (dropdownElement) {
|
||||
SelectorEngine__default.default.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE));
|
||||
const complete = () => {
|
||||
if (element.getAttribute('role') !== 'tab') {
|
||||
element.classList.add(CLASS_NAME_SHOW);
|
||||
return;
|
||||
}
|
||||
|
||||
element.setAttribute('aria-expanded', true);
|
||||
element.removeAttribute('tabindex');
|
||||
element.setAttribute('aria-selected', true);
|
||||
this._toggleDropDown(element, true);
|
||||
EventHandler.trigger(element, EVENT_SHOWN, {
|
||||
relatedTarget: relatedElem
|
||||
});
|
||||
};
|
||||
this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
|
||||
}
|
||||
_deactivate(element, relatedElem) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
element.classList.remove(CLASS_NAME_ACTIVE);
|
||||
element.blur();
|
||||
this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
const complete = () => {
|
||||
if (element.getAttribute('role') !== 'tab') {
|
||||
element.classList.remove(CLASS_NAME_SHOW);
|
||||
return;
|
||||
}
|
||||
element.setAttribute('aria-selected', false);
|
||||
element.setAttribute('tabindex', '-1');
|
||||
this._toggleDropDown(element, false);
|
||||
EventHandler.trigger(element, EVENT_HIDDEN, {
|
||||
relatedTarget: relatedElem
|
||||
});
|
||||
};
|
||||
this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE));
|
||||
}
|
||||
_keydown(event) {
|
||||
if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) {
|
||||
return;
|
||||
}
|
||||
} // Static
|
||||
event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
|
||||
event.preventDefault();
|
||||
const children = this._getChildren().filter(element => !index_js.isDisabled(element));
|
||||
let nextActiveElement;
|
||||
if ([HOME_KEY, END_KEY].includes(event.key)) {
|
||||
nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1];
|
||||
} else {
|
||||
const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
|
||||
nextActiveElement = index_js.getNextActiveElement(children, event.target, isNext, true);
|
||||
}
|
||||
if (nextActiveElement) {
|
||||
nextActiveElement.focus({
|
||||
preventScroll: true
|
||||
});
|
||||
Tab.getOrCreateInstance(nextActiveElement).show();
|
||||
}
|
||||
}
|
||||
_getChildren() {
|
||||
// collection of inner elements
|
||||
return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);
|
||||
}
|
||||
_getActiveElem() {
|
||||
return this._getChildren().find(child => this._elemIsActive(child)) || null;
|
||||
}
|
||||
_setInitialAttributes(parent, children) {
|
||||
this._setAttributeIfNotExists(parent, 'role', 'tablist');
|
||||
for (const child of children) {
|
||||
this._setInitialAttributesOnChild(child);
|
||||
}
|
||||
}
|
||||
_setInitialAttributesOnChild(child) {
|
||||
child = this._getInnerElement(child);
|
||||
const isActive = this._elemIsActive(child);
|
||||
const outerElem = this._getOuterElement(child);
|
||||
child.setAttribute('aria-selected', isActive);
|
||||
if (outerElem !== child) {
|
||||
this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
|
||||
}
|
||||
if (!isActive) {
|
||||
child.setAttribute('tabindex', '-1');
|
||||
}
|
||||
this._setAttributeIfNotExists(child, 'role', 'tab');
|
||||
|
||||
// set attributes to the related panel too
|
||||
this._setInitialAttributesOnTargetPanel(child);
|
||||
}
|
||||
_setInitialAttributesOnTargetPanel(child) {
|
||||
const target = SelectorEngine.getElementFromSelector(child);
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
this._setAttributeIfNotExists(target, 'role', 'tabpanel');
|
||||
if (child.id) {
|
||||
this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`);
|
||||
}
|
||||
}
|
||||
_toggleDropDown(element, open) {
|
||||
const outerElem = this._getOuterElement(element);
|
||||
if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
|
||||
return;
|
||||
}
|
||||
const toggle = (selector, className) => {
|
||||
const element = SelectorEngine.findOne(selector, outerElem);
|
||||
if (element) {
|
||||
element.classList.toggle(className, open);
|
||||
}
|
||||
};
|
||||
toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
|
||||
toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW);
|
||||
outerElem.setAttribute('aria-expanded', open);
|
||||
}
|
||||
_setAttributeIfNotExists(element, attribute, value) {
|
||||
if (!element.hasAttribute(attribute)) {
|
||||
element.setAttribute(attribute, value);
|
||||
}
|
||||
}
|
||||
_elemIsActive(elem) {
|
||||
return elem.classList.contains(CLASS_NAME_ACTIVE);
|
||||
}
|
||||
|
||||
// Try to get the inner element (usually the .nav-link)
|
||||
_getInnerElement(elem) {
|
||||
return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);
|
||||
}
|
||||
|
||||
// Try to get the outer element (usually the .nav-item)
|
||||
_getOuterElement(elem) {
|
||||
return elem.closest(SELECTOR_OUTER) || elem;
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Tab.getOrCreateInstance(this);
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config]();
|
||||
if (typeof config !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
data[config]();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
|
||||
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||||
if (['A', 'AREA'].includes(this.tagName)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (isDisabled(this)) {
|
||||
if (index_js.isDisabled(this)) {
|
||||
return;
|
||||
}
|
||||
Tab.getOrCreateInstance(this).show();
|
||||
});
|
||||
|
||||
const data = Tab.getOrCreateInstance(this);
|
||||
data.show();
|
||||
/**
|
||||
* Initialize on focus
|
||||
*/
|
||||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||||
for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
|
||||
Tab.getOrCreateInstance(element);
|
||||
}
|
||||
});
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Tab to jQuery only if jQuery is present
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Tab);
|
||||
index_js.defineJQueryPlugin(Tab);
|
||||
|
||||
return Tab;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,202 +1,24 @@
|
|||
/*!
|
||||
* Bootstrap toast.js v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Bootstrap toast.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./base-component.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./dom/event-handler', './dom/manipulator', './base-component'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Toast = factory(global.EventHandler, global.Manipulator, global.Base));
|
||||
})(this, (function (EventHandler, Manipulator, BaseComponent) { 'use strict';
|
||||
|
||||
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
||||
|
||||
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
||||
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
||||
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./util/component-functions.js'), require('./util/index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './util/component-functions', './util/index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Toast = factory(global.BaseComponent, global.EventHandler, global.ComponentFunctions, global.Index));
|
||||
})(this, (function (BaseComponent, EventHandler, componentFunctions_js, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/index.js
|
||||
* Bootstrap toast.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const toType = obj => {
|
||||
if (obj === null || obj === undefined) {
|
||||
return `${obj}`;
|
||||
}
|
||||
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
const getSelector = element => {
|
||||
let selector = element.getAttribute('data-bs-target');
|
||||
|
||||
if (!selector || selector === '#') {
|
||||
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
||||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||||
// `document.querySelector` will rightfully complain it is invalid.
|
||||
// See https://github.com/twbs/bootstrap/issues/32273
|
||||
|
||||
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
||||
return null;
|
||||
} // Just in case some CMS puts out a full URL with the anchor appended
|
||||
|
||||
|
||||
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
||||
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
||||
}
|
||||
|
||||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
const getElementFromSelector = element => {
|
||||
const selector = getSelector(element);
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
};
|
||||
|
||||
const isElement = obj => {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof obj.jquery !== 'undefined') {
|
||||
obj = obj[0];
|
||||
}
|
||||
|
||||
return typeof obj.nodeType !== 'undefined';
|
||||
};
|
||||
|
||||
const typeCheckConfig = (componentName, config, configTypes) => {
|
||||
Object.keys(configTypes).forEach(property => {
|
||||
const expectedTypes = configTypes[property];
|
||||
const value = config[property];
|
||||
const valueType = value && isElement(value) ? 'element' : toType(value);
|
||||
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
|
||||
|
||||
const reflow = element => {
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
element.offsetHeight;
|
||||
};
|
||||
|
||||
const getjQuery = () => {
|
||||
const {
|
||||
jQuery
|
||||
} = window;
|
||||
|
||||
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return jQuery;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
DOMContentLoadedCallbacks.forEach(callback => callback());
|
||||
});
|
||||
}
|
||||
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): util/component-functions.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const enableDismissTrigger = (component, method = 'hide') => {
|
||||
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
||||
const name = component.NAME;
|
||||
EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
||||
if (['A', 'AREA'].includes(this.tagName)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (isDisabled(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = getElementFromSelector(this) || this.closest(`.${name}`);
|
||||
const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
||||
|
||||
instance[method]();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v5.1.3): toast.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'toast';
|
||||
|
|
@ -212,7 +34,6 @@
|
|||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
||||
const CLASS_NAME_FADE = 'fade';
|
||||
const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility
|
||||
|
||||
const CLASS_NAME_SHOW = 'show';
|
||||
const CLASS_NAME_SHOWING = 'showing';
|
||||
const DefaultType = {
|
||||
|
|
@ -225,197 +46,152 @@
|
|||
autohide: true,
|
||||
delay: 5000
|
||||
};
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Class Definition
|
||||
* ------------------------------------------------------------------------
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Toast extends BaseComponent__default.default {
|
||||
class Toast extends BaseComponent {
|
||||
constructor(element, config) {
|
||||
super(element);
|
||||
this._config = this._getConfig(config);
|
||||
super(element, config);
|
||||
this._timeout = null;
|
||||
this._hasMouseInteraction = false;
|
||||
this._hasKeyboardInteraction = false;
|
||||
|
||||
this._setListeners();
|
||||
} // Getters
|
||||
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
} // Public
|
||||
|
||||
}
|
||||
|
||||
// Public
|
||||
show() {
|
||||
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW);
|
||||
|
||||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);
|
||||
if (showEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._clearTimeout();
|
||||
|
||||
if (this._config.animation) {
|
||||
this._element.classList.add(CLASS_NAME_FADE);
|
||||
}
|
||||
|
||||
const complete = () => {
|
||||
this._element.classList.remove(CLASS_NAME_SHOWING);
|
||||
|
||||
EventHandler__default.default.trigger(this._element, EVENT_SHOWN);
|
||||
|
||||
EventHandler.trigger(this._element, EVENT_SHOWN);
|
||||
this._maybeScheduleHide();
|
||||
};
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated
|
||||
|
||||
|
||||
reflow(this._element);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_SHOW);
|
||||
|
||||
this._element.classList.add(CLASS_NAME_SHOWING);
|
||||
|
||||
index_js.reflow(this._element);
|
||||
this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING);
|
||||
this._queueCallback(complete, this._element, this._config.animation);
|
||||
}
|
||||
|
||||
hide() {
|
||||
if (!this._element.classList.contains(CLASS_NAME_SHOW)) {
|
||||
if (!this.isShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
|
||||
|
||||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
|
||||
if (hideEvent.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
const complete = () => {
|
||||
this._element.classList.add(CLASS_NAME_HIDE); // @deprecated
|
||||
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_SHOWING);
|
||||
|
||||
this._element.classList.remove(CLASS_NAME_SHOW);
|
||||
|
||||
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
|
||||
this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW);
|
||||
EventHandler.trigger(this._element, EVENT_HIDDEN);
|
||||
};
|
||||
|
||||
this._element.classList.add(CLASS_NAME_SHOWING);
|
||||
|
||||
this._queueCallback(complete, this._element, this._config.animation);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._clearTimeout();
|
||||
|
||||
if (this._element.classList.contains(CLASS_NAME_SHOW)) {
|
||||
if (this.isShown()) {
|
||||
this._element.classList.remove(CLASS_NAME_SHOW);
|
||||
}
|
||||
|
||||
super.dispose();
|
||||
} // Private
|
||||
|
||||
|
||||
_getConfig(config) {
|
||||
config = { ...Default,
|
||||
...Manipulator__default.default.getDataAttributes(this._element),
|
||||
...(typeof config === 'object' && config ? config : {})
|
||||
};
|
||||
typeCheckConfig(NAME, config, this.constructor.DefaultType);
|
||||
return config;
|
||||
}
|
||||
isShown() {
|
||||
return this._element.classList.contains(CLASS_NAME_SHOW);
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
_maybeScheduleHide() {
|
||||
if (!this._config.autohide) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._hasMouseInteraction || this._hasKeyboardInteraction) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._timeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, this._config.delay);
|
||||
}
|
||||
|
||||
_onInteraction(event, isInteracting) {
|
||||
switch (event.type) {
|
||||
case 'mouseover':
|
||||
case 'mouseout':
|
||||
this._hasMouseInteraction = isInteracting;
|
||||
break;
|
||||
|
||||
{
|
||||
this._hasMouseInteraction = isInteracting;
|
||||
break;
|
||||
}
|
||||
case 'focusin':
|
||||
case 'focusout':
|
||||
this._hasKeyboardInteraction = isInteracting;
|
||||
break;
|
||||
{
|
||||
this._hasKeyboardInteraction = isInteracting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isInteracting) {
|
||||
this._clearTimeout();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const nextElement = event.relatedTarget;
|
||||
|
||||
if (this._element === nextElement || this._element.contains(nextElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._maybeScheduleHide();
|
||||
}
|
||||
|
||||
_setListeners() {
|
||||
EventHandler__default.default.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));
|
||||
EventHandler__default.default.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));
|
||||
EventHandler__default.default.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));
|
||||
EventHandler__default.default.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));
|
||||
EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));
|
||||
EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));
|
||||
EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));
|
||||
EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));
|
||||
}
|
||||
|
||||
_clearTimeout() {
|
||||
clearTimeout(this._timeout);
|
||||
this._timeout = null;
|
||||
} // Static
|
||||
|
||||
}
|
||||
|
||||
// Static
|
||||
static jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
const data = Toast.getOrCreateInstance(this, config);
|
||||
|
||||
if (typeof config === 'string') {
|
||||
if (typeof data[config] === 'undefined') {
|
||||
throw new TypeError(`No method named "${config}"`);
|
||||
}
|
||||
|
||||
data[config](this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enableDismissTrigger(Toast);
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
* add .Toast to jQuery only if jQuery is present
|
||||
* Data API implementation
|
||||
*/
|
||||
|
||||
defineJQueryPlugin(Toast);
|
||||
componentFunctions_js.enableDismissTrigger(Toast);
|
||||
|
||||
/**
|
||||
* jQuery
|
||||
*/
|
||||
|
||||
index_js.defineJQueryPlugin(Toast);
|
||||
|
||||
return Toast;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
139
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/backdrop.js
vendored
Normal file
139
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/backdrop.js
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*!
|
||||
* Bootstrap backdrop.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/event-handler.js'), require('./config.js'), require('./index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../dom/event-handler', './config', './index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Backdrop = factory(global.EventHandler, global.Config, global.Index));
|
||||
})(this, (function (EventHandler, Config, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/backdrop.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const NAME = 'backdrop';
|
||||
const CLASS_NAME_FADE = 'fade';
|
||||
const CLASS_NAME_SHOW = 'show';
|
||||
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`;
|
||||
const Default = {
|
||||
className: 'modal-backdrop',
|
||||
clickCallback: null,
|
||||
isAnimated: false,
|
||||
isVisible: true,
|
||||
// if false, we use the backdrop helper without adding any element to the dom
|
||||
rootElement: 'body' // give the choice to place backdrop under different elements
|
||||
};
|
||||
const DefaultType = {
|
||||
className: 'string',
|
||||
clickCallback: '(function|null)',
|
||||
isAnimated: 'boolean',
|
||||
isVisible: 'boolean',
|
||||
rootElement: '(element|string)'
|
||||
};
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Backdrop extends Config {
|
||||
constructor(config) {
|
||||
super();
|
||||
this._config = this._getConfig(config);
|
||||
this._isAppended = false;
|
||||
this._element = null;
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
// Public
|
||||
show(callback) {
|
||||
if (!this._config.isVisible) {
|
||||
index_js.execute(callback);
|
||||
return;
|
||||
}
|
||||
this._append();
|
||||
const element = this._getElement();
|
||||
if (this._config.isAnimated) {
|
||||
index_js.reflow(element);
|
||||
}
|
||||
element.classList.add(CLASS_NAME_SHOW);
|
||||
this._emulateAnimation(() => {
|
||||
index_js.execute(callback);
|
||||
});
|
||||
}
|
||||
hide(callback) {
|
||||
if (!this._config.isVisible) {
|
||||
index_js.execute(callback);
|
||||
return;
|
||||
}
|
||||
this._getElement().classList.remove(CLASS_NAME_SHOW);
|
||||
this._emulateAnimation(() => {
|
||||
this.dispose();
|
||||
index_js.execute(callback);
|
||||
});
|
||||
}
|
||||
dispose() {
|
||||
if (!this._isAppended) {
|
||||
return;
|
||||
}
|
||||
EventHandler.off(this._element, EVENT_MOUSEDOWN);
|
||||
this._element.remove();
|
||||
this._isAppended = false;
|
||||
}
|
||||
|
||||
// Private
|
||||
_getElement() {
|
||||
if (!this._element) {
|
||||
const backdrop = document.createElement('div');
|
||||
backdrop.className = this._config.className;
|
||||
if (this._config.isAnimated) {
|
||||
backdrop.classList.add(CLASS_NAME_FADE);
|
||||
}
|
||||
this._element = backdrop;
|
||||
}
|
||||
return this._element;
|
||||
}
|
||||
_configAfterMerge(config) {
|
||||
// use getElement() with the default "body" to get a fresh Element on each instantiation
|
||||
config.rootElement = index_js.getElement(config.rootElement);
|
||||
return config;
|
||||
}
|
||||
_append() {
|
||||
if (this._isAppended) {
|
||||
return;
|
||||
}
|
||||
const element = this._getElement();
|
||||
this._config.rootElement.append(element);
|
||||
EventHandler.on(element, EVENT_MOUSEDOWN, () => {
|
||||
index_js.execute(this._config.clickCallback);
|
||||
});
|
||||
this._isAppended = true;
|
||||
}
|
||||
_emulateAnimation(callback) {
|
||||
index_js.executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
|
||||
}
|
||||
}
|
||||
|
||||
return Backdrop;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=backdrop.js.map
|
||||
42
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/component-functions.js
vendored
Normal file
42
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/component-functions.js
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*!
|
||||
* Bootstrap component-functions.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('../dom/event-handler.js'), require('../dom/selector-engine.js'), require('./index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['exports', '../dom/event-handler', '../dom/selector-engine', './index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComponentFunctions = {}, global.EventHandler, global.SelectorEngine, global.Index));
|
||||
})(this, (function (exports, EventHandler, SelectorEngine, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/component-functions.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const enableDismissTrigger = (component, method = 'hide') => {
|
||||
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
||||
const name = component.NAME;
|
||||
EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
||||
if (['A', 'AREA'].includes(this.tagName)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
if (index_js.isDisabled(this)) {
|
||||
return;
|
||||
}
|
||||
const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);
|
||||
const instance = component.getOrCreateInstance(target);
|
||||
|
||||
// Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
||||
instance[method]();
|
||||
});
|
||||
};
|
||||
|
||||
exports.enableDismissTrigger = enableDismissTrigger;
|
||||
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=component-functions.js.map
|
||||
68
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/config.js
vendored
Normal file
68
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/config.js
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*!
|
||||
* Bootstrap config.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/manipulator.js'), require('./index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../dom/manipulator', './index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Config = factory(global.Manipulator, global.Index));
|
||||
})(this, (function (Manipulator, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/config.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Config {
|
||||
// Getters
|
||||
static get Default() {
|
||||
return {};
|
||||
}
|
||||
static get DefaultType() {
|
||||
return {};
|
||||
}
|
||||
static get NAME() {
|
||||
throw new Error('You have to implement the static method "NAME", for each component!');
|
||||
}
|
||||
_getConfig(config) {
|
||||
config = this._mergeConfigObj(config);
|
||||
config = this._configAfterMerge(config);
|
||||
this._typeCheckConfig(config);
|
||||
return config;
|
||||
}
|
||||
_configAfterMerge(config) {
|
||||
return config;
|
||||
}
|
||||
_mergeConfigObj(config, element) {
|
||||
const jsonConfig = index_js.isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse
|
||||
|
||||
return {
|
||||
...this.constructor.Default,
|
||||
...(typeof jsonConfig === 'object' ? jsonConfig : {}),
|
||||
...(index_js.isElement(element) ? Manipulator.getDataAttributes(element) : {}),
|
||||
...(typeof config === 'object' ? config : {})
|
||||
};
|
||||
}
|
||||
_typeCheckConfig(config, configTypes = this.constructor.DefaultType) {
|
||||
for (const [property, expectedTypes] of Object.entries(configTypes)) {
|
||||
const value = config[property];
|
||||
const valueType = index_js.isElement(value) ? 'element' : index_js.toType(value);
|
||||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||||
throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Config;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=config.js.map
|
||||
113
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/focustrap.js
vendored
Normal file
113
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/focustrap.js
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*!
|
||||
* Bootstrap focustrap.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/event-handler.js'), require('../dom/selector-engine.js'), require('./config.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../dom/event-handler', '../dom/selector-engine', './config'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Focustrap = factory(global.EventHandler, global.SelectorEngine, global.Config));
|
||||
})(this, (function (EventHandler, SelectorEngine, Config) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/focustrap.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const NAME = 'focustrap';
|
||||
const DATA_KEY = 'bs.focustrap';
|
||||
const EVENT_KEY = `.${DATA_KEY}`;
|
||||
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
|
||||
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`;
|
||||
const TAB_KEY = 'Tab';
|
||||
const TAB_NAV_FORWARD = 'forward';
|
||||
const TAB_NAV_BACKWARD = 'backward';
|
||||
const Default = {
|
||||
autofocus: true,
|
||||
trapElement: null // The element to trap focus inside of
|
||||
};
|
||||
const DefaultType = {
|
||||
autofocus: 'boolean',
|
||||
trapElement: 'element'
|
||||
};
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class FocusTrap extends Config {
|
||||
constructor(config) {
|
||||
super();
|
||||
this._config = this._getConfig(config);
|
||||
this._isActive = false;
|
||||
this._lastTabNavDirection = null;
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
// Public
|
||||
activate() {
|
||||
if (this._isActive) {
|
||||
return;
|
||||
}
|
||||
if (this._config.autofocus) {
|
||||
this._config.trapElement.focus();
|
||||
}
|
||||
EventHandler.off(document, EVENT_KEY); // guard against infinite focus loop
|
||||
EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
|
||||
EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
|
||||
this._isActive = true;
|
||||
}
|
||||
deactivate() {
|
||||
if (!this._isActive) {
|
||||
return;
|
||||
}
|
||||
this._isActive = false;
|
||||
EventHandler.off(document, EVENT_KEY);
|
||||
}
|
||||
|
||||
// Private
|
||||
_handleFocusin(event) {
|
||||
const {
|
||||
trapElement
|
||||
} = this._config;
|
||||
if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
|
||||
return;
|
||||
}
|
||||
const elements = SelectorEngine.focusableChildren(trapElement);
|
||||
if (elements.length === 0) {
|
||||
trapElement.focus();
|
||||
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
||||
elements[elements.length - 1].focus();
|
||||
} else {
|
||||
elements[0].focus();
|
||||
}
|
||||
}
|
||||
_handleKeydown(event) {
|
||||
if (event.key !== TAB_KEY) {
|
||||
return;
|
||||
}
|
||||
this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
|
||||
}
|
||||
}
|
||||
|
||||
return FocusTrap;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=focustrap.js.map
|
||||
281
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/index.js
vendored
Normal file
281
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/index.js
vendored
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/*!
|
||||
* Bootstrap index.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Index = {}));
|
||||
})(this, (function (exports) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/index.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const MAX_UID = 1000000;
|
||||
const MILLISECONDS_MULTIPLIER = 1000;
|
||||
const TRANSITION_END = 'transitionend';
|
||||
|
||||
/**
|
||||
* Properly escape IDs selectors to handle weird IDs
|
||||
* @param {string} selector
|
||||
* @returns {string}
|
||||
*/
|
||||
const parseSelector = selector => {
|
||||
if (selector && window.CSS && window.CSS.escape) {
|
||||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||||
}
|
||||
return selector;
|
||||
};
|
||||
|
||||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||||
const toType = object => {
|
||||
if (object === null || object === undefined) {
|
||||
return `${object}`;
|
||||
}
|
||||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Public Util API
|
||||
*/
|
||||
|
||||
const getUID = prefix => {
|
||||
do {
|
||||
prefix += Math.floor(Math.random() * MAX_UID);
|
||||
} while (document.getElementById(prefix));
|
||||
return prefix;
|
||||
};
|
||||
const getTransitionDurationFromElement = element => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get transition-duration of the element
|
||||
let {
|
||||
transitionDuration,
|
||||
transitionDelay
|
||||
} = window.getComputedStyle(element);
|
||||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||||
|
||||
// Return 0 if element or transition duration is not found
|
||||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If multiple durations are defined, take the first
|
||||
transitionDuration = transitionDuration.split(',')[0];
|
||||
transitionDelay = transitionDelay.split(',')[0];
|
||||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||||
};
|
||||
const triggerTransitionEnd = element => {
|
||||
element.dispatchEvent(new Event(TRANSITION_END));
|
||||
};
|
||||
const isElement = object => {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return false;
|
||||
}
|
||||
if (typeof object.jquery !== 'undefined') {
|
||||
object = object[0];
|
||||
}
|
||||
return typeof object.nodeType !== 'undefined';
|
||||
};
|
||||
const getElement = object => {
|
||||
// it's a jQuery object or a node element
|
||||
if (isElement(object)) {
|
||||
return object.jquery ? object[0] : object;
|
||||
}
|
||||
if (typeof object === 'string' && object.length > 0) {
|
||||
return document.querySelector(parseSelector(object));
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const isVisible = element => {
|
||||
if (!isElement(element) || element.getClientRects().length === 0) {
|
||||
return false;
|
||||
}
|
||||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||||
const closedDetails = element.closest('details:not([open])');
|
||||
if (!closedDetails) {
|
||||
return elementIsVisible;
|
||||
}
|
||||
if (closedDetails !== element) {
|
||||
const summary = element.closest('summary');
|
||||
if (summary && summary.parentNode !== closedDetails) {
|
||||
return false;
|
||||
}
|
||||
if (summary === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return elementIsVisible;
|
||||
};
|
||||
const isDisabled = element => {
|
||||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||||
return true;
|
||||
}
|
||||
if (element.classList.contains('disabled')) {
|
||||
return true;
|
||||
}
|
||||
if (typeof element.disabled !== 'undefined') {
|
||||
return element.disabled;
|
||||
}
|
||||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||||
};
|
||||
const findShadowRoot = element => {
|
||||
if (!document.documentElement.attachShadow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can find the shadow root otherwise it'll return the document
|
||||
if (typeof element.getRootNode === 'function') {
|
||||
const root = element.getRootNode();
|
||||
return root instanceof ShadowRoot ? root : null;
|
||||
}
|
||||
if (element instanceof ShadowRoot) {
|
||||
return element;
|
||||
}
|
||||
|
||||
// when we don't find a shadow root
|
||||
if (!element.parentNode) {
|
||||
return null;
|
||||
}
|
||||
return findShadowRoot(element.parentNode);
|
||||
};
|
||||
const noop = () => {};
|
||||
|
||||
/**
|
||||
* Trick to restart an element's animation
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @return void
|
||||
*
|
||||
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||||
*/
|
||||
const reflow = element => {
|
||||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||||
};
|
||||
const getjQuery = () => {
|
||||
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||||
return window.jQuery;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const DOMContentLoadedCallbacks = [];
|
||||
const onDOMContentLoaded = callback => {
|
||||
if (document.readyState === 'loading') {
|
||||
// add listener on the first call when the document is in loading state
|
||||
if (!DOMContentLoadedCallbacks.length) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
for (const callback of DOMContentLoadedCallbacks) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
DOMContentLoadedCallbacks.push(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||||
const defineJQueryPlugin = plugin => {
|
||||
onDOMContentLoaded(() => {
|
||||
const $ = getjQuery();
|
||||
/* istanbul ignore if */
|
||||
if ($) {
|
||||
const name = plugin.NAME;
|
||||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||||
$.fn[name] = plugin.jQueryInterface;
|
||||
$.fn[name].Constructor = plugin;
|
||||
$.fn[name].noConflict = () => {
|
||||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||||
return plugin.jQueryInterface;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
||||
return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;
|
||||
};
|
||||
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
||||
if (!waitForTransition) {
|
||||
execute(callback);
|
||||
return;
|
||||
}
|
||||
const durationPadding = 5;
|
||||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||||
let called = false;
|
||||
const handler = ({
|
||||
target
|
||||
}) => {
|
||||
if (target !== transitionElement) {
|
||||
return;
|
||||
}
|
||||
called = true;
|
||||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||||
execute(callback);
|
||||
};
|
||||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||||
setTimeout(() => {
|
||||
if (!called) {
|
||||
triggerTransitionEnd(transitionElement);
|
||||
}
|
||||
}, emulatedDuration);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the previous/next element of a list.
|
||||
*
|
||||
* @param {array} list The list of elements
|
||||
* @param activeElement The active element
|
||||
* @param shouldGetNext Choose to get next or previous element
|
||||
* @param isCycleAllowed
|
||||
* @return {Element|elem} The proper element
|
||||
*/
|
||||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||||
const listLength = list.length;
|
||||
let index = list.indexOf(activeElement);
|
||||
|
||||
// if the element does not exist in the list return an element
|
||||
// depending on the direction and if cycle is allowed
|
||||
if (index === -1) {
|
||||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||||
}
|
||||
index += shouldGetNext ? 1 : -1;
|
||||
if (isCycleAllowed) {
|
||||
index = (index + listLength) % listLength;
|
||||
}
|
||||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||||
};
|
||||
|
||||
exports.defineJQueryPlugin = defineJQueryPlugin;
|
||||
exports.execute = execute;
|
||||
exports.executeAfterTransition = executeAfterTransition;
|
||||
exports.findShadowRoot = findShadowRoot;
|
||||
exports.getElement = getElement;
|
||||
exports.getNextActiveElement = getNextActiveElement;
|
||||
exports.getTransitionDurationFromElement = getTransitionDurationFromElement;
|
||||
exports.getUID = getUID;
|
||||
exports.getjQuery = getjQuery;
|
||||
exports.isDisabled = isDisabled;
|
||||
exports.isElement = isElement;
|
||||
exports.isRTL = isRTL;
|
||||
exports.isVisible = isVisible;
|
||||
exports.noop = noop;
|
||||
exports.onDOMContentLoaded = onDOMContentLoaded;
|
||||
exports.parseSelector = parseSelector;
|
||||
exports.reflow = reflow;
|
||||
exports.toType = toType;
|
||||
exports.triggerTransitionEnd = triggerTransitionEnd;
|
||||
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=index.js.map
|
||||
114
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/sanitizer.js
vendored
Normal file
114
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/sanitizer.js
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*!
|
||||
* Bootstrap sanitizer.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Sanitizer = {}));
|
||||
})(this, (function (exports) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/sanitizer.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// js-docs-start allow-list
|
||||
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
|
||||
const DefaultAllowlist = {
|
||||
// Global attributes allowed on any supplied element below.
|
||||
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
|
||||
a: ['target', 'href', 'title', 'rel'],
|
||||
area: [],
|
||||
b: [],
|
||||
br: [],
|
||||
col: [],
|
||||
code: [],
|
||||
dd: [],
|
||||
div: [],
|
||||
dl: [],
|
||||
dt: [],
|
||||
em: [],
|
||||
hr: [],
|
||||
h1: [],
|
||||
h2: [],
|
||||
h3: [],
|
||||
h4: [],
|
||||
h5: [],
|
||||
h6: [],
|
||||
i: [],
|
||||
img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
|
||||
li: [],
|
||||
ol: [],
|
||||
p: [],
|
||||
pre: [],
|
||||
s: [],
|
||||
small: [],
|
||||
span: [],
|
||||
sub: [],
|
||||
sup: [],
|
||||
strong: [],
|
||||
u: [],
|
||||
ul: []
|
||||
};
|
||||
// js-docs-end allow-list
|
||||
|
||||
const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
|
||||
|
||||
/**
|
||||
* A pattern that recognizes URLs that are safe wrt. XSS in URL navigation
|
||||
* contexts.
|
||||
*
|
||||
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
|
||||
*/
|
||||
// eslint-disable-next-line unicorn/better-regex
|
||||
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
|
||||
const allowedAttribute = (attribute, allowedAttributeList) => {
|
||||
const attributeName = attribute.nodeName.toLowerCase();
|
||||
if (allowedAttributeList.includes(attributeName)) {
|
||||
if (uriAttributes.has(attributeName)) {
|
||||
return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if a regular expression validates the attribute.
|
||||
return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));
|
||||
};
|
||||
function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
|
||||
if (!unsafeHtml.length) {
|
||||
return unsafeHtml;
|
||||
}
|
||||
if (sanitizeFunction && typeof sanitizeFunction === 'function') {
|
||||
return sanitizeFunction(unsafeHtml);
|
||||
}
|
||||
const domParser = new window.DOMParser();
|
||||
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
|
||||
const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
|
||||
for (const element of elements) {
|
||||
const elementName = element.nodeName.toLowerCase();
|
||||
if (!Object.keys(allowList).includes(elementName)) {
|
||||
element.remove();
|
||||
continue;
|
||||
}
|
||||
const attributeList = [].concat(...element.attributes);
|
||||
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
|
||||
for (const attribute of attributeList) {
|
||||
if (!allowedAttribute(attribute, allowedAttributes)) {
|
||||
element.removeAttribute(attribute.nodeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return createdDocument.body.innerHTML;
|
||||
}
|
||||
|
||||
exports.DefaultAllowlist = DefaultAllowlist;
|
||||
exports.sanitizeHtml = sanitizeHtml;
|
||||
|
||||
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=sanitizer.js.map
|
||||
113
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/scrollbar.js
vendored
Normal file
113
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/scrollbar.js
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*!
|
||||
* Bootstrap scrollbar.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/manipulator.js'), require('../dom/selector-engine.js'), require('./index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../dom/manipulator', '../dom/selector-engine', './index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Scrollbar = factory(global.Manipulator, global.SelectorEngine, global.Index));
|
||||
})(this, (function (Manipulator, SelectorEngine, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/scrollBar.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
|
||||
const SELECTOR_STICKY_CONTENT = '.sticky-top';
|
||||
const PROPERTY_PADDING = 'padding-right';
|
||||
const PROPERTY_MARGIN = 'margin-right';
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class ScrollBarHelper {
|
||||
constructor() {
|
||||
this._element = document.body;
|
||||
}
|
||||
|
||||
// Public
|
||||
getWidth() {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
|
||||
const documentWidth = document.documentElement.clientWidth;
|
||||
return Math.abs(window.innerWidth - documentWidth);
|
||||
}
|
||||
hide() {
|
||||
const width = this.getWidth();
|
||||
this._disableOverFlow();
|
||||
// give padding to element to balance the hidden scrollbar width
|
||||
this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
|
||||
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
|
||||
this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
|
||||
this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);
|
||||
}
|
||||
reset() {
|
||||
this._resetElementAttributes(this._element, 'overflow');
|
||||
this._resetElementAttributes(this._element, PROPERTY_PADDING);
|
||||
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);
|
||||
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);
|
||||
}
|
||||
isOverflowing() {
|
||||
return this.getWidth() > 0;
|
||||
}
|
||||
|
||||
// Private
|
||||
_disableOverFlow() {
|
||||
this._saveInitialAttribute(this._element, 'overflow');
|
||||
this._element.style.overflow = 'hidden';
|
||||
}
|
||||
_setElementAttributes(selector, styleProperty, callback) {
|
||||
const scrollbarWidth = this.getWidth();
|
||||
const manipulationCallBack = element => {
|
||||
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
||||
return;
|
||||
}
|
||||
this._saveInitialAttribute(element, styleProperty);
|
||||
const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);
|
||||
element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);
|
||||
};
|
||||
this._applyManipulationCallback(selector, manipulationCallBack);
|
||||
}
|
||||
_saveInitialAttribute(element, styleProperty) {
|
||||
const actualValue = element.style.getPropertyValue(styleProperty);
|
||||
if (actualValue) {
|
||||
Manipulator.setDataAttribute(element, styleProperty, actualValue);
|
||||
}
|
||||
}
|
||||
_resetElementAttributes(selector, styleProperty) {
|
||||
const manipulationCallBack = element => {
|
||||
const value = Manipulator.getDataAttribute(element, styleProperty);
|
||||
// We only want to remove the property if the value is `null`; the value can also be zero
|
||||
if (value === null) {
|
||||
element.style.removeProperty(styleProperty);
|
||||
return;
|
||||
}
|
||||
Manipulator.removeDataAttribute(element, styleProperty);
|
||||
element.style.setProperty(styleProperty, value);
|
||||
};
|
||||
this._applyManipulationCallback(selector, manipulationCallBack);
|
||||
}
|
||||
_applyManipulationCallback(selector, callBack) {
|
||||
if (index_js.isElement(selector)) {
|
||||
callBack(selector);
|
||||
return;
|
||||
}
|
||||
for (const sel of SelectorEngine.find(selector, this._element)) {
|
||||
callBack(sel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ScrollBarHelper;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=scrollbar.js.map
|
||||
135
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/swipe.js
vendored
Normal file
135
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/swipe.js
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*!
|
||||
* Bootstrap swipe.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/event-handler.js'), require('./config.js'), require('./index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../dom/event-handler', './config', './index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Swipe = factory(global.EventHandler, global.Config, global.Index));
|
||||
})(this, (function (EventHandler, Config, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/swipe.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const NAME = 'swipe';
|
||||
const EVENT_KEY = '.bs.swipe';
|
||||
const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`;
|
||||
const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`;
|
||||
const EVENT_TOUCHEND = `touchend${EVENT_KEY}`;
|
||||
const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`;
|
||||
const EVENT_POINTERUP = `pointerup${EVENT_KEY}`;
|
||||
const POINTER_TYPE_TOUCH = 'touch';
|
||||
const POINTER_TYPE_PEN = 'pen';
|
||||
const CLASS_NAME_POINTER_EVENT = 'pointer-event';
|
||||
const SWIPE_THRESHOLD = 40;
|
||||
const Default = {
|
||||
endCallback: null,
|
||||
leftCallback: null,
|
||||
rightCallback: null
|
||||
};
|
||||
const DefaultType = {
|
||||
endCallback: '(function|null)',
|
||||
leftCallback: '(function|null)',
|
||||
rightCallback: '(function|null)'
|
||||
};
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class Swipe extends Config {
|
||||
constructor(element, config) {
|
||||
super();
|
||||
this._element = element;
|
||||
if (!element || !Swipe.isSupported()) {
|
||||
return;
|
||||
}
|
||||
this._config = this._getConfig(config);
|
||||
this._deltaX = 0;
|
||||
this._supportPointerEvents = Boolean(window.PointerEvent);
|
||||
this._initEvents();
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
// Public
|
||||
dispose() {
|
||||
EventHandler.off(this._element, EVENT_KEY);
|
||||
}
|
||||
|
||||
// Private
|
||||
_start(event) {
|
||||
if (!this._supportPointerEvents) {
|
||||
this._deltaX = event.touches[0].clientX;
|
||||
return;
|
||||
}
|
||||
if (this._eventIsPointerPenTouch(event)) {
|
||||
this._deltaX = event.clientX;
|
||||
}
|
||||
}
|
||||
_end(event) {
|
||||
if (this._eventIsPointerPenTouch(event)) {
|
||||
this._deltaX = event.clientX - this._deltaX;
|
||||
}
|
||||
this._handleSwipe();
|
||||
index_js.execute(this._config.endCallback);
|
||||
}
|
||||
_move(event) {
|
||||
this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;
|
||||
}
|
||||
_handleSwipe() {
|
||||
const absDeltaX = Math.abs(this._deltaX);
|
||||
if (absDeltaX <= SWIPE_THRESHOLD) {
|
||||
return;
|
||||
}
|
||||
const direction = absDeltaX / this._deltaX;
|
||||
this._deltaX = 0;
|
||||
if (!direction) {
|
||||
return;
|
||||
}
|
||||
index_js.execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);
|
||||
}
|
||||
_initEvents() {
|
||||
if (this._supportPointerEvents) {
|
||||
EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));
|
||||
EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));
|
||||
this._element.classList.add(CLASS_NAME_POINTER_EVENT);
|
||||
} else {
|
||||
EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));
|
||||
EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));
|
||||
EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));
|
||||
}
|
||||
}
|
||||
_eventIsPointerPenTouch(event) {
|
||||
return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);
|
||||
}
|
||||
|
||||
// Static
|
||||
static isSupported() {
|
||||
return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return Swipe;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=swipe.js.map
|
||||
151
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/template-factory.js
vendored
Normal file
151
odoo-bringout-oca-ocb-web/web/static/lib/bootstrap/js/dist/util/template-factory.js
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*!
|
||||
* Bootstrap template-factory.js v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/selector-engine.js'), require('./config.js'), require('./sanitizer.js'), require('./index.js')) :
|
||||
typeof define === 'function' && define.amd ? define(['../dom/selector-engine', './config', './sanitizer', './index'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.TemplateFactory = factory(global.SelectorEngine, global.Config, global.Sanitizer, global.Index));
|
||||
})(this, (function (SelectorEngine, Config, sanitizer_js, index_js) { 'use strict';
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap util/template-factory.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const NAME = 'TemplateFactory';
|
||||
const Default = {
|
||||
allowList: sanitizer_js.DefaultAllowlist,
|
||||
content: {},
|
||||
// { selector : text , selector2 : text2 , }
|
||||
extraClass: '',
|
||||
html: false,
|
||||
sanitize: true,
|
||||
sanitizeFn: null,
|
||||
template: '<div></div>'
|
||||
};
|
||||
const DefaultType = {
|
||||
allowList: 'object',
|
||||
content: 'object',
|
||||
extraClass: '(string|function)',
|
||||
html: 'boolean',
|
||||
sanitize: 'boolean',
|
||||
sanitizeFn: '(null|function)',
|
||||
template: 'string'
|
||||
};
|
||||
const DefaultContentType = {
|
||||
entry: '(string|element|function|null)',
|
||||
selector: '(string|element)'
|
||||
};
|
||||
|
||||
/**
|
||||
* Class definition
|
||||
*/
|
||||
|
||||
class TemplateFactory extends Config {
|
||||
constructor(config) {
|
||||
super();
|
||||
this._config = this._getConfig(config);
|
||||
}
|
||||
|
||||
// Getters
|
||||
static get Default() {
|
||||
return Default;
|
||||
}
|
||||
static get DefaultType() {
|
||||
return DefaultType;
|
||||
}
|
||||
static get NAME() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
// Public
|
||||
getContent() {
|
||||
return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);
|
||||
}
|
||||
hasContent() {
|
||||
return this.getContent().length > 0;
|
||||
}
|
||||
changeContent(content) {
|
||||
this._checkContent(content);
|
||||
this._config.content = {
|
||||
...this._config.content,
|
||||
...content
|
||||
};
|
||||
return this;
|
||||
}
|
||||
toHtml() {
|
||||
const templateWrapper = document.createElement('div');
|
||||
templateWrapper.innerHTML = this._maybeSanitize(this._config.template);
|
||||
for (const [selector, text] of Object.entries(this._config.content)) {
|
||||
this._setContent(templateWrapper, text, selector);
|
||||
}
|
||||
const template = templateWrapper.children[0];
|
||||
const extraClass = this._resolvePossibleFunction(this._config.extraClass);
|
||||
if (extraClass) {
|
||||
template.classList.add(...extraClass.split(' '));
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
// Private
|
||||
_typeCheckConfig(config) {
|
||||
super._typeCheckConfig(config);
|
||||
this._checkContent(config.content);
|
||||
}
|
||||
_checkContent(arg) {
|
||||
for (const [selector, content] of Object.entries(arg)) {
|
||||
super._typeCheckConfig({
|
||||
selector,
|
||||
entry: content
|
||||
}, DefaultContentType);
|
||||
}
|
||||
}
|
||||
_setContent(template, content, selector) {
|
||||
const templateElement = SelectorEngine.findOne(selector, template);
|
||||
if (!templateElement) {
|
||||
return;
|
||||
}
|
||||
content = this._resolvePossibleFunction(content);
|
||||
if (!content) {
|
||||
templateElement.remove();
|
||||
return;
|
||||
}
|
||||
if (index_js.isElement(content)) {
|
||||
this._putElementInTemplate(index_js.getElement(content), templateElement);
|
||||
return;
|
||||
}
|
||||
if (this._config.html) {
|
||||
templateElement.innerHTML = this._maybeSanitize(content);
|
||||
return;
|
||||
}
|
||||
templateElement.textContent = content;
|
||||
}
|
||||
_maybeSanitize(arg) {
|
||||
return this._config.sanitize ? sanitizer_js.sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;
|
||||
}
|
||||
_resolvePossibleFunction(arg) {
|
||||
return index_js.execute(arg, [this]);
|
||||
}
|
||||
_putElementInTemplate(element, templateElement) {
|
||||
if (this._config.html) {
|
||||
templateElement.innerHTML = '';
|
||||
templateElement.append(element);
|
||||
return;
|
||||
}
|
||||
templateElement.textContent = element.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
return TemplateFactory;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=template-factory.js.map
|
||||
|
|
@ -2,43 +2,69 @@
|
|||
// Base styles
|
||||
//
|
||||
|
||||
.accordion {
|
||||
// scss-docs-start accordion-css-vars
|
||||
--#{$prefix}accordion-color: #{$accordion-color};
|
||||
--#{$prefix}accordion-bg: #{$accordion-bg};
|
||||
--#{$prefix}accordion-transition: #{$accordion-transition};
|
||||
--#{$prefix}accordion-border-color: #{$accordion-border-color};
|
||||
--#{$prefix}accordion-border-width: #{$accordion-border-width};
|
||||
--#{$prefix}accordion-border-radius: #{$accordion-border-radius};
|
||||
--#{$prefix}accordion-inner-border-radius: #{$accordion-inner-border-radius};
|
||||
--#{$prefix}accordion-btn-padding-x: #{$accordion-button-padding-x};
|
||||
--#{$prefix}accordion-btn-padding-y: #{$accordion-button-padding-y};
|
||||
--#{$prefix}accordion-btn-color: #{$accordion-button-color};
|
||||
--#{$prefix}accordion-btn-bg: #{$accordion-button-bg};
|
||||
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon)};
|
||||
--#{$prefix}accordion-btn-icon-width: #{$accordion-icon-width};
|
||||
--#{$prefix}accordion-btn-icon-transform: #{$accordion-icon-transform};
|
||||
--#{$prefix}accordion-btn-icon-transition: #{$accordion-icon-transition};
|
||||
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon)};
|
||||
--#{$prefix}accordion-btn-focus-box-shadow: #{$accordion-button-focus-box-shadow};
|
||||
--#{$prefix}accordion-body-padding-x: #{$accordion-body-padding-x};
|
||||
--#{$prefix}accordion-body-padding-y: #{$accordion-body-padding-y};
|
||||
--#{$prefix}accordion-active-color: #{$accordion-button-active-color};
|
||||
--#{$prefix}accordion-active-bg: #{$accordion-button-active-bg};
|
||||
// scss-docs-end accordion-css-vars
|
||||
}
|
||||
|
||||
.accordion-button {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: $accordion-button-padding-y $accordion-button-padding-x;
|
||||
padding: var(--#{$prefix}accordion-btn-padding-y) var(--#{$prefix}accordion-btn-padding-x);
|
||||
@include font-size($font-size-base);
|
||||
color: $accordion-button-color;
|
||||
color: var(--#{$prefix}accordion-btn-color);
|
||||
text-align: left; // Reset button style
|
||||
background-color: $accordion-button-bg;
|
||||
background-color: var(--#{$prefix}accordion-btn-bg);
|
||||
border: 0;
|
||||
@include border-radius(0);
|
||||
overflow-anchor: none;
|
||||
@include transition($accordion-transition);
|
||||
@include transition(var(--#{$prefix}accordion-transition));
|
||||
|
||||
&:not(.collapsed) {
|
||||
color: $accordion-button-active-color;
|
||||
background-color: $accordion-button-active-bg;
|
||||
box-shadow: inset 0 ($accordion-border-width * -1) 0 $accordion-border-color;
|
||||
color: var(--#{$prefix}accordion-active-color);
|
||||
background-color: var(--#{$prefix}accordion-active-bg);
|
||||
box-shadow: inset 0 calc(-1 * var(--#{$prefix}accordion-border-width)) 0 var(--#{$prefix}accordion-border-color); // stylelint-disable-line function-disallowed-list
|
||||
|
||||
&::after {
|
||||
background-image: escape-svg($accordion-button-active-icon);
|
||||
transform: $accordion-icon-transform;
|
||||
background-image: var(--#{$prefix}accordion-btn-active-icon);
|
||||
transform: var(--#{$prefix}accordion-btn-icon-transform);
|
||||
}
|
||||
}
|
||||
|
||||
// Accordion icon
|
||||
&::after {
|
||||
flex-shrink: 0;
|
||||
width: $accordion-icon-width;
|
||||
height: $accordion-icon-width;
|
||||
width: var(--#{$prefix}accordion-btn-icon-width);
|
||||
height: var(--#{$prefix}accordion-btn-icon-width);
|
||||
margin-left: auto;
|
||||
content: "";
|
||||
background-image: escape-svg($accordion-button-icon);
|
||||
background-image: var(--#{$prefix}accordion-btn-icon);
|
||||
background-repeat: no-repeat;
|
||||
background-size: $accordion-icon-width;
|
||||
@include transition($accordion-icon-transition);
|
||||
background-size: var(--#{$prefix}accordion-btn-icon-width);
|
||||
@include transition(var(--#{$prefix}accordion-btn-icon-transition));
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
|
@ -47,9 +73,8 @@
|
|||
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
border-color: $accordion-button-focus-border-color;
|
||||
outline: 0;
|
||||
box-shadow: $accordion-button-focus-box-shadow;
|
||||
box-shadow: var(--#{$prefix}accordion-btn-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,14 +83,15 @@
|
|||
}
|
||||
|
||||
.accordion-item {
|
||||
background-color: $accordion-bg;
|
||||
border: $accordion-border-width solid $accordion-border-color;
|
||||
color: var(--#{$prefix}accordion-color);
|
||||
background-color: var(--#{$prefix}accordion-bg);
|
||||
border: var(--#{$prefix}accordion-border-width) solid var(--#{$prefix}accordion-border-color);
|
||||
|
||||
&:first-of-type {
|
||||
@include border-top-radius($accordion-border-radius);
|
||||
@include border-top-radius(var(--#{$prefix}accordion-border-radius));
|
||||
|
||||
.accordion-button {
|
||||
@include border-top-radius($accordion-inner-border-radius);
|
||||
> .accordion-header .accordion-button {
|
||||
@include border-top-radius(var(--#{$prefix}accordion-inner-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,22 +101,22 @@
|
|||
|
||||
// Only set a border-radius on the last item if the accordion is collapsed
|
||||
&:last-of-type {
|
||||
@include border-bottom-radius($accordion-border-radius);
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
|
||||
|
||||
.accordion-button {
|
||||
> .accordion-header .accordion-button {
|
||||
&.collapsed {
|
||||
@include border-bottom-radius($accordion-inner-border-radius);
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-inner-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-collapse {
|
||||
@include border-bottom-radius($accordion-border-radius);
|
||||
> .accordion-collapse {
|
||||
@include border-bottom-radius(var(--#{$prefix}accordion-border-radius));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
padding: $accordion-body-padding-y $accordion-body-padding-x;
|
||||
padding: var(--#{$prefix}accordion-body-padding-y) var(--#{$prefix}accordion-body-padding-x);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -99,11 +125,7 @@
|
|||
// Remove borders and border-radius to keep accordion items edge-to-edge.
|
||||
|
||||
.accordion-flush {
|
||||
.accordion-collapse {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.accordion-item {
|
||||
> .accordion-item {
|
||||
border-right: 0;
|
||||
border-left: 0;
|
||||
@include border-radius(0);
|
||||
|
|
@ -111,8 +133,26 @@
|
|||
&:first-child { border-top: 0; }
|
||||
&:last-child { border-bottom: 0; }
|
||||
|
||||
.accordion-button {
|
||||
// stylelint-disable selector-max-class
|
||||
> .accordion-header .accordion-button {
|
||||
&,
|
||||
&.collapsed {
|
||||
@include border-radius(0);
|
||||
}
|
||||
}
|
||||
// stylelint-enable selector-max-class
|
||||
|
||||
> .accordion-collapse {
|
||||
@include border-radius(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
.accordion-button::after {
|
||||
--#{$prefix}accordion-btn-icon: #{escape-svg($accordion-button-icon-dark)};
|
||||
--#{$prefix}accordion-btn-active-icon: #{escape-svg($accordion-button-active-icon-dark)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,25 @@
|
|||
//
|
||||
|
||||
.alert {
|
||||
// scss-docs-start alert-css-vars
|
||||
--#{$prefix}alert-bg: transparent;
|
||||
--#{$prefix}alert-padding-x: #{$alert-padding-x};
|
||||
--#{$prefix}alert-padding-y: #{$alert-padding-y};
|
||||
--#{$prefix}alert-margin-bottom: #{$alert-margin-bottom};
|
||||
--#{$prefix}alert-color: inherit;
|
||||
--#{$prefix}alert-border-color: transparent;
|
||||
--#{$prefix}alert-border: #{$alert-border-width} solid var(--#{$prefix}alert-border-color);
|
||||
--#{$prefix}alert-border-radius: #{$alert-border-radius};
|
||||
--#{$prefix}alert-link-color: inherit;
|
||||
// scss-docs-end alert-css-vars
|
||||
|
||||
position: relative;
|
||||
padding: $alert-padding-y $alert-padding-x;
|
||||
margin-bottom: $alert-margin-bottom;
|
||||
border: $alert-border-width solid transparent;
|
||||
@include border-radius($alert-border-radius);
|
||||
padding: var(--#{$prefix}alert-padding-y) var(--#{$prefix}alert-padding-x);
|
||||
margin-bottom: var(--#{$prefix}alert-margin-bottom);
|
||||
color: var(--#{$prefix}alert-color);
|
||||
background-color: var(--#{$prefix}alert-bg);
|
||||
border: var(--#{$prefix}alert-border);
|
||||
@include border-radius(var(--#{$prefix}alert-border-radius));
|
||||
}
|
||||
|
||||
// Headings for larger alerts
|
||||
|
|
@ -19,6 +33,7 @@
|
|||
// Provide class for links that match alerts
|
||||
.alert-link {
|
||||
font-weight: $alert-link-font-weight;
|
||||
color: var(--#{$prefix}alert-link-color);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -41,17 +56,13 @@
|
|||
|
||||
|
||||
// scss-docs-start alert-modifiers
|
||||
// Generate contextual modifier classes for colorizing the alert.
|
||||
|
||||
@each $state, $value in $theme-colors {
|
||||
$alert-background: shift-color($value, $alert-bg-scale);
|
||||
$alert-border: shift-color($value, $alert-border-scale);
|
||||
$alert-color: shift-color($value, $alert-color-scale);
|
||||
@if (contrast-ratio($alert-background, $alert-color) < $min-contrast-ratio) {
|
||||
$alert-color: mix($value, color-contrast($alert-background), abs($alert-color-scale));
|
||||
}
|
||||
// Generate contextual modifier classes for colorizing the alert
|
||||
@each $state in map-keys($theme-colors) {
|
||||
.alert-#{$state} {
|
||||
@include alert-variant($alert-background, $alert-border, $alert-color);
|
||||
--#{$prefix}alert-color: var(--#{$prefix}#{$state}-text-emphasis);
|
||||
--#{$prefix}alert-bg: var(--#{$prefix}#{$state}-bg-subtle);
|
||||
--#{$prefix}alert-border-color: var(--#{$prefix}#{$state}-border-subtle);
|
||||
--#{$prefix}alert-link-color: var(--#{$prefix}#{$state}-text-emphasis);
|
||||
}
|
||||
}
|
||||
// scss-docs-end alert-modifiers
|
||||
|
|
|
|||
|
|
@ -4,16 +4,25 @@
|
|||
// `background-color`.
|
||||
|
||||
.badge {
|
||||
// scss-docs-start badge-css-vars
|
||||
--#{$prefix}badge-padding-x: #{$badge-padding-x};
|
||||
--#{$prefix}badge-padding-y: #{$badge-padding-y};
|
||||
@include rfs($badge-font-size, --#{$prefix}badge-font-size);
|
||||
--#{$prefix}badge-font-weight: #{$badge-font-weight};
|
||||
--#{$prefix}badge-color: #{$badge-color};
|
||||
--#{$prefix}badge-border-radius: #{$badge-border-radius};
|
||||
// scss-docs-end badge-css-vars
|
||||
|
||||
display: inline-block;
|
||||
padding: $badge-padding-y $badge-padding-x;
|
||||
@include font-size($badge-font-size);
|
||||
font-weight: $badge-font-weight;
|
||||
padding: var(--#{$prefix}badge-padding-y) var(--#{$prefix}badge-padding-x);
|
||||
@include font-size(var(--#{$prefix}badge-font-size));
|
||||
font-weight: var(--#{$prefix}badge-font-weight);
|
||||
line-height: 1;
|
||||
color: $badge-color;
|
||||
color: var(--#{$prefix}badge-color);
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
@include border-radius($badge-border-radius);
|
||||
@include border-radius(var(--#{$prefix}badge-border-radius));
|
||||
@include gradient-bg();
|
||||
|
||||
// Empty badges collapse automatically
|
||||
|
|
|
|||
|
|
@ -1,28 +1,40 @@
|
|||
.breadcrumb {
|
||||
// scss-docs-start breadcrumb-css-vars
|
||||
--#{$prefix}breadcrumb-padding-x: #{$breadcrumb-padding-x};
|
||||
--#{$prefix}breadcrumb-padding-y: #{$breadcrumb-padding-y};
|
||||
--#{$prefix}breadcrumb-margin-bottom: #{$breadcrumb-margin-bottom};
|
||||
@include rfs($breadcrumb-font-size, --#{$prefix}breadcrumb-font-size);
|
||||
--#{$prefix}breadcrumb-bg: #{$breadcrumb-bg};
|
||||
--#{$prefix}breadcrumb-border-radius: #{$breadcrumb-border-radius};
|
||||
--#{$prefix}breadcrumb-divider-color: #{$breadcrumb-divider-color};
|
||||
--#{$prefix}breadcrumb-item-padding-x: #{$breadcrumb-item-padding-x};
|
||||
--#{$prefix}breadcrumb-item-active-color: #{$breadcrumb-active-color};
|
||||
// scss-docs-end breadcrumb-css-vars
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
|
||||
margin-bottom: $breadcrumb-margin-bottom;
|
||||
@include font-size($breadcrumb-font-size);
|
||||
padding: var(--#{$prefix}breadcrumb-padding-y) var(--#{$prefix}breadcrumb-padding-x);
|
||||
margin-bottom: var(--#{$prefix}breadcrumb-margin-bottom);
|
||||
@include font-size(var(--#{$prefix}breadcrumb-font-size));
|
||||
list-style: none;
|
||||
background-color: $breadcrumb-bg;
|
||||
@include border-radius($breadcrumb-border-radius);
|
||||
background-color: var(--#{$prefix}breadcrumb-bg);
|
||||
@include border-radius(var(--#{$prefix}breadcrumb-border-radius));
|
||||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
// The separator between breadcrumbs (by default, a forward-slash: "/")
|
||||
+ .breadcrumb-item {
|
||||
padding-left: $breadcrumb-item-padding-x;
|
||||
padding-left: var(--#{$prefix}breadcrumb-item-padding-x);
|
||||
|
||||
&::before {
|
||||
float: left; // Suppress inline spacings and underlining of the separator
|
||||
padding-right: $breadcrumb-item-padding-x;
|
||||
color: $breadcrumb-divider-color;
|
||||
content: var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$variable-prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"};
|
||||
padding-right: var(--#{$prefix}breadcrumb-item-padding-x);
|
||||
color: var(--#{$prefix}breadcrumb-divider-color);
|
||||
content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"};
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $breadcrumb-active-color;
|
||||
color: var(--#{$prefix}breadcrumb-item-active-color);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,14 +34,17 @@
|
|||
}
|
||||
|
||||
.btn-group {
|
||||
@include border-radius($btn-border-radius);
|
||||
|
||||
// Prevent double borders when buttons are next to each other
|
||||
> .btn:not(:first-child),
|
||||
> :not(.btn-check:first-child) + .btn,
|
||||
> .btn-group:not(:first-child) {
|
||||
margin-left: -$btn-border-width;
|
||||
margin-left: calc(#{$btn-border-width} * -1); // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
// Reset rounded corners
|
||||
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||
> .btn.dropdown-toggle-split:first-child,
|
||||
> .btn-group:not(:last-child) > .btn {
|
||||
@include border-end-radius(0);
|
||||
}
|
||||
|
|
@ -123,7 +126,7 @@
|
|||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) {
|
||||
margin-top: -$btn-border-width;
|
||||
margin-top: calc(#{$btn-border-width} * -1); // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
// Reset rounded corners
|
||||
|
|
|
|||
|
|
@ -3,49 +3,121 @@
|
|||
//
|
||||
|
||||
.btn {
|
||||
// scss-docs-start btn-css-vars
|
||||
--#{$prefix}btn-padding-x: #{$btn-padding-x};
|
||||
--#{$prefix}btn-padding-y: #{$btn-padding-y};
|
||||
--#{$prefix}btn-font-family: #{$btn-font-family};
|
||||
@include rfs($btn-font-size, --#{$prefix}btn-font-size);
|
||||
--#{$prefix}btn-font-weight: #{$btn-font-weight};
|
||||
--#{$prefix}btn-line-height: #{$btn-line-height};
|
||||
--#{$prefix}btn-color: #{$btn-color};
|
||||
--#{$prefix}btn-bg: transparent;
|
||||
--#{$prefix}btn-border-width: #{$btn-border-width};
|
||||
--#{$prefix}btn-border-color: transparent;
|
||||
--#{$prefix}btn-border-radius: #{$btn-border-radius};
|
||||
--#{$prefix}btn-hover-border-color: transparent;
|
||||
--#{$prefix}btn-box-shadow: #{$btn-box-shadow};
|
||||
--#{$prefix}btn-disabled-opacity: #{$btn-disabled-opacity};
|
||||
--#{$prefix}btn-focus-box-shadow: 0 0 0 #{$btn-focus-width} rgba(var(--#{$prefix}btn-focus-shadow-rgb), .5);
|
||||
// scss-docs-end btn-css-vars
|
||||
|
||||
display: inline-block;
|
||||
font-family: $btn-font-family;
|
||||
font-weight: $btn-font-weight;
|
||||
line-height: $btn-line-height;
|
||||
color: $body-color;
|
||||
padding: var(--#{$prefix}btn-padding-y) var(--#{$prefix}btn-padding-x);
|
||||
font-family: var(--#{$prefix}btn-font-family);
|
||||
@include font-size(var(--#{$prefix}btn-font-size));
|
||||
font-weight: var(--#{$prefix}btn-font-weight);
|
||||
line-height: var(--#{$prefix}btn-line-height);
|
||||
color: var(--#{$prefix}btn-color);
|
||||
text-align: center;
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
white-space: $btn-white-space;
|
||||
vertical-align: middle;
|
||||
cursor: if($enable-button-pointers, pointer, null);
|
||||
user-select: none;
|
||||
background-color: transparent;
|
||||
border: $btn-border-width solid transparent;
|
||||
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius);
|
||||
border: var(--#{$prefix}btn-border-width) solid var(--#{$prefix}btn-border-color);
|
||||
@include border-radius(var(--#{$prefix}btn-border-radius));
|
||||
@include gradient-bg(var(--#{$prefix}btn-bg));
|
||||
@include box-shadow(var(--#{$prefix}btn-box-shadow));
|
||||
@include transition($btn-transition);
|
||||
|
||||
&:hover {
|
||||
color: $body-color;
|
||||
color: var(--#{$prefix}btn-hover-color);
|
||||
text-decoration: if($link-hover-decoration == underline, none, null);
|
||||
background-color: var(--#{$prefix}btn-hover-bg);
|
||||
border-color: var(--#{$prefix}btn-hover-border-color);
|
||||
}
|
||||
|
||||
.btn-check:focus + &,
|
||||
&:focus {
|
||||
.btn-check + &:hover {
|
||||
// override for the checkbox/radio buttons
|
||||
color: var(--#{$prefix}btn-color);
|
||||
background-color: var(--#{$prefix}btn-bg);
|
||||
border-color: var(--#{$prefix}btn-border-color);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
color: var(--#{$prefix}btn-hover-color);
|
||||
@include gradient-bg(var(--#{$prefix}btn-hover-bg));
|
||||
border-color: var(--#{$prefix}btn-hover-border-color);
|
||||
outline: 0;
|
||||
box-shadow: $btn-focus-box-shadow;
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
@if $enable-shadows {
|
||||
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
|
||||
} @else {
|
||||
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-check:focus-visible + & {
|
||||
border-color: var(--#{$prefix}btn-hover-border-color);
|
||||
outline: 0;
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
@if $enable-shadows {
|
||||
box-shadow: var(--#{$prefix}btn-box-shadow), var(--#{$prefix}btn-focus-box-shadow);
|
||||
} @else {
|
||||
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-check:checked + &,
|
||||
.btn-check:active + &,
|
||||
&:active,
|
||||
&.active {
|
||||
@include box-shadow($btn-active-box-shadow);
|
||||
:not(.btn-check) + &:active,
|
||||
&:first-child:active,
|
||||
&.active,
|
||||
&.show {
|
||||
color: var(--#{$prefix}btn-active-color);
|
||||
background-color: var(--#{$prefix}btn-active-bg);
|
||||
// Remove CSS gradients if they're enabled
|
||||
background-image: if($enable-gradients, none, null);
|
||||
border-color: var(--#{$prefix}btn-active-border-color);
|
||||
@include box-shadow(var(--#{$prefix}btn-active-shadow));
|
||||
|
||||
&:focus {
|
||||
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
|
||||
&:focus-visible {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
@if $enable-shadows {
|
||||
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow);
|
||||
} @else {
|
||||
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-check:checked:focus-visible + & {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
@if $enable-shadows {
|
||||
box-shadow: var(--#{$prefix}btn-active-shadow), var(--#{$prefix}btn-focus-box-shadow);
|
||||
} @else {
|
||||
box-shadow: var(--#{$prefix}btn-focus-box-shadow);
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled,
|
||||
fieldset:disabled & {
|
||||
color: var(--#{$prefix}btn-disabled-color);
|
||||
pointer-events: none;
|
||||
opacity: $btn-disabled-opacity;
|
||||
background-color: var(--#{$prefix}btn-disabled-bg);
|
||||
background-image: if($enable-gradients, none, null);
|
||||
border-color: var(--#{$prefix}btn-disabled-border-color);
|
||||
opacity: var(--#{$prefix}btn-disabled-opacity);
|
||||
@include box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
|
@ -58,7 +130,27 @@
|
|||
// scss-docs-start btn-variant-loops
|
||||
@each $color, $value in $theme-colors {
|
||||
.btn-#{$color} {
|
||||
@include button-variant($value, $value);
|
||||
@if $color == "light" {
|
||||
@include button-variant(
|
||||
$value,
|
||||
$value,
|
||||
$hover-background: shade-color($value, $btn-hover-bg-shade-amount),
|
||||
$hover-border: shade-color($value, $btn-hover-border-shade-amount),
|
||||
$active-background: shade-color($value, $btn-active-bg-shade-amount),
|
||||
$active-border: shade-color($value, $btn-active-border-shade-amount)
|
||||
);
|
||||
} @else if $color == "dark" {
|
||||
@include button-variant(
|
||||
$value,
|
||||
$value,
|
||||
$hover-background: tint-color($value, $btn-hover-bg-tint-amount),
|
||||
$hover-border: tint-color($value, $btn-hover-border-tint-amount),
|
||||
$active-background: tint-color($value, $btn-active-bg-tint-amount),
|
||||
$active-border: tint-color($value, $btn-active-border-tint-amount)
|
||||
);
|
||||
} @else {
|
||||
@include button-variant($value, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -76,22 +168,35 @@
|
|||
|
||||
// Make a button look and behave like a link
|
||||
.btn-link {
|
||||
font-weight: $font-weight-normal;
|
||||
color: $btn-link-color;
|
||||
--#{$prefix}btn-font-weight: #{$font-weight-normal};
|
||||
--#{$prefix}btn-color: #{$btn-link-color};
|
||||
--#{$prefix}btn-bg: transparent;
|
||||
--#{$prefix}btn-border-color: transparent;
|
||||
--#{$prefix}btn-hover-color: #{$btn-link-hover-color};
|
||||
--#{$prefix}btn-hover-border-color: transparent;
|
||||
--#{$prefix}btn-active-color: #{$btn-link-hover-color};
|
||||
--#{$prefix}btn-active-border-color: transparent;
|
||||
--#{$prefix}btn-disabled-color: #{$btn-link-disabled-color};
|
||||
--#{$prefix}btn-disabled-border-color: transparent;
|
||||
--#{$prefix}btn-box-shadow: 0 0 0 #000; // Can't use `none` as keyword negates all values when used with multiple shadows
|
||||
--#{$prefix}btn-focus-shadow-rgb: #{$btn-link-focus-shadow-rgb};
|
||||
|
||||
text-decoration: $link-decoration;
|
||||
@if $enable-gradients {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
color: var(--#{$prefix}btn-color);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $btn-link-hover-color;
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $btn-link-disabled-color;
|
||||
color: var(--#{$prefix}btn-hover-color);
|
||||
}
|
||||
|
||||
// No need for an active state here
|
||||
|
|
|
|||
|
|
@ -3,17 +3,40 @@
|
|||
//
|
||||
|
||||
.card {
|
||||
// scss-docs-start card-css-vars
|
||||
--#{$prefix}card-spacer-y: #{$card-spacer-y};
|
||||
--#{$prefix}card-spacer-x: #{$card-spacer-x};
|
||||
--#{$prefix}card-title-spacer-y: #{$card-title-spacer-y};
|
||||
--#{$prefix}card-title-color: #{$card-title-color};
|
||||
--#{$prefix}card-subtitle-color: #{$card-subtitle-color};
|
||||
--#{$prefix}card-border-width: #{$card-border-width};
|
||||
--#{$prefix}card-border-color: #{$card-border-color};
|
||||
--#{$prefix}card-border-radius: #{$card-border-radius};
|
||||
--#{$prefix}card-box-shadow: #{$card-box-shadow};
|
||||
--#{$prefix}card-inner-border-radius: #{$card-inner-border-radius};
|
||||
--#{$prefix}card-cap-padding-y: #{$card-cap-padding-y};
|
||||
--#{$prefix}card-cap-padding-x: #{$card-cap-padding-x};
|
||||
--#{$prefix}card-cap-bg: #{$card-cap-bg};
|
||||
--#{$prefix}card-cap-color: #{$card-cap-color};
|
||||
--#{$prefix}card-height: #{$card-height};
|
||||
--#{$prefix}card-color: #{$card-color};
|
||||
--#{$prefix}card-bg: #{$card-bg};
|
||||
--#{$prefix}card-img-overlay-padding: #{$card-img-overlay-padding};
|
||||
--#{$prefix}card-group-margin: #{$card-group-margin};
|
||||
// scss-docs-end card-css-vars
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
|
||||
height: $card-height;
|
||||
height: var(--#{$prefix}card-height);
|
||||
color: var(--#{$prefix}body-color);
|
||||
word-wrap: break-word;
|
||||
background-color: $card-bg;
|
||||
background-color: var(--#{$prefix}card-bg);
|
||||
background-clip: border-box;
|
||||
border: $card-border-width solid $card-border-color;
|
||||
@include border-radius($card-border-radius);
|
||||
@include box-shadow($card-box-shadow);
|
||||
border: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
|
||||
@include border-radius(var(--#{$prefix}card-border-radius));
|
||||
@include box-shadow(var(--#{$prefix}card-box-shadow));
|
||||
|
||||
> hr {
|
||||
margin-right: 0;
|
||||
|
|
@ -26,12 +49,12 @@
|
|||
|
||||
&:first-child {
|
||||
border-top-width: 0;
|
||||
@include border-top-radius($card-inner-border-radius);
|
||||
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-width: 0;
|
||||
@include border-bottom-radius($card-inner-border-radius);
|
||||
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,17 +70,19 @@
|
|||
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
|
||||
// as much space as possible, ensuring footers are aligned to the bottom.
|
||||
flex: 1 1 auto;
|
||||
padding: $card-spacer-y $card-spacer-x;
|
||||
color: $card-color;
|
||||
padding: var(--#{$prefix}card-spacer-y) var(--#{$prefix}card-spacer-x);
|
||||
color: var(--#{$prefix}card-color);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
margin-bottom: $card-title-spacer-y;
|
||||
margin-bottom: var(--#{$prefix}card-title-spacer-y);
|
||||
color: var(--#{$prefix}card-title-color);
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
margin-top: -$card-title-spacer-y * .5;
|
||||
margin-top: calc(-.5 * var(--#{$prefix}card-title-spacer-y)); // stylelint-disable-line function-disallowed-list
|
||||
margin-bottom: 0;
|
||||
color: var(--#{$prefix}card-subtitle-color);
|
||||
}
|
||||
|
||||
.card-text:last-child {
|
||||
|
|
@ -70,7 +95,7 @@
|
|||
}
|
||||
|
||||
+ .card-link {
|
||||
margin-left: $card-spacer-x;
|
||||
margin-left: var(--#{$prefix}card-spacer-x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -79,25 +104,25 @@
|
|||
//
|
||||
|
||||
.card-header {
|
||||
padding: $card-cap-padding-y $card-cap-padding-x;
|
||||
padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
|
||||
margin-bottom: 0; // Removes the default margin-bottom of <hN>
|
||||
color: $card-cap-color;
|
||||
background-color: $card-cap-bg;
|
||||
border-bottom: $card-border-width solid $card-border-color;
|
||||
color: var(--#{$prefix}card-cap-color);
|
||||
background-color: var(--#{$prefix}card-cap-bg);
|
||||
border-bottom: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
|
||||
|
||||
&:first-child {
|
||||
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
|
||||
@include border-radius(var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius) 0 0);
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: $card-cap-padding-y $card-cap-padding-x;
|
||||
color: $card-cap-color;
|
||||
background-color: $card-cap-bg;
|
||||
border-top: $card-border-width solid $card-border-color;
|
||||
padding: var(--#{$prefix}card-cap-padding-y) var(--#{$prefix}card-cap-padding-x);
|
||||
color: var(--#{$prefix}card-cap-color);
|
||||
background-color: var(--#{$prefix}card-cap-bg);
|
||||
border-top: var(--#{$prefix}card-border-width) solid var(--#{$prefix}card-border-color);
|
||||
|
||||
&:last-child {
|
||||
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
|
||||
@include border-radius(0 0 var(--#{$prefix}card-inner-border-radius) var(--#{$prefix}card-inner-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,22 +132,20 @@
|
|||
//
|
||||
|
||||
.card-header-tabs {
|
||||
margin-right: -$card-cap-padding-x * .5;
|
||||
margin-bottom: -$card-cap-padding-y;
|
||||
margin-left: -$card-cap-padding-x * .5;
|
||||
margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
|
||||
margin-bottom: calc(-1 * var(--#{$prefix}card-cap-padding-y)); // stylelint-disable-line function-disallowed-list
|
||||
margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
|
||||
border-bottom: 0;
|
||||
|
||||
@if $nav-tabs-link-active-bg != $card-bg {
|
||||
.nav-link.active {
|
||||
background-color: $card-bg;
|
||||
border-bottom-color: $card-bg;
|
||||
}
|
||||
.nav-link.active {
|
||||
background-color: var(--#{$prefix}card-bg);
|
||||
border-bottom-color: var(--#{$prefix}card-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.card-header-pills {
|
||||
margin-right: -$card-cap-padding-x * .5;
|
||||
margin-left: -$card-cap-padding-x * .5;
|
||||
margin-right: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
|
||||
margin-left: calc(-.5 * var(--#{$prefix}card-cap-padding-x)); // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
// Card image
|
||||
|
|
@ -132,8 +155,8 @@
|
|||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: $card-img-overlay-padding;
|
||||
@include border-radius($card-inner-border-radius);
|
||||
padding: var(--#{$prefix}card-img-overlay-padding);
|
||||
@include border-radius(var(--#{$prefix}card-inner-border-radius));
|
||||
}
|
||||
|
||||
.card-img,
|
||||
|
|
@ -144,12 +167,12 @@
|
|||
|
||||
.card-img,
|
||||
.card-img-top {
|
||||
@include border-top-radius($card-inner-border-radius);
|
||||
@include border-top-radius(var(--#{$prefix}card-inner-border-radius));
|
||||
}
|
||||
|
||||
.card-img,
|
||||
.card-img-bottom {
|
||||
@include border-bottom-radius($card-inner-border-radius);
|
||||
@include border-bottom-radius(var(--#{$prefix}card-inner-border-radius));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -161,7 +184,7 @@
|
|||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card {
|
||||
margin-bottom: $card-group-margin;
|
||||
margin-bottom: var(--#{$prefix}card-group-margin);
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
display: block;
|
||||
}
|
||||
|
||||
/* rtl:begin:ignore */
|
||||
.carousel-item-next:not(.carousel-item-start),
|
||||
.active.carousel-item-end {
|
||||
transform: translateX(100%);
|
||||
|
|
@ -53,8 +52,6 @@
|
|||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
/* rtl:end:ignore */
|
||||
|
||||
|
||||
//
|
||||
// Alternate transitions
|
||||
|
|
@ -135,19 +132,11 @@
|
|||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
/* rtl:options: {
|
||||
"autoRename": true,
|
||||
"stringMap":[ {
|
||||
"name" : "prev-next",
|
||||
"search" : "prev",
|
||||
"replace" : "next"
|
||||
} ]
|
||||
} */
|
||||
.carousel-control-prev-icon {
|
||||
background-image: escape-svg($carousel-control-prev-icon-bg);
|
||||
background-image: escape-svg($carousel-control-prev-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-next-icon-bg) + "*/"};
|
||||
}
|
||||
.carousel-control-next-icon {
|
||||
background-image: escape-svg($carousel-control-next-icon-bg);
|
||||
background-image: escape-svg($carousel-control-next-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-prev-icon-bg) + "*/"};
|
||||
}
|
||||
|
||||
// Optional indicator pips/controls
|
||||
|
|
@ -168,7 +157,6 @@
|
|||
margin-right: $carousel-control-width;
|
||||
margin-bottom: 1rem;
|
||||
margin-left: $carousel-control-width;
|
||||
list-style: none;
|
||||
|
||||
[data-bs-target] {
|
||||
box-sizing: content-box;
|
||||
|
|
@ -213,7 +201,7 @@
|
|||
|
||||
// Dark mode carousel
|
||||
|
||||
.carousel-dark {
|
||||
@mixin carousel-dark() {
|
||||
.carousel-control-prev-icon,
|
||||
.carousel-control-next-icon {
|
||||
filter: $carousel-dark-control-icon-filter;
|
||||
|
|
@ -227,3 +215,22 @@
|
|||
color: $carousel-dark-caption-color;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-dark {
|
||||
@include carousel-dark();
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
@if $color-mode-type == "media-query" {
|
||||
.carousel {
|
||||
@include carousel-dark();
|
||||
}
|
||||
} @else {
|
||||
.carousel,
|
||||
&.carousel {
|
||||
@include carousel-dark();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,63 @@
|
|||
// transparent background and border properties included for button version.
|
||||
// Transparent background and border properties included for button version.
|
||||
// iOS requires the button element instead of an anchor tag.
|
||||
// If you want the anchor version, it requires `href="#"`.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
|
||||
|
||||
.btn-close {
|
||||
// scss-docs-start close-css-vars
|
||||
--#{$prefix}btn-close-color: #{$btn-close-color};
|
||||
--#{$prefix}btn-close-bg: #{ escape-svg($btn-close-bg) };
|
||||
--#{$prefix}btn-close-opacity: #{$btn-close-opacity};
|
||||
--#{$prefix}btn-close-hover-opacity: #{$btn-close-hover-opacity};
|
||||
--#{$prefix}btn-close-focus-shadow: #{$btn-close-focus-shadow};
|
||||
--#{$prefix}btn-close-focus-opacity: #{$btn-close-focus-opacity};
|
||||
--#{$prefix}btn-close-disabled-opacity: #{$btn-close-disabled-opacity};
|
||||
--#{$prefix}btn-close-white-filter: #{$btn-close-white-filter};
|
||||
// scss-docs-end close-css-vars
|
||||
|
||||
box-sizing: content-box;
|
||||
width: $btn-close-width;
|
||||
height: $btn-close-height;
|
||||
padding: $btn-close-padding-y $btn-close-padding-x;
|
||||
color: $btn-close-color;
|
||||
background: transparent escape-svg($btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements
|
||||
color: var(--#{$prefix}btn-close-color);
|
||||
background: transparent var(--#{$prefix}btn-close-bg) center / $btn-close-width auto no-repeat; // include transparent for button elements
|
||||
border: 0; // for button elements
|
||||
@include border-radius();
|
||||
opacity: $btn-close-opacity;
|
||||
opacity: var(--#{$prefix}btn-close-opacity);
|
||||
|
||||
// Override <a>'s hover style
|
||||
&:hover {
|
||||
color: $btn-close-color;
|
||||
color: var(--#{$prefix}btn-close-color);
|
||||
text-decoration: none;
|
||||
opacity: $btn-close-hover-opacity;
|
||||
opacity: var(--#{$prefix}btn-close-hover-opacity);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
box-shadow: $btn-close-focus-shadow;
|
||||
opacity: $btn-close-focus-opacity;
|
||||
box-shadow: var(--#{$prefix}btn-close-focus-shadow);
|
||||
opacity: var(--#{$prefix}btn-close-focus-opacity);
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
opacity: $btn-close-disabled-opacity;
|
||||
opacity: var(--#{$prefix}btn-close-disabled-opacity);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-close-white {
|
||||
filter: $btn-close-white-filter;
|
||||
@mixin btn-close-white() {
|
||||
filter: var(--#{$prefix}btn-close-white-filter);
|
||||
}
|
||||
|
||||
.btn-close-white {
|
||||
@include btn-close-white();
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
.btn-close {
|
||||
@include btn-close-white();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// Set the container width, and override it for fixed navbars in media queries.
|
||||
|
||||
@if $enable-grid-classes {
|
||||
@if $enable-container-classes {
|
||||
// Single container class with breakpoint max-widths
|
||||
.container,
|
||||
// 100% wide container at all breakpoints
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
.dropup,
|
||||
.dropend,
|
||||
.dropdown,
|
||||
.dropstart {
|
||||
.dropstart,
|
||||
.dropup-center,
|
||||
.dropdown-center {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
|
@ -15,26 +17,67 @@
|
|||
|
||||
// The dropdown menu
|
||||
.dropdown-menu {
|
||||
// scss-docs-start dropdown-css-vars
|
||||
--#{$prefix}dropdown-zindex: #{$zindex-dropdown};
|
||||
--#{$prefix}dropdown-min-width: #{$dropdown-min-width};
|
||||
--#{$prefix}dropdown-padding-x: #{$dropdown-padding-x};
|
||||
--#{$prefix}dropdown-padding-y: #{$dropdown-padding-y};
|
||||
--#{$prefix}dropdown-spacer: #{$dropdown-spacer};
|
||||
@include rfs($dropdown-font-size, --#{$prefix}dropdown-font-size);
|
||||
--#{$prefix}dropdown-color: #{$dropdown-color};
|
||||
--#{$prefix}dropdown-bg: #{$dropdown-bg};
|
||||
--#{$prefix}dropdown-border-color: #{$dropdown-border-color};
|
||||
--#{$prefix}dropdown-border-radius: #{$dropdown-border-radius};
|
||||
--#{$prefix}dropdown-border-width: #{$dropdown-border-width};
|
||||
--#{$prefix}dropdown-inner-border-radius: #{$dropdown-inner-border-radius};
|
||||
--#{$prefix}dropdown-divider-bg: #{$dropdown-divider-bg};
|
||||
--#{$prefix}dropdown-divider-margin-y: #{$dropdown-divider-margin-y};
|
||||
--#{$prefix}dropdown-box-shadow: #{$dropdown-box-shadow};
|
||||
--#{$prefix}dropdown-link-color: #{$dropdown-link-color};
|
||||
--#{$prefix}dropdown-link-hover-color: #{$dropdown-link-hover-color};
|
||||
--#{$prefix}dropdown-link-hover-bg: #{$dropdown-link-hover-bg};
|
||||
--#{$prefix}dropdown-link-active-color: #{$dropdown-link-active-color};
|
||||
--#{$prefix}dropdown-link-active-bg: #{$dropdown-link-active-bg};
|
||||
--#{$prefix}dropdown-link-disabled-color: #{$dropdown-link-disabled-color};
|
||||
--#{$prefix}dropdown-item-padding-x: #{$dropdown-item-padding-x};
|
||||
--#{$prefix}dropdown-item-padding-y: #{$dropdown-item-padding-y};
|
||||
--#{$prefix}dropdown-header-color: #{$dropdown-header-color};
|
||||
--#{$prefix}dropdown-header-padding-x: #{$dropdown-header-padding-x};
|
||||
--#{$prefix}dropdown-header-padding-y: #{$dropdown-header-padding-y};
|
||||
// scss-docs-end dropdown-css-vars
|
||||
|
||||
position: absolute;
|
||||
z-index: $zindex-dropdown;
|
||||
z-index: var(--#{$prefix}dropdown-zindex);
|
||||
display: none; // none by default, but block on "open" of the menu
|
||||
min-width: $dropdown-min-width;
|
||||
padding: $dropdown-padding-y $dropdown-padding-x;
|
||||
min-width: var(--#{$prefix}dropdown-min-width);
|
||||
padding: var(--#{$prefix}dropdown-padding-y) var(--#{$prefix}dropdown-padding-x);
|
||||
margin: 0; // Override default margin of ul
|
||||
@include font-size($dropdown-font-size);
|
||||
color: $dropdown-color;
|
||||
@include font-size(var(--#{$prefix}dropdown-font-size));
|
||||
color: var(--#{$prefix}dropdown-color);
|
||||
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
|
||||
list-style: none;
|
||||
background-color: $dropdown-bg;
|
||||
background-color: var(--#{$prefix}dropdown-bg);
|
||||
background-clip: padding-box;
|
||||
border: $dropdown-border-width solid $dropdown-border-color;
|
||||
@include border-radius($dropdown-border-radius);
|
||||
@include box-shadow($dropdown-box-shadow);
|
||||
border: var(--#{$prefix}dropdown-border-width) solid var(--#{$prefix}dropdown-border-color);
|
||||
@include border-radius(var(--#{$prefix}dropdown-border-radius));
|
||||
@include box-shadow(var(--#{$prefix}dropdown-box-shadow));
|
||||
|
||||
&[data-bs-popper] {
|
||||
top: 100%;
|
||||
left: 0;
|
||||
margin-top: $dropdown-spacer;
|
||||
margin-top: var(--#{$prefix}dropdown-spacer);
|
||||
}
|
||||
|
||||
@if $dropdown-padding-y == 0 {
|
||||
> .dropdown-item:first-child,
|
||||
> li:first-child .dropdown-item {
|
||||
@include border-top-radius(var(--#{$prefix}dropdown-inner-border-radius));
|
||||
}
|
||||
> .dropdown-item:last-child,
|
||||
> li:last-child .dropdown-item {
|
||||
@include border-bottom-radius(var(--#{$prefix}dropdown-inner-border-radius));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +117,7 @@
|
|||
top: auto;
|
||||
bottom: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: $dropdown-spacer;
|
||||
margin-bottom: var(--#{$prefix}dropdown-spacer);
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
|
|
@ -88,7 +131,7 @@
|
|||
right: auto;
|
||||
left: 100%;
|
||||
margin-top: 0;
|
||||
margin-left: $dropdown-spacer;
|
||||
margin-left: var(--#{$prefix}dropdown-spacer);
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
|
|
@ -105,7 +148,7 @@
|
|||
right: 100%;
|
||||
left: auto;
|
||||
margin-top: 0;
|
||||
margin-right: $dropdown-spacer;
|
||||
margin-right: var(--#{$prefix}dropdown-spacer);
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
|
|
@ -120,9 +163,10 @@
|
|||
// Dividers (basically an `<hr>`) within the dropdown
|
||||
.dropdown-divider {
|
||||
height: 0;
|
||||
margin: $dropdown-divider-margin-y 0;
|
||||
margin: var(--#{$prefix}dropdown-divider-margin-y) 0;
|
||||
overflow: hidden;
|
||||
border-top: 1px solid $dropdown-divider-bg;
|
||||
border-top: 1px solid var(--#{$prefix}dropdown-divider-bg);
|
||||
opacity: 1; // Revisit in v6 to de-dupe styles that conflict with <hr> element
|
||||
}
|
||||
|
||||
// Links, buttons, and more within the dropdown menu
|
||||
|
|
@ -131,45 +175,34 @@
|
|||
.dropdown-item {
|
||||
display: block;
|
||||
width: 100%; // For `<button>`s
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||
padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
|
||||
clear: both;
|
||||
font-weight: $font-weight-normal;
|
||||
color: $dropdown-link-color;
|
||||
color: var(--#{$prefix}dropdown-link-color);
|
||||
text-align: inherit; // For `<button>`s
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
white-space: nowrap; // prevent links from randomly breaking onto new lines
|
||||
background-color: transparent; // For `<button>`s
|
||||
border: 0; // For `<button>`s
|
||||
|
||||
// Prevent dropdown overflow if there's no padding
|
||||
// See https://github.com/twbs/bootstrap/pull/27703
|
||||
@if $dropdown-padding-y == 0 {
|
||||
&:first-child {
|
||||
@include border-top-radius($dropdown-inner-border-radius);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include border-bottom-radius($dropdown-inner-border-radius);
|
||||
}
|
||||
}
|
||||
@include border-radius(var(--#{$prefix}dropdown-item-border-radius, 0));
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $dropdown-link-hover-color;
|
||||
color: var(--#{$prefix}dropdown-link-hover-color);
|
||||
text-decoration: if($link-hover-decoration == underline, none, null);
|
||||
@include gradient-bg($dropdown-link-hover-bg);
|
||||
@include gradient-bg(var(--#{$prefix}dropdown-link-hover-bg));
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
color: $dropdown-link-active-color;
|
||||
color: var(--#{$prefix}dropdown-link-active-color);
|
||||
text-decoration: none;
|
||||
@include gradient-bg($dropdown-link-active-bg);
|
||||
@include gradient-bg(var(--#{$prefix}dropdown-link-active-bg));
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: $dropdown-link-disabled-color;
|
||||
color: var(--#{$prefix}dropdown-link-disabled-color);
|
||||
pointer-events: none;
|
||||
background-color: transparent;
|
||||
// Remove CSS gradients if they're enabled
|
||||
|
|
@ -184,57 +217,34 @@
|
|||
// Dropdown section headers
|
||||
.dropdown-header {
|
||||
display: block;
|
||||
padding: $dropdown-header-padding;
|
||||
padding: var(--#{$prefix}dropdown-header-padding-y) var(--#{$prefix}dropdown-header-padding-x);
|
||||
margin-bottom: 0; // for use with heading elements
|
||||
@include font-size($font-size-sm);
|
||||
color: $dropdown-header-color;
|
||||
color: var(--#{$prefix}dropdown-header-color);
|
||||
white-space: nowrap; // as with > li > a
|
||||
}
|
||||
|
||||
// Dropdown text
|
||||
.dropdown-item-text {
|
||||
display: block;
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||
color: $dropdown-link-color;
|
||||
padding: var(--#{$prefix}dropdown-item-padding-y) var(--#{$prefix}dropdown-item-padding-x);
|
||||
color: var(--#{$prefix}dropdown-link-color);
|
||||
}
|
||||
|
||||
// Dark dropdowns
|
||||
.dropdown-menu-dark {
|
||||
color: $dropdown-dark-color;
|
||||
background-color: $dropdown-dark-bg;
|
||||
border-color: $dropdown-dark-border-color;
|
||||
@include box-shadow($dropdown-dark-box-shadow);
|
||||
|
||||
.dropdown-item {
|
||||
color: $dropdown-dark-link-color;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $dropdown-dark-link-hover-color;
|
||||
@include gradient-bg($dropdown-dark-link-hover-bg);
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
color: $dropdown-dark-link-active-color;
|
||||
@include gradient-bg($dropdown-dark-link-active-bg);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: $dropdown-dark-link-disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-divider {
|
||||
border-color: $dropdown-dark-divider-bg;
|
||||
}
|
||||
|
||||
.dropdown-item-text {
|
||||
color: $dropdown-dark-link-color;
|
||||
}
|
||||
|
||||
.dropdown-header {
|
||||
color: $dropdown-dark-header-color;
|
||||
}
|
||||
// scss-docs-start dropdown-dark-css-vars
|
||||
--#{$prefix}dropdown-color: #{$dropdown-dark-color};
|
||||
--#{$prefix}dropdown-bg: #{$dropdown-dark-bg};
|
||||
--#{$prefix}dropdown-border-color: #{$dropdown-dark-border-color};
|
||||
--#{$prefix}dropdown-box-shadow: #{$dropdown-dark-box-shadow};
|
||||
--#{$prefix}dropdown-link-color: #{$dropdown-dark-link-color};
|
||||
--#{$prefix}dropdown-link-hover-color: #{$dropdown-dark-link-hover-color};
|
||||
--#{$prefix}dropdown-divider-bg: #{$dropdown-dark-divider-bg};
|
||||
--#{$prefix}dropdown-link-hover-bg: #{$dropdown-dark-link-hover-bg};
|
||||
--#{$prefix}dropdown-link-active-color: #{$dropdown-dark-link-active-color};
|
||||
--#{$prefix}dropdown-link-active-bg: #{$dropdown-dark-link-active-bg};
|
||||
--#{$prefix}dropdown-link-disabled-color: #{$dropdown-dark-link-disabled-color};
|
||||
--#{$prefix}dropdown-header-color: #{$dropdown-dark-header-color};
|
||||
// scss-docs-end dropdown-dark-css-vars
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@
|
|||
// stylelint-disable scss/dollar-variable-pattern
|
||||
@function rgba-css-var($identifier, $target) {
|
||||
@if $identifier == "body" and $target == "bg" {
|
||||
@return rgba(var(--#{$variable-prefix}#{$identifier}-bg-rgb), var(--#{$variable-prefix}#{$target}-opacity));
|
||||
@return rgba(var(--#{$prefix}#{$identifier}-bg-rgb), var(--#{$prefix}#{$target}-opacity));
|
||||
} @if $identifier == "body" and $target == "text" {
|
||||
@return rgba(var(--#{$variable-prefix}#{$identifier}-color-rgb), var(--#{$variable-prefix}#{$target}-opacity));
|
||||
@return rgba(var(--#{$prefix}#{$identifier}-color-rgb), var(--#{$prefix}#{$target}-opacity));
|
||||
} @else {
|
||||
@return rgba(var(--#{$variable-prefix}#{$identifier}-rgb), var(--#{$variable-prefix}#{$target}-opacity));
|
||||
@return rgba(var(--#{$prefix}#{$identifier}-rgb), var(--#{$prefix}#{$target}-opacity));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
@function varify($list) {
|
||||
$result: null;
|
||||
@each $entry in $list {
|
||||
$result: append($result, var(--#{$variable-prefix}#{$entry}), space);
|
||||
$result: append($result, var(--#{$prefix}#{$entry}), space);
|
||||
}
|
||||
@return $result;
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@
|
|||
// Replace `$search` with `$replace` in `$string`
|
||||
// Used on our SVG icon backgrounds for custom forms.
|
||||
//
|
||||
// @author Hugo Giraudel
|
||||
// @author Kitty Giraudel
|
||||
// @param {String} $string - Initial string
|
||||
// @param {String} $search - Substring to replace
|
||||
// @param {String} $replace ('') - New value
|
||||
|
|
@ -177,9 +177,9 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003
|
|||
@return if($l1 > $l2, divide($l1 + .05, $l2 + .05), divide($l2 + .05, $l1 + .05));
|
||||
}
|
||||
|
||||
// Return WCAG2.0 relative luminance
|
||||
// See https://www.w3.org/WAI/GL/wiki/Relative_luminance
|
||||
// See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
|
||||
// Return WCAG2.1 relative luminance
|
||||
// See https://www.w3.org/TR/WCAG/#dfn-relative-luminance
|
||||
// See https://www.w3.org/TR/WCAG/#dfn-contrast-ratio
|
||||
@function luminance($color) {
|
||||
$rgb: (
|
||||
"r": red($color),
|
||||
|
|
@ -188,7 +188,7 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003
|
|||
);
|
||||
|
||||
@each $name, $value in $rgb {
|
||||
$value: if(divide($value, 255) < .03928, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1));
|
||||
$value: if(divide($value, 255) < .04045, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1));
|
||||
$rgb: map-merge($rgb, ($name: $value));
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ $_luminance-list: .0008 .001 .0011 .0013 .0015 .0017 .002 .0022 .0025 .0027 .003
|
|||
// Return opaque color
|
||||
// opaque(#fff, rgba(0, 0, 0, .5)) => #808080
|
||||
@function opaque($background, $foreground) {
|
||||
@return mix(rgba($foreground, 1), $background, opacity($foreground) * 100);
|
||||
@return mix(rgba($foreground, 1), $background, opacity($foreground) * 100%);
|
||||
}
|
||||
|
||||
// scss-docs-start color-functions
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
//
|
||||
// Rows contain your columns.
|
||||
|
||||
:root {
|
||||
@each $name, $value in $grid-breakpoints {
|
||||
--#{$prefix}breakpoint-#{$name}: #{$value};
|
||||
}
|
||||
}
|
||||
|
||||
@if $enable-grid-classes {
|
||||
.row {
|
||||
@include make-row();
|
||||
|
|
@ -15,9 +21,9 @@
|
|||
@if $enable-cssgrid {
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-rows: repeat(var(--#{$variable-prefix}rows, 1), 1fr);
|
||||
grid-template-columns: repeat(var(--#{$variable-prefix}columns, #{$grid-columns}), 1fr);
|
||||
gap: var(--#{$variable-prefix}gap, #{$grid-gutter-width});
|
||||
grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr);
|
||||
grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr);
|
||||
gap: var(--#{$prefix}gap, #{$grid-gutter-width});
|
||||
|
||||
@include make-cssgrid();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
@import "helpers/clearfix";
|
||||
@import "helpers/color-bg";
|
||||
@import "helpers/colored-links";
|
||||
@import "helpers/focus-ring";
|
||||
@import "helpers/icon-link";
|
||||
@import "helpers/ratio";
|
||||
@import "helpers/position";
|
||||
@import "helpers/stacks";
|
||||
|
|
|
|||
|
|
@ -3,27 +3,46 @@
|
|||
// Easily usable on <ul>, <ol>, or <div>.
|
||||
|
||||
.list-group {
|
||||
// scss-docs-start list-group-css-vars
|
||||
--#{$prefix}list-group-color: #{$list-group-color};
|
||||
--#{$prefix}list-group-bg: #{$list-group-bg};
|
||||
--#{$prefix}list-group-border-color: #{$list-group-border-color};
|
||||
--#{$prefix}list-group-border-width: #{$list-group-border-width};
|
||||
--#{$prefix}list-group-border-radius: #{$list-group-border-radius};
|
||||
--#{$prefix}list-group-item-padding-x: #{$list-group-item-padding-x};
|
||||
--#{$prefix}list-group-item-padding-y: #{$list-group-item-padding-y};
|
||||
--#{$prefix}list-group-action-color: #{$list-group-action-color};
|
||||
--#{$prefix}list-group-action-hover-color: #{$list-group-action-hover-color};
|
||||
--#{$prefix}list-group-action-hover-bg: #{$list-group-hover-bg};
|
||||
--#{$prefix}list-group-action-active-color: #{$list-group-action-active-color};
|
||||
--#{$prefix}list-group-action-active-bg: #{$list-group-action-active-bg};
|
||||
--#{$prefix}list-group-disabled-color: #{$list-group-disabled-color};
|
||||
--#{$prefix}list-group-disabled-bg: #{$list-group-disabled-bg};
|
||||
--#{$prefix}list-group-active-color: #{$list-group-active-color};
|
||||
--#{$prefix}list-group-active-bg: #{$list-group-active-bg};
|
||||
--#{$prefix}list-group-active-border-color: #{$list-group-active-border-color};
|
||||
// scss-docs-end list-group-css-vars
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// No need to set list-style: none; since .list-group-item is block level
|
||||
padding-left: 0; // reset padding because ul and ol
|
||||
margin-bottom: 0;
|
||||
@include border-radius($list-group-border-radius);
|
||||
@include border-radius(var(--#{$prefix}list-group-border-radius));
|
||||
}
|
||||
|
||||
.list-group-numbered {
|
||||
list-style-type: none;
|
||||
counter-reset: section;
|
||||
|
||||
> li::before {
|
||||
> .list-group-item::before {
|
||||
// Increments only this instance of the section counter
|
||||
content: counters(section, ".") ". ";
|
||||
counter-increment: section;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Interactive list items
|
||||
//
|
||||
// Use anchor or button elements instead of `li`s or `div`s to create interactive
|
||||
|
|
@ -31,25 +50,24 @@
|
|||
|
||||
.list-group-item-action {
|
||||
width: 100%; // For `<button>`s (anchors become 100% by default though)
|
||||
color: $list-group-action-color;
|
||||
color: var(--#{$prefix}list-group-action-color);
|
||||
text-align: inherit; // For `<button>`s (anchors inherit)
|
||||
|
||||
// Hover state
|
||||
&:hover,
|
||||
&:focus {
|
||||
z-index: 1; // Place hover/focus items above their siblings for proper border styling
|
||||
color: $list-group-action-hover-color;
|
||||
color: var(--#{$prefix}list-group-action-hover-color);
|
||||
text-decoration: none;
|
||||
background-color: $list-group-hover-bg;
|
||||
background-color: var(--#{$prefix}list-group-action-hover-bg);
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $list-group-action-active-color;
|
||||
background-color: $list-group-action-active-bg;
|
||||
color: var(--#{$prefix}list-group-action-active-color);
|
||||
background-color: var(--#{$prefix}list-group-action-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Individual list items
|
||||
//
|
||||
// Use on `li`s or `div`s within the `.list-group` parent.
|
||||
|
|
@ -57,11 +75,11 @@
|
|||
.list-group-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: $list-group-item-padding-y $list-group-item-padding-x;
|
||||
color: $list-group-color;
|
||||
padding: var(--#{$prefix}list-group-item-padding-y) var(--#{$prefix}list-group-item-padding-x);
|
||||
color: var(--#{$prefix}list-group-color);
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
background-color: $list-group-bg;
|
||||
border: $list-group-border-width solid $list-group-border-color;
|
||||
background-color: var(--#{$prefix}list-group-bg);
|
||||
border: var(--#{$prefix}list-group-border-width) solid var(--#{$prefix}list-group-border-color);
|
||||
|
||||
&:first-child {
|
||||
@include border-top-radius(inherit);
|
||||
|
|
@ -73,30 +91,30 @@
|
|||
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: $list-group-disabled-color;
|
||||
color: var(--#{$prefix}list-group-disabled-color);
|
||||
pointer-events: none;
|
||||
background-color: $list-group-disabled-bg;
|
||||
background-color: var(--#{$prefix}list-group-disabled-bg);
|
||||
}
|
||||
|
||||
// Include both here for `<a>`s and `<button>`s
|
||||
&.active {
|
||||
z-index: 2; // Place active items above their siblings for proper border styling
|
||||
color: $list-group-active-color;
|
||||
background-color: $list-group-active-bg;
|
||||
border-color: $list-group-active-border-color;
|
||||
color: var(--#{$prefix}list-group-active-color);
|
||||
background-color: var(--#{$prefix}list-group-active-bg);
|
||||
border-color: var(--#{$prefix}list-group-active-border-color);
|
||||
}
|
||||
|
||||
& + & {
|
||||
// stylelint-disable-next-line scss/selector-no-redundant-nesting-selector
|
||||
& + .list-group-item {
|
||||
border-top-width: 0;
|
||||
|
||||
&.active {
|
||||
margin-top: -$list-group-border-width;
|
||||
border-top-width: $list-group-border-width;
|
||||
margin-top: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
border-top-width: var(--#{$prefix}list-group-border-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Horizontal
|
||||
//
|
||||
// Change the layout of list group items from vertical (default) to horizontal.
|
||||
|
|
@ -109,13 +127,13 @@
|
|||
flex-direction: row;
|
||||
|
||||
> .list-group-item {
|
||||
&:first-child {
|
||||
@include border-bottom-start-radius($list-group-border-radius);
|
||||
&:first-child:not(:last-child) {
|
||||
@include border-bottom-start-radius(var(--#{$prefix}list-group-border-radius));
|
||||
@include border-top-end-radius(0);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include border-top-end-radius($list-group-border-radius);
|
||||
&:last-child:not(:first-child) {
|
||||
@include border-top-end-radius(var(--#{$prefix}list-group-border-radius));
|
||||
@include border-bottom-start-radius(0);
|
||||
}
|
||||
|
||||
|
|
@ -124,12 +142,12 @@
|
|||
}
|
||||
|
||||
+ .list-group-item {
|
||||
border-top-width: $list-group-border-width;
|
||||
border-top-width: var(--#{$prefix}list-group-border-width);
|
||||
border-left-width: 0;
|
||||
|
||||
&.active {
|
||||
margin-left: -$list-group-border-width;
|
||||
border-left-width: $list-group-border-width;
|
||||
margin-left: calc(-1 * var(--#{$prefix}list-group-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
border-left-width: var(--#{$prefix}list-group-border-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -147,7 +165,7 @@
|
|||
@include border-radius(0);
|
||||
|
||||
> .list-group-item {
|
||||
border-width: 0 0 $list-group-border-width;
|
||||
border-width: 0 0 var(--#{$prefix}list-group-border-width);
|
||||
|
||||
&:last-child {
|
||||
border-bottom-width: 0;
|
||||
|
|
@ -162,13 +180,18 @@
|
|||
// Add modifier classes to change text and background color on individual items.
|
||||
// Organizationally, this must come after the `:hover` states.
|
||||
|
||||
@each $state, $value in $theme-colors {
|
||||
$list-group-variant-bg: shift-color($value, $list-group-item-bg-scale);
|
||||
$list-group-variant-color: shift-color($value, $list-group-item-color-scale);
|
||||
@if (contrast-ratio($list-group-variant-bg, $list-group-variant-color) < $min-contrast-ratio) {
|
||||
$list-group-variant-color: mix($value, color-contrast($list-group-variant-bg), abs($list-group-item-color-scale));
|
||||
@each $state in map-keys($theme-colors) {
|
||||
.list-group-item-#{$state} {
|
||||
--#{$prefix}list-group-color: var(--#{$prefix}#{$state}-text-emphasis);
|
||||
--#{$prefix}list-group-bg: var(--#{$prefix}#{$state}-bg-subtle);
|
||||
--#{$prefix}list-group-border-color: var(--#{$prefix}#{$state}-border-subtle);
|
||||
--#{$prefix}list-group-action-hover-color: var(--#{$prefix}emphasis-color);
|
||||
--#{$prefix}list-group-action-hover-bg: var(--#{$prefix}#{$state}-border-subtle);
|
||||
--#{$prefix}list-group-action-active-color: var(--#{$prefix}emphasis-color);
|
||||
--#{$prefix}list-group-action-active-bg: var(--#{$prefix}#{$state}-border-subtle);
|
||||
--#{$prefix}list-group-active-color: var(--#{$prefix}#{$state}-bg-subtle);
|
||||
--#{$prefix}list-group-active-bg: var(--#{$prefix}#{$state}-text-emphasis);
|
||||
--#{$prefix}list-group-active-border-color: var(--#{$prefix}#{$state}-text-emphasis);
|
||||
}
|
||||
|
||||
@include list-group-item-variant($state, $list-group-variant-bg, $list-group-variant-color);
|
||||
}
|
||||
// scss-docs-end list-group-modifiers
|
||||
|
|
|
|||
|
|
@ -0,0 +1,174 @@
|
|||
// Re-assigned maps
|
||||
//
|
||||
// Placed here so that others can override the default Sass maps and see automatic updates to utilities and more.
|
||||
|
||||
// scss-docs-start theme-colors-rgb
|
||||
$theme-colors-rgb: map-loop($theme-colors, to-rgb, "$value") !default;
|
||||
// scss-docs-end theme-colors-rgb
|
||||
|
||||
// scss-docs-start theme-text-map
|
||||
$theme-colors-text: (
|
||||
"primary": $primary-text-emphasis,
|
||||
"secondary": $secondary-text-emphasis,
|
||||
"success": $success-text-emphasis,
|
||||
"info": $info-text-emphasis,
|
||||
"warning": $warning-text-emphasis,
|
||||
"danger": $danger-text-emphasis,
|
||||
"light": $light-text-emphasis,
|
||||
"dark": $dark-text-emphasis,
|
||||
) !default;
|
||||
// scss-docs-end theme-text-map
|
||||
|
||||
// scss-docs-start theme-bg-subtle-map
|
||||
$theme-colors-bg-subtle: (
|
||||
"primary": $primary-bg-subtle,
|
||||
"secondary": $secondary-bg-subtle,
|
||||
"success": $success-bg-subtle,
|
||||
"info": $info-bg-subtle,
|
||||
"warning": $warning-bg-subtle,
|
||||
"danger": $danger-bg-subtle,
|
||||
"light": $light-bg-subtle,
|
||||
"dark": $dark-bg-subtle,
|
||||
) !default;
|
||||
// scss-docs-end theme-bg-subtle-map
|
||||
|
||||
// scss-docs-start theme-border-subtle-map
|
||||
$theme-colors-border-subtle: (
|
||||
"primary": $primary-border-subtle,
|
||||
"secondary": $secondary-border-subtle,
|
||||
"success": $success-border-subtle,
|
||||
"info": $info-border-subtle,
|
||||
"warning": $warning-border-subtle,
|
||||
"danger": $danger-border-subtle,
|
||||
"light": $light-border-subtle,
|
||||
"dark": $dark-border-subtle,
|
||||
) !default;
|
||||
// scss-docs-end theme-border-subtle-map
|
||||
|
||||
$theme-colors-text-dark: null !default;
|
||||
$theme-colors-bg-subtle-dark: null !default;
|
||||
$theme-colors-border-subtle-dark: null !default;
|
||||
|
||||
@if $enable-dark-mode {
|
||||
// scss-docs-start theme-text-dark-map
|
||||
$theme-colors-text-dark: (
|
||||
"primary": $primary-text-emphasis-dark,
|
||||
"secondary": $secondary-text-emphasis-dark,
|
||||
"success": $success-text-emphasis-dark,
|
||||
"info": $info-text-emphasis-dark,
|
||||
"warning": $warning-text-emphasis-dark,
|
||||
"danger": $danger-text-emphasis-dark,
|
||||
"light": $light-text-emphasis-dark,
|
||||
"dark": $dark-text-emphasis-dark,
|
||||
) !default;
|
||||
// scss-docs-end theme-text-dark-map
|
||||
|
||||
// scss-docs-start theme-bg-subtle-dark-map
|
||||
$theme-colors-bg-subtle-dark: (
|
||||
"primary": $primary-bg-subtle-dark,
|
||||
"secondary": $secondary-bg-subtle-dark,
|
||||
"success": $success-bg-subtle-dark,
|
||||
"info": $info-bg-subtle-dark,
|
||||
"warning": $warning-bg-subtle-dark,
|
||||
"danger": $danger-bg-subtle-dark,
|
||||
"light": $light-bg-subtle-dark,
|
||||
"dark": $dark-bg-subtle-dark,
|
||||
) !default;
|
||||
// scss-docs-end theme-bg-subtle-dark-map
|
||||
|
||||
// scss-docs-start theme-border-subtle-dark-map
|
||||
$theme-colors-border-subtle-dark: (
|
||||
"primary": $primary-border-subtle-dark,
|
||||
"secondary": $secondary-border-subtle-dark,
|
||||
"success": $success-border-subtle-dark,
|
||||
"info": $info-border-subtle-dark,
|
||||
"warning": $warning-border-subtle-dark,
|
||||
"danger": $danger-border-subtle-dark,
|
||||
"light": $light-border-subtle-dark,
|
||||
"dark": $dark-border-subtle-dark,
|
||||
) !default;
|
||||
// scss-docs-end theme-border-subtle-dark-map
|
||||
}
|
||||
|
||||
// Utilities maps
|
||||
//
|
||||
// Extends the default `$theme-colors` maps to help create our utilities.
|
||||
|
||||
// Come v6, we'll de-dupe these variables. Until then, for backward compatibility, we keep them to reassign.
|
||||
// scss-docs-start utilities-colors
|
||||
$utilities-colors: $theme-colors-rgb !default;
|
||||
// scss-docs-end utilities-colors
|
||||
|
||||
// scss-docs-start utilities-text-colors
|
||||
$utilities-text: map-merge(
|
||||
$utilities-colors,
|
||||
(
|
||||
"black": to-rgb($black),
|
||||
"white": to-rgb($white),
|
||||
"body": to-rgb($body-color)
|
||||
)
|
||||
) !default;
|
||||
$utilities-text-colors: map-loop($utilities-text, rgba-css-var, "$key", "text") !default;
|
||||
|
||||
$utilities-text-emphasis-colors: (
|
||||
"primary-emphasis": var(--#{$prefix}primary-text-emphasis),
|
||||
"secondary-emphasis": var(--#{$prefix}secondary-text-emphasis),
|
||||
"success-emphasis": var(--#{$prefix}success-text-emphasis),
|
||||
"info-emphasis": var(--#{$prefix}info-text-emphasis),
|
||||
"warning-emphasis": var(--#{$prefix}warning-text-emphasis),
|
||||
"danger-emphasis": var(--#{$prefix}danger-text-emphasis),
|
||||
"light-emphasis": var(--#{$prefix}light-text-emphasis),
|
||||
"dark-emphasis": var(--#{$prefix}dark-text-emphasis)
|
||||
) !default;
|
||||
// scss-docs-end utilities-text-colors
|
||||
|
||||
// scss-docs-start utilities-bg-colors
|
||||
$utilities-bg: map-merge(
|
||||
$utilities-colors,
|
||||
(
|
||||
"black": to-rgb($black),
|
||||
"white": to-rgb($white),
|
||||
"body": to-rgb($body-bg)
|
||||
)
|
||||
) !default;
|
||||
$utilities-bg-colors: map-loop($utilities-bg, rgba-css-var, "$key", "bg") !default;
|
||||
|
||||
$utilities-bg-subtle: (
|
||||
"primary-subtle": var(--#{$prefix}primary-bg-subtle),
|
||||
"secondary-subtle": var(--#{$prefix}secondary-bg-subtle),
|
||||
"success-subtle": var(--#{$prefix}success-bg-subtle),
|
||||
"info-subtle": var(--#{$prefix}info-bg-subtle),
|
||||
"warning-subtle": var(--#{$prefix}warning-bg-subtle),
|
||||
"danger-subtle": var(--#{$prefix}danger-bg-subtle),
|
||||
"light-subtle": var(--#{$prefix}light-bg-subtle),
|
||||
"dark-subtle": var(--#{$prefix}dark-bg-subtle)
|
||||
) !default;
|
||||
// scss-docs-end utilities-bg-colors
|
||||
|
||||
// scss-docs-start utilities-border-colors
|
||||
$utilities-border: map-merge(
|
||||
$utilities-colors,
|
||||
(
|
||||
"black": to-rgb($black),
|
||||
"white": to-rgb($white)
|
||||
)
|
||||
) !default;
|
||||
$utilities-border-colors: map-loop($utilities-border, rgba-css-var, "$key", "border") !default;
|
||||
|
||||
$utilities-border-subtle: (
|
||||
"primary-subtle": var(--#{$prefix}primary-border-subtle),
|
||||
"secondary-subtle": var(--#{$prefix}secondary-border-subtle),
|
||||
"success-subtle": var(--#{$prefix}success-border-subtle),
|
||||
"info-subtle": var(--#{$prefix}info-border-subtle),
|
||||
"warning-subtle": var(--#{$prefix}warning-border-subtle),
|
||||
"danger-subtle": var(--#{$prefix}danger-border-subtle),
|
||||
"light-subtle": var(--#{$prefix}light-border-subtle),
|
||||
"dark-subtle": var(--#{$prefix}dark-border-subtle)
|
||||
) !default;
|
||||
// scss-docs-end utilities-border-colors
|
||||
|
||||
$utilities-links-underline: map-loop($utilities-colors, rgba-css-var, "$key", "link-underline") !default;
|
||||
|
||||
$negative-spacers: if($enable-negative-margins, negativify-map($spacers), null) !default;
|
||||
|
||||
$gutters: $spacers !default;
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
// Helpers
|
||||
@import "mixins/breakpoints";
|
||||
@import "mixins/color-mode";
|
||||
@import "mixins/color-scheme";
|
||||
@import "mixins/image";
|
||||
@import "mixins/resize";
|
||||
|
|
@ -21,13 +22,11 @@
|
|||
@import "mixins/utilities";
|
||||
|
||||
// Components
|
||||
@import "mixins/alert";
|
||||
@import "mixins/backdrop";
|
||||
@import "mixins/buttons";
|
||||
@import "mixins/caret";
|
||||
@import "mixins/pagination";
|
||||
@import "mixins/lists";
|
||||
@import "mixins/list-group";
|
||||
@import "mixins/forms";
|
||||
@import "mixins/table-variants";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// stylelint-disable function-disallowed-list
|
||||
|
||||
// .modal-open - body class for killing the scroll
|
||||
// .modal - container to scroll within
|
||||
// .modal-dialog - positioning shell for the actual modal
|
||||
|
|
@ -6,10 +8,34 @@
|
|||
|
||||
// Container that the modal scrolls within
|
||||
.modal {
|
||||
// scss-docs-start modal-css-vars
|
||||
--#{$prefix}modal-zindex: #{$zindex-modal};
|
||||
--#{$prefix}modal-width: #{$modal-md};
|
||||
--#{$prefix}modal-padding: #{$modal-inner-padding};
|
||||
--#{$prefix}modal-margin: #{$modal-dialog-margin};
|
||||
--#{$prefix}modal-color: #{$modal-content-color};
|
||||
--#{$prefix}modal-bg: #{$modal-content-bg};
|
||||
--#{$prefix}modal-border-color: #{$modal-content-border-color};
|
||||
--#{$prefix}modal-border-width: #{$modal-content-border-width};
|
||||
--#{$prefix}modal-border-radius: #{$modal-content-border-radius};
|
||||
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs};
|
||||
--#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius};
|
||||
--#{$prefix}modal-header-padding-x: #{$modal-header-padding-x};
|
||||
--#{$prefix}modal-header-padding-y: #{$modal-header-padding-y};
|
||||
--#{$prefix}modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
|
||||
--#{$prefix}modal-header-border-color: #{$modal-header-border-color};
|
||||
--#{$prefix}modal-header-border-width: #{$modal-header-border-width};
|
||||
--#{$prefix}modal-title-line-height: #{$modal-title-line-height};
|
||||
--#{$prefix}modal-footer-gap: #{$modal-footer-margin-between};
|
||||
--#{$prefix}modal-footer-bg: #{$modal-footer-bg};
|
||||
--#{$prefix}modal-footer-border-color: #{$modal-footer-border-color};
|
||||
--#{$prefix}modal-footer-border-width: #{$modal-footer-border-width};
|
||||
// scss-docs-end modal-css-vars
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: $zindex-modal;
|
||||
z-index: var(--#{$prefix}modal-zindex);
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -27,7 +53,7 @@
|
|||
.modal-dialog {
|
||||
position: relative;
|
||||
width: auto;
|
||||
margin: $modal-dialog-margin;
|
||||
margin: var(--#{$prefix}modal-margin);
|
||||
// allow clicks to pass through for custom click handling to close modal
|
||||
pointer-events: none;
|
||||
|
||||
|
|
@ -47,7 +73,7 @@
|
|||
}
|
||||
|
||||
.modal-dialog-scrollable {
|
||||
height: subtract(100%, $modal-dialog-margin * 2);
|
||||
height: calc(100% - var(--#{$prefix}modal-margin) * 2);
|
||||
|
||||
.modal-content {
|
||||
max-height: 100%;
|
||||
|
|
@ -62,7 +88,7 @@
|
|||
.modal-dialog-centered {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: subtract(100%, $modal-dialog-margin * 2);
|
||||
min-height: calc(100% - var(--#{$prefix}modal-margin) * 2);
|
||||
}
|
||||
|
||||
// Actual modal
|
||||
|
|
@ -72,20 +98,26 @@
|
|||
flex-direction: column;
|
||||
width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
|
||||
// counteract the pointer-events: none; in the .modal-dialog
|
||||
color: $modal-content-color;
|
||||
color: var(--#{$prefix}modal-color);
|
||||
pointer-events: auto;
|
||||
background-color: $modal-content-bg;
|
||||
background-color: var(--#{$prefix}modal-bg);
|
||||
background-clip: padding-box;
|
||||
border: $modal-content-border-width solid $modal-content-border-color;
|
||||
@include border-radius($modal-content-border-radius);
|
||||
@include box-shadow($modal-content-box-shadow-xs);
|
||||
border: var(--#{$prefix}modal-border-width) solid var(--#{$prefix}modal-border-color);
|
||||
@include border-radius(var(--#{$prefix}modal-border-radius));
|
||||
@include box-shadow(var(--#{$prefix}modal-box-shadow));
|
||||
// Remove focus outline from opened modal
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
// Modal background
|
||||
.modal-backdrop {
|
||||
@include overlay-backdrop($zindex-modal-backdrop, $modal-backdrop-bg, $modal-backdrop-opacity);
|
||||
// scss-docs-start modal-backdrop-css-vars
|
||||
--#{$prefix}backdrop-zindex: #{$zindex-modal-backdrop};
|
||||
--#{$prefix}backdrop-bg: #{$modal-backdrop-bg};
|
||||
--#{$prefix}backdrop-opacity: #{$modal-backdrop-opacity};
|
||||
// scss-docs-end modal-backdrop-css-vars
|
||||
|
||||
@include overlay-backdrop(var(--#{$prefix}backdrop-zindex), var(--#{$prefix}backdrop-bg), var(--#{$prefix}backdrop-opacity));
|
||||
}
|
||||
|
||||
// Modal header
|
||||
|
|
@ -94,21 +126,20 @@
|
|||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
|
||||
padding: $modal-header-padding;
|
||||
border-bottom: $modal-header-border-width solid $modal-header-border-color;
|
||||
@include border-top-radius($modal-content-inner-border-radius);
|
||||
padding: var(--#{$prefix}modal-header-padding);
|
||||
border-bottom: var(--#{$prefix}modal-header-border-width) solid var(--#{$prefix}modal-header-border-color);
|
||||
@include border-top-radius(var(--#{$prefix}modal-inner-border-radius));
|
||||
|
||||
.btn-close {
|
||||
padding: ($modal-header-padding-y * .5) ($modal-header-padding-x * .5);
|
||||
margin: ($modal-header-padding-y * -.5) ($modal-header-padding-x * -.5) ($modal-header-padding-y * -.5) auto;
|
||||
padding: calc(var(--#{$prefix}modal-header-padding-y) * .5) calc(var(--#{$prefix}modal-header-padding-x) * .5);
|
||||
margin: calc(-.5 * var(--#{$prefix}modal-header-padding-y)) calc(-.5 * var(--#{$prefix}modal-header-padding-x)) calc(-.5 * var(--#{$prefix}modal-header-padding-y)) auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Title text within header
|
||||
.modal-title {
|
||||
margin-bottom: 0;
|
||||
line-height: $modal-title-line-height;
|
||||
line-height: var(--#{$prefix}modal-title-line-height);
|
||||
}
|
||||
|
||||
// Modal body
|
||||
|
|
@ -118,60 +149,59 @@
|
|||
// Enable `flex-grow: 1` so that the body take up as much space as possible
|
||||
// when there should be a fixed height on `.modal-dialog`.
|
||||
flex: 1 1 auto;
|
||||
padding: $modal-inner-padding;
|
||||
padding: var(--#{$prefix}modal-padding);
|
||||
}
|
||||
|
||||
// Footer (for actions)
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
align-items: center; // vertically center
|
||||
justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
|
||||
padding: $modal-inner-padding - $modal-footer-margin-between * .5;
|
||||
border-top: $modal-footer-border-width solid $modal-footer-border-color;
|
||||
@include border-bottom-radius($modal-content-inner-border-radius);
|
||||
padding: calc(var(--#{$prefix}modal-padding) - var(--#{$prefix}modal-footer-gap) * .5);
|
||||
background-color: var(--#{$prefix}modal-footer-bg);
|
||||
border-top: var(--#{$prefix}modal-footer-border-width) solid var(--#{$prefix}modal-footer-border-color);
|
||||
@include border-bottom-radius(var(--#{$prefix}modal-inner-border-radius));
|
||||
|
||||
// Place margin between footer elements
|
||||
// This solution is far from ideal because of the universal selector usage,
|
||||
// but is needed to fix https://github.com/twbs/bootstrap/issues/24800
|
||||
> * {
|
||||
margin: $modal-footer-margin-between * .5;
|
||||
margin: calc(var(--#{$prefix}modal-footer-gap) * .5); // Todo in v6: replace with gap on parent class
|
||||
}
|
||||
}
|
||||
|
||||
// Scale up the modal
|
||||
@include media-breakpoint-up(sm) {
|
||||
.modal {
|
||||
--#{$prefix}modal-margin: #{$modal-dialog-margin-y-sm-up};
|
||||
--#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-sm-up};
|
||||
}
|
||||
|
||||
// Automatically set modal's width for larger viewports
|
||||
.modal-dialog {
|
||||
max-width: $modal-md;
|
||||
margin: $modal-dialog-margin-y-sm-up auto;
|
||||
max-width: var(--#{$prefix}modal-width);
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.modal-dialog-scrollable {
|
||||
height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
|
||||
.modal-sm {
|
||||
--#{$prefix}modal-width: #{$modal-sm};
|
||||
}
|
||||
|
||||
.modal-dialog-centered {
|
||||
min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
@include box-shadow($modal-content-box-shadow-sm-up);
|
||||
}
|
||||
|
||||
.modal-sm { max-width: $modal-sm; }
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
.modal-lg,
|
||||
.modal-xl {
|
||||
max-width: $modal-lg;
|
||||
--#{$prefix}modal-width: #{$modal-lg};
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xl) {
|
||||
.modal-xl { max-width: $modal-xl; }
|
||||
.modal-xl {
|
||||
--#{$prefix}modal-width: #{$modal-xl};
|
||||
}
|
||||
}
|
||||
|
||||
// scss-docs-start modal-fullscreen-loop
|
||||
|
|
@ -192,17 +222,14 @@
|
|||
@include border-radius(0);
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
.modal-header,
|
||||
.modal-footer {
|
||||
@include border-radius(0);
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
@include border-radius(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@
|
|||
// `<nav>`s, `<ul>`s or `<ol>`s.
|
||||
|
||||
.nav {
|
||||
// scss-docs-start nav-css-vars
|
||||
--#{$prefix}nav-link-padding-x: #{$nav-link-padding-x};
|
||||
--#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
|
||||
@include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
|
||||
--#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
|
||||
--#{$prefix}nav-link-color: #{$nav-link-color};
|
||||
--#{$prefix}nav-link-hover-color: #{$nav-link-hover-color};
|
||||
--#{$prefix}nav-link-disabled-color: #{$nav-link-disabled-color};
|
||||
// scss-docs-end nav-css-vars
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-left: 0;
|
||||
|
|
@ -13,22 +23,30 @@
|
|||
|
||||
.nav-link {
|
||||
display: block;
|
||||
padding: $nav-link-padding-y $nav-link-padding-x;
|
||||
@include font-size($nav-link-font-size);
|
||||
font-weight: $nav-link-font-weight;
|
||||
color: $nav-link-color;
|
||||
padding: var(--#{$prefix}nav-link-padding-y) var(--#{$prefix}nav-link-padding-x);
|
||||
@include font-size(var(--#{$prefix}nav-link-font-size));
|
||||
font-weight: var(--#{$prefix}nav-link-font-weight);
|
||||
color: var(--#{$prefix}nav-link-color);
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
background: none;
|
||||
border: 0;
|
||||
@include transition($nav-link-transition);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $nav-link-hover-color;
|
||||
color: var(--#{$prefix}nav-link-hover-color);
|
||||
text-decoration: if($link-hover-decoration == underline, none, null);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 0;
|
||||
box-shadow: $nav-link-focus-box-shadow;
|
||||
}
|
||||
|
||||
// Disabled state lightens text
|
||||
&.disabled {
|
||||
color: $nav-link-disabled-color;
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: var(--#{$prefix}nav-link-disabled-color);
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
|
@ -39,38 +57,41 @@
|
|||
//
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
|
||||
// scss-docs-start nav-tabs-css-vars
|
||||
--#{$prefix}nav-tabs-border-width: #{$nav-tabs-border-width};
|
||||
--#{$prefix}nav-tabs-border-color: #{$nav-tabs-border-color};
|
||||
--#{$prefix}nav-tabs-border-radius: #{$nav-tabs-border-radius};
|
||||
--#{$prefix}nav-tabs-link-hover-border-color: #{$nav-tabs-link-hover-border-color};
|
||||
--#{$prefix}nav-tabs-link-active-color: #{$nav-tabs-link-active-color};
|
||||
--#{$prefix}nav-tabs-link-active-bg: #{$nav-tabs-link-active-bg};
|
||||
--#{$prefix}nav-tabs-link-active-border-color: #{$nav-tabs-link-active-border-color};
|
||||
// scss-docs-end nav-tabs-css-vars
|
||||
|
||||
border-bottom: var(--#{$prefix}nav-tabs-border-width) solid var(--#{$prefix}nav-tabs-border-color);
|
||||
|
||||
.nav-link {
|
||||
margin-bottom: -$nav-tabs-border-width;
|
||||
background: none;
|
||||
border: $nav-tabs-border-width solid transparent;
|
||||
@include border-top-radius($nav-tabs-border-radius);
|
||||
margin-bottom: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
border: var(--#{$prefix}nav-tabs-border-width) solid transparent;
|
||||
@include border-top-radius(var(--#{$prefix}nav-tabs-border-radius));
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-color: $nav-tabs-link-hover-border-color;
|
||||
// Prevents active .nav-link tab overlapping focus outline of previous/next .nav-link
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: $nav-link-disabled-color;
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
border-color: var(--#{$prefix}nav-tabs-link-hover-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
.nav-link.active,
|
||||
.nav-item.show .nav-link {
|
||||
color: $nav-tabs-link-active-color;
|
||||
background-color: $nav-tabs-link-active-bg;
|
||||
border-color: $nav-tabs-link-active-border-color;
|
||||
color: var(--#{$prefix}nav-tabs-link-active-color);
|
||||
background-color: var(--#{$prefix}nav-tabs-link-active-bg);
|
||||
border-color: var(--#{$prefix}nav-tabs-link-active-border-color);
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
// Make dropdown border overlap tab border
|
||||
margin-top: -$nav-tabs-border-width;
|
||||
margin-top: calc(-1 * var(--#{$prefix}nav-tabs-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
// Remove the top rounded corners here since there is a hard edge above the menu
|
||||
@include border-top-radius(0);
|
||||
}
|
||||
|
|
@ -82,16 +103,53 @@
|
|||
//
|
||||
|
||||
.nav-pills {
|
||||
// scss-docs-start nav-pills-css-vars
|
||||
--#{$prefix}nav-pills-border-radius: #{$nav-pills-border-radius};
|
||||
--#{$prefix}nav-pills-link-active-color: #{$nav-pills-link-active-color};
|
||||
--#{$prefix}nav-pills-link-active-bg: #{$nav-pills-link-active-bg};
|
||||
// scss-docs-end nav-pills-css-vars
|
||||
|
||||
.nav-link {
|
||||
background: none;
|
||||
border: 0;
|
||||
@include border-radius($nav-pills-border-radius);
|
||||
@include border-radius(var(--#{$prefix}nav-pills-border-radius));
|
||||
}
|
||||
|
||||
.nav-link.active,
|
||||
.show > .nav-link {
|
||||
color: $nav-pills-link-active-color;
|
||||
@include gradient-bg($nav-pills-link-active-bg);
|
||||
color: var(--#{$prefix}nav-pills-link-active-color);
|
||||
@include gradient-bg(var(--#{$prefix}nav-pills-link-active-bg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Underline
|
||||
//
|
||||
|
||||
.nav-underline {
|
||||
// scss-docs-start nav-underline-css-vars
|
||||
--#{$prefix}nav-underline-gap: #{$nav-underline-gap};
|
||||
--#{$prefix}nav-underline-border-width: #{$nav-underline-border-width};
|
||||
--#{$prefix}nav-underline-link-active-color: #{$nav-underline-link-active-color};
|
||||
// scss-docs-end nav-underline-css-vars
|
||||
|
||||
gap: var(--#{$prefix}nav-underline-gap);
|
||||
|
||||
.nav-link {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
border-bottom: var(--#{$prefix}nav-underline-border-width) solid transparent;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-bottom-color: currentcolor;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-link.active,
|
||||
.show > .nav-link {
|
||||
font-weight: $font-weight-bold;
|
||||
color: var(--#{$prefix}nav-underline-link-active-color);
|
||||
border-bottom-color: currentcolor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +1,38 @@
|
|||
// Contents
|
||||
//
|
||||
// Navbar
|
||||
// Navbar brand
|
||||
// Navbar nav
|
||||
// Navbar text
|
||||
// Responsive navbar
|
||||
// Navbar position
|
||||
// Navbar themes
|
||||
|
||||
|
||||
// Navbar
|
||||
//
|
||||
// Provide a static navbar from which we expand to create full-width, fixed, and
|
||||
// other navbar variations.
|
||||
|
||||
.navbar {
|
||||
// scss-docs-start navbar-css-vars
|
||||
--#{$prefix}navbar-padding-x: #{if($navbar-padding-x == null, 0, $navbar-padding-x)};
|
||||
--#{$prefix}navbar-padding-y: #{$navbar-padding-y};
|
||||
--#{$prefix}navbar-color: #{$navbar-light-color};
|
||||
--#{$prefix}navbar-hover-color: #{$navbar-light-hover-color};
|
||||
--#{$prefix}navbar-disabled-color: #{$navbar-light-disabled-color};
|
||||
--#{$prefix}navbar-active-color: #{$navbar-light-active-color};
|
||||
--#{$prefix}navbar-brand-padding-y: #{$navbar-brand-padding-y};
|
||||
--#{$prefix}navbar-brand-margin-end: #{$navbar-brand-margin-end};
|
||||
--#{$prefix}navbar-brand-font-size: #{$navbar-brand-font-size};
|
||||
--#{$prefix}navbar-brand-color: #{$navbar-light-brand-color};
|
||||
--#{$prefix}navbar-brand-hover-color: #{$navbar-light-brand-hover-color};
|
||||
--#{$prefix}navbar-nav-link-padding-x: #{$navbar-nav-link-padding-x};
|
||||
--#{$prefix}navbar-toggler-padding-y: #{$navbar-toggler-padding-y};
|
||||
--#{$prefix}navbar-toggler-padding-x: #{$navbar-toggler-padding-x};
|
||||
--#{$prefix}navbar-toggler-font-size: #{$navbar-toggler-font-size};
|
||||
--#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-light-toggler-icon-bg)};
|
||||
--#{$prefix}navbar-toggler-border-color: #{$navbar-light-toggler-border-color};
|
||||
--#{$prefix}navbar-toggler-border-radius: #{$navbar-toggler-border-radius};
|
||||
--#{$prefix}navbar-toggler-focus-width: #{$navbar-toggler-focus-width};
|
||||
--#{$prefix}navbar-toggler-transition: #{$navbar-toggler-transition};
|
||||
// scss-docs-end navbar-css-vars
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap; // allow us to do the line break for collapsing content
|
||||
align-items: center;
|
||||
justify-content: space-between; // space out brand from logo
|
||||
padding-top: $navbar-padding-y;
|
||||
padding-right: $navbar-padding-x; // default: null
|
||||
padding-bottom: $navbar-padding-y;
|
||||
padding-left: $navbar-padding-x; // default: null
|
||||
padding: var(--#{$prefix}navbar-padding-y) var(--#{$prefix}navbar-padding-x);
|
||||
@include gradient-bg();
|
||||
|
||||
// Because flex properties aren't inherited, we need to redeclare these first
|
||||
|
|
@ -54,15 +63,17 @@
|
|||
// Used for brand, project, or site names.
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: $navbar-brand-padding-y;
|
||||
padding-bottom: $navbar-brand-padding-y;
|
||||
margin-right: $navbar-brand-margin-end;
|
||||
@include font-size($navbar-brand-font-size);
|
||||
padding-top: var(--#{$prefix}navbar-brand-padding-y);
|
||||
padding-bottom: var(--#{$prefix}navbar-brand-padding-y);
|
||||
margin-right: var(--#{$prefix}navbar-brand-margin-end);
|
||||
@include font-size(var(--#{$prefix}navbar-brand-font-size));
|
||||
color: var(--#{$prefix}navbar-brand-color);
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: var(--#{$prefix}navbar-brand-hover-color);
|
||||
text-decoration: if($link-hover-decoration == underline, none, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -73,6 +84,16 @@
|
|||
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
|
||||
|
||||
.navbar-nav {
|
||||
// scss-docs-start navbar-nav-css-vars
|
||||
--#{$prefix}nav-link-padding-x: 0;
|
||||
--#{$prefix}nav-link-padding-y: #{$nav-link-padding-y};
|
||||
@include rfs($nav-link-font-size, --#{$prefix}nav-link-font-size);
|
||||
--#{$prefix}nav-link-font-weight: #{$nav-link-font-weight};
|
||||
--#{$prefix}nav-link-color: var(--#{$prefix}navbar-color);
|
||||
--#{$prefix}nav-link-hover-color: var(--#{$prefix}navbar-hover-color);
|
||||
--#{$prefix}nav-link-disabled-color: var(--#{$prefix}navbar-disabled-color);
|
||||
// scss-docs-end navbar-nav-css-vars
|
||||
|
||||
display: flex;
|
||||
flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
|
||||
padding-left: 0;
|
||||
|
|
@ -80,8 +101,10 @@
|
|||
list-style: none;
|
||||
|
||||
.nav-link {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
&.active,
|
||||
&.show {
|
||||
color: var(--#{$prefix}navbar-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
|
|
@ -97,6 +120,13 @@
|
|||
.navbar-text {
|
||||
padding-top: $nav-link-padding-y;
|
||||
padding-bottom: $nav-link-padding-y;
|
||||
color: var(--#{$prefix}navbar-color);
|
||||
|
||||
a,
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: var(--#{$prefix}navbar-active-color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -118,13 +148,14 @@
|
|||
|
||||
// Button for toggling the navbar when in its collapsed state
|
||||
.navbar-toggler {
|
||||
padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;
|
||||
@include font-size($navbar-toggler-font-size);
|
||||
padding: var(--#{$prefix}navbar-toggler-padding-y) var(--#{$prefix}navbar-toggler-padding-x);
|
||||
@include font-size(var(--#{$prefix}navbar-toggler-font-size));
|
||||
line-height: 1;
|
||||
color: var(--#{$prefix}navbar-color);
|
||||
background-color: transparent; // remove default button style
|
||||
border: $border-width solid transparent; // remove default button style
|
||||
@include border-radius($navbar-toggler-border-radius);
|
||||
@include transition($navbar-toggler-transition);
|
||||
border: var(--#{$prefix}border-width) solid var(--#{$prefix}navbar-toggler-border-color); // remove default button style
|
||||
@include border-radius(var(--#{$prefix}navbar-toggler-border-radius));
|
||||
@include transition(var(--#{$prefix}navbar-toggler-transition));
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
|
|
@ -133,7 +164,7 @@
|
|||
&:focus {
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 $navbar-toggler-focus-width;
|
||||
box-shadow: 0 0 0 var(--#{$prefix}navbar-toggler-focus-width);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -144,13 +175,14 @@
|
|||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
vertical-align: middle;
|
||||
background-image: var(--#{$prefix}navbar-toggler-icon-bg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.navbar-nav-scroll {
|
||||
max-height: var(--#{$variable-prefix}scroll-height, 75vh);
|
||||
max-height: var(--#{$prefix}scroll-height, 75vh);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
|
@ -176,8 +208,8 @@
|
|||
}
|
||||
|
||||
.nav-link {
|
||||
padding-right: $navbar-nav-link-padding-x;
|
||||
padding-left: $navbar-nav-link-padding-x;
|
||||
padding-right: var(--#{$prefix}navbar-nav-link-padding-x);
|
||||
padding-left: var(--#{$prefix}navbar-nav-link-padding-x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,34 +226,31 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.offcanvas-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.offcanvas {
|
||||
position: inherit;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
// stylelint-disable declaration-no-important
|
||||
position: static;
|
||||
z-index: auto;
|
||||
flex-grow: 1;
|
||||
visibility: visible !important; // stylelint-disable-line declaration-no-important
|
||||
background-color: transparent;
|
||||
border-right: 0;
|
||||
border-left: 0;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
visibility: visible !important;
|
||||
background-color: transparent !important;
|
||||
border: 0 !important;
|
||||
transform: none !important;
|
||||
@include box-shadow(none);
|
||||
@include transition(none);
|
||||
transform: none;
|
||||
}
|
||||
.offcanvas-top,
|
||||
.offcanvas-bottom {
|
||||
height: auto;
|
||||
border-top: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
// stylelint-enable declaration-no-important
|
||||
|
||||
.offcanvas-body {
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
padding: 0;
|
||||
overflow-y: visible;
|
||||
.offcanvas-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.offcanvas-body {
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
padding: 0;
|
||||
overflow-y: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -233,103 +262,28 @@
|
|||
//
|
||||
// Styles for switching between navbars with light or dark background.
|
||||
|
||||
// Dark links against a light background
|
||||
.navbar-light {
|
||||
.navbar-brand {
|
||||
color: $navbar-light-brand-color;
|
||||
@include deprecate("`.navbar-light`", "v5.2.0", "v6.0.0", true);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $navbar-light-brand-hover-color;
|
||||
}
|
||||
}
|
||||
.navbar-dark,
|
||||
.navbar[data-bs-theme="dark"] {
|
||||
// scss-docs-start navbar-dark-css-vars
|
||||
--#{$prefix}navbar-color: #{$navbar-dark-color};
|
||||
--#{$prefix}navbar-hover-color: #{$navbar-dark-hover-color};
|
||||
--#{$prefix}navbar-disabled-color: #{$navbar-dark-disabled-color};
|
||||
--#{$prefix}navbar-active-color: #{$navbar-dark-active-color};
|
||||
--#{$prefix}navbar-brand-color: #{$navbar-dark-brand-color};
|
||||
--#{$prefix}navbar-brand-hover-color: #{$navbar-dark-brand-hover-color};
|
||||
--#{$prefix}navbar-toggler-border-color: #{$navbar-dark-toggler-border-color};
|
||||
--#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
|
||||
// scss-docs-end navbar-dark-css-vars
|
||||
}
|
||||
|
||||
.navbar-nav {
|
||||
.nav-link {
|
||||
color: $navbar-light-color;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $navbar-light-hover-color;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: $navbar-light-disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
.show > .nav-link,
|
||||
.nav-link.active {
|
||||
color: $navbar-light-active-color;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
color: $navbar-light-color;
|
||||
border-color: $navbar-light-toggler-border-color;
|
||||
}
|
||||
|
||||
.navbar-toggler-icon {
|
||||
background-image: escape-svg($navbar-light-toggler-icon-bg);
|
||||
}
|
||||
|
||||
.navbar-text {
|
||||
color: $navbar-light-color;
|
||||
|
||||
a,
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: $navbar-light-active-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// White links against a dark background
|
||||
.navbar-dark {
|
||||
.navbar-brand {
|
||||
color: $navbar-dark-brand-color;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $navbar-dark-brand-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-nav {
|
||||
.nav-link {
|
||||
color: $navbar-dark-color;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $navbar-dark-hover-color;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: $navbar-dark-disabled-color;
|
||||
}
|
||||
}
|
||||
|
||||
.show > .nav-link,
|
||||
.nav-link.active {
|
||||
color: $navbar-dark-active-color;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-toggler {
|
||||
color: $navbar-dark-color;
|
||||
border-color: $navbar-dark-toggler-border-color;
|
||||
}
|
||||
|
||||
.navbar-toggler-icon {
|
||||
background-image: escape-svg($navbar-dark-toggler-icon-bg);
|
||||
}
|
||||
|
||||
.navbar-text {
|
||||
color: $navbar-dark-color;
|
||||
a,
|
||||
a:hover,
|
||||
a:focus {
|
||||
color: $navbar-dark-active-color;
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
.navbar-toggler-icon {
|
||||
--#{$prefix}navbar-toggler-icon-bg: #{escape-svg($navbar-dark-toggler-icon-bg)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,119 @@
|
|||
.offcanvas {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: $zindex-offcanvas;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 100%;
|
||||
color: $offcanvas-color;
|
||||
visibility: hidden;
|
||||
background-color: $offcanvas-bg-color;
|
||||
background-clip: padding-box;
|
||||
outline: 0;
|
||||
@include box-shadow($offcanvas-box-shadow);
|
||||
@include transition(transform $offcanvas-transition-duration ease-in-out);
|
||||
// stylelint-disable function-disallowed-list
|
||||
|
||||
%offcanvas-css-vars {
|
||||
// scss-docs-start offcanvas-css-vars
|
||||
--#{$prefix}offcanvas-zindex: #{$zindex-offcanvas};
|
||||
--#{$prefix}offcanvas-width: #{$offcanvas-horizontal-width};
|
||||
--#{$prefix}offcanvas-height: #{$offcanvas-vertical-height};
|
||||
--#{$prefix}offcanvas-padding-x: #{$offcanvas-padding-x};
|
||||
--#{$prefix}offcanvas-padding-y: #{$offcanvas-padding-y};
|
||||
--#{$prefix}offcanvas-color: #{$offcanvas-color};
|
||||
--#{$prefix}offcanvas-bg: #{$offcanvas-bg-color};
|
||||
--#{$prefix}offcanvas-border-width: #{$offcanvas-border-width};
|
||||
--#{$prefix}offcanvas-border-color: #{$offcanvas-border-color};
|
||||
--#{$prefix}offcanvas-box-shadow: #{$offcanvas-box-shadow};
|
||||
--#{$prefix}offcanvas-transition: #{transform $offcanvas-transition-duration ease-in-out};
|
||||
--#{$prefix}offcanvas-title-line-height: #{$offcanvas-title-line-height};
|
||||
// scss-docs-end offcanvas-css-vars
|
||||
}
|
||||
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
$next: breakpoint-next($breakpoint, $grid-breakpoints);
|
||||
$infix: breakpoint-infix($next, $grid-breakpoints);
|
||||
|
||||
.offcanvas#{$infix} {
|
||||
@extend %offcanvas-css-vars;
|
||||
}
|
||||
}
|
||||
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
$next: breakpoint-next($breakpoint, $grid-breakpoints);
|
||||
$infix: breakpoint-infix($next, $grid-breakpoints);
|
||||
|
||||
.offcanvas#{$infix} {
|
||||
@include media-breakpoint-down($next) {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: var(--#{$prefix}offcanvas-zindex);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 100%;
|
||||
color: var(--#{$prefix}offcanvas-color);
|
||||
visibility: hidden;
|
||||
background-color: var(--#{$prefix}offcanvas-bg);
|
||||
background-clip: padding-box;
|
||||
outline: 0;
|
||||
@include box-shadow(var(--#{$prefix}offcanvas-box-shadow));
|
||||
@include transition(var(--#{$prefix}offcanvas-transition));
|
||||
|
||||
&.offcanvas-start {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: var(--#{$prefix}offcanvas-width);
|
||||
border-right: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
&.offcanvas-end {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: var(--#{$prefix}offcanvas-width);
|
||||
border-left: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
&.offcanvas-top {
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: var(--#{$prefix}offcanvas-height);
|
||||
max-height: 100%;
|
||||
border-bottom: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
&.offcanvas-bottom {
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: var(--#{$prefix}offcanvas-height);
|
||||
max-height: 100%;
|
||||
border-top: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
&.showing,
|
||||
&.show:not(.hiding) {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
&.showing,
|
||||
&.hiding,
|
||||
&.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@if not ($infix == "") {
|
||||
@include media-breakpoint-up($next) {
|
||||
--#{$prefix}offcanvas-height: auto;
|
||||
--#{$prefix}offcanvas-border-width: 0;
|
||||
background-color: transparent !important; // stylelint-disable-line declaration-no-important
|
||||
|
||||
.offcanvas-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.offcanvas-body {
|
||||
display: flex;
|
||||
flex-grow: 0;
|
||||
padding: 0;
|
||||
overflow-y: visible;
|
||||
// Reset `background-color` in case `.bg-*` classes are used in offcanvas
|
||||
background-color: transparent !important; // stylelint-disable-line declaration-no-important
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.offcanvas-backdrop {
|
||||
|
|
@ -21,63 +123,21 @@
|
|||
.offcanvas-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: $offcanvas-padding-y $offcanvas-padding-x;
|
||||
padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
|
||||
|
||||
.btn-close {
|
||||
padding: ($offcanvas-padding-y * .5) ($offcanvas-padding-x * .5);
|
||||
margin-top: $offcanvas-padding-y * -.5;
|
||||
margin-right: $offcanvas-padding-x * -.5;
|
||||
margin-bottom: $offcanvas-padding-y * -.5;
|
||||
padding: calc(var(--#{$prefix}offcanvas-padding-y) * .5) calc(var(--#{$prefix}offcanvas-padding-x) * .5);
|
||||
margin: calc(-.5 * var(--#{$prefix}offcanvas-padding-y)) calc(-.5 * var(--#{$prefix}offcanvas-padding-x)) calc(-.5 * var(--#{$prefix}offcanvas-padding-y)) auto;
|
||||
}
|
||||
}
|
||||
|
||||
.offcanvas-title {
|
||||
margin-bottom: 0;
|
||||
line-height: $offcanvas-title-line-height;
|
||||
line-height: var(--#{$prefix}offcanvas-title-line-height);
|
||||
}
|
||||
|
||||
.offcanvas-body {
|
||||
flex-grow: 1;
|
||||
padding: $offcanvas-padding-y $offcanvas-padding-x;
|
||||
padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.offcanvas-start {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: $offcanvas-horizontal-width;
|
||||
border-right: $offcanvas-border-width solid $offcanvas-border-color;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.offcanvas-end {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: $offcanvas-horizontal-width;
|
||||
border-left: $offcanvas-border-width solid $offcanvas-border-color;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.offcanvas-top {
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: $offcanvas-vertical-height;
|
||||
max-height: 100%;
|
||||
border-bottom: $offcanvas-border-width solid $offcanvas-border-color;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.offcanvas-bottom {
|
||||
right: 0;
|
||||
left: 0;
|
||||
height: $offcanvas-vertical-height;
|
||||
max-height: 100%;
|
||||
border-top: $offcanvas-border-width solid $offcanvas-border-color;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
.offcanvas.show {
|
||||
transform: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,27 @@
|
|||
.pagination {
|
||||
// scss-docs-start pagination-css-vars
|
||||
--#{$prefix}pagination-padding-x: #{$pagination-padding-x};
|
||||
--#{$prefix}pagination-padding-y: #{$pagination-padding-y};
|
||||
@include rfs($pagination-font-size, --#{$prefix}pagination-font-size);
|
||||
--#{$prefix}pagination-color: #{$pagination-color};
|
||||
--#{$prefix}pagination-bg: #{$pagination-bg};
|
||||
--#{$prefix}pagination-border-width: #{$pagination-border-width};
|
||||
--#{$prefix}pagination-border-color: #{$pagination-border-color};
|
||||
--#{$prefix}pagination-border-radius: #{$pagination-border-radius};
|
||||
--#{$prefix}pagination-hover-color: #{$pagination-hover-color};
|
||||
--#{$prefix}pagination-hover-bg: #{$pagination-hover-bg};
|
||||
--#{$prefix}pagination-hover-border-color: #{$pagination-hover-border-color};
|
||||
--#{$prefix}pagination-focus-color: #{$pagination-focus-color};
|
||||
--#{$prefix}pagination-focus-bg: #{$pagination-focus-bg};
|
||||
--#{$prefix}pagination-focus-box-shadow: #{$pagination-focus-box-shadow};
|
||||
--#{$prefix}pagination-active-color: #{$pagination-active-color};
|
||||
--#{$prefix}pagination-active-bg: #{$pagination-active-bg};
|
||||
--#{$prefix}pagination-active-border-color: #{$pagination-active-border-color};
|
||||
--#{$prefix}pagination-disabled-color: #{$pagination-disabled-color};
|
||||
--#{$prefix}pagination-disabled-bg: #{$pagination-disabled-bg};
|
||||
--#{$prefix}pagination-disabled-border-color: #{$pagination-disabled-border-color};
|
||||
// scss-docs-end pagination-css-vars
|
||||
|
||||
display: flex;
|
||||
@include list-unstyled();
|
||||
}
|
||||
|
|
@ -6,26 +29,44 @@
|
|||
.page-link {
|
||||
position: relative;
|
||||
display: block;
|
||||
color: $pagination-color;
|
||||
padding: var(--#{$prefix}pagination-padding-y) var(--#{$prefix}pagination-padding-x);
|
||||
@include font-size(var(--#{$prefix}pagination-font-size));
|
||||
color: var(--#{$prefix}pagination-color);
|
||||
text-decoration: if($link-decoration == none, null, none);
|
||||
background-color: $pagination-bg;
|
||||
border: $pagination-border-width solid $pagination-border-color;
|
||||
background-color: var(--#{$prefix}pagination-bg);
|
||||
border: var(--#{$prefix}pagination-border-width) solid var(--#{$prefix}pagination-border-color);
|
||||
@include transition($pagination-transition);
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
color: $pagination-hover-color;
|
||||
color: var(--#{$prefix}pagination-hover-color);
|
||||
text-decoration: if($link-hover-decoration == underline, none, null);
|
||||
background-color: $pagination-hover-bg;
|
||||
border-color: $pagination-hover-border-color;
|
||||
background-color: var(--#{$prefix}pagination-hover-bg);
|
||||
border-color: var(--#{$prefix}pagination-hover-border-color);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
color: $pagination-focus-color;
|
||||
background-color: $pagination-focus-bg;
|
||||
color: var(--#{$prefix}pagination-focus-color);
|
||||
background-color: var(--#{$prefix}pagination-focus-bg);
|
||||
outline: $pagination-focus-outline;
|
||||
box-shadow: $pagination-focus-box-shadow;
|
||||
box-shadow: var(--#{$prefix}pagination-focus-box-shadow);
|
||||
}
|
||||
|
||||
&.active,
|
||||
.active > & {
|
||||
z-index: 3;
|
||||
color: var(--#{$prefix}pagination-active-color);
|
||||
@include gradient-bg(var(--#{$prefix}pagination-active-bg));
|
||||
border-color: var(--#{$prefix}pagination-active-border-color);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
.disabled > & {
|
||||
color: var(--#{$prefix}pagination-disabled-color);
|
||||
pointer-events: none;
|
||||
background-color: var(--#{$prefix}pagination-disabled-bg);
|
||||
border-color: var(--#{$prefix}pagination-disabled-border-color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -34,18 +75,23 @@
|
|||
margin-left: $pagination-margin-start;
|
||||
}
|
||||
|
||||
&.active .page-link {
|
||||
z-index: 3;
|
||||
color: $pagination-active-color;
|
||||
@include gradient-bg($pagination-active-bg);
|
||||
border-color: $pagination-active-border-color;
|
||||
}
|
||||
@if $pagination-margin-start == calc(#{$pagination-border-width} * -1) {
|
||||
&:first-child {
|
||||
.page-link {
|
||||
@include border-start-radius(var(--#{$prefix}pagination-border-radius));
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled .page-link {
|
||||
color: $pagination-disabled-color;
|
||||
pointer-events: none;
|
||||
background-color: $pagination-disabled-bg;
|
||||
border-color: $pagination-disabled-border-color;
|
||||
&:last-child {
|
||||
.page-link {
|
||||
@include border-end-radius(var(--#{$prefix}pagination-border-radius));
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
// Add border-radius to all pageLinks in case they have left margin
|
||||
.page-link {
|
||||
@include border-radius(var(--#{$prefix}pagination-border-radius));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +99,6 @@
|
|||
//
|
||||
// Sizing
|
||||
//
|
||||
@include pagination-size($pagination-padding-y, $pagination-padding-x, null, $pagination-border-radius);
|
||||
|
||||
.pagination-lg {
|
||||
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $pagination-border-radius-lg);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
min-height: 1em;
|
||||
vertical-align: middle;
|
||||
cursor: wait;
|
||||
background-color: currentColor;
|
||||
background-color: currentcolor;
|
||||
opacity: $placeholder-opacity-max;
|
||||
|
||||
&.btn::before {
|
||||
|
|
|
|||
|
|
@ -1,27 +1,46 @@
|
|||
.popover {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0 #{"/* rtl:ignore */"};
|
||||
z-index: $zindex-popover;
|
||||
// scss-docs-start popover-css-vars
|
||||
--#{$prefix}popover-zindex: #{$zindex-popover};
|
||||
--#{$prefix}popover-max-width: #{$popover-max-width};
|
||||
@include rfs($popover-font-size, --#{$prefix}popover-font-size);
|
||||
--#{$prefix}popover-bg: #{$popover-bg};
|
||||
--#{$prefix}popover-border-width: #{$popover-border-width};
|
||||
--#{$prefix}popover-border-color: #{$popover-border-color};
|
||||
--#{$prefix}popover-border-radius: #{$popover-border-radius};
|
||||
--#{$prefix}popover-inner-border-radius: #{$popover-inner-border-radius};
|
||||
--#{$prefix}popover-box-shadow: #{$popover-box-shadow};
|
||||
--#{$prefix}popover-header-padding-x: #{$popover-header-padding-x};
|
||||
--#{$prefix}popover-header-padding-y: #{$popover-header-padding-y};
|
||||
@include rfs($popover-header-font-size, --#{$prefix}popover-header-font-size);
|
||||
--#{$prefix}popover-header-color: #{$popover-header-color};
|
||||
--#{$prefix}popover-header-bg: #{$popover-header-bg};
|
||||
--#{$prefix}popover-body-padding-x: #{$popover-body-padding-x};
|
||||
--#{$prefix}popover-body-padding-y: #{$popover-body-padding-y};
|
||||
--#{$prefix}popover-body-color: #{$popover-body-color};
|
||||
--#{$prefix}popover-arrow-width: #{$popover-arrow-width};
|
||||
--#{$prefix}popover-arrow-height: #{$popover-arrow-height};
|
||||
--#{$prefix}popover-arrow-border: var(--#{$prefix}popover-border-color);
|
||||
// scss-docs-end popover-css-vars
|
||||
|
||||
z-index: var(--#{$prefix}popover-zindex);
|
||||
display: block;
|
||||
max-width: $popover-max-width;
|
||||
max-width: var(--#{$prefix}popover-max-width);
|
||||
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
|
||||
// So reset our font and text properties to avoid inheriting weird values.
|
||||
@include reset-text();
|
||||
@include font-size($popover-font-size);
|
||||
@include font-size(var(--#{$prefix}popover-font-size));
|
||||
// Allow breaking very long words so they don't overflow the popover's bounds
|
||||
word-wrap: break-word;
|
||||
background-color: $popover-bg;
|
||||
background-color: var(--#{$prefix}popover-bg);
|
||||
background-clip: padding-box;
|
||||
border: $popover-border-width solid $popover-border-color;
|
||||
@include border-radius($popover-border-radius);
|
||||
@include box-shadow($popover-box-shadow);
|
||||
border: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
|
||||
@include border-radius(var(--#{$prefix}popover-border-radius));
|
||||
@include box-shadow(var(--#{$prefix}popover-box-shadow));
|
||||
|
||||
.popover-arrow {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: $popover-arrow-width;
|
||||
height: $popover-arrow-height;
|
||||
width: var(--#{$prefix}popover-arrow-width);
|
||||
height: var(--#{$prefix}popover-arrow-height);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
|
|
@ -30,62 +49,75 @@
|
|||
content: "";
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bs-popover-top {
|
||||
> .popover-arrow {
|
||||
bottom: subtract(-$popover-arrow-height, $popover-border-width);
|
||||
bottom: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-width: var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
&::before {
|
||||
bottom: 0;
|
||||
border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;
|
||||
border-top-color: $popover-arrow-outer-color;
|
||||
border-top-color: var(--#{$prefix}popover-arrow-border);
|
||||
}
|
||||
|
||||
&::after {
|
||||
bottom: $popover-border-width;
|
||||
border-width: $popover-arrow-height ($popover-arrow-width * .5) 0;
|
||||
border-top-color: $popover-arrow-color;
|
||||
bottom: var(--#{$prefix}popover-border-width);
|
||||
border-top-color: var(--#{$prefix}popover-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* rtl:begin:ignore */
|
||||
.bs-popover-end {
|
||||
> .popover-arrow {
|
||||
left: subtract(-$popover-arrow-height, $popover-border-width);
|
||||
width: $popover-arrow-height;
|
||||
height: $popover-arrow-width;
|
||||
left: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
width: var(--#{$prefix}popover-arrow-height);
|
||||
height: var(--#{$prefix}popover-arrow-width);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height) calc(var(--#{$prefix}popover-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 0;
|
||||
border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;
|
||||
border-right-color: $popover-arrow-outer-color;
|
||||
border-right-color: var(--#{$prefix}popover-arrow-border);
|
||||
}
|
||||
|
||||
&::after {
|
||||
left: $popover-border-width;
|
||||
border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0;
|
||||
border-right-color: $popover-arrow-color;
|
||||
left: var(--#{$prefix}popover-border-width);
|
||||
border-right-color: var(--#{$prefix}popover-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* rtl:end:ignore */
|
||||
|
||||
.bs-popover-bottom {
|
||||
> .popover-arrow {
|
||||
top: subtract(-$popover-arrow-height, $popover-border-width);
|
||||
top: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-width: 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
&::before {
|
||||
top: 0;
|
||||
border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);
|
||||
border-bottom-color: $popover-arrow-outer-color;
|
||||
border-bottom-color: var(--#{$prefix}popover-arrow-border);
|
||||
}
|
||||
|
||||
&::after {
|
||||
top: $popover-border-width;
|
||||
border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5);
|
||||
border-bottom-color: $popover-arrow-color;
|
||||
top: var(--#{$prefix}popover-border-width);
|
||||
border-bottom-color: var(--#{$prefix}popover-bg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,33 +127,39 @@
|
|||
top: 0;
|
||||
left: 50%;
|
||||
display: block;
|
||||
width: $popover-arrow-width;
|
||||
margin-left: -$popover-arrow-width * .5;
|
||||
width: var(--#{$prefix}popover-arrow-width);
|
||||
margin-left: calc(-.5 * var(--#{$prefix}popover-arrow-width)); // stylelint-disable-line function-disallowed-list
|
||||
content: "";
|
||||
border-bottom: $popover-border-width solid $popover-header-bg;
|
||||
border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-header-bg);
|
||||
}
|
||||
}
|
||||
|
||||
/* rtl:begin:ignore */
|
||||
.bs-popover-start {
|
||||
> .popover-arrow {
|
||||
right: subtract(-$popover-arrow-height, $popover-border-width);
|
||||
width: $popover-arrow-height;
|
||||
height: $popover-arrow-width;
|
||||
right: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width)); // stylelint-disable-line function-disallowed-list
|
||||
width: var(--#{$prefix}popover-arrow-height);
|
||||
height: var(--#{$prefix}popover-arrow-width);
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
border-width: calc(var(--#{$prefix}popover-arrow-width) * .5) 0 calc(var(--#{$prefix}popover-arrow-width) * .5) var(--#{$prefix}popover-arrow-height); // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
&::before {
|
||||
right: 0;
|
||||
border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;
|
||||
border-left-color: $popover-arrow-outer-color;
|
||||
border-left-color: var(--#{$prefix}popover-arrow-border);
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: $popover-border-width;
|
||||
border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height;
|
||||
border-left-color: $popover-arrow-color;
|
||||
right: var(--#{$prefix}popover-border-width);
|
||||
border-left-color: var(--#{$prefix}popover-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* rtl:end:ignore */
|
||||
|
||||
.bs-popover-auto {
|
||||
&[data-popper-placement^="top"] {
|
||||
@extend .bs-popover-top;
|
||||
|
|
@ -139,13 +177,13 @@
|
|||
|
||||
// Offset the popover to account for the popover arrow
|
||||
.popover-header {
|
||||
padding: $popover-header-padding-y $popover-header-padding-x;
|
||||
padding: var(--#{$prefix}popover-header-padding-y) var(--#{$prefix}popover-header-padding-x);
|
||||
margin-bottom: 0; // Reset the default from Reboot
|
||||
@include font-size($font-size-base);
|
||||
color: $popover-header-color;
|
||||
background-color: $popover-header-bg;
|
||||
border-bottom: $popover-border-width solid $popover-border-color;
|
||||
@include border-top-radius($popover-inner-border-radius);
|
||||
@include font-size(var(--#{$prefix}popover-header-font-size));
|
||||
color: var(--#{$prefix}popover-header-color);
|
||||
background-color: var(--#{$prefix}popover-header-bg);
|
||||
border-bottom: var(--#{$prefix}popover-border-width) solid var(--#{$prefix}popover-border-color);
|
||||
@include border-top-radius(var(--#{$prefix}popover-inner-border-radius));
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
|
@ -153,6 +191,6 @@
|
|||
}
|
||||
|
||||
.popover-body {
|
||||
padding: $popover-body-padding-y $popover-body-padding-x;
|
||||
color: $popover-body-color;
|
||||
padding: var(--#{$prefix}popover-body-padding-y) var(--#{$prefix}popover-body-padding-x);
|
||||
color: var(--#{$prefix}popover-body-color);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,26 @@
|
|||
}
|
||||
// scss-docs-end progress-keyframes
|
||||
|
||||
.progress {
|
||||
.progress,
|
||||
.progress-stacked {
|
||||
// scss-docs-start progress-css-vars
|
||||
--#{$prefix}progress-height: #{$progress-height};
|
||||
@include rfs($progress-font-size, --#{$prefix}progress-font-size);
|
||||
--#{$prefix}progress-bg: #{$progress-bg};
|
||||
--#{$prefix}progress-border-radius: #{$progress-border-radius};
|
||||
--#{$prefix}progress-box-shadow: #{$progress-box-shadow};
|
||||
--#{$prefix}progress-bar-color: #{$progress-bar-color};
|
||||
--#{$prefix}progress-bar-bg: #{$progress-bar-bg};
|
||||
--#{$prefix}progress-bar-transition: #{$progress-bar-transition};
|
||||
// scss-docs-end progress-css-vars
|
||||
|
||||
display: flex;
|
||||
height: $progress-height;
|
||||
height: var(--#{$prefix}progress-height);
|
||||
overflow: hidden; // force rounded corners by cropping it
|
||||
@include font-size($progress-font-size);
|
||||
background-color: $progress-bg;
|
||||
@include border-radius($progress-border-radius);
|
||||
@include box-shadow($progress-box-shadow);
|
||||
@include font-size(var(--#{$prefix}progress-font-size));
|
||||
background-color: var(--#{$prefix}progress-bg);
|
||||
@include border-radius(var(--#{$prefix}progress-border-radius));
|
||||
@include box-shadow(var(--#{$prefix}progress-box-shadow));
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
|
|
@ -23,16 +35,24 @@
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
color: $progress-bar-color;
|
||||
color: var(--#{$prefix}progress-bar-color);
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
background-color: $progress-bar-bg;
|
||||
@include transition($progress-bar-transition);
|
||||
background-color: var(--#{$prefix}progress-bar-bg);
|
||||
@include transition(var(--#{$prefix}progress-bar-transition));
|
||||
}
|
||||
|
||||
.progress-bar-striped {
|
||||
@include gradient-striped();
|
||||
background-size: $progress-height $progress-height;
|
||||
background-size: var(--#{$prefix}progress-height) var(--#{$prefix}progress-height);
|
||||
}
|
||||
|
||||
.progress-stacked > .progress {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.progress-stacked > .progress > .progress-bar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@if $enable-transitions {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
:root {
|
||||
@if $font-size-root != null {
|
||||
font-size: var(--#{$variable-prefix}root-font-size);
|
||||
@include font-size(var(--#{$prefix}root-font-size));
|
||||
}
|
||||
|
||||
@if $enable-smooth-scroll {
|
||||
|
|
@ -48,13 +48,13 @@
|
|||
// scss-docs-start reboot-body-rules
|
||||
body {
|
||||
margin: 0; // 1
|
||||
font-family: var(--#{$variable-prefix}body-font-family);
|
||||
@include font-size(var(--#{$variable-prefix}body-font-size));
|
||||
font-weight: var(--#{$variable-prefix}body-font-weight);
|
||||
line-height: var(--#{$variable-prefix}body-line-height);
|
||||
color: var(--#{$variable-prefix}body-color);
|
||||
text-align: var(--#{$variable-prefix}body-text-align);
|
||||
background-color: var(--#{$variable-prefix}body-bg); // 2
|
||||
font-family: var(--#{$prefix}body-font-family);
|
||||
@include font-size(var(--#{$prefix}body-font-size));
|
||||
font-weight: var(--#{$prefix}body-font-weight);
|
||||
line-height: var(--#{$prefix}body-line-height);
|
||||
color: var(--#{$prefix}body-color);
|
||||
text-align: var(--#{$prefix}body-text-align);
|
||||
background-color: var(--#{$prefix}body-bg); // 2
|
||||
-webkit-text-size-adjust: 100%; // 3
|
||||
-webkit-tap-highlight-color: rgba($black, 0); // 4
|
||||
}
|
||||
|
|
@ -64,20 +64,15 @@ body {
|
|||
// Content grouping
|
||||
//
|
||||
// 1. Reset Firefox's gray color
|
||||
// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field
|
||||
|
||||
hr {
|
||||
margin: $hr-margin-y 0;
|
||||
color: $hr-color; // 1
|
||||
background-color: currentColor;
|
||||
border: 0;
|
||||
border-top: $hr-border-width solid $hr-border-color;
|
||||
opacity: $hr-opacity;
|
||||
}
|
||||
|
||||
hr:not([size]) {
|
||||
height: $hr-height; // 2
|
||||
}
|
||||
|
||||
|
||||
// Typography
|
||||
//
|
||||
|
|
@ -92,7 +87,7 @@ hr:not([size]) {
|
|||
font-style: $headings-font-style;
|
||||
font-weight: $headings-font-weight;
|
||||
line-height: $headings-line-height;
|
||||
color: $headings-color;
|
||||
color: var(--#{$prefix}heading-color);
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
|
@ -139,16 +134,14 @@ p {
|
|||
|
||||
// Abbreviations
|
||||
//
|
||||
// 1. Duplicate behavior to the data-bs-* attribute for our tooltip plugin
|
||||
// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
|
||||
// 3. Add explicit cursor to indicate changed behavior.
|
||||
// 4. Prevent the text-decoration to be skipped.
|
||||
// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
|
||||
// 2. Add explicit cursor to indicate changed behavior.
|
||||
// 3. Prevent the text-decoration to be skipped.
|
||||
|
||||
abbr[title],
|
||||
abbr[data-bs-original-title] { // 1
|
||||
text-decoration: underline dotted; // 2
|
||||
cursor: help; // 3
|
||||
text-decoration-skip-ink: none; // 4
|
||||
abbr[title] {
|
||||
text-decoration: underline dotted; // 1
|
||||
cursor: help; // 2
|
||||
text-decoration-skip-ink: none; // 3
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -224,7 +217,8 @@ small {
|
|||
|
||||
mark {
|
||||
padding: $mark-padding;
|
||||
background-color: $mark-bg;
|
||||
color: var(--#{$prefix}highlight-color);
|
||||
background-color: var(--#{$prefix}highlight-bg);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -248,11 +242,11 @@ sup { top: -.5em; }
|
|||
// Links
|
||||
|
||||
a {
|
||||
color: $link-color;
|
||||
color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, 1));
|
||||
text-decoration: $link-decoration;
|
||||
|
||||
&:hover {
|
||||
color: $link-hover-color;
|
||||
--#{$prefix}link-color-rgb: var(--#{$prefix}link-hover-color-rgb);
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
}
|
||||
|
|
@ -279,8 +273,6 @@ kbd,
|
|||
samp {
|
||||
font-family: $font-family-code;
|
||||
@include font-size(1em); // Correct the odd `em` font sizing in all browsers.
|
||||
direction: ltr #{"/* rtl:ignore */"};
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
// 1. Remove browser default top margin
|
||||
|
|
@ -305,7 +297,7 @@ pre {
|
|||
|
||||
code {
|
||||
@include font-size($code-font-size);
|
||||
color: $code-color;
|
||||
color: var(--#{$prefix}code-color);
|
||||
word-wrap: break-word;
|
||||
|
||||
// Streamline the style when inside anchors to avoid broken underline and more
|
||||
|
|
@ -445,11 +437,11 @@ select {
|
|||
}
|
||||
}
|
||||
|
||||
// Remove the dropdown arrow in Chrome from inputs built with datalists.
|
||||
// Remove the dropdown arrow only from text type inputs built with datalists in Chrome.
|
||||
// See https://stackoverflow.com/a/54997118
|
||||
|
||||
[list]::-webkit-calendar-picker-indicator {
|
||||
display: none;
|
||||
[list]:not([type="date"]):not([type="datetime-local"]):not([type="month"]):not([type="week"]):not([type="time"])::-webkit-calendar-picker-indicator {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
|
||||
|
|
@ -533,15 +525,15 @@ legend {
|
|||
height: auto;
|
||||
}
|
||||
|
||||
// 1. Correct the outline style in Safari.
|
||||
// 2. This overrides the extra rounded corners on search inputs in iOS so that our
|
||||
// 1. This overrides the extra rounded corners on search inputs in iOS so that our
|
||||
// `.form-control` class can properly style them. Note that this cannot simply
|
||||
// be added to `.form-control` as it's not specific enough. For details, see
|
||||
// https://github.com/twbs/bootstrap/issues/11586.
|
||||
// 2. Correct the outline style in Safari.
|
||||
|
||||
[type="search"] {
|
||||
outline-offset: -2px; // 1
|
||||
-webkit-appearance: textfield; // 2
|
||||
-webkit-appearance: textfield; // 1
|
||||
outline-offset: -2px; // 2
|
||||
}
|
||||
|
||||
// 1. A few input types should stay LTR
|
||||
|
|
@ -571,16 +563,10 @@ legend {
|
|||
}
|
||||
|
||||
|
||||
// Inherit font family and line height for file input buttons
|
||||
|
||||
::file-selector-button {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
// 1. Change font properties to `inherit`
|
||||
// 1. Inherit font family and line height for file input buttons
|
||||
// 2. Correct the inability to style clickable types in iOS and Safari.
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
::file-selector-button {
|
||||
font: inherit; // 1
|
||||
-webkit-appearance: button; // 2
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
:root,
|
||||
[data-bs-theme="light"] {
|
||||
// Note: Custom variable values only support SassScript inside `#{}`.
|
||||
|
||||
// Colors
|
||||
|
|
@ -6,49 +7,181 @@
|
|||
// Generate palettes for full colors, grays, and theme colors.
|
||||
|
||||
@each $color, $value in $colors {
|
||||
--#{$variable-prefix}#{$color}: #{$value};
|
||||
--#{$prefix}#{$color}: #{$value};
|
||||
}
|
||||
|
||||
@each $color, $value in $grays {
|
||||
--#{$variable-prefix}gray-#{$color}: #{$value};
|
||||
--#{$prefix}gray-#{$color}: #{$value};
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
--#{$variable-prefix}#{$color}: #{$value};
|
||||
--#{$prefix}#{$color}: #{$value};
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors-rgb {
|
||||
--#{$variable-prefix}#{$color}-rgb: #{$value};
|
||||
--#{$prefix}#{$color}-rgb: #{$value};
|
||||
}
|
||||
|
||||
--#{$variable-prefix}white-rgb: #{to-rgb($white)};
|
||||
--#{$variable-prefix}black-rgb: #{to-rgb($black)};
|
||||
--#{$variable-prefix}body-color-rgb: #{to-rgb($body-color)};
|
||||
--#{$variable-prefix}body-bg-rgb: #{to-rgb($body-bg)};
|
||||
@each $color, $value in $theme-colors-text {
|
||||
--#{$prefix}#{$color}-text-emphasis: #{$value};
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors-bg-subtle {
|
||||
--#{$prefix}#{$color}-bg-subtle: #{$value};
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors-border-subtle {
|
||||
--#{$prefix}#{$color}-border-subtle: #{$value};
|
||||
}
|
||||
|
||||
--#{$prefix}white-rgb: #{to-rgb($white)};
|
||||
--#{$prefix}black-rgb: #{to-rgb($black)};
|
||||
|
||||
// Fonts
|
||||
|
||||
// Note: Use `inspect` for lists so that quoted items keep the quotes.
|
||||
// See https://github.com/sass/sass/issues/2383#issuecomment-336349172
|
||||
--#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)};
|
||||
--#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)};
|
||||
--#{$variable-prefix}gradient: #{$gradient};
|
||||
--#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)};
|
||||
--#{$prefix}font-monospace: #{inspect($font-family-monospace)};
|
||||
--#{$prefix}gradient: #{$gradient};
|
||||
|
||||
// Root and body
|
||||
// stylelint-disable custom-property-empty-line-before
|
||||
// scss-docs-start root-body-variables
|
||||
@if $font-size-root != null {
|
||||
--#{$variable-prefix}root-font-size: #{$font-size-root};
|
||||
--#{$prefix}root-font-size: #{$font-size-root};
|
||||
}
|
||||
--#{$variable-prefix}body-font-family: #{$font-family-base};
|
||||
--#{$variable-prefix}body-font-size: #{$font-size-base};
|
||||
--#{$variable-prefix}body-font-weight: #{$font-weight-base};
|
||||
--#{$variable-prefix}body-line-height: #{$line-height-base};
|
||||
--#{$variable-prefix}body-color: #{$body-color};
|
||||
--#{$prefix}body-font-family: #{inspect($font-family-base)};
|
||||
@include rfs($font-size-base, --#{$prefix}body-font-size);
|
||||
--#{$prefix}body-font-weight: #{$font-weight-base};
|
||||
--#{$prefix}body-line-height: #{$line-height-base};
|
||||
@if $body-text-align != null {
|
||||
--#{$variable-prefix}body-text-align: #{$body-text-align};
|
||||
--#{$prefix}body-text-align: #{$body-text-align};
|
||||
}
|
||||
--#{$variable-prefix}body-bg: #{$body-bg};
|
||||
|
||||
--#{$prefix}body-color: #{$body-color};
|
||||
--#{$prefix}body-color-rgb: #{to-rgb($body-color)};
|
||||
--#{$prefix}body-bg: #{$body-bg};
|
||||
--#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};
|
||||
|
||||
--#{$prefix}emphasis-color: #{$body-emphasis-color};
|
||||
--#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color)};
|
||||
|
||||
--#{$prefix}secondary-color: #{$body-secondary-color};
|
||||
--#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};
|
||||
--#{$prefix}secondary-bg: #{$body-secondary-bg};
|
||||
--#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};
|
||||
|
||||
--#{$prefix}tertiary-color: #{$body-tertiary-color};
|
||||
--#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};
|
||||
--#{$prefix}tertiary-bg: #{$body-tertiary-bg};
|
||||
--#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};
|
||||
// scss-docs-end root-body-variables
|
||||
// stylelint-enable custom-property-empty-line-before
|
||||
|
||||
--#{$prefix}heading-color: #{$headings-color};
|
||||
|
||||
--#{$prefix}link-color: #{$link-color};
|
||||
--#{$prefix}link-color-rgb: #{to-rgb($link-color)};
|
||||
--#{$prefix}link-decoration: #{$link-decoration};
|
||||
|
||||
--#{$prefix}link-hover-color: #{$link-hover-color};
|
||||
--#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color)};
|
||||
|
||||
@if $link-hover-decoration != null {
|
||||
--#{$prefix}link-hover-decoration: #{$link-hover-decoration};
|
||||
}
|
||||
|
||||
--#{$prefix}code-color: #{$code-color};
|
||||
--#{$prefix}highlight-color: #{$mark-color};
|
||||
--#{$prefix}highlight-bg: #{$mark-bg};
|
||||
|
||||
// scss-docs-start root-border-var
|
||||
--#{$prefix}border-width: #{$border-width};
|
||||
--#{$prefix}border-style: #{$border-style};
|
||||
--#{$prefix}border-color: #{$border-color};
|
||||
--#{$prefix}border-color-translucent: #{$border-color-translucent};
|
||||
|
||||
--#{$prefix}border-radius: #{$border-radius};
|
||||
--#{$prefix}border-radius-sm: #{$border-radius-sm};
|
||||
--#{$prefix}border-radius-lg: #{$border-radius-lg};
|
||||
--#{$prefix}border-radius-xl: #{$border-radius-xl};
|
||||
--#{$prefix}border-radius-xxl: #{$border-radius-xxl};
|
||||
--#{$prefix}border-radius-2xl: var(--#{$prefix}border-radius-xxl); // Deprecated in v5.3.0 for consistency
|
||||
--#{$prefix}border-radius-pill: #{$border-radius-pill};
|
||||
// scss-docs-end root-border-var
|
||||
|
||||
--#{$prefix}box-shadow: #{$box-shadow};
|
||||
--#{$prefix}box-shadow-sm: #{$box-shadow-sm};
|
||||
--#{$prefix}box-shadow-lg: #{$box-shadow-lg};
|
||||
--#{$prefix}box-shadow-inset: #{$box-shadow-inset};
|
||||
|
||||
// Focus styles
|
||||
// scss-docs-start root-focus-variables
|
||||
--#{$prefix}focus-ring-width: #{$focus-ring-width};
|
||||
--#{$prefix}focus-ring-opacity: #{$focus-ring-opacity};
|
||||
--#{$prefix}focus-ring-color: #{$focus-ring-color};
|
||||
// scss-docs-end root-focus-variables
|
||||
|
||||
// scss-docs-start root-form-validation-variables
|
||||
--#{$prefix}form-valid-color: #{$form-valid-color};
|
||||
--#{$prefix}form-valid-border-color: #{$form-valid-border-color};
|
||||
--#{$prefix}form-invalid-color: #{$form-invalid-color};
|
||||
--#{$prefix}form-invalid-border-color: #{$form-invalid-border-color};
|
||||
// scss-docs-end root-form-validation-variables
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark, true) {
|
||||
color-scheme: dark;
|
||||
|
||||
// scss-docs-start root-dark-mode-vars
|
||||
--#{$prefix}body-color: #{$body-color-dark};
|
||||
--#{$prefix}body-color-rgb: #{to-rgb($body-color-dark)};
|
||||
--#{$prefix}body-bg: #{$body-bg-dark};
|
||||
--#{$prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};
|
||||
|
||||
--#{$prefix}emphasis-color: #{$body-emphasis-color-dark};
|
||||
--#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color-dark)};
|
||||
|
||||
--#{$prefix}secondary-color: #{$body-secondary-color-dark};
|
||||
--#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};
|
||||
--#{$prefix}secondary-bg: #{$body-secondary-bg-dark};
|
||||
--#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};
|
||||
|
||||
--#{$prefix}tertiary-color: #{$body-tertiary-color-dark};
|
||||
--#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};
|
||||
--#{$prefix}tertiary-bg: #{$body-tertiary-bg-dark};
|
||||
--#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};
|
||||
|
||||
@each $color, $value in $theme-colors-text-dark {
|
||||
--#{$prefix}#{$color}-text-emphasis: #{$value};
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors-bg-subtle-dark {
|
||||
--#{$prefix}#{$color}-bg-subtle: #{$value};
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors-border-subtle-dark {
|
||||
--#{$prefix}#{$color}-border-subtle: #{$value};
|
||||
}
|
||||
|
||||
--#{$prefix}heading-color: #{$headings-color-dark};
|
||||
|
||||
--#{$prefix}link-color: #{$link-color-dark};
|
||||
--#{$prefix}link-hover-color: #{$link-hover-color-dark};
|
||||
--#{$prefix}link-color-rgb: #{to-rgb($link-color-dark)};
|
||||
--#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};
|
||||
|
||||
--#{$prefix}code-color: #{$code-color-dark};
|
||||
--#{$prefix}highlight-color: #{$mark-color-dark};
|
||||
--#{$prefix}highlight-bg: #{$mark-bg-dark};
|
||||
|
||||
--#{$prefix}border-color: #{$border-color-dark};
|
||||
--#{$prefix}border-color-translucent: #{$border-color-translucent-dark};
|
||||
|
||||
--#{$prefix}form-valid-color: #{$form-valid-color-dark};
|
||||
--#{$prefix}form-valid-border-color: #{$form-valid-border-color-dark};
|
||||
--#{$prefix}form-invalid-color: #{$form-invalid-color-dark};
|
||||
--#{$prefix}form-invalid-border-color: #{$form-invalid-border-color-dark};
|
||||
// scss-docs-end root-dark-mode-vars
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,17 @@
|
|||
// Rotating border
|
||||
//
|
||||
|
||||
.spinner-grow,
|
||||
.spinner-border {
|
||||
display: inline-block;
|
||||
width: var(--#{$prefix}spinner-width);
|
||||
height: var(--#{$prefix}spinner-height);
|
||||
vertical-align: var(--#{$prefix}spinner-vertical-align);
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: 50%;
|
||||
animation: var(--#{$prefix}spinner-animation-speed) linear infinite var(--#{$prefix}spinner-animation-name);
|
||||
}
|
||||
|
||||
// scss-docs-start spinner-border-keyframes
|
||||
@keyframes spinner-border {
|
||||
to { transform: rotate(360deg) #{"/* rtl:ignore */"}; }
|
||||
|
|
@ -9,21 +20,25 @@
|
|||
// scss-docs-end spinner-border-keyframes
|
||||
|
||||
.spinner-border {
|
||||
display: inline-block;
|
||||
width: $spinner-width;
|
||||
height: $spinner-height;
|
||||
vertical-align: $spinner-vertical-align;
|
||||
border: $spinner-border-width solid currentColor;
|
||||
// scss-docs-start spinner-border-css-vars
|
||||
--#{$prefix}spinner-width: #{$spinner-width};
|
||||
--#{$prefix}spinner-height: #{$spinner-height};
|
||||
--#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
|
||||
--#{$prefix}spinner-border-width: #{$spinner-border-width};
|
||||
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
|
||||
--#{$prefix}spinner-animation-name: spinner-border;
|
||||
// scss-docs-end spinner-border-css-vars
|
||||
|
||||
border: var(--#{$prefix}spinner-border-width) solid currentcolor;
|
||||
border-right-color: transparent;
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: 50%;
|
||||
animation: $spinner-animation-speed linear infinite spinner-border;
|
||||
}
|
||||
|
||||
.spinner-border-sm {
|
||||
width: $spinner-width-sm;
|
||||
height: $spinner-height-sm;
|
||||
border-width: $spinner-border-width-sm;
|
||||
// scss-docs-start spinner-border-sm-css-vars
|
||||
--#{$prefix}spinner-width: #{$spinner-width-sm};
|
||||
--#{$prefix}spinner-height: #{$spinner-height-sm};
|
||||
--#{$prefix}spinner-border-width: #{$spinner-border-width-sm};
|
||||
// scss-docs-end spinner-border-sm-css-vars
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -43,27 +58,28 @@
|
|||
// scss-docs-end spinner-grow-keyframes
|
||||
|
||||
.spinner-grow {
|
||||
display: inline-block;
|
||||
width: $spinner-width;
|
||||
height: $spinner-height;
|
||||
vertical-align: $spinner-vertical-align;
|
||||
background-color: currentColor;
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: 50%;
|
||||
// scss-docs-start spinner-grow-css-vars
|
||||
--#{$prefix}spinner-width: #{$spinner-width};
|
||||
--#{$prefix}spinner-height: #{$spinner-height};
|
||||
--#{$prefix}spinner-vertical-align: #{$spinner-vertical-align};
|
||||
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed};
|
||||
--#{$prefix}spinner-animation-name: spinner-grow;
|
||||
// scss-docs-end spinner-grow-css-vars
|
||||
|
||||
background-color: currentcolor;
|
||||
opacity: 0;
|
||||
animation: $spinner-animation-speed linear infinite spinner-grow;
|
||||
}
|
||||
|
||||
.spinner-grow-sm {
|
||||
width: $spinner-width-sm;
|
||||
height: $spinner-height-sm;
|
||||
--#{$prefix}spinner-width: #{$spinner-width-sm};
|
||||
--#{$prefix}spinner-height: #{$spinner-height-sm};
|
||||
}
|
||||
|
||||
@if $enable-reduced-motion {
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.spinner-border,
|
||||
.spinner-grow {
|
||||
animation-duration: $spinner-animation-speed * 2;
|
||||
--#{$prefix}spinner-animation-speed: #{$spinner-animation-speed * 2};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,20 +3,27 @@
|
|||
//
|
||||
|
||||
.table {
|
||||
--#{$variable-prefix}table-bg: #{$table-bg};
|
||||
--#{$variable-prefix}table-accent-bg: #{$table-accent-bg};
|
||||
--#{$variable-prefix}table-striped-color: #{$table-striped-color};
|
||||
--#{$variable-prefix}table-striped-bg: #{$table-striped-bg};
|
||||
--#{$variable-prefix}table-active-color: #{$table-active-color};
|
||||
--#{$variable-prefix}table-active-bg: #{$table-active-bg};
|
||||
--#{$variable-prefix}table-hover-color: #{$table-hover-color};
|
||||
--#{$variable-prefix}table-hover-bg: #{$table-hover-bg};
|
||||
// Reset needed for nesting tables
|
||||
--#{$prefix}table-color-type: initial;
|
||||
--#{$prefix}table-bg-type: initial;
|
||||
--#{$prefix}table-color-state: initial;
|
||||
--#{$prefix}table-bg-state: initial;
|
||||
// End of reset
|
||||
--#{$prefix}table-color: #{$table-color};
|
||||
--#{$prefix}table-bg: #{$table-bg};
|
||||
--#{$prefix}table-border-color: #{$table-border-color};
|
||||
--#{$prefix}table-accent-bg: #{$table-accent-bg};
|
||||
--#{$prefix}table-striped-color: #{$table-striped-color};
|
||||
--#{$prefix}table-striped-bg: #{$table-striped-bg};
|
||||
--#{$prefix}table-active-color: #{$table-active-color};
|
||||
--#{$prefix}table-active-bg: #{$table-active-bg};
|
||||
--#{$prefix}table-hover-color: #{$table-hover-color};
|
||||
--#{$prefix}table-hover-bg: #{$table-hover-bg};
|
||||
|
||||
width: 100%;
|
||||
margin-bottom: $spacer;
|
||||
color: $table-color;
|
||||
vertical-align: $table-cell-vertical-align;
|
||||
border-color: $table-border-color;
|
||||
border-color: var(--#{$prefix}table-border-color);
|
||||
|
||||
// Target th & td
|
||||
// We need the child combinator to prevent styles leaking to nested tables which doesn't have a `.table` class.
|
||||
|
|
@ -25,9 +32,11 @@
|
|||
// stylelint-disable-next-line selector-max-universal
|
||||
> :not(caption) > * > * {
|
||||
padding: $table-cell-padding-y $table-cell-padding-x;
|
||||
background-color: var(--#{$variable-prefix}table-bg);
|
||||
// Following the precept of cascades: https://codepen.io/miriamsuzanne/full/vYNgodb
|
||||
color: var(--#{$prefix}table-color-state, var(--#{$prefix}table-color-type, var(--#{$prefix}table-color)));
|
||||
background-color: var(--#{$prefix}table-bg);
|
||||
border-bottom-width: $table-border-width;
|
||||
box-shadow: inset 0 0 0 9999px var(--#{$variable-prefix}table-accent-bg);
|
||||
box-shadow: inset 0 0 0 9999px var(--#{$prefix}table-bg-state, var(--#{$prefix}table-bg-type, var(--#{$prefix}table-accent-bg)));
|
||||
}
|
||||
|
||||
> tbody {
|
||||
|
|
@ -37,13 +46,11 @@
|
|||
> thead {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
// Highlight border color between thead, tbody and tfoot.
|
||||
> :not(:first-child) {
|
||||
border-top: (2 * $table-border-width) solid $table-group-separator-color;
|
||||
}
|
||||
}
|
||||
|
||||
.table-group-divider {
|
||||
border-top: calc(#{$table-border-width} * 2) solid $table-group-separator-color; // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
//
|
||||
// Change placement of captions with a class
|
||||
|
|
@ -72,7 +79,7 @@
|
|||
//
|
||||
// When borders are added on all sides of the cells, the corners can render odd when
|
||||
// these borders do not have the same color or if they are semi-transparent.
|
||||
// Therefor we add top and border bottoms to the `tr`s and left and right borders
|
||||
// Therefore we add top and border bottoms to the `tr`s and left and right borders
|
||||
// to the `td`s or `th`s
|
||||
|
||||
.table-bordered {
|
||||
|
|
@ -101,10 +108,19 @@
|
|||
//
|
||||
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
|
||||
|
||||
// For rows
|
||||
.table-striped {
|
||||
> tbody > tr:nth-of-type(#{$table-striped-order}) > * {
|
||||
--#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-striped-bg);
|
||||
color: var(--#{$variable-prefix}table-striped-color);
|
||||
--#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
|
||||
--#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
|
||||
}
|
||||
}
|
||||
|
||||
// For columns
|
||||
.table-striped-columns {
|
||||
> :not(caption) > tr > :nth-child(#{$table-striped-columns-order}) {
|
||||
--#{$prefix}table-color-type: var(--#{$prefix}table-striped-color);
|
||||
--#{$prefix}table-bg-type: var(--#{$prefix}table-striped-bg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -113,8 +129,8 @@
|
|||
// The `.table-active` class can be added to highlight rows or cells
|
||||
|
||||
.table-active {
|
||||
--#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-active-bg);
|
||||
color: var(--#{$variable-prefix}table-active-color);
|
||||
--#{$prefix}table-color-state: var(--#{$prefix}table-active-color);
|
||||
--#{$prefix}table-bg-state: var(--#{$prefix}table-active-bg);
|
||||
}
|
||||
|
||||
// Hover effect
|
||||
|
|
@ -123,8 +139,8 @@
|
|||
|
||||
.table-hover {
|
||||
> tbody > tr:hover > * {
|
||||
--#{$variable-prefix}table-accent-bg: var(--#{$variable-prefix}table-hover-bg);
|
||||
color: var(--#{$variable-prefix}table-hover-color);
|
||||
--#{$prefix}table-color-state: var(--#{$prefix}table-hover-color);
|
||||
--#{$prefix}table-bg-state: var(--#{$prefix}table-hover-bg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,32 @@
|
|||
.toast {
|
||||
width: $toast-max-width;
|
||||
// scss-docs-start toast-css-vars
|
||||
--#{$prefix}toast-zindex: #{$zindex-toast};
|
||||
--#{$prefix}toast-padding-x: #{$toast-padding-x};
|
||||
--#{$prefix}toast-padding-y: #{$toast-padding-y};
|
||||
--#{$prefix}toast-spacing: #{$toast-spacing};
|
||||
--#{$prefix}toast-max-width: #{$toast-max-width};
|
||||
@include rfs($toast-font-size, --#{$prefix}toast-font-size);
|
||||
--#{$prefix}toast-color: #{$toast-color};
|
||||
--#{$prefix}toast-bg: #{$toast-background-color};
|
||||
--#{$prefix}toast-border-width: #{$toast-border-width};
|
||||
--#{$prefix}toast-border-color: #{$toast-border-color};
|
||||
--#{$prefix}toast-border-radius: #{$toast-border-radius};
|
||||
--#{$prefix}toast-box-shadow: #{$toast-box-shadow};
|
||||
--#{$prefix}toast-header-color: #{$toast-header-color};
|
||||
--#{$prefix}toast-header-bg: #{$toast-header-background-color};
|
||||
--#{$prefix}toast-header-border-color: #{$toast-header-border-color};
|
||||
// scss-docs-end toast-css-vars
|
||||
|
||||
width: var(--#{$prefix}toast-max-width);
|
||||
max-width: 100%;
|
||||
@include font-size($toast-font-size);
|
||||
color: $toast-color;
|
||||
@include font-size(var(--#{$prefix}toast-font-size));
|
||||
color: var(--#{$prefix}toast-color);
|
||||
pointer-events: auto;
|
||||
background-color: $toast-background-color;
|
||||
background-color: var(--#{$prefix}toast-bg);
|
||||
background-clip: padding-box;
|
||||
border: $toast-border-width solid $toast-border-color;
|
||||
box-shadow: $toast-box-shadow;
|
||||
@include border-radius($toast-border-radius);
|
||||
border: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-border-color);
|
||||
box-shadow: var(--#{$prefix}toast-box-shadow);
|
||||
@include border-radius(var(--#{$prefix}toast-border-radius));
|
||||
|
||||
&.showing {
|
||||
opacity: 0;
|
||||
|
|
@ -20,32 +38,36 @@
|
|||
}
|
||||
|
||||
.toast-container {
|
||||
--#{$prefix}toast-zindex: #{$zindex-toast};
|
||||
|
||||
position: absolute;
|
||||
z-index: var(--#{$prefix}toast-zindex);
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
> :not(:last-child) {
|
||||
margin-bottom: $toast-spacing;
|
||||
margin-bottom: var(--#{$prefix}toast-spacing);
|
||||
}
|
||||
}
|
||||
|
||||
.toast-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $toast-padding-y $toast-padding-x;
|
||||
color: $toast-header-color;
|
||||
background-color: $toast-header-background-color;
|
||||
padding: var(--#{$prefix}toast-padding-y) var(--#{$prefix}toast-padding-x);
|
||||
color: var(--#{$prefix}toast-header-color);
|
||||
background-color: var(--#{$prefix}toast-header-bg);
|
||||
background-clip: padding-box;
|
||||
border-bottom: $toast-border-width solid $toast-header-border-color;
|
||||
@include border-top-radius(subtract($toast-border-radius, $toast-border-width));
|
||||
border-bottom: var(--#{$prefix}toast-border-width) solid var(--#{$prefix}toast-header-border-color);
|
||||
@include border-top-radius(calc(var(--#{$prefix}toast-border-radius) - var(--#{$prefix}toast-border-width)));
|
||||
|
||||
.btn-close {
|
||||
margin-right: $toast-padding-x * -.5;
|
||||
margin-left: $toast-padding-x;
|
||||
margin-right: calc(-.5 * var(--#{$prefix}toast-padding-x)); // stylelint-disable-line function-disallowed-list
|
||||
margin-left: var(--#{$prefix}toast-padding-x);
|
||||
}
|
||||
}
|
||||
|
||||
.toast-body {
|
||||
padding: $toast-padding-x; // apply to both vertical and horizontal
|
||||
padding: var(--#{$prefix}toast-padding-x);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,38 @@
|
|||
// Base class
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
z-index: $zindex-tooltip;
|
||||
// scss-docs-start tooltip-css-vars
|
||||
--#{$prefix}tooltip-zindex: #{$zindex-tooltip};
|
||||
--#{$prefix}tooltip-max-width: #{$tooltip-max-width};
|
||||
--#{$prefix}tooltip-padding-x: #{$tooltip-padding-x};
|
||||
--#{$prefix}tooltip-padding-y: #{$tooltip-padding-y};
|
||||
--#{$prefix}tooltip-margin: #{$tooltip-margin};
|
||||
@include rfs($tooltip-font-size, --#{$prefix}tooltip-font-size);
|
||||
--#{$prefix}tooltip-color: #{$tooltip-color};
|
||||
--#{$prefix}tooltip-bg: #{$tooltip-bg};
|
||||
--#{$prefix}tooltip-border-radius: #{$tooltip-border-radius};
|
||||
--#{$prefix}tooltip-opacity: #{$tooltip-opacity};
|
||||
--#{$prefix}tooltip-arrow-width: #{$tooltip-arrow-width};
|
||||
--#{$prefix}tooltip-arrow-height: #{$tooltip-arrow-height};
|
||||
// scss-docs-end tooltip-css-vars
|
||||
|
||||
z-index: var(--#{$prefix}tooltip-zindex);
|
||||
display: block;
|
||||
margin: $tooltip-margin;
|
||||
margin: var(--#{$prefix}tooltip-margin);
|
||||
@include deprecate("`$tooltip-margin`", "v5", "v5.x", true);
|
||||
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
|
||||
// So reset our font and text properties to avoid inheriting weird values.
|
||||
@include reset-text();
|
||||
@include font-size($tooltip-font-size);
|
||||
@include font-size(var(--#{$prefix}tooltip-font-size));
|
||||
// Allow breaking very long words so they don't overflow the tooltip's bounds
|
||||
word-wrap: break-word;
|
||||
opacity: 0;
|
||||
|
||||
&.show { opacity: $tooltip-opacity; }
|
||||
&.show { opacity: var(--#{$prefix}tooltip-opacity); }
|
||||
|
||||
.tooltip-arrow {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: $tooltip-arrow-width;
|
||||
height: $tooltip-arrow-height;
|
||||
width: var(--#{$prefix}tooltip-arrow-width);
|
||||
height: var(--#{$prefix}tooltip-arrow-height);
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
|
|
@ -29,66 +43,56 @@
|
|||
}
|
||||
}
|
||||
|
||||
.bs-tooltip-top {
|
||||
padding: $tooltip-arrow-height 0;
|
||||
.bs-tooltip-top .tooltip-arrow {
|
||||
bottom: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
|
||||
|
||||
.tooltip-arrow {
|
||||
bottom: 0;
|
||||
|
||||
&::before {
|
||||
top: -1px;
|
||||
border-width: $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;
|
||||
border-top-color: $tooltip-arrow-color;
|
||||
}
|
||||
&::before {
|
||||
top: -1px;
|
||||
border-width: var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
|
||||
border-top-color: var(--#{$prefix}tooltip-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.bs-tooltip-end {
|
||||
padding: 0 $tooltip-arrow-height;
|
||||
/* rtl:begin:ignore */
|
||||
.bs-tooltip-end .tooltip-arrow {
|
||||
left: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
|
||||
width: var(--#{$prefix}tooltip-arrow-height);
|
||||
height: var(--#{$prefix}tooltip-arrow-width);
|
||||
|
||||
.tooltip-arrow {
|
||||
left: 0;
|
||||
width: $tooltip-arrow-height;
|
||||
height: $tooltip-arrow-width;
|
||||
|
||||
&::before {
|
||||
right: -1px;
|
||||
border-width: ($tooltip-arrow-width * .5) $tooltip-arrow-height ($tooltip-arrow-width * .5) 0;
|
||||
border-right-color: $tooltip-arrow-color;
|
||||
}
|
||||
&::before {
|
||||
right: -1px;
|
||||
border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height) calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0; // stylelint-disable-line function-disallowed-list
|
||||
border-right-color: var(--#{$prefix}tooltip-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.bs-tooltip-bottom {
|
||||
padding: $tooltip-arrow-height 0;
|
||||
/* rtl:end:ignore */
|
||||
|
||||
.tooltip-arrow {
|
||||
top: 0;
|
||||
.bs-tooltip-bottom .tooltip-arrow {
|
||||
top: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
|
||||
|
||||
&::before {
|
||||
bottom: -1px;
|
||||
border-width: 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;
|
||||
border-bottom-color: $tooltip-arrow-color;
|
||||
}
|
||||
&::before {
|
||||
bottom: -1px;
|
||||
border-width: 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
|
||||
border-bottom-color: var(--#{$prefix}tooltip-bg);
|
||||
}
|
||||
}
|
||||
|
||||
.bs-tooltip-start {
|
||||
padding: 0 $tooltip-arrow-height;
|
||||
/* rtl:begin:ignore */
|
||||
.bs-tooltip-start .tooltip-arrow {
|
||||
right: calc(-1 * var(--#{$prefix}tooltip-arrow-height)); // stylelint-disable-line function-disallowed-list
|
||||
width: var(--#{$prefix}tooltip-arrow-height);
|
||||
height: var(--#{$prefix}tooltip-arrow-width);
|
||||
|
||||
.tooltip-arrow {
|
||||
right: 0;
|
||||
width: $tooltip-arrow-height;
|
||||
height: $tooltip-arrow-width;
|
||||
|
||||
&::before {
|
||||
left: -1px;
|
||||
border-width: ($tooltip-arrow-width * .5) 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height;
|
||||
border-left-color: $tooltip-arrow-color;
|
||||
}
|
||||
&::before {
|
||||
left: -1px;
|
||||
border-width: calc(var(--#{$prefix}tooltip-arrow-width) * .5) 0 calc(var(--#{$prefix}tooltip-arrow-width) * .5) var(--#{$prefix}tooltip-arrow-height); // stylelint-disable-line function-disallowed-list
|
||||
border-left-color: var(--#{$prefix}tooltip-bg);
|
||||
}
|
||||
}
|
||||
|
||||
/* rtl:end:ignore */
|
||||
|
||||
.bs-tooltip-auto {
|
||||
&[data-popper-placement^="top"] {
|
||||
@extend .bs-tooltip-top;
|
||||
|
|
@ -106,10 +110,10 @@
|
|||
|
||||
// Wrapper for the tooltip content
|
||||
.tooltip-inner {
|
||||
max-width: $tooltip-max-width;
|
||||
padding: $tooltip-padding-y $tooltip-padding-x;
|
||||
color: $tooltip-color;
|
||||
max-width: var(--#{$prefix}tooltip-max-width);
|
||||
padding: var(--#{$prefix}tooltip-padding-y) var(--#{$prefix}tooltip-padding-x);
|
||||
color: var(--#{$prefix}tooltip-color);
|
||||
text-align: center;
|
||||
background-color: $tooltip-bg;
|
||||
@include border-radius($tooltip-border-radius);
|
||||
background-color: var(--#{$prefix}tooltip-bg);
|
||||
@include border-radius(var(--#{$prefix}tooltip-border-radius));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
@each $display, $font-size in $display-font-sizes {
|
||||
.display-#{$display} {
|
||||
@include font-size($font-size);
|
||||
font-family: $display-font-family;
|
||||
font-style: $display-font-style;
|
||||
font-weight: $display-font-weight;
|
||||
line-height: $display-line-height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
// stylelint-disable indentation
|
||||
|
||||
// Utilities
|
||||
|
||||
$utilities: () !default;
|
||||
|
|
@ -24,6 +22,20 @@ $utilities: map-merge(
|
|||
)
|
||||
),
|
||||
// scss-docs-end utils-float
|
||||
// Object Fit utilities
|
||||
// scss-docs-start utils-object-fit
|
||||
"object-fit": (
|
||||
responsive: true,
|
||||
property: object-fit,
|
||||
values: (
|
||||
contain: contain,
|
||||
cover: cover,
|
||||
fill: fill,
|
||||
scale: scale-down,
|
||||
none: none,
|
||||
)
|
||||
),
|
||||
// scss-docs-end utils-object-fit
|
||||
// Opacity utilities
|
||||
// scss-docs-start utils-opacity
|
||||
"opacity": (
|
||||
|
|
@ -42,6 +54,14 @@ $utilities: map-merge(
|
|||
property: overflow,
|
||||
values: auto hidden visible scroll,
|
||||
),
|
||||
"overflow-x": (
|
||||
property: overflow-x,
|
||||
values: auto hidden visible scroll,
|
||||
),
|
||||
"overflow-y": (
|
||||
property: overflow-y,
|
||||
values: auto hidden visible scroll,
|
||||
),
|
||||
// scss-docs-end utils-overflow
|
||||
// scss-docs-start utils-display
|
||||
"display": (
|
||||
|
|
@ -49,7 +69,7 @@ $utilities: map-merge(
|
|||
print: true,
|
||||
property: display,
|
||||
class: d,
|
||||
values: inline inline-block block grid table table-row table-cell flex inline-flex none
|
||||
values: inline inline-block block grid inline-grid table table-row table-cell flex inline-flex none
|
||||
),
|
||||
// scss-docs-end utils-display
|
||||
// scss-docs-start utils-shadow
|
||||
|
|
@ -57,13 +77,21 @@ $utilities: map-merge(
|
|||
property: box-shadow,
|
||||
class: shadow,
|
||||
values: (
|
||||
null: $box-shadow,
|
||||
sm: $box-shadow-sm,
|
||||
lg: $box-shadow-lg,
|
||||
null: var(--#{$prefix}box-shadow),
|
||||
sm: var(--#{$prefix}box-shadow-sm),
|
||||
lg: var(--#{$prefix}box-shadow-lg),
|
||||
none: none,
|
||||
)
|
||||
),
|
||||
// scss-docs-end utils-shadow
|
||||
// scss-docs-start utils-focus-ring
|
||||
"focus-ring": (
|
||||
css-var: true,
|
||||
css-variable-name: focus-ring-color,
|
||||
class: focus-ring,
|
||||
values: map-loop($theme-colors-rgb, rgba-css-var, "$key", "focus-ring")
|
||||
),
|
||||
// scss-docs-end utils-focus-ring
|
||||
// scss-docs-start utils-position
|
||||
"position": (
|
||||
property: position,
|
||||
|
|
@ -101,14 +129,14 @@ $utilities: map-merge(
|
|||
"border": (
|
||||
property: border,
|
||||
values: (
|
||||
null: $border-width solid $border-color,
|
||||
null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
|
||||
0: 0,
|
||||
)
|
||||
),
|
||||
"border-top": (
|
||||
property: border-top,
|
||||
values: (
|
||||
null: $border-width solid $border-color,
|
||||
null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
|
||||
0: 0,
|
||||
)
|
||||
),
|
||||
|
|
@ -116,14 +144,14 @@ $utilities: map-merge(
|
|||
property: border-right,
|
||||
class: border-end,
|
||||
values: (
|
||||
null: $border-width solid $border-color,
|
||||
null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
|
||||
0: 0,
|
||||
)
|
||||
),
|
||||
"border-bottom": (
|
||||
property: border-bottom,
|
||||
values: (
|
||||
null: $border-width solid $border-color,
|
||||
null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
|
||||
0: 0,
|
||||
)
|
||||
),
|
||||
|
|
@ -131,20 +159,39 @@ $utilities: map-merge(
|
|||
property: border-left,
|
||||
class: border-start,
|
||||
values: (
|
||||
null: $border-width solid $border-color,
|
||||
null: var(--#{$prefix}border-width) var(--#{$prefix}border-style) var(--#{$prefix}border-color),
|
||||
0: 0,
|
||||
)
|
||||
),
|
||||
"border-color": (
|
||||
property: border-color,
|
||||
class: border,
|
||||
values: map-merge($theme-colors, ("white": $white))
|
||||
local-vars: (
|
||||
"border-opacity": 1
|
||||
),
|
||||
values: $utilities-border-colors
|
||||
),
|
||||
"subtle-border-color": (
|
||||
property: border-color,
|
||||
class: border,
|
||||
values: $utilities-border-subtle
|
||||
),
|
||||
"border-width": (
|
||||
property: border-width,
|
||||
class: border,
|
||||
values: $border-widths
|
||||
),
|
||||
"border-opacity": (
|
||||
css-var: true,
|
||||
class: border-opacity,
|
||||
values: (
|
||||
10: .1,
|
||||
25: .25,
|
||||
50: .5,
|
||||
75: .75,
|
||||
100: 1
|
||||
)
|
||||
),
|
||||
// scss-docs-end utils-borders
|
||||
// Sizing utilities
|
||||
// scss-docs-start utils-sizing
|
||||
|
|
@ -238,12 +285,6 @@ $utilities: map-merge(
|
|||
class: flex,
|
||||
values: wrap nowrap wrap-reverse
|
||||
),
|
||||
"gap": (
|
||||
responsive: true,
|
||||
property: gap,
|
||||
class: gap,
|
||||
values: $spacers
|
||||
),
|
||||
"justify-content": (
|
||||
responsive: true,
|
||||
property: justify-content,
|
||||
|
|
@ -436,13 +477,32 @@ $utilities: map-merge(
|
|||
class: ps,
|
||||
values: $spacers
|
||||
),
|
||||
// Gap utility
|
||||
"gap": (
|
||||
responsive: true,
|
||||
property: gap,
|
||||
class: gap,
|
||||
values: $spacers
|
||||
),
|
||||
"row-gap": (
|
||||
responsive: true,
|
||||
property: row-gap,
|
||||
class: row-gap,
|
||||
values: $spacers
|
||||
),
|
||||
"column-gap": (
|
||||
responsive: true,
|
||||
property: column-gap,
|
||||
class: column-gap,
|
||||
values: $spacers
|
||||
),
|
||||
// scss-docs-end utils-spacing
|
||||
// Text
|
||||
// scss-docs-start utils-text
|
||||
"font-family": (
|
||||
property: font-family,
|
||||
class: font,
|
||||
values: (monospace: var(--#{$variable-prefix}font-monospace))
|
||||
values: (monospace: var(--#{$prefix}font-monospace))
|
||||
),
|
||||
"font-size": (
|
||||
rfs: true,
|
||||
|
|
@ -459,9 +519,11 @@ $utilities: map-merge(
|
|||
property: font-weight,
|
||||
class: fw,
|
||||
values: (
|
||||
light: $font-weight-light,
|
||||
lighter: $font-weight-lighter,
|
||||
light: $font-weight-light,
|
||||
normal: $font-weight-normal,
|
||||
medium: $font-weight-medium,
|
||||
semibold: $font-weight-semibold,
|
||||
bold: $font-weight-bold,
|
||||
bolder: $font-weight-bolder
|
||||
)
|
||||
|
|
@ -520,9 +582,12 @@ $utilities: map-merge(
|
|||
values: map-merge(
|
||||
$utilities-text-colors,
|
||||
(
|
||||
"muted": $text-muted,
|
||||
"muted": var(--#{$prefix}secondary-color), // deprecated
|
||||
"black-50": rgba($black, .5), // deprecated
|
||||
"white-50": rgba($white, .5), // deprecated
|
||||
"body-secondary": var(--#{$prefix}secondary-color),
|
||||
"body-tertiary": var(--#{$prefix}tertiary-color),
|
||||
"body-emphasis": var(--#{$prefix}emphasis-color),
|
||||
"reset": inherit,
|
||||
)
|
||||
)
|
||||
|
|
@ -537,7 +602,62 @@ $utilities: map-merge(
|
|||
100: 1
|
||||
)
|
||||
),
|
||||
"text-color": (
|
||||
property: color,
|
||||
class: text,
|
||||
values: $utilities-text-emphasis-colors
|
||||
),
|
||||
// scss-docs-end utils-color
|
||||
// scss-docs-start utils-links
|
||||
"link-opacity": (
|
||||
css-var: true,
|
||||
class: link-opacity,
|
||||
state: hover,
|
||||
values: (
|
||||
10: .1,
|
||||
25: .25,
|
||||
50: .5,
|
||||
75: .75,
|
||||
100: 1
|
||||
)
|
||||
),
|
||||
"link-offset": (
|
||||
property: text-underline-offset,
|
||||
class: link-offset,
|
||||
state: hover,
|
||||
values: (
|
||||
1: .125em,
|
||||
2: .25em,
|
||||
3: .375em,
|
||||
)
|
||||
),
|
||||
"link-underline": (
|
||||
property: text-decoration-color,
|
||||
class: link-underline,
|
||||
local-vars: (
|
||||
"link-underline-opacity": 1
|
||||
),
|
||||
values: map-merge(
|
||||
$utilities-links-underline,
|
||||
(
|
||||
null: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-underline-opacity, 1)),
|
||||
)
|
||||
)
|
||||
),
|
||||
"link-underline-opacity": (
|
||||
css-var: true,
|
||||
class: link-underline-opacity,
|
||||
state: hover,
|
||||
values: (
|
||||
0: 0,
|
||||
10: .1,
|
||||
25: .25,
|
||||
50: .5,
|
||||
75: .75,
|
||||
100: 1
|
||||
),
|
||||
),
|
||||
// scss-docs-end utils-links
|
||||
// scss-docs-start utils-bg-color
|
||||
"background-color": (
|
||||
property: background-color,
|
||||
|
|
@ -548,7 +668,9 @@ $utilities: map-merge(
|
|||
values: map-merge(
|
||||
$utilities-bg-colors,
|
||||
(
|
||||
"transparent": transparent
|
||||
"transparent": transparent,
|
||||
"body-secondary": rgba(var(--#{$prefix}secondary-bg-rgb), var(--#{$prefix}bg-opacity)),
|
||||
"body-tertiary": rgba(var(--#{$prefix}tertiary-bg-rgb), var(--#{$prefix}bg-opacity)),
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
@ -563,11 +685,16 @@ $utilities: map-merge(
|
|||
100: 1
|
||||
)
|
||||
),
|
||||
"subtle-background-color": (
|
||||
property: background-color,
|
||||
class: bg,
|
||||
values: $utilities-bg-subtle
|
||||
),
|
||||
// scss-docs-end utils-bg-color
|
||||
"gradient": (
|
||||
property: background-image,
|
||||
class: bg,
|
||||
values: (gradient: var(--#{$variable-prefix}gradient))
|
||||
values: (gradient: var(--#{$prefix}gradient))
|
||||
),
|
||||
// scss-docs-start utils-interaction
|
||||
"user-select": (
|
||||
|
|
@ -585,34 +712,76 @@ $utilities: map-merge(
|
|||
property: border-radius,
|
||||
class: rounded,
|
||||
values: (
|
||||
null: $border-radius,
|
||||
null: var(--#{$prefix}border-radius),
|
||||
0: 0,
|
||||
1: $border-radius-sm,
|
||||
2: $border-radius,
|
||||
3: $border-radius-lg,
|
||||
1: var(--#{$prefix}border-radius-sm),
|
||||
2: var(--#{$prefix}border-radius),
|
||||
3: var(--#{$prefix}border-radius-lg),
|
||||
4: var(--#{$prefix}border-radius-xl),
|
||||
5: var(--#{$prefix}border-radius-xxl),
|
||||
circle: 50%,
|
||||
pill: $border-radius-pill
|
||||
pill: var(--#{$prefix}border-radius-pill)
|
||||
)
|
||||
),
|
||||
"rounded-top": (
|
||||
property: border-top-left-radius border-top-right-radius,
|
||||
class: rounded-top,
|
||||
values: (null: $border-radius)
|
||||
values: (
|
||||
null: var(--#{$prefix}border-radius),
|
||||
0: 0,
|
||||
1: var(--#{$prefix}border-radius-sm),
|
||||
2: var(--#{$prefix}border-radius),
|
||||
3: var(--#{$prefix}border-radius-lg),
|
||||
4: var(--#{$prefix}border-radius-xl),
|
||||
5: var(--#{$prefix}border-radius-xxl),
|
||||
circle: 50%,
|
||||
pill: var(--#{$prefix}border-radius-pill)
|
||||
)
|
||||
),
|
||||
"rounded-end": (
|
||||
property: border-top-right-radius border-bottom-right-radius,
|
||||
class: rounded-end,
|
||||
values: (null: $border-radius)
|
||||
values: (
|
||||
null: var(--#{$prefix}border-radius),
|
||||
0: 0,
|
||||
1: var(--#{$prefix}border-radius-sm),
|
||||
2: var(--#{$prefix}border-radius),
|
||||
3: var(--#{$prefix}border-radius-lg),
|
||||
4: var(--#{$prefix}border-radius-xl),
|
||||
5: var(--#{$prefix}border-radius-xxl),
|
||||
circle: 50%,
|
||||
pill: var(--#{$prefix}border-radius-pill)
|
||||
)
|
||||
),
|
||||
"rounded-bottom": (
|
||||
property: border-bottom-right-radius border-bottom-left-radius,
|
||||
class: rounded-bottom,
|
||||
values: (null: $border-radius)
|
||||
values: (
|
||||
null: var(--#{$prefix}border-radius),
|
||||
0: 0,
|
||||
1: var(--#{$prefix}border-radius-sm),
|
||||
2: var(--#{$prefix}border-radius),
|
||||
3: var(--#{$prefix}border-radius-lg),
|
||||
4: var(--#{$prefix}border-radius-xl),
|
||||
5: var(--#{$prefix}border-radius-xxl),
|
||||
circle: 50%,
|
||||
pill: var(--#{$prefix}border-radius-pill)
|
||||
)
|
||||
),
|
||||
"rounded-start": (
|
||||
property: border-bottom-left-radius border-top-left-radius,
|
||||
class: rounded-start,
|
||||
values: (null: $border-radius)
|
||||
values: (
|
||||
null: var(--#{$prefix}border-radius),
|
||||
0: 0,
|
||||
1: var(--#{$prefix}border-radius-sm),
|
||||
2: var(--#{$prefix}border-radius),
|
||||
3: var(--#{$prefix}border-radius-lg),
|
||||
4: var(--#{$prefix}border-radius-xl),
|
||||
5: var(--#{$prefix}border-radius-xxl),
|
||||
circle: 50%,
|
||||
pill: var(--#{$prefix}border-radius-pill)
|
||||
)
|
||||
),
|
||||
// scss-docs-end utils-border-radius
|
||||
// scss-docs-start utils-visibility
|
||||
|
|
@ -623,8 +792,15 @@ $utilities: map-merge(
|
|||
visible: visible,
|
||||
invisible: hidden,
|
||||
)
|
||||
)
|
||||
),
|
||||
// scss-docs-end utils-visibility
|
||||
// scss-docs-start utils-zindex
|
||||
"z-index": (
|
||||
property: z-index,
|
||||
class: z,
|
||||
values: $zindex-levels,
|
||||
)
|
||||
// scss-docs-end utils-zindex
|
||||
),
|
||||
$utilities
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
// Dark color mode variables
|
||||
//
|
||||
// Custom variables for the `[data-bs-theme="dark"]` theme. Use this as a starting point for your own custom color modes by creating a new theme-specific file like `_variables-dark.scss` and adding the variables you need.
|
||||
|
||||
//
|
||||
// Global colors
|
||||
//
|
||||
|
||||
// scss-docs-start sass-dark-mode-vars
|
||||
// scss-docs-start theme-text-dark-variables
|
||||
$primary-text-emphasis-dark: tint-color($primary, 40%) !default;
|
||||
$secondary-text-emphasis-dark: tint-color($secondary, 40%) !default;
|
||||
$success-text-emphasis-dark: tint-color($success, 40%) !default;
|
||||
$info-text-emphasis-dark: tint-color($info, 40%) !default;
|
||||
$warning-text-emphasis-dark: tint-color($warning, 40%) !default;
|
||||
$danger-text-emphasis-dark: tint-color($danger, 40%) !default;
|
||||
$light-text-emphasis-dark: $gray-100 !default;
|
||||
$dark-text-emphasis-dark: $gray-300 !default;
|
||||
// scss-docs-end theme-text-dark-variables
|
||||
|
||||
// scss-docs-start theme-bg-subtle-dark-variables
|
||||
$primary-bg-subtle-dark: shade-color($primary, 80%) !default;
|
||||
$secondary-bg-subtle-dark: shade-color($secondary, 80%) !default;
|
||||
$success-bg-subtle-dark: shade-color($success, 80%) !default;
|
||||
$info-bg-subtle-dark: shade-color($info, 80%) !default;
|
||||
$warning-bg-subtle-dark: shade-color($warning, 80%) !default;
|
||||
$danger-bg-subtle-dark: shade-color($danger, 80%) !default;
|
||||
$light-bg-subtle-dark: $gray-800 !default;
|
||||
$dark-bg-subtle-dark: mix($gray-800, $black) !default;
|
||||
// scss-docs-end theme-bg-subtle-dark-variables
|
||||
|
||||
// scss-docs-start theme-border-subtle-dark-variables
|
||||
$primary-border-subtle-dark: shade-color($primary, 40%) !default;
|
||||
$secondary-border-subtle-dark: shade-color($secondary, 40%) !default;
|
||||
$success-border-subtle-dark: shade-color($success, 40%) !default;
|
||||
$info-border-subtle-dark: shade-color($info, 40%) !default;
|
||||
$warning-border-subtle-dark: shade-color($warning, 40%) !default;
|
||||
$danger-border-subtle-dark: shade-color($danger, 40%) !default;
|
||||
$light-border-subtle-dark: $gray-700 !default;
|
||||
$dark-border-subtle-dark: $gray-800 !default;
|
||||
// scss-docs-end theme-border-subtle-dark-variables
|
||||
|
||||
$body-color-dark: $gray-300 !default;
|
||||
$body-bg-dark: $gray-900 !default;
|
||||
$body-secondary-color-dark: rgba($body-color-dark, .75) !default;
|
||||
$body-secondary-bg-dark: $gray-800 !default;
|
||||
$body-tertiary-color-dark: rgba($body-color-dark, .5) !default;
|
||||
$body-tertiary-bg-dark: mix($gray-800, $gray-900, 50%) !default;
|
||||
$body-emphasis-color-dark: $white !default;
|
||||
$border-color-dark: $gray-700 !default;
|
||||
$border-color-translucent-dark: rgba($white, .15) !default;
|
||||
$headings-color-dark: inherit !default;
|
||||
$link-color-dark: tint-color($primary, 40%) !default;
|
||||
$link-hover-color-dark: shift-color($link-color-dark, -$link-shade-percentage) !default;
|
||||
$code-color-dark: tint-color($code-color, 40%) !default;
|
||||
$mark-color-dark: $body-color-dark !default;
|
||||
$mark-bg-dark: $yellow-800 !default;
|
||||
|
||||
|
||||
//
|
||||
// Forms
|
||||
//
|
||||
|
||||
$form-select-indicator-color-dark: $body-color-dark !default;
|
||||
$form-select-indicator-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#{$form-select-indicator-color-dark}' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/></svg>") !default;
|
||||
|
||||
$form-switch-color-dark: rgba($white, .25) !default;
|
||||
$form-switch-bg-image-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#{$form-switch-color-dark}'/></svg>") !default;
|
||||
|
||||
// scss-docs-start form-validation-colors-dark
|
||||
$form-valid-color-dark: $green-300 !default;
|
||||
$form-valid-border-color-dark: $green-300 !default;
|
||||
$form-invalid-color-dark: $red-300 !default;
|
||||
$form-invalid-border-color-dark: $red-300 !default;
|
||||
// scss-docs-end form-validation-colors-dark
|
||||
|
||||
|
||||
//
|
||||
// Accordion
|
||||
//
|
||||
|
||||
$accordion-icon-color-dark: $primary-text-emphasis-dark !default;
|
||||
$accordion-icon-active-color-dark: $primary-text-emphasis-dark !default;
|
||||
|
||||
$accordion-button-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default;
|
||||
$accordion-button-active-icon-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color-dark}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default;
|
||||
// scss-docs-end sass-dark-mode-vars
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +1,13 @@
|
|||
/*!
|
||||
* Bootstrap Grid v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
@import "mixins/banner";
|
||||
@include bsBanner(Grid);
|
||||
|
||||
$include-column-box-sizing: true !default;
|
||||
|
||||
@import "functions";
|
||||
@import "variables";
|
||||
@import "variables-dark";
|
||||
@import "maps";
|
||||
|
||||
@import "mixins/lists";
|
||||
@import "mixins/breakpoints";
|
||||
@import "mixins/container";
|
||||
@import "mixins/grid";
|
||||
|
|
@ -18,8 +15,6 @@ $include-column-box-sizing: true !default;
|
|||
|
||||
@import "vendor/rfs";
|
||||
|
||||
@import "root";
|
||||
|
||||
@import "containers";
|
||||
@import "grid";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
@import "mixins/banner";
|
||||
@include bsBanner(Reboot);
|
||||
|
||||
@import "functions";
|
||||
@import "variables";
|
||||
@import "variables-dark";
|
||||
@import "maps";
|
||||
@import "mixins";
|
||||
@import "root";
|
||||
@import "reboot";
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
/*!
|
||||
* Bootstrap Utilities v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
@import "mixins/banner";
|
||||
@include bsBanner(Utilities);
|
||||
|
||||
// Configuration
|
||||
@import "functions";
|
||||
@import "variables";
|
||||
@import "variables-dark";
|
||||
@import "maps";
|
||||
@import "mixins";
|
||||
@import "utilities";
|
||||
|
||||
// Layout & components
|
||||
@import "root";
|
||||
|
||||
// Helpers
|
||||
@import "helpers";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
/*!
|
||||
* Bootstrap v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
@import "mixins/banner";
|
||||
@include bsBanner("");
|
||||
|
||||
|
||||
// scss-docs-start import-stack
|
||||
// Configuration
|
||||
@import "functions";
|
||||
@import "variables";
|
||||
@import "variables-dark";
|
||||
@import "maps";
|
||||
@import "mixins";
|
||||
@import "utilities";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@
|
|||
position: relative;
|
||||
|
||||
> .form-control,
|
||||
> .form-control-plaintext,
|
||||
> .form-select {
|
||||
height: $form-floating-height;
|
||||
min-height: $form-floating-height;
|
||||
line-height: $form-floating-line-height;
|
||||
}
|
||||
|
||||
|
|
@ -11,16 +13,21 @@
|
|||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
height: 100%; // allow textareas
|
||||
padding: $form-floating-padding-y $form-floating-padding-x;
|
||||
overflow: hidden;
|
||||
text-align: start;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
border: $input-border-width solid transparent; // Required for aligning label's text with the input as it affects inner box model
|
||||
transform-origin: 0 0;
|
||||
@include transition($form-floating-transition);
|
||||
}
|
||||
|
||||
// stylelint-disable no-duplicate-selectors
|
||||
> .form-control {
|
||||
> .form-control,
|
||||
> .form-control-plaintext {
|
||||
padding: $form-floating-padding-y $form-floating-padding-x;
|
||||
|
||||
&::placeholder {
|
||||
|
|
@ -46,18 +53,43 @@
|
|||
|
||||
> .form-control:focus,
|
||||
> .form-control:not(:placeholder-shown),
|
||||
> .form-control-plaintext,
|
||||
> .form-select {
|
||||
~ label {
|
||||
opacity: $form-floating-label-opacity;
|
||||
color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
|
||||
transform: $form-floating-label-transform;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
inset: $form-floating-padding-y ($form-floating-padding-x * .5);
|
||||
z-index: -1;
|
||||
height: $form-floating-label-height;
|
||||
content: "";
|
||||
background-color: $input-bg;
|
||||
@include border-radius($input-border-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Duplicated because `:-webkit-autofill` invalidates other selectors when grouped
|
||||
> .form-control:-webkit-autofill {
|
||||
~ label {
|
||||
opacity: $form-floating-label-opacity;
|
||||
color: rgba(var(--#{$prefix}body-color-rgb), #{$form-floating-label-opacity});
|
||||
transform: $form-floating-label-transform;
|
||||
}
|
||||
}
|
||||
// stylelint-enable no-duplicate-selectors
|
||||
|
||||
> .form-control-plaintext {
|
||||
~ label {
|
||||
border-width: $input-border-width 0; // Required to properly position label text - as explained above
|
||||
}
|
||||
}
|
||||
|
||||
> :disabled ~ label,
|
||||
> .form-control:disabled ~ label { // Required for `.form-control`s because of specificity
|
||||
color: $form-floating-label-disabled-color;
|
||||
|
||||
&::after {
|
||||
background-color: $input-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,18 +14,34 @@
|
|||
}
|
||||
}
|
||||
|
||||
.form-check-reverse {
|
||||
padding-right: $form-check-padding-start;
|
||||
padding-left: 0;
|
||||
text-align: right;
|
||||
|
||||
.form-check-input {
|
||||
float: right;
|
||||
margin-right: $form-check-padding-start * -1;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
--#{$prefix}form-check-bg: #{$form-check-input-bg};
|
||||
|
||||
flex-shrink: 0;
|
||||
width: $form-check-input-width;
|
||||
height: $form-check-input-width;
|
||||
margin-top: ($line-height-base - $form-check-input-width) * .5; // line-height minus check height
|
||||
vertical-align: top;
|
||||
background-color: $form-check-input-bg;
|
||||
appearance: none;
|
||||
background-color: var(--#{$prefix}form-check-bg);
|
||||
background-image: var(--#{$prefix}form-check-bg-image);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
border: $form-check-input-border;
|
||||
appearance: none;
|
||||
color-adjust: exact; // Keep themed appearance for print
|
||||
print-color-adjust: exact; // Keep themed appearance for print
|
||||
@include transition($form-check-transition);
|
||||
|
||||
&[type="checkbox"] {
|
||||
|
|
@ -53,17 +69,17 @@
|
|||
|
||||
&[type="checkbox"] {
|
||||
@if $enable-gradients {
|
||||
background-image: escape-svg($form-check-input-checked-bg-image), var(--#{$variable-prefix}gradient);
|
||||
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)}, var(--#{$prefix}gradient);
|
||||
} @else {
|
||||
background-image: escape-svg($form-check-input-checked-bg-image);
|
||||
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-checked-bg-image)};
|
||||
}
|
||||
}
|
||||
|
||||
&[type="radio"] {
|
||||
@if $enable-gradients {
|
||||
background-image: escape-svg($form-check-radio-checked-bg-image), var(--#{$variable-prefix}gradient);
|
||||
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)}, var(--#{$prefix}gradient);
|
||||
} @else {
|
||||
background-image: escape-svg($form-check-radio-checked-bg-image);
|
||||
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-radio-checked-bg-image)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -73,9 +89,9 @@
|
|||
border-color: $form-check-input-indeterminate-border-color;
|
||||
|
||||
@if $enable-gradients {
|
||||
background-image: escape-svg($form-check-input-indeterminate-bg-image), var(--#{$variable-prefix}gradient);
|
||||
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)}, var(--#{$prefix}gradient);
|
||||
} @else {
|
||||
background-image: escape-svg($form-check-input-indeterminate-bg-image);
|
||||
--#{$prefix}form-check-bg-image: #{escape-svg($form-check-input-indeterminate-bg-image)};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +106,7 @@
|
|||
&[disabled],
|
||||
&:disabled {
|
||||
~ .form-check-label {
|
||||
cursor: default;
|
||||
opacity: $form-check-label-disabled-opacity;
|
||||
}
|
||||
}
|
||||
|
|
@ -108,27 +125,39 @@
|
|||
padding-left: $form-switch-padding-start;
|
||||
|
||||
.form-check-input {
|
||||
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
|
||||
|
||||
width: $form-switch-width;
|
||||
margin-left: $form-switch-padding-start * -1;
|
||||
background-image: escape-svg($form-switch-bg-image);
|
||||
background-image: var(--#{$prefix}form-switch-bg);
|
||||
background-position: left center;
|
||||
@include border-radius($form-switch-border-radius);
|
||||
@include border-radius($form-switch-border-radius, 0);
|
||||
@include transition($form-switch-transition);
|
||||
|
||||
&:focus {
|
||||
background-image: escape-svg($form-switch-focus-bg-image);
|
||||
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-focus-bg-image)};
|
||||
}
|
||||
|
||||
&:checked {
|
||||
background-position: $form-switch-checked-bg-position;
|
||||
|
||||
@if $enable-gradients {
|
||||
background-image: escape-svg($form-switch-checked-bg-image), var(--#{$variable-prefix}gradient);
|
||||
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)}, var(--#{$prefix}gradient);
|
||||
} @else {
|
||||
background-image: escape-svg($form-switch-checked-bg-image);
|
||||
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.form-check-reverse {
|
||||
padding-right: $form-switch-padding-start;
|
||||
padding-left: 0;
|
||||
|
||||
.form-check-input {
|
||||
margin-right: $form-switch-padding-start * -1;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-inline {
|
||||
|
|
@ -150,3 +179,11 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
.form-switch .form-check-input:not(:checked):not(:focus) {
|
||||
--#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image-dark)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@
|
|||
font-weight: $input-font-weight;
|
||||
line-height: $input-line-height;
|
||||
color: $input-color;
|
||||
appearance: none; // Fix appearance for date inputs in Safari
|
||||
background-color: $input-bg;
|
||||
background-clip: padding-box;
|
||||
border: $input-border-width solid $input-border-color;
|
||||
appearance: none; // Fix appearance for date inputs in Safari
|
||||
|
||||
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
|
||||
@include border-radius($input-border-radius, 0);
|
||||
|
|
@ -44,12 +44,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Add some height to date inputs on iOS
|
||||
// https://github.com/twbs/bootstrap/issues/23307
|
||||
// TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved
|
||||
&::-webkit-date-and-time-value {
|
||||
// On Android Chrome, form-control's "width: 100%" makes the input width too small
|
||||
// Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109
|
||||
//
|
||||
// On iOS Safari, form-control's "appearance: none" + "width: 100%" makes the input width too small
|
||||
// Tested under iOS 16.2 / Safari 16.2
|
||||
min-width: 85px; // Seems to be a good minimum safe width
|
||||
|
||||
// Add some height to date inputs on iOS
|
||||
// https://github.com/twbs/bootstrap/issues/23307
|
||||
// TODO: we can remove this workaround once https://bugs.webkit.org/show_bug.cgi?id=198959 is resolved
|
||||
// Multiply line-height by 1em if it has no unit
|
||||
height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height);
|
||||
|
||||
// Android Chrome type="date" is taller than the other inputs
|
||||
// because of "margin: 1px 24px 1px 4px" inside the shadow DOM
|
||||
// Tested under Android 11 / Chrome 89, Android 12 / Chrome 100, Android 13 / Chrome 109
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// Prevent excessive date input height in Webkit
|
||||
// https://github.com/twbs/bootstrap/issues/34433
|
||||
&::-webkit-datetime-edit {
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
// Placeholder
|
||||
|
|
@ -59,13 +78,13 @@
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
// Disabled and read-only inputs
|
||||
// Disabled inputs
|
||||
//
|
||||
// HTML5 says that controls under a fieldset > legend:first-child won't be
|
||||
// disabled if the fieldset is disabled. Due to implementation difficulty, we
|
||||
// don't honor that edge case; we style them as disabled anyway.
|
||||
&:disabled,
|
||||
&[readonly] {
|
||||
&:disabled {
|
||||
color: $input-disabled-color;
|
||||
background-color: $input-disabled-bg;
|
||||
border-color: $input-disabled-border-color;
|
||||
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
|
||||
|
|
@ -91,25 +110,6 @@
|
|||
&:hover:not(:disabled):not([readonly])::file-selector-button {
|
||||
background-color: $form-file-button-hover-bg;
|
||||
}
|
||||
|
||||
&::-webkit-file-upload-button {
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
margin: (-$input-padding-y) (-$input-padding-x);
|
||||
margin-inline-end: $input-padding-x;
|
||||
color: $form-file-button-color;
|
||||
@include gradient-bg($form-file-button-bg);
|
||||
pointer-events: none;
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
border-inline-end-width: $input-border-width;
|
||||
border-radius: 0; // stylelint-disable-line property-disallowed-list
|
||||
@include transition($btn-transition);
|
||||
}
|
||||
|
||||
&:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {
|
||||
background-color: $form-file-button-hover-bg;
|
||||
}
|
||||
}
|
||||
|
||||
// Readonly controls as plain text
|
||||
|
|
@ -128,6 +128,10 @@
|
|||
border: solid transparent;
|
||||
border-width: $input-border-width 0;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&.form-control-sm,
|
||||
&.form-control-lg {
|
||||
padding-right: 0;
|
||||
|
|
@ -153,12 +157,6 @@
|
|||
margin: (-$input-padding-y-sm) (-$input-padding-x-sm);
|
||||
margin-inline-end: $input-padding-x-sm;
|
||||
}
|
||||
|
||||
&::-webkit-file-upload-button {
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
margin: (-$input-padding-y-sm) (-$input-padding-x-sm);
|
||||
margin-inline-end: $input-padding-x-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.form-control-lg {
|
||||
|
|
@ -172,12 +170,6 @@
|
|||
margin: (-$input-padding-y-lg) (-$input-padding-x-lg);
|
||||
margin-inline-end: $input-padding-x-lg;
|
||||
}
|
||||
|
||||
&::-webkit-file-upload-button {
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
margin: (-$input-padding-y-lg) (-$input-padding-x-lg);
|
||||
margin-inline-end: $input-padding-x-lg;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure textareas don't shrink too much when resized
|
||||
|
|
@ -200,7 +192,7 @@ textarea {
|
|||
|
||||
.form-control-color {
|
||||
width: $form-color-width;
|
||||
height: auto; // Override fixed browser height
|
||||
height: $input-height;
|
||||
padding: $input-padding-y;
|
||||
|
||||
&:not(:disabled):not([readonly]) {
|
||||
|
|
@ -208,12 +200,15 @@ textarea {
|
|||
}
|
||||
|
||||
&::-moz-color-swatch {
|
||||
height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height);
|
||||
border: 0 !important; // stylelint-disable-line declaration-no-important
|
||||
@include border-radius($input-border-radius);
|
||||
}
|
||||
|
||||
&::-webkit-color-swatch {
|
||||
height: if(unit($input-line-height) == "", $input-line-height * 1em, $input-line-height);
|
||||
border: 0 !important; // stylelint-disable-line declaration-no-important
|
||||
@include border-radius($input-border-radius);
|
||||
}
|
||||
|
||||
&.form-control-sm { height: $input-height-sm; }
|
||||
&.form-control-lg { height: $input-height-lg; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
width: 100%;
|
||||
height: add($form-range-thumb-height, $form-range-thumb-focus-box-shadow-width * 2);
|
||||
padding: 0; // Need to reset padding
|
||||
background-color: transparent;
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
|
|
@ -28,12 +28,12 @@
|
|||
width: $form-range-thumb-width;
|
||||
height: $form-range-thumb-height;
|
||||
margin-top: ($form-range-track-height - $form-range-thumb-height) * .5; // Webkit specific
|
||||
appearance: none;
|
||||
@include gradient-bg($form-range-thumb-bg);
|
||||
border: $form-range-thumb-border;
|
||||
@include border-radius($form-range-thumb-border-radius);
|
||||
@include box-shadow($form-range-thumb-box-shadow);
|
||||
@include transition($form-range-thumb-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($form-range-thumb-active-bg);
|
||||
|
|
@ -54,12 +54,12 @@
|
|||
&::-moz-range-thumb {
|
||||
width: $form-range-thumb-width;
|
||||
height: $form-range-thumb-height;
|
||||
appearance: none;
|
||||
@include gradient-bg($form-range-thumb-bg);
|
||||
border: $form-range-thumb-border;
|
||||
@include border-radius($form-range-thumb-border-radius);
|
||||
@include box-shadow($form-range-thumb-box-shadow);
|
||||
@include transition($form-range-thumb-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($form-range-thumb-active-bg);
|
||||
|
|
|
|||
|
|
@ -4,18 +4,19 @@
|
|||
// https://primer.github.io/.
|
||||
|
||||
.form-select {
|
||||
--#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator)};
|
||||
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $form-select-padding-y $form-select-indicator-padding $form-select-padding-y $form-select-padding-x;
|
||||
// stylelint-disable-next-line property-no-vendor-prefix
|
||||
-moz-padding-start: subtract($form-select-padding-x, 3px); // See https://github.com/twbs/bootstrap/issues/32636
|
||||
font-family: $form-select-font-family;
|
||||
@include font-size($form-select-font-size);
|
||||
font-weight: $form-select-font-weight;
|
||||
line-height: $form-select-line-height;
|
||||
color: $form-select-color;
|
||||
appearance: none;
|
||||
background-color: $form-select-bg;
|
||||
background-image: escape-svg($form-select-indicator);
|
||||
background-image: var(--#{$prefix}form-select-bg-img), var(--#{$prefix}form-select-bg-icon, none);
|
||||
background-repeat: no-repeat;
|
||||
background-position: $form-select-bg-position;
|
||||
background-size: $form-select-bg-size;
|
||||
|
|
@ -23,7 +24,6 @@
|
|||
@include border-radius($form-select-border-radius, 0);
|
||||
@include box-shadow($form-select-box-shadow);
|
||||
@include transition($form-select-transition);
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
border-color: $form-select-focus-border-color;
|
||||
|
|
@ -70,3 +70,11 @@
|
|||
@include font-size($form-select-font-size-lg);
|
||||
@include border-radius($form-select-border-radius-lg);
|
||||
}
|
||||
|
||||
@if $enable-dark-mode {
|
||||
@include color-mode(dark) {
|
||||
.form-select {
|
||||
--#{$prefix}form-select-bg-img: #{escape-svg($form-select-indicator-dark)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
width: 100%;
|
||||
|
||||
> .form-control,
|
||||
> .form-select {
|
||||
> .form-select,
|
||||
> .form-floating {
|
||||
position: relative; // For focus state's z-index
|
||||
flex: 1 1 auto;
|
||||
width: 1%;
|
||||
|
|
@ -19,8 +20,9 @@
|
|||
|
||||
// Bring the "active" form control to the top of surrounding elements
|
||||
> .form-control:focus,
|
||||
> .form-select:focus {
|
||||
z-index: 3;
|
||||
> .form-select:focus,
|
||||
> .form-floating:focus-within {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
// Ensure buttons are always above inputs for more visually pleasing borders.
|
||||
|
|
@ -31,7 +33,7 @@
|
|||
z-index: 2;
|
||||
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
z-index: 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -96,15 +98,19 @@
|
|||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
.input-group {
|
||||
&:not(.has-validation) {
|
||||
> :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu),
|
||||
> .dropdown-toggle:nth-last-child(n + 3) {
|
||||
> :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
|
||||
> .dropdown-toggle:nth-last-child(n + 3),
|
||||
> .form-floating:not(:last-child) > .form-control,
|
||||
> .form-floating:not(:last-child) > .form-select {
|
||||
@include border-end-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
&.has-validation {
|
||||
> :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu),
|
||||
> .dropdown-toggle:nth-last-child(n + 4) {
|
||||
> :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
|
||||
> .dropdown-toggle:nth-last-child(n + 4),
|
||||
> .form-floating:nth-last-child(n + 3) > .form-control,
|
||||
> .form-floating:nth-last-child(n + 3) > .form-select {
|
||||
@include border-end-radius(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,7 +121,12 @@
|
|||
}
|
||||
|
||||
> :not(:first-child):not(.dropdown-menu)#{$validation-messages} {
|
||||
margin-left: -$input-border-width;
|
||||
margin-left: calc(#{$input-border-width} * -1); // stylelint-disable-line function-disallowed-list
|
||||
@include border-start-radius(0);
|
||||
}
|
||||
|
||||
> .form-floating:not(:first-child) > .form-control,
|
||||
> .form-floating:not(:first-child) > .form-select {
|
||||
@include border-start-radius(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
|
||||
@each $color, $value in $theme-colors {
|
||||
.text-bg-#{$color} {
|
||||
color: color-contrast($value) if($enable-important-utilities, !important, null);
|
||||
background-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}bg-opacity, 1)) if($enable-important-utilities, !important, null);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,30 @@
|
|||
// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
|
||||
@each $color, $value in $theme-colors {
|
||||
.link-#{$color} {
|
||||
color: $value;
|
||||
color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
|
||||
text-decoration-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
|
||||
|
||||
@if $link-shade-percentage != 0 {
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage));
|
||||
$hover-color: if(color-contrast($value) == $color-contrast-light, shade-color($value, $link-shade-percentage), tint-color($value, $link-shade-percentage));
|
||||
color: RGBA(#{to-rgb($hover-color)}, var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
|
||||
text-decoration-color: RGBA(to-rgb($hover-color), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// One-off special link helper as a bridge until v6
|
||||
.link-body-emphasis {
|
||||
color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, 1)) if($enable-important-utilities, !important, null);
|
||||
text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, 1)) if($enable-important-utilities, !important, null);
|
||||
|
||||
@if $link-shade-percentage != 0 {
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-opacity, .75)) if($enable-important-utilities, !important, null);
|
||||
text-decoration-color: RGBA(var(--#{$prefix}emphasis-color-rgb), var(--#{$prefix}link-underline-opacity, .75)) if($enable-important-utilities, !important, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
.focus-ring:focus {
|
||||
outline: 0;
|
||||
// By default, there is no `--bs-focus-ring-x`, `--bs-focus-ring-y`, or `--bs-focus-ring-blur`, but we provide CSS variables with fallbacks to initial `0` values
|
||||
box-shadow: var(--#{$prefix}focus-ring-x, 0) var(--#{$prefix}focus-ring-y, 0) var(--#{$prefix}focus-ring-blur, 0) var(--#{$prefix}focus-ring-width) var(--#{$prefix}focus-ring-color);
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
.icon-link {
|
||||
display: inline-flex;
|
||||
gap: $icon-link-gap;
|
||||
align-items: center;
|
||||
text-decoration-color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, .5));
|
||||
text-underline-offset: $icon-link-underline-offset;
|
||||
backface-visibility: hidden;
|
||||
|
||||
> .bi {
|
||||
flex-shrink: 0;
|
||||
width: $icon-link-icon-size;
|
||||
height: $icon-link-icon-size;
|
||||
fill: currentcolor;
|
||||
@include transition($icon-link-icon-transition);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-link-hover {
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
> .bi {
|
||||
transform: var(--#{$prefix}icon-link-transform, $icon-link-icon-transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
z-index: $zindex-fixed;
|
||||
}
|
||||
|
||||
// Responsive sticky top
|
||||
// Responsive sticky top and bottom
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
|
@ -26,5 +26,11 @@
|
|||
top: 0;
|
||||
z-index: $zindex-sticky;
|
||||
}
|
||||
|
||||
.sticky#{$infix}-bottom {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
z-index: $zindex-sticky;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
&::before {
|
||||
display: block;
|
||||
padding-top: var(--#{$variable-prefix}aspect-ratio);
|
||||
padding-top: var(--#{$prefix}aspect-ratio);
|
||||
content: "";
|
||||
}
|
||||
|
||||
|
|
@ -21,6 +21,6 @@
|
|||
|
||||
@each $key, $ratio in $aspect-ratios {
|
||||
.ratio-#{$key} {
|
||||
--#{$variable-prefix}aspect-ratio: #{$ratio};
|
||||
--#{$prefix}aspect-ratio: #{$ratio};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
.vr {
|
||||
display: inline-block;
|
||||
align-self: stretch;
|
||||
width: 1px;
|
||||
width: $vr-border-width;
|
||||
min-height: 1em;
|
||||
background-color: currentColor;
|
||||
background-color: currentcolor;
|
||||
opacity: $hr-opacity;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,18 @@
|
|||
@include deprecate("`alert-variant()`", "v5.3.0", "v6.0.0");
|
||||
|
||||
// scss-docs-start alert-variant-mixin
|
||||
@mixin alert-variant($background, $border, $color) {
|
||||
color: $color;
|
||||
@include gradient-bg($background);
|
||||
border-color: $border;
|
||||
--#{$prefix}alert-color: #{$color};
|
||||
--#{$prefix}alert-bg: #{$background};
|
||||
--#{$prefix}alert-border-color: #{$border};
|
||||
--#{$prefix}alert-link-color: #{shade-color($color, 20%)};
|
||||
|
||||
@if $enable-gradients {
|
||||
background-image: var(--#{$prefix}gradient);
|
||||
}
|
||||
|
||||
.alert-link {
|
||||
color: shade-color($color, 20%);
|
||||
color: var(--#{$prefix}alert-link-color);
|
||||
}
|
||||
}
|
||||
// scss-docs-end alert-variant-mixin
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
@mixin bsBanner($file) {
|
||||
/*!
|
||||
* Bootstrap #{$file} v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// Breakpoints are defined as a map of (name: minimum width), order from small to large:
|
||||
//
|
||||
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
|
||||
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)
|
||||
//
|
||||
// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
|
||||
|
||||
|
|
@ -10,9 +10,9 @@
|
|||
//
|
||||
// >> breakpoint-next(sm)
|
||||
// md
|
||||
// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
||||
// md
|
||||
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
|
||||
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))
|
||||
// md
|
||||
@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
|
||||
$n: index($breakpoint-names, $name);
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
// Minimum breakpoint width. Null for the smallest (first) breakpoint.
|
||||
//
|
||||
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
||||
// 576px
|
||||
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
|
||||
$min: map-get($breakpoints, $name);
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
|
||||
// See https://bugs.webkit.org/show_bug.cgi?id=178261
|
||||
//
|
||||
// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
||||
// 767.98px
|
||||
@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
|
||||
$max: map-get($breakpoints, $name);
|
||||
|
|
@ -48,9 +48,9 @@
|
|||
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
|
||||
// Useful for making responsive utilities.
|
||||
//
|
||||
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
||||
// "" (Returns a blank string)
|
||||
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
|
||||
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))
|
||||
// "-sm"
|
||||
@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
|
||||
@return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
|
||||
|
|
@ -109,7 +109,7 @@
|
|||
@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
|
||||
$min: breakpoint-min($name, $breakpoints);
|
||||
$next: breakpoint-next($name, $breakpoints);
|
||||
$max: breakpoint-max($next);
|
||||
$max: breakpoint-max($next, $breakpoints);
|
||||
|
||||
@if $min != null and $max != null {
|
||||
@media (min-width: $min) and (max-width: $max) {
|
||||
|
|
|
|||
|
|
@ -18,59 +18,20 @@
|
|||
$disabled-border: $border,
|
||||
$disabled-color: color-contrast($disabled-background)
|
||||
) {
|
||||
color: $color;
|
||||
@include gradient-bg($background);
|
||||
border-color: $border;
|
||||
@include box-shadow($btn-box-shadow);
|
||||
|
||||
&:hover {
|
||||
color: $hover-color;
|
||||
@include gradient-bg($hover-background);
|
||||
border-color: $hover-border;
|
||||
}
|
||||
|
||||
.btn-check:focus + &,
|
||||
&:focus {
|
||||
color: $hover-color;
|
||||
@include gradient-bg($hover-background);
|
||||
border-color: $hover-border;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5));
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5);
|
||||
}
|
||||
}
|
||||
|
||||
.btn-check:checked + &,
|
||||
.btn-check:active + &,
|
||||
&:active,
|
||||
&.active,
|
||||
.show > &.dropdown-toggle {
|
||||
color: $active-color;
|
||||
background-color: $active-background;
|
||||
// Remove CSS gradients if they're enabled
|
||||
background-image: if($enable-gradients, none, null);
|
||||
border-color: $active-border;
|
||||
|
||||
&:focus {
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5));
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba(mix($color, $border, 15%), .5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $disabled-color;
|
||||
background-color: $disabled-background;
|
||||
// Remove CSS gradients if they're enabled
|
||||
background-image: if($enable-gradients, none, null);
|
||||
border-color: $disabled-border;
|
||||
}
|
||||
--#{$prefix}btn-color: #{$color};
|
||||
--#{$prefix}btn-bg: #{$background};
|
||||
--#{$prefix}btn-border-color: #{$border};
|
||||
--#{$prefix}btn-hover-color: #{$hover-color};
|
||||
--#{$prefix}btn-hover-bg: #{$hover-background};
|
||||
--#{$prefix}btn-hover-border-color: #{$hover-border};
|
||||
--#{$prefix}btn-focus-shadow-rgb: #{to-rgb(mix($color, $border, 15%))};
|
||||
--#{$prefix}btn-active-color: #{$active-color};
|
||||
--#{$prefix}btn-active-bg: #{$active-background};
|
||||
--#{$prefix}btn-active-border-color: #{$active-border};
|
||||
--#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};
|
||||
--#{$prefix}btn-disabled-color: #{$disabled-color};
|
||||
--#{$prefix}btn-disabled-bg: #{$disabled-background};
|
||||
--#{$prefix}btn-disabled-border-color: #{$disabled-border};
|
||||
}
|
||||
// scss-docs-end btn-variant-mixin
|
||||
|
||||
|
|
@ -82,52 +43,28 @@
|
|||
$active-border: $color,
|
||||
$active-color: color-contrast($active-background)
|
||||
) {
|
||||
color: $color;
|
||||
border-color: $color;
|
||||
|
||||
&:hover {
|
||||
color: $color-hover;
|
||||
background-color: $active-background;
|
||||
border-color: $active-border;
|
||||
}
|
||||
|
||||
.btn-check:focus + &,
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
|
||||
}
|
||||
|
||||
.btn-check:checked + &,
|
||||
.btn-check:active + &,
|
||||
&:active,
|
||||
&.active,
|
||||
&.dropdown-toggle.show {
|
||||
color: $active-color;
|
||||
background-color: $active-background;
|
||||
border-color: $active-border;
|
||||
|
||||
&:focus {
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $color;
|
||||
background-color: transparent;
|
||||
}
|
||||
--#{$prefix}btn-color: #{$color};
|
||||
--#{$prefix}btn-border-color: #{$color};
|
||||
--#{$prefix}btn-hover-color: #{$color-hover};
|
||||
--#{$prefix}btn-hover-bg: #{$active-background};
|
||||
--#{$prefix}btn-hover-border-color: #{$active-border};
|
||||
--#{$prefix}btn-focus-shadow-rgb: #{to-rgb($color)};
|
||||
--#{$prefix}btn-active-color: #{$active-color};
|
||||
--#{$prefix}btn-active-bg: #{$active-background};
|
||||
--#{$prefix}btn-active-border-color: #{$active-border};
|
||||
--#{$prefix}btn-active-shadow: #{$btn-active-box-shadow};
|
||||
--#{$prefix}btn-disabled-color: #{$color};
|
||||
--#{$prefix}btn-disabled-bg: transparent;
|
||||
--#{$prefix}btn-disabled-border-color: #{$color};
|
||||
--#{$prefix}gradient: none;
|
||||
}
|
||||
// scss-docs-end btn-outline-variant-mixin
|
||||
|
||||
// scss-docs-start btn-size-mixin
|
||||
@mixin button-size($padding-y, $padding-x, $font-size, $border-radius) {
|
||||
padding: $padding-y $padding-x;
|
||||
@include font-size($font-size);
|
||||
// Manually declare to provide an override to the browser default
|
||||
@include border-radius($border-radius, 0);
|
||||
--#{$prefix}btn-padding-y: #{$padding-y};
|
||||
--#{$prefix}btn-padding-x: #{$padding-x};
|
||||
@include rfs($font-size, --#{$prefix}btn-font-size);
|
||||
--#{$prefix}btn-border-radius: #{$border-radius};
|
||||
}
|
||||
// scss-docs-end btn-size-mixin
|
||||
|
|
|
|||
|
|
@ -1,44 +1,49 @@
|
|||
// scss-docs-start caret-mixins
|
||||
@mixin caret-down {
|
||||
border-top: $caret-width solid;
|
||||
border-right: $caret-width solid transparent;
|
||||
@mixin caret-down($width: $caret-width) {
|
||||
border-top: $width solid;
|
||||
border-right: $width solid transparent;
|
||||
border-bottom: 0;
|
||||
border-left: $caret-width solid transparent;
|
||||
border-left: $width solid transparent;
|
||||
}
|
||||
|
||||
@mixin caret-up {
|
||||
@mixin caret-up($width: $caret-width) {
|
||||
border-top: 0;
|
||||
border-right: $caret-width solid transparent;
|
||||
border-bottom: $caret-width solid;
|
||||
border-left: $caret-width solid transparent;
|
||||
border-right: $width solid transparent;
|
||||
border-bottom: $width solid;
|
||||
border-left: $width solid transparent;
|
||||
}
|
||||
|
||||
@mixin caret-end {
|
||||
border-top: $caret-width solid transparent;
|
||||
@mixin caret-end($width: $caret-width) {
|
||||
border-top: $width solid transparent;
|
||||
border-right: 0;
|
||||
border-bottom: $caret-width solid transparent;
|
||||
border-left: $caret-width solid;
|
||||
border-bottom: $width solid transparent;
|
||||
border-left: $width solid;
|
||||
}
|
||||
|
||||
@mixin caret-start {
|
||||
border-top: $caret-width solid transparent;
|
||||
border-right: $caret-width solid;
|
||||
border-bottom: $caret-width solid transparent;
|
||||
@mixin caret-start($width: $caret-width) {
|
||||
border-top: $width solid transparent;
|
||||
border-right: $width solid;
|
||||
border-bottom: $width solid transparent;
|
||||
}
|
||||
|
||||
@mixin caret($direction: down) {
|
||||
@mixin caret(
|
||||
$direction: down,
|
||||
$width: $caret-width,
|
||||
$spacing: $caret-spacing,
|
||||
$vertical-align: $caret-vertical-align
|
||||
) {
|
||||
@if $enable-caret {
|
||||
&::after {
|
||||
display: inline-block;
|
||||
margin-left: $caret-spacing;
|
||||
vertical-align: $caret-vertical-align;
|
||||
margin-left: $spacing;
|
||||
vertical-align: $vertical-align;
|
||||
content: "";
|
||||
@if $direction == down {
|
||||
@include caret-down();
|
||||
@include caret-down($width);
|
||||
} @else if $direction == up {
|
||||
@include caret-up();
|
||||
@include caret-up($width);
|
||||
} @else if $direction == end {
|
||||
@include caret-end();
|
||||
@include caret-end($width);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -49,10 +54,10 @@
|
|||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
margin-right: $caret-spacing;
|
||||
vertical-align: $caret-vertical-align;
|
||||
margin-right: $spacing;
|
||||
vertical-align: $vertical-align;
|
||||
content: "";
|
||||
@include caret-start();
|
||||
@include caret-start($width);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
// scss-docs-start color-mode-mixin
|
||||
@mixin color-mode($mode: light, $root: false) {
|
||||
@if $color-mode-type == "media-query" {
|
||||
@if $root == true {
|
||||
@media (prefers-color-scheme: $mode) {
|
||||
:root {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
@media (prefers-color-scheme: $mode) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
[data-bs-theme="#{$mode}"] {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
// scss-docs-end color-mode-mixin
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
// Container mixins
|
||||
|
||||
@mixin make-container($gutter: $container-padding-x) {
|
||||
--#{$prefix}gutter-x: #{$gutter};
|
||||
--#{$prefix}gutter-y: 0;
|
||||
width: 100%;
|
||||
padding-right: var(--#{$variable-prefix}gutter-x, #{$gutter});
|
||||
padding-left: var(--#{$variable-prefix}gutter-x, #{$gutter});
|
||||
padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
|
||||
padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
$icon,
|
||||
$tooltip-color: color-contrast($color),
|
||||
$tooltip-bg-color: rgba($color, $form-feedback-tooltip-opacity),
|
||||
$focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity)
|
||||
$focus-box-shadow: 0 0 $input-btn-focus-blur $input-focus-width rgba($color, $input-btn-focus-color-opacity),
|
||||
$border-color: $color
|
||||
) {
|
||||
.#{$state}-feedback {
|
||||
display: none;
|
||||
|
|
@ -56,7 +57,7 @@
|
|||
|
||||
.form-control {
|
||||
@include form-validation-state-selector($state) {
|
||||
border-color: $color;
|
||||
border-color: $border-color;
|
||||
|
||||
@if $enable-validation-icons {
|
||||
padding-right: $input-height-inner;
|
||||
|
|
@ -67,8 +68,13 @@
|
|||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $color;
|
||||
box-shadow: $focus-box-shadow;
|
||||
border-color: $border-color;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($input-box-shadow, $focus-box-shadow);
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: $focus-box-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,28 +91,41 @@
|
|||
|
||||
.form-select {
|
||||
@include form-validation-state-selector($state) {
|
||||
border-color: $color;
|
||||
border-color: $border-color;
|
||||
|
||||
@if $enable-validation-icons {
|
||||
&:not([multiple]):not([size]),
|
||||
&:not([multiple])[size="1"] {
|
||||
--#{$prefix}form-select-bg-icon: #{escape-svg($icon)};
|
||||
padding-right: $form-select-feedback-icon-padding-end;
|
||||
background-image: escape-svg($form-select-indicator), escape-svg($icon);
|
||||
background-position: $form-select-bg-position, $form-select-feedback-icon-position;
|
||||
background-size: $form-select-bg-size, $form-select-feedback-icon-size;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $color;
|
||||
box-shadow: $focus-box-shadow;
|
||||
border-color: $border-color;
|
||||
@if $enable-shadows {
|
||||
@include box-shadow($form-select-box-shadow, $focus-box-shadow);
|
||||
} @else {
|
||||
// Avoid using mixin so we can pass custom focus shadow properly
|
||||
box-shadow: $focus-box-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-control-color {
|
||||
@include form-validation-state-selector($state) {
|
||||
@if $enable-validation-icons {
|
||||
width: add($form-color-width, $input-height-inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
@include form-validation-state-selector($state) {
|
||||
border-color: $color;
|
||||
border-color: $border-color;
|
||||
|
||||
&:checked {
|
||||
background-color: $color;
|
||||
|
|
@ -127,16 +146,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
.input-group .form-control,
|
||||
.input-group .form-select {
|
||||
@include form-validation-state-selector($state) {
|
||||
@if $state == "valid" {
|
||||
z-index: 1;
|
||||
} @else if $state == "invalid" {
|
||||
z-index: 2;
|
||||
}
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
.input-group {
|
||||
> .form-control:not(:focus),
|
||||
> .form-select:not(:focus),
|
||||
> .form-floating:not(:focus-within) {
|
||||
@include form-validation-state-selector($state) {
|
||||
@if $state == "valid" {
|
||||
z-index: 3;
|
||||
} @else if $state == "invalid" {
|
||||
z-index: 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
background-color: $color;
|
||||
|
||||
@if $enable-gradients {
|
||||
background-image: var(--#{$variable-prefix}gradient);
|
||||
background-image: var(--#{$prefix}gradient);
|
||||
}
|
||||
}
|
||||
// scss-docs-end gradient-bg-mixin
|
||||
|
|
|
|||
|
|
@ -3,17 +3,17 @@
|
|||
// Generate semantic grid columns with these mixins.
|
||||
|
||||
@mixin make-row($gutter: $grid-gutter-width) {
|
||||
--#{$variable-prefix}gutter-x: #{$gutter};
|
||||
--#{$variable-prefix}gutter-y: 0;
|
||||
--#{$prefix}gutter-x: #{$gutter};
|
||||
--#{$prefix}gutter-y: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed
|
||||
margin-top: calc(-1 * var(--#{$variable-prefix}gutter-y)); // stylelint-disable-line function-disallowed-list
|
||||
margin-right: calc(-.5 * var(--#{$variable-prefix}gutter-x)); // stylelint-disable-line function-disallowed-list
|
||||
margin-left: calc(-.5 * var(--#{$variable-prefix}gutter-x)); // stylelint-disable-line function-disallowed-list
|
||||
margin-top: calc(-1 * var(--#{$prefix}gutter-y)); // stylelint-disable-line function-disallowed-list
|
||||
margin-right: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list
|
||||
margin-left: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list
|
||||
}
|
||||
|
||||
@mixin make-col-ready($gutter: $grid-gutter-width) {
|
||||
@mixin make-col-ready() {
|
||||
// Add box sizing if only the grid is loaded
|
||||
box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);
|
||||
// Prevent columns from becoming too narrow when at smaller grid tiers by
|
||||
|
|
@ -22,9 +22,9 @@
|
|||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid
|
||||
padding-right: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
|
||||
padding-left: calc(var(--#{$variable-prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
|
||||
margin-top: var(--#{$variable-prefix}gutter-y);
|
||||
padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
|
||||
padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list
|
||||
margin-top: var(--#{$prefix}gutter-y);
|
||||
}
|
||||
|
||||
@mixin make-col($size: false, $columns: $grid-columns) {
|
||||
|
|
@ -51,12 +51,12 @@
|
|||
// Row columns
|
||||
//
|
||||
// Specify on a parent element(e.g., .row) to force immediate children into NN
|
||||
// numberof columns. Supports wrapping to new lines, but does not do a Masonry
|
||||
// number of columns. Supports wrapping to new lines, but does not do a Masonry
|
||||
// style grid.
|
||||
@mixin row-cols($count) {
|
||||
> * {
|
||||
flex: 0 0 auto;
|
||||
width: divide(100%, $count);
|
||||
width: percentage(divide(1, $count));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,12 +114,12 @@
|
|||
@each $key, $value in $gutters {
|
||||
.g#{$infix}-#{$key},
|
||||
.gx#{$infix}-#{$key} {
|
||||
--#{$variable-prefix}gutter-x: #{$value};
|
||||
--#{$prefix}gutter-x: #{$value};
|
||||
}
|
||||
|
||||
.g#{$infix}-#{$key},
|
||||
.gy#{$infix}-#{$key} {
|
||||
--#{$variable-prefix}gutter-y: #{$value};
|
||||
--#{$prefix}gutter-y: #{$value};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Start with `1` because `0` is and invalid value.
|
||||
// Start with `1` because `0` is an invalid value.
|
||||
// Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.
|
||||
@for $i from 1 through ($columns - 1) {
|
||||
.g-start#{$infix}-#{$i} {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
@include deprecate("`list-group-item-variant()`", "v5.3.0", "v6.0.0");
|
||||
|
||||
// List Groups
|
||||
|
||||
// scss-docs-start list-group-mixin
|
||||
|
|
|
|||
|
|
@ -2,30 +2,9 @@
|
|||
|
||||
// scss-docs-start pagination-mixin
|
||||
@mixin pagination-size($padding-y, $padding-x, $font-size, $border-radius) {
|
||||
.page-link {
|
||||
padding: $padding-y $padding-x;
|
||||
@include font-size($font-size);
|
||||
}
|
||||
|
||||
.page-item {
|
||||
@if $pagination-margin-start == (-$pagination-border-width) {
|
||||
&:first-child {
|
||||
.page-link {
|
||||
@include border-start-radius($border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.page-link {
|
||||
@include border-end-radius($border-radius);
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
//Add border-radius to all pageLinks in case they have left margin
|
||||
.page-link {
|
||||
@include border-radius($border-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
--#{$prefix}pagination-padding-x: #{$padding-x};
|
||||
--#{$prefix}pagination-padding-y: #{$padding-y};
|
||||
@include rfs($font-size, --#{$prefix}pagination-font-size);
|
||||
--#{$prefix}pagination-border-radius: #{$border-radius};
|
||||
}
|
||||
// scss-docs-end pagination-mixin
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-break: normal;
|
||||
word-spacing: normal;
|
||||
white-space: normal;
|
||||
word-spacing: normal;
|
||||
line-break: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,20 @@
|
|||
$hover-bg: mix($color, $background, percentage($table-hover-bg-factor));
|
||||
$striped-bg: mix($color, $background, percentage($table-striped-bg-factor));
|
||||
$active-bg: mix($color, $background, percentage($table-active-bg-factor));
|
||||
$table-border-color: mix($color, $background, percentage($table-border-factor));
|
||||
|
||||
--#{$variable-prefix}table-bg: #{$background};
|
||||
--#{$variable-prefix}table-striped-bg: #{$striped-bg};
|
||||
--#{$variable-prefix}table-striped-color: #{color-contrast($striped-bg)};
|
||||
--#{$variable-prefix}table-active-bg: #{$active-bg};
|
||||
--#{$variable-prefix}table-active-color: #{color-contrast($active-bg)};
|
||||
--#{$variable-prefix}table-hover-bg: #{$hover-bg};
|
||||
--#{$variable-prefix}table-hover-color: #{color-contrast($hover-bg)};
|
||||
--#{$prefix}table-color: #{$color};
|
||||
--#{$prefix}table-bg: #{$background};
|
||||
--#{$prefix}table-border-color: #{$table-border-color};
|
||||
--#{$prefix}table-striped-bg: #{$striped-bg};
|
||||
--#{$prefix}table-striped-color: #{color-contrast($striped-bg)};
|
||||
--#{$prefix}table-active-bg: #{$active-bg};
|
||||
--#{$prefix}table-active-color: #{color-contrast($active-bg)};
|
||||
--#{$prefix}table-hover-bg: #{$hover-bg};
|
||||
--#{$prefix}table-hover-color: #{color-contrast($hover-bg)};
|
||||
|
||||
color: $color;
|
||||
border-color: mix($color, $background, percentage($table-border-factor));
|
||||
color: var(--#{$prefix}table-color);
|
||||
border-color: var(--#{$prefix}table-border-color);
|
||||
}
|
||||
}
|
||||
// scss-docs-end table-variant
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Utility generator
|
||||
// Used to generate utilities & print utilities
|
||||
@mixin generate-utility($utility, $infix, $is-rfs-media-query: false) {
|
||||
@mixin generate-utility($utility, $infix: "", $is-rfs-media-query: false) {
|
||||
$values: map-get($utility, values);
|
||||
|
||||
// If the values are a list or string, convert it into a map
|
||||
|
|
@ -20,12 +20,15 @@
|
|||
$property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));
|
||||
$property-class: if($property-class == null, "", $property-class);
|
||||
|
||||
// Use custom CSS variable name if present, otherwise default to `class`
|
||||
$css-variable-name: if(map-has-key($utility, css-variable-name), map-get($utility, css-variable-name), map-get($utility, class));
|
||||
|
||||
// State params to generate pseudo-classes
|
||||
$state: if(map-has-key($utility, state), map-get($utility, state), ());
|
||||
|
||||
$infix: if($property-class == "" and str-slice($infix, 1, 1) == "-", str-slice($infix, 2), $infix);
|
||||
|
||||
// Don't prefix if value key is null (eg. with shadow class)
|
||||
// Don't prefix if value key is null (e.g. with shadow class)
|
||||
$property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, "");
|
||||
|
||||
@if map-get($utility, rfs) {
|
||||
|
|
@ -52,20 +55,20 @@
|
|||
|
||||
@if $is-css-var {
|
||||
.#{$property-class + $infix + $property-class-modifier} {
|
||||
--#{$variable-prefix}#{$property-class}: #{$value};
|
||||
--#{$prefix}#{$css-variable-name}: #{$value};
|
||||
}
|
||||
|
||||
@each $pseudo in $state {
|
||||
.#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
|
||||
--#{$variable-prefix}#{$property-class}: #{$value};
|
||||
--#{$prefix}#{$css-variable-name}: #{$value};
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
.#{$property-class + $infix + $property-class-modifier} {
|
||||
@each $property in $properties {
|
||||
@if $is-local-vars {
|
||||
@each $local-var, $value in $is-local-vars {
|
||||
--#{$variable-prefix}#{$local-var}: #{$value};
|
||||
@each $local-var, $variable in $is-local-vars {
|
||||
--#{$prefix}#{$local-var}: #{$variable};
|
||||
}
|
||||
}
|
||||
#{$property}: $value if($enable-important-utilities, !important, null);
|
||||
|
|
@ -75,6 +78,11 @@
|
|||
@each $pseudo in $state {
|
||||
.#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
|
||||
@each $property in $properties {
|
||||
@if $is-local-vars {
|
||||
@each $local-var, $variable in $is-local-vars {
|
||||
--#{$prefix}#{$local-var}: #{$variable};
|
||||
}
|
||||
}
|
||||
#{$property}: $value if($enable-important-utilities, !important, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
// See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/
|
||||
|
||||
@mixin visually-hidden() {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
padding: 0 !important;
|
||||
|
|
@ -15,6 +14,11 @@
|
|||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
border: 0 !important;
|
||||
|
||||
// Fix for positioned table caption that could become anonymous cells
|
||||
&:not(caption) {
|
||||
position: absolute !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Use to only display content when it's focused, or one of its child elements is focused
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// stylelint-disable property-blacklist, scss/dollar-variable-default
|
||||
// stylelint-disable scss/dimension-no-non-numeric-values
|
||||
|
||||
// SCSS RFS mixin
|
||||
//
|
||||
|
|
@ -154,8 +154,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
&.enable-rfs {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@else {
|
||||
} @else {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
|
@ -168,7 +167,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
@content;
|
||||
}
|
||||
|
||||
@include _rfs-media-query {
|
||||
@include _rfs-media-query () {
|
||||
.enable-rfs &,
|
||||
&.enable-rfs {
|
||||
@content;
|
||||
|
|
@ -182,7 +181,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
@content;
|
||||
}
|
||||
}
|
||||
@include _rfs-media-query {
|
||||
@include _rfs-media-query () {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
|
@ -193,12 +192,12 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
// Convert to list
|
||||
$values: if(type-of($values) != list, ($values,), $values);
|
||||
|
||||
$val: '';
|
||||
$val: "";
|
||||
|
||||
// Loop over each value and calculate value
|
||||
@each $value in $values {
|
||||
@if $value == 0 {
|
||||
$val: $val + ' 0';
|
||||
$val: $val + " 0";
|
||||
}
|
||||
@else {
|
||||
// Cache $value unit
|
||||
|
|
@ -206,15 +205,14 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
|
||||
@if $unit == px {
|
||||
// Convert to rem if needed
|
||||
$val: $val + ' ' + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);
|
||||
$val: $val + " " + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);
|
||||
}
|
||||
@else if $unit == rem {
|
||||
// Convert to px if needed
|
||||
$val: $val + ' ' + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);
|
||||
}
|
||||
@else {
|
||||
$val: $val + " " + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);
|
||||
} @else {
|
||||
// If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
|
||||
$val: $val + ' ' + $value;
|
||||
$val: $val + " " + $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -228,30 +226,26 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
// Convert to list
|
||||
$values: if(type-of($values) != list, ($values,), $values);
|
||||
|
||||
$val: '';
|
||||
$val: "";
|
||||
|
||||
// Loop over each value and calculate value
|
||||
@each $value in $values {
|
||||
@if $value == 0 {
|
||||
$val: $val + ' 0';
|
||||
}
|
||||
|
||||
@else {
|
||||
$val: $val + " 0";
|
||||
} @else {
|
||||
// Cache $value unit
|
||||
$unit: if(type-of($value) == "number", unit($value), false);
|
||||
|
||||
// If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
|
||||
@if not $unit or $unit != px and $unit != rem {
|
||||
$val: $val + ' ' + $value;
|
||||
}
|
||||
|
||||
@else {
|
||||
$val: $val + " " + $value;
|
||||
} @else {
|
||||
// Remove unit from $value for calculations
|
||||
$value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));
|
||||
|
||||
// Only add the media query if the value is greater than the minimum value
|
||||
@if abs($value) <= $rfs-base-value or not $enable-rfs {
|
||||
$val: $val + ' ' + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);
|
||||
$val: $val + " " + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);
|
||||
}
|
||||
@else {
|
||||
// Calculate the minimum value
|
||||
|
|
@ -273,7 +267,7 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
$variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};
|
||||
|
||||
// Return the calculated value
|
||||
$val: $val + ' calc(' + $min-width + if($value < 0, ' - ', ' + ') + $variable-width + ')';
|
||||
$val: $val + " calc(" + $min-width + if($value < 0, " - ", " + ") + $variable-width + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -287,22 +281,22 @@ $rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height
|
|||
@mixin rfs($values, $property: font-size) {
|
||||
@if $values != null {
|
||||
$val: rfs-value($values);
|
||||
$fluidVal: rfs-fluid-value($values);
|
||||
$fluid-val: rfs-fluid-value($values);
|
||||
|
||||
// Do not print the media query if responsive & non-responsive values are the same
|
||||
@if $val == $fluidVal {
|
||||
@if $val == $fluid-val {
|
||||
#{$property}: $val;
|
||||
}
|
||||
@else {
|
||||
@include _rfs-rule {
|
||||
#{$property}: if($rfs-mode == max-media-query, $val, $fluidVal);
|
||||
@include _rfs-rule () {
|
||||
#{$property}: if($rfs-mode == max-media-query, $val, $fluid-val);
|
||||
|
||||
// Include safari iframe resize fix if needed
|
||||
min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);
|
||||
}
|
||||
|
||||
@include _rfs-media-query-rule {
|
||||
#{$property}: if($rfs-mode == max-media-query, $fluidVal, $val);
|
||||
@include _rfs-media-query-rule () {
|
||||
#{$property}: if($rfs-mode == max-media-query, $fluid-val, $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue