{% if page.toc %}
diff --git a/_layouts/base.html b/_layouts/base.html
index eac7b1c17..cb90f9b9e 100644
--- a/_layouts/base.html
+++ b/_layouts/base.html
@@ -7,7 +7,7 @@
{% include header.html %}
-
+
{% include skip.html %}
{{ content }}
diff --git a/_layouts/compress.html b/_layouts/compress.html
index 76462cb43..bb34487d2 100644
--- a/_layouts/compress.html
+++ b/_layouts/compress.html
@@ -1,10 +1,10 @@
---
# Jekyll layout that compresses HTML
-# v3.0.4
+# v3.1.0
# http://jch.penibelst.de/
# © 2014–2015 Anatol Broder
# MIT License
---
{% capture _LINE_FEED %}
-{% endcapture %}{% if site.compress_html.ignore.envs contains jekyll.environment %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% assign _profile = site.compress_html.profile %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if _profile and _endings %}{% assign _profile_endings = _content | size | plus: 1 %}{% endif %}{% for _element in site.compress_html.startings %}{% capture _start %}<{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _start %}{% endfor %}{% if _profile and site.compress_html.startings %}{% assign _profile_startings = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.comments == "all" %}{% assign _comments = "" | split: " " %}{% else %}{% assign _comments = site.compress_html.comments %}{% endif %}{% if _comments.size == 2 %}{% capture _comment_befores %}.{{ _content }}{% endcapture %}{% assign _comment_befores = _comment_befores | split: _comments.first %}{% for _comment_before in _comment_befores %}{% if forloop.first %}{% continue %}{% endif %}{% capture _comment_outside %}{% if _carry %}{{ _comments.first }}{% endif %}{{ _comment_before }}{% endcapture %}{% capture _comment %}{% unless _carry %}{{ _comments.first }}{% endunless %}{{ _comment_outside | split: _comments.last | first }}{% if _comment_outside contains _comments.last %}{{ _comments.last }}{% assign _carry = false %}{% else %}{% assign _carry = true %}{% endif %}{% endcapture %}{% assign _content = _content | remove_first: _comment %}{% endfor %}{% if _profile %}{% assign _profile_comments = _content | size | plus: 1 %}{% endif %}{% endif %}{% assign _pre_befores = _content | split: "
" %}{% assign _pres_after = "" %}{% if _pres.size != 0 %}{% if site.compress_html.blanklines %}{% assign _lines = _pres.last | split: _LINE_FEED %}{% capture _pres_after %}{% for _line in _lines %}{% assign _trimmed = _line | split: " " | join: " " %}{% if _trimmed != empty or forloop.last %}{% unless forloop.first %}{{ _LINE_FEED }}{% endunless %}{{ _line }}{% endif %}{% endfor %}{% endcapture %}{% else %}{% assign _pres_after = _pres.last | split: " " | join: " " %}{% endif %}{% endif %}{% capture _content %}{{ _content }}{% if _pre_before contains "
" %}
{% endif %}{% unless _pre_before contains "
" and _pres.size == 1 %}{{ _pres_after }}{% endunless %}{% endcapture %}{% endfor %}{% if _profile %}{% assign _profile_collapse = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = " \
;; ;" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{% if _profile and _clippings %}{% assign _profile_clippings = _content | size | plus: 1 %}{% endif %}{{ _content }}{% if _profile %}
Step | Bytes |
raw | {{ content | size }}{% if _profile_endings %} |
endings | {{ _profile_endings }}{% endif %}{% if _profile_startings %} |
startings | {{ _profile_startings }}{% endif %}{% if _profile_comments %} |
comments | {{ _profile_comments }}{% endif %}{% if _profile_collapse %} |
collapse | {{ _profile_collapse }}{% endif %}{% if _profile_clippings %} |
clippings | {{ _profile_clippings }}{% endif %} |
{% endif %}{% endif %}
+{% endcapture %}{% if site.compress_html.ignore.envs contains jekyll.environment or site.compress_html.ignore.envs == "all" %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% assign _profile = site.compress_html.profile %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if _profile and _endings %}{% assign _profile_endings = _content | size | plus: 1 %}{% endif %}{% for _element in site.compress_html.startings %}{% capture _start %}<{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _start %}{% endfor %}{% if _profile and site.compress_html.startings %}{% assign _profile_startings = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.comments == "all" %}{% assign _comments = "" | split: " " %}{% else %}{% assign _comments = site.compress_html.comments %}{% endif %}{% if _comments.size == 2 %}{% capture _comment_befores %}.{{ _content }}{% endcapture %}{% assign _comment_befores = _comment_befores | split: _comments.first %}{% for _comment_before in _comment_befores %}{% if forloop.first %}{% continue %}{% endif %}{% capture _comment_outside %}{% if _carry %}{{ _comments.first }}{% endif %}{{ _comment_before }}{% endcapture %}{% capture _comment %}{% unless _carry %}{{ _comments.first }}{% endunless %}{{ _comment_outside | split: _comments.last | first }}{% if _comment_outside contains _comments.last %}{{ _comments.last }}{% assign _carry = false %}{% else %}{% assign _carry = true %}{% endif %}{% endcapture %}{% assign _content = _content | remove_first: _comment %}{% endfor %}{% if _profile %}{% assign _profile_comments = _content | size | plus: 1 %}{% endif %}{% endif %}{% assign _pre_befores = _content | split: "
" %}{% assign _pres_after = "" %}{% if _pres.size != 0 %}{% if site.compress_html.blanklines %}{% assign _lines = _pres.last | split: _LINE_FEED %}{% capture _pres_after %}{% for _line in _lines %}{% assign _trimmed = _line | split: " " | join: " " %}{% if _trimmed != empty or forloop.last %}{% unless forloop.first %}{{ _LINE_FEED }}{% endunless %}{{ _line }}{% endif %}{% endfor %}{% endcapture %}{% else %}{% assign _pres_after = _pres.last | split: " " | join: " " %}{% endif %}{% endif %}{% capture _content %}{{ _content }}{% if _pre_before contains "
" %}
{% endif %}{% unless _pre_before contains "
" and _pres.size == 1 %}{{ _pres_after }}{% endunless %}{% endcapture %}{% endfor %}{% if _profile %}{% assign _profile_collapse = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = "
;; ;" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{% if _profile and _clippings %}{% assign _profile_clippings = _content | size | plus: 1 %}{% endif %}{{ _content }}{% if _profile %}
Step | Bytes |
raw | {{ content | size }}{% if _profile_endings %} |
endings | {{ _profile_endings }}{% endif %}{% if _profile_startings %} |
startings | {{ _profile_startings }}{% endif %}{% if _profile_comments %} |
comments | {{ _profile_comments }}{% endif %}{% if _profile_collapse %} |
collapse | {{ _profile_collapse }}{% endif %}{% if _profile_clippings %} |
clippings | {{ _profile_clippings }}{% endif %} |
{% endif %}{% endif %}
diff --git a/_layouts/redirect.html b/_layouts/redirect.html
new file mode 100644
index 000000000..ab4553dce
--- /dev/null
+++ b/_layouts/redirect.html
@@ -0,0 +1,16 @@
+
+
+
+
Redirecting...
+
+
+
+
+
+
+
Redirecting...
+
Click here if you are not redirected.
+
+
+
+
diff --git a/apple-touch-icon.png b/apple-touch-icon.png
index 828e10cd9..26ae8ae8f 100644
Binary files a/apple-touch-icon.png and b/apple-touch-icon.png differ
diff --git a/assets/js/index.js b/assets/js/index.js
index e1d5496f5..ef78c9dc8 100644
--- a/assets/js/index.js
+++ b/assets/js/index.js
@@ -1,8 +1,10 @@
-import $ from 'jquery'
+// import $ from 'jquery'
+import 'element-closest-polyfill' // IE10 closest fix
import ExpansionPanel from './src/expansion-panel'
import FloatingLabel from './src/floating-label'
import NavDrawer from './src/nav-drawer'
import PickDate from './src/pickdate'
+import Ripplet from './src/ripplet'
import SelectionControlFocus from './src/selection-control-focus'
import TabSwitch from './src/tab-switch'
import Util from './src/util'
@@ -13,6 +15,7 @@ export {
FloatingLabel,
NavDrawer,
PickDate,
+ Ripplet,
SelectionControlFocus,
TabSwitch
}
diff --git a/assets/js/src/pickdate.js b/assets/js/src/pickdate.js
index 1f0b61904..32de23fcf 100644
--- a/assets/js/src/pickdate.js
+++ b/assets/js/src/pickdate.js
@@ -27,9 +27,9 @@ const PickDate = (($) => {
hiddenSuffix : '',
klass : {
// button
- buttonClear : 'btn btn-outline-primary picker-button-clear',
- buttonClose : 'btn btn-outline-primary picker-button-close',
- buttonToday : 'btn btn-outline-primary picker-button-today',
+ buttonClear : 'btn btn-flat-primary picker-button-clear',
+ buttonClose : 'btn btn-flat-primary picker-button-close',
+ buttonToday : 'btn btn-flat-primary picker-button-today',
// day
day : 'picker-day',
@@ -70,8 +70,8 @@ const PickDate = (($) => {
},
labelMonthNext : 'Next month',
labelMonthPrev : 'Previous month',
- labelMonthSelect : 'Select a month',
- labelYearSelect : 'Select a year',
+ labelMonthSelect : 'Choose a month',
+ labelYearSelect : 'Choose a year',
max : false,
min : false,
monthsFull : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
@@ -147,7 +147,7 @@ const PickDate = (($) => {
display(datepickerApi, datepickerRoot, datepickerValue) {
$('.picker-date-display', datepickerRoot).remove()
- $('.picker-wrap', datepickerRoot).prepend(`
${datepickerApi.get(datepickerValue, 'yyyy')}
${datepickerApi.get(datepickerValue, 'dddd')}${datepickerApi.get(datepickerValue, 'd')}${datepickerApi.get(datepickerValue, 'mmm')}
`)
+ $('.picker-wrap', datepickerRoot).prepend(`
${datepickerApi.get(datepickerValue, 'yyyy')}
${datepickerApi.get(datepickerValue, 'dddd')}${datepickerApi.get(datepickerValue, 'mmm')}${datepickerApi.get(datepickerValue, 'd')}
`)
}
show() {
diff --git a/assets/js/src/ripplet.js b/assets/js/src/ripplet.js
new file mode 100644
index 000000000..1c26f6f82
--- /dev/null
+++ b/assets/js/src/ripplet.js
@@ -0,0 +1,89 @@
+import ripplet,
+{
+ defaultOptions
+} from 'ripplet.js'
+
+/*
+ * Config for ripplet.js by luncheon
+ */
+
+// Values from https://github.com/material-components/material-components-web/blob/master/packages/mdc-ripple/_variables.scss
+
+const Ripplet = (() => {
+ /* eslint complexity: ["error", 40] */
+ addEventListener('pointerdown', (event) => {
+ defaultOptions.color = 'rgba(0,0,0,0.12)'
+ defaultOptions.opacity = 1
+ defaultOptions.spreadingDelay = '15ms'
+ defaultOptions.spreadingDuration = '175ms'
+ defaultOptions.clearingDelay = '300ms'
+ defaultOptions.clearingDuration = '150ms'
+ defaultOptions.clearingTimingFunction = 'linear'
+
+ if (event.button !== 0) {
+ return
+ }
+ const currentTarget = event.target.closest('.btn, .card-link, .card-primary-action, .list-group-item-action, [data-ripplet]')
+ if (!currentTarget || currentTarget.disabled) {
+ return
+ }
+
+ const rippleTarget = {
+ currentTarget,
+ clientX: event.clientX,
+ clientY: event.clientY
+ }
+
+ currentTarget.setAttribute('data-ripplet', '')
+ const cls = currentTarget.classList
+
+ if (
+ cls.contains('btn-outline-primary') ||
+ cls.contains('btn-outline-secondary') ||
+ cls.contains('btn-outline-danger') ||
+ cls.contains('btn-outline-info') ||
+ cls.contains('btn-outline-success') ||
+ cls.contains('btn-outline-warning') ||
+ cls.contains('btn-outline-dark') ||
+ cls.contains('btn-outline-light') ||
+ cls.contains('btn-link') ||
+ cls.contains('card-link') ||
+ cls.contains('btn-flat-primary') ||
+ cls.contains('btn-flat-secondary') ||
+ cls.contains('btn-flat-danger') ||
+ cls.contains('btn-flat-info') ||
+ cls.contains('btn-flat-success') ||
+ cls.contains('btn-flat-warning') ||
+ cls.contains('btn-flat-dark') ||
+ cls.contains('btn-flat-light')
+ ) {
+ ripplet(rippleTarget, {
+ color: getComputedStyle(currentTarget).color,
+ opacity: 0.12
+ })
+ } else if (
+ cls.contains('btn-primary') ||
+ cls.contains('btn-secondary') ||
+ cls.contains('btn-success') ||
+ cls.contains('btn-danger') ||
+ cls.contains('btn-warning') ||
+ cls.contains('btn-info') ||
+ cls.contains('btn-dark')
+ ) {
+ ripplet(rippleTarget, {
+ color: 'rgba(255,255,255,0.24)'
+ })
+ } else if (
+ cls.contains('nav-link')
+ ) {
+ ripplet(rippleTarget, {
+ color: getComputedStyle(currentTarget, ':active').color,
+ opacity: 0.12
+ })
+ } else {
+ ripplet(rippleTarget)
+ }
+ })
+})()
+
+export default Ripplet
diff --git a/assets/js/src/tab-switch.js b/assets/js/src/tab-switch.js
index c40f560c7..1def99b33 100644
--- a/assets/js/src/tab-switch.js
+++ b/assets/js/src/tab-switch.js
@@ -3,7 +3,7 @@ import Util from './util'
/*
* Tab indicator animation
- * Requires Bootstrap's (v4.1.X) `tab.js`
+ * Requires Bootstrap's (v4.4.X) `tab.js`
*/
const TabSwitch = (($) => {
diff --git a/assets/js/src/util.js b/assets/js/src/util.js
index c3bb7f18c..c8fa61f77 100644
--- a/assets/js/src/util.js
+++ b/assets/js/src/util.js
@@ -2,133 +2,195 @@ import $ from 'jquery'
/*
* Global util js
- * Based on Bootstrap's (v4.1.X) `util.js`
+ * Based on Bootstrap's (v4.6.0) `util.js`
*/
-const Util = (($) => {
- const MAX_UID = 1000000
- const MILLISECONDS_MULTIPLIER = 1000
- const TRANSITION_END = 'transitionend'
-
- function getSpecialTransitionEndEvent() {
- return {
- bindType : TRANSITION_END,
- delegateType : TRANSITION_END,
- handle(event) {
- if ($(event.target).is(this)) {
- return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
- }
- return undefined // eslint-disable-line no-undefined
+/**
+ * ------------------------------------------------------------------------
+ * Private TransitionEnd Helpers
+ * ------------------------------------------------------------------------
+ */
+
+const TRANSITION_END = 'transitionend'
+const MAX_UID = 1000000
+const MILLISECONDS_MULTIPLIER = 1000
+
+// Shoutout AngusCroll (https://goo.gl/pxwQGp)
+function toType(obj) {
+ if (obj === null || typeof obj === 'undefined') {
+ return `${obj}`
+ }
+
+ return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()
+}
+
+function getSpecialTransitionEndEvent() {
+ return {
+ bindType: TRANSITION_END,
+ delegateType: TRANSITION_END,
+ handle(event) {
+ if ($(event.target).is(this)) {
+ return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
}
+
+ return undefined
}
}
+}
- function setTransitionEndSupport() {
- $.fn.emulateTransitionEnd = transitionEndEmulator
- $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
- }
+function transitionEndEmulator(duration) {
+ let called = false
- function toType(obj) {
- return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()
- }
+ $(this).one(Util.TRANSITION_END, () => {
+ called = true
+ })
- function transitionEndEmulator(duration) {
- let called = false
+ setTimeout(() => {
+ if (!called) {
+ Util.triggerTransitionEnd(this)
+ }
+ }, duration)
- $(this).one(Util.TRANSITION_END, () => {
- called = true
- })
+ return this
+}
- setTimeout(() => {
- if (!called) {
- Util.triggerTransitionEnd(this)
- }
- }, duration)
+function setTransitionEndSupport() {
+ $.fn.emulateTransitionEnd = transitionEndEmulator
+ $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent()
+}
- return this
- }
+/**
+ * --------------------------------------------------------------------------
+ * Public Util Api
+ * --------------------------------------------------------------------------
+ */
- const Util = {
+const Util = {
+ TRANSITION_END: 'bsTransitionEnd',
- TRANSITION_END: 'mdTransitionEnd',
+ getUID(prefix) {
+ do {
+ prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
+ } while (document.getElementById(prefix))
- getSelectorFromElement(element) {
- let selector = element.getAttribute('data-target')
+ return prefix
+ },
- if (!selector || selector === '#') {
- selector = element.getAttribute('href') || ''
- }
+ getSelectorFromElement(element) {
+ let selector = element.getAttribute('data-target')
- try {
- const $selector = $(document).find(selector)
+ if (!selector || selector === '#') {
+ const hrefAttr = element.getAttribute('href')
+ selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''
+ }
- return $selector.length > 0 ? selector : null
- } catch (err) {
- return null
- }
- },
+ try {
+ return document.querySelector(selector) ? selector : null
+ } catch (_) {
+ return null
+ }
+ },
- getTransitionDurationFromElement(element) {
- if (!element) {
- return 0
- }
+ getTransitionDurationFromElement(element) {
+ if (!element) {
+ return 0
+ }
- let transitionDuration = $(element).css('transition-duration')
+ // Get transition-duration of the element
+ let transitionDuration = $(element).css('transition-duration')
+ let transitionDelay = $(element).css('transition-delay')
- if (!transitionDuration) {
- return 0
- }
+ const floatTransitionDuration = parseFloat(transitionDuration)
+ const floatTransitionDelay = parseFloat(transitionDelay)
- transitionDuration = transitionDuration.split(',')[0]
-
- return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER
- },
-
- getUID(prefix) {
- do {
- // eslint-disable-next-line no-bitwise
- prefix += ~~(Math.random() * MAX_UID)
- } while (document.getElementById(prefix))
- return prefix
- },
-
- isElement(obj) {
- return (obj[0] || obj).nodeType
- },
-
- reflow(element) {
- return element.offsetHeight
- },
-
- supportsTransitionEnd() {
- return Boolean(TRANSITION_END)
- },
-
- triggerTransitionEnd(element) {
- $(element).trigger(TRANSITION_END)
- },
-
- typeCheckConfig(componentName, config, configTypes) {
- for (const property in configTypes) {
- if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
- const expectedTypes = configTypes[property]
- const value = config[property]
- const valueType = value && Util.isElement(value) ? 'element' : toType(value)
-
- if (!new RegExp(expectedTypes).test(valueType)) {
- throw new Error(
- `${componentName.toUpperCase()}: ` +
- `Option "${property}" provided type "${valueType}" ` +
- `but expected type "${expectedTypes}".`)
- }
+ // 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 (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER
+ },
+
+ reflow(element) {
+ return element.offsetHeight
+ },
+
+ triggerTransitionEnd(element) {
+ $(element).trigger(TRANSITION_END)
+ },
+
+ supportsTransitionEnd() {
+ return Boolean(TRANSITION_END)
+ },
+
+ isElement(obj) {
+ return (obj[0] || obj).nodeType
+ },
+
+ typeCheckConfig(componentName, config, configTypes) {
+ for (const property in configTypes) {
+ if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
+ const expectedTypes = configTypes[property]
+ const value = config[property]
+ const valueType = value && Util.isElement(value) ?
+ 'element' : toType(value)
+
+ if (!new RegExp(expectedTypes).test(valueType)) {
+ throw new Error(
+ `${componentName.toUpperCase()}: ` +
+ `Option "${property}" provided type "${valueType}" ` +
+ `but expected type "${expectedTypes}".`)
}
}
}
- }
+ },
- setTransitionEndSupport()
+ 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 Util.findShadowRoot(element.parentNode)
+ },
+
+ jQueryDetection() {
+ if (typeof $ === 'undefined') {
+ throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.')
+ }
+
+ const version = $.fn.jquery.split(' ')[0].split('.')
+ const minMajor = 1
+ const ltMajor = 2
+ const minMinor = 9
+ const minPatch = 1
+ const maxMajor = 4
+
+ if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
+ throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0')
+ }
+ }
+}
- return Util
-})($)
+Util.jQueryDetection()
+setTransitionEndSupport()
export default Util
diff --git a/assets/scss/_colors.scss b/assets/scss/_colors.scss
index ce5342027..06638cae9 100644
--- a/assets/scss/_colors.scss
+++ b/assets/scss/_colors.scss
@@ -1,4 +1,4 @@
-// Material colour palette
+// Material color palette
// Based on https://material.google.com/style/color.html#color-color-palette
$material-color-amber-050: #fff8e1 !default;
@@ -113,16 +113,16 @@ $material-color-green-a200: #69f0ae !default;
$material-color-green-a400: #00e676 !default;
$material-color-green-a700: #00c853 !default;
-$material-color-grey-050: #fafafa !default;
-$material-color-grey-100: #f5f5f5 !default;
-$material-color-grey-200: #eeeeee !default;
-$material-color-grey-300: #e0e0e0 !default;
-$material-color-grey-400: #bdbdbd !default;
-$material-color-grey-500: #9e9e9e !default;
-$material-color-grey-600: #757575 !default;
-$material-color-grey-700: #616161 !default;
-$material-color-grey-800: #424242 !default;
-$material-color-grey-900: #212121 !default;
+$material-color-grey-050: #fafafa !default; // rgba(0,0,0, .02)
+$material-color-grey-100: #f5f5f5 !default; // rgba(0,0,0, .04)
+$material-color-grey-200: #eeeeee !default; // ~ rgba(0,0,0, .08)
+$material-color-grey-300: #e0e0e0 !default; // rgba(0,0,0, .12)
+$material-color-grey-400: #bdbdbd !default; // rgba(0,0,0, .14)
+$material-color-grey-500: #9e9e9e !default; // rgba(0,0,0, .38)
+$material-color-grey-600: #757575 !default; // rgba(0,0,0, .54)
+$material-color-grey-700: #616161 !default; // rgba(0,0,0, .62)
+$material-color-grey-800: #424242 !default; // rgba(0,0,0, .74)
+$material-color-grey-900: #212121 !default; // rgba(0,0,0, .87)
$material-color-indigo-050: #e8eaf6 !default;
$material-color-indigo-100: #c5cae9 !default;
@@ -275,6 +275,7 @@ $material-color-yellow-a400: #ffea00 !default;
$material-color-yellow-a700: #ffd600 !default;
// stylelint-disable scss/dollar-variable-default
+
$ambers: () !default;
$ambers: map-merge(
(
@@ -687,7 +688,8 @@ $colors: map-merge(
),
$colors
);
-// stylelint-enable
+
+// stylelint-enable scss/dollar-variable-default
// Black and white
// Based on https://material.google.com/style/color.html#color-text-background-colors
@@ -695,36 +697,55 @@ $colors: map-merge(
$black: #000000 !default;
$black-primary-opacity: 0.87 !default;
+$black-caption-opacity: 0.6 !default; // Form helper text
$black-secondary-opacity: 0.54 !default;
$black-hint-opacity: 0.38 !default;
$black-divider-opacity: 0.12 !default;
-$black-primary: rgba(red($black), green($black), blue($black), $black-primary-opacity) !default;
-$black-secondary: rgba(red($black), green($black), blue($black), $black-secondary-opacity) !default;
-$black-hint: rgba(red($black), green($black), blue($black), $black-hint-opacity) !default;
-$black-divider: rgba(red($black), green($black), blue($black), $black-divider-opacity) !default;
+$black-primary: rgba($black, $black-primary-opacity) !default;
+$black-caption: rgba($black, $black-caption-opacity) !default;
+$black-secondary: rgba($black, $black-secondary-opacity) !default;
+$black-hint: rgba($black, $black-hint-opacity) !default;
+$black-divider: rgba($black, $black-divider-opacity) !default;
$white: #ffffff !default;
$white-primary-opacity: 1 !default;
$white-secondary-opacity: 0.7 !default;
$white-hint-opacity: 0.5 !default;
-$white-divider-opacity: 0.12 !default;
-
-$white-primary: rgba(red($white), green($white), blue($white), $white-primary-opacity) !default;
-$white-secondary: rgba(red($white), green($white), blue($white), $white-secondary-opacity) !default;
-$white-hint: rgba(red($white), green($white), blue($white), $white-hint-opacity) !default;
-$white-divider: rgba(red($white), green($white), blue($white), $white-divider-opacity) !default;
+$white-divider-opacity: $black-divider-opacity !default;
+
+$white-primary: rgba($white, $white-primary-opacity) !default;
+$white-secondary: rgba($white, $white-secondary-opacity) !default;
+$white-hint: rgba($white, $white-hint-opacity) !default;
+$white-divider: rgba($white, $white-divider-opacity) !default;
+
+// States
+// Based on https://material.io/design/interaction/states.html#usage
+
+$overlay-hover-colored-opacity: 0.08 !default;
+$overlay-focus-colored-opacity: 0.24 !default;
+$overlay-selected-colored-opacity: 0.16 !default;
+$overlay-activated-colored-opacity: 0.24 !default;
+$overlay-pressed-colored-opacity: 0.32 !default;
+//$overlay-dragged-colored-opacity: .16 !default;
+
+$overlay-hover-white-opacity: 0.04 !default;
+$overlay-focus-white-opacity: 0.12 !default;
+$overlay-selected-white-opacity: 0.08 !default;
+$overlay-activated-white-opacity: 0.12 !default;
+$overlay-pressed-white-opacity: 0.12 * 2 !default;
+// $overlay-dragged-white-opacity: 0.08 !default;
// Theme
// Based on https://material.google.com/style/color.html#color-themes
-$dark-theme-1: #000000 !default;
+$dark-theme-1: $black !default;
$dark-theme-2: $material-color-grey-900 !default;
$dark-theme-3: #303030 !default;
-$dark-theme-4: $material-color-grey-800 !default;
+$dark-theme-4: #3c3c46 !default;
$light-theme-1: $material-color-grey-300 !default;
$light-theme-2: $material-color-grey-100 !default;
$light-theme-3: $material-color-grey-050 !default;
-$light-theme-4: #ffffff !default;
+$light-theme-4: $white !default;
diff --git a/assets/scss/_functions.scss b/assets/scss/_functions.scss
index bf3c492b7..8dc3ec6ab 100644
--- a/assets/scss/_functions.scss
+++ b/assets/scss/_functions.scss
@@ -1,37 +1,67 @@
+// Bootstrap functions
+//
+// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
+
+// stylelint-disable at-rule-empty-line-before
+
+// Ascending
+// Used to evaluate Sass maps like our grid breakpoints.
@mixin _assert-ascending($map, $map-name) {
$prev-key: null;
$prev-num: null;
@each $key, $num in $map {
- @if $prev-num == null {
+ @if $prev-num == null or unit($num) == '%' or unit($prev-num) == '%' {
// Do nothing
- } @else if not comparable($num, $prev-num) {
- @warn 'Potentially invalid value for #{$map-name}: This map must be in ascending order, but key "#{$key}" has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key "#{$prev-key}"!';
- } @else if $num <= $prev-num {
- @warn 'Invalid value for #{$map-name}: This map must be in ascending order, but key "#{$key}" has value #{$num} which is not greater than #{$prev-num}, the value of the previous key "#{$prev-key}"!';
+ } @else if not comparable($prev-num, $num) {
+ @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
+ } @else if $prev-num >= $num {
+ @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
}
-
$prev-key: $key;
$prev-num: $num;
}
}
-@mixin _assert-starts-at-zero($map) {
- $first-value: nth(map-values($map), 1);
+// Starts at zero
+// Used to ensure the min-width of the lowest breakpoint starts at 0.
+@mixin _assert-starts-at-zero($map, $map-name: '$grid-breakpoints') {
+ @if length($map) > 0 {
+ $values: map-values($map);
+ $first-value: nth($values, 1);
- @if $first-value != 0 {
- @warn 'First breakpoint in `$grid-breakpoints` must start at 0, but starts at #{$first-value}.';
+ @if $first-value != 0 {
+ @warn 'First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.';
+ }
}
}
-// Colour contrast
+// See https://codepen.io/kevinweber/pen/dXWoRw
+//
+// Requires the use of quotes around data URIs.
+
+@function escape-svg($string) {
+ @if str-index($string, 'data:image/svg+xml') {
+ @each $char, $encoded in $escaped-characters {
+ // Do not escape the url brackets
+ @if str-index($string, 'url(') == 1 {
+ $string: url('#{str-replace(str-slice($string, 6, -3), $char, $encoded)}');
+ } @else {
+ $string: str-replace($string, $char, $encoded);
+ }
+ }
+ }
-@function color-yiq($color) {
+ @return $string;
+}
+
+// Color contrast
+@function color-yiq($color) { // color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
$r: red($color);
$g: green($color);
$b: blue($color);
- $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
+ $yiq: (($r * 299) + ($g * 587) + ($b * 114)) * 0.001;
@if ($yiq >= $yiq-contrasted-threshold) {
@return $yiq-text-dark;
@@ -41,6 +71,7 @@
}
// Replace `$key` with `$replace` in `$content`
+// Different from BS 4.4.1
@function str-replace($content, $key, $replace: '') {
$index: str-index($content, $key);
@@ -70,8 +101,108 @@
@return map-get(map-get($theme-colors, $key), light);
}
+// Return valid calc
+@function add($value1, $value2, $return-calc: true) {
+ @if $value1 == null {
+ @return $value2;
+ }
+
+ @if $value2 == null {
+ @return $value1;
+ }
+
+ @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
+ @return $value1 + $value2;
+ }
+
+ @return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(' + ') + $value2);
+}
+
+@function subtract($value1, $value2, $return-calc: true) {
+ @if $value1 == null and $value2 == null {
+ @return null;
+ }
+
+ @if $value1 == null {
+ @return -$value2;
+ }
+
+ @if $value2 == null {
+ @return $value1;
+ }
+
+ @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
+ @return $value1 - $value2;
+ }
+
+ @if type-of($value2) != number {
+ $value2: unquote('(") + $value2 + unquote(")');
+ }
+
+ @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(' - ') + $value2);
+}
+
+@function divide($dividend, $divisor, $precision: 10) {
+ $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);
+ $dividend: abs($dividend);
+ $divisor: abs($divisor);
+ @if $dividend == 0 {
+ @return 0;
+ }
+ @if $divisor == 0 {
+ @error 'Cannot divide by 0';
+ }
+ $remainder: $dividend;
+ $result: 0;
+ $factor: 10;
+ @while ($remainder > 0 and $precision >= 0) {
+ $quotient: 0;
+ @while ($remainder >= $divisor) {
+ $remainder: $remainder - $divisor;
+ $quotient: $quotient + 1;
+ }
+ $result: $result * 10 + $quotient;
+ $factor: $factor * 0.1;
+ $remainder: $remainder * 10;
+ $precision: $precision - 1;
+ @if ($precision < 0 and $remainder >= $divisor * 5) {
+ $result: $result + 1;
+ }
+ }
+ $result: $result * $factor * $sign;
+ $dividend-unit: unit($dividend);
+ $divisor-unit: unit($divisor);
+ $unit-map: (
+ 'px': 1px,
+ 'rem': 1rem,
+ 'em': 1em,
+ '%': 1%
+ );
+ @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {
+ $result: $result * map-get($unit-map, $dividend-unit);
+ }
+ @return $result;
+}
+
// Strip unit
@function strip-unit($val) {
@return $val / ($val * 0 + 1);
}
+
+// Use secondary color for selection controls/inputs
+
+@function selection-theme-color() {
+ @if $secondary-color-for-controls {
+ @return theme-color(secondary);
+ } @else {
+ @return theme-color(primary);
+ }
+}
+
+// RGBA to RGB
+// Credits: https://makandracards.com/makandra/42500-sass-how-to-convert-an-rgba-color-to-its-rgb-look-alike
+
+@function rgba-to-rgb($rgba, $background: #fff) {
+ @return mix(rgb(red($rgba), green($rgba), blue($rgba)), $background, alpha($rgba) * 100%);
+}
diff --git a/assets/scss/_mixins.scss b/assets/scss/_mixins.scss
index daf8cb8b2..1e8cc56aa 100644
--- a/assets/scss/_mixins.scss
+++ b/assets/scss/_mixins.scss
@@ -1,21 +1,34 @@
-@import 'mixins/background-variant';
-@import 'mixins/border-radius';
-@import 'mixins/breakpoint';
-@import 'mixins/clearfix';
-@import 'mixins/float';
-@import 'mixins/form';
-@import 'mixins/grid';
-@import 'mixins/grid-framework';
+@import 'mixins/deprecate';
+
+// Utilities
+@import 'mixins/breakpoints';
@import 'mixins/hover';
@import 'mixins/image';
-@import 'mixins/list';
-@import 'mixins/material-icons';
-@import 'mixins/nav-divider';
+@import 'mixins/resize';
+@import 'mixins/screen-reader';
@import 'mixins/reset-text';
-@import 'mixins/screenreader';
-@import 'mixins/text-alignment';
@import 'mixins/text-emphasis';
@import 'mixins/text-hide';
@import 'mixins/text-truncate';
+@import 'mixins/visibility';
+
+// Components
+@import 'mixins/lists';
+@import 'mixins/nav-divider';
+@import 'mixins/forms';
+
+// Skins
+@import 'mixins/background-variant';
+@import 'mixins/border-radius';
@import 'mixins/transition';
+
+// Layout
+@import 'mixins/clearfix';
+@import 'mixins/grid-framework';
+@import 'mixins/grid';
+@import 'mixins/float';
+
+// Material
+@import 'mixins/material-icons';
+@import 'mixins/text-alignment';
@import 'mixins/typography';
diff --git a/assets/scss/_plugins.scss b/assets/scss/_plugins.scss
new file mode 100644
index 000000000..859c30b74
--- /dev/null
+++ b/assets/scss/_plugins.scss
@@ -0,0 +1,6 @@
+
+@import 'plugins/datatables';
+@import 'plugins/flatpickr';
+@import 'plugins/ion-rangeslider';
+@import 'plugins/select2';
+@import 'plugins/textarea-autosize';
diff --git a/assets/scss/_print.scss b/assets/scss/_print.scss
index d663664a8..de634f46f 100644
--- a/assets/scss/_print.scss
+++ b/assets/scss/_print.scss
@@ -2,37 +2,41 @@
@if $enable-print-styles {
@media print {
- @page {
- size: $print-page-size;
- }
-
*,
- *::after,
- *::before {
+ *::before,
+ *::after {
box-shadow: none !important;
text-shadow: none !important;
}
a:not(.btn) {
- text-decoration: underline;
+ //text-decoration: underline;
}
- // stylelint-disable-next-line selector-no-qualifying-type
+ // stylelint-disable
abbr[title]::after {
- content: ' (" attr(title) ") ';
+ content: ' ("attr(title) ") ';
}
+ // stylelint-enable
+ pre {
+ white-space: pre-wrap !important;
+ }
+
+ pre,
blockquote {
+ border: $border-width solid rgba($black, 0.12);
page-break-inside: avoid;
}
- body {
- min-width: $print-body-min-width !important;
+ tr,
+ img {
+ page-break-inside: avoid;
}
+ p,
h2,
- h3,
- p {
+ h3 {
orphans: 3;
widows: 3;
}
@@ -42,29 +46,67 @@
page-break-inside: avoid;
}
- img {
- page-break-inside: avoid;
+ // stylelint-disable
+ @page {
+ size: $print-page-size;
}
+ // stylelint-enable
- pre {
- page-break-inside: avoid;
- white-space: pre-wrap !important;
+ body {
+ min-width: $print-body-min-width !important;
}
- thead {
- display: table-header-group;
+ .container {
+ min-width: $print-body-min-width !important;
}
- tr {
- page-break-inside: avoid;
+ .fab-actions,
+ .navbar,
+ .tooltip {
+ display: none;
}
- .card {
- border: $border-width solid $border-color-solid;
+ .badge {
+ border: $border-width solid $black;
}
- .container {
- min-width: $print-body-min-width !important;
+ .table {
+ border-collapse: collapse !important;
+
+ td,
+ th {
+ background-color: $white !important;
+ }
+ }
+
+ .table-bordered {
+ th,
+ td {
+ border: 1px solid $border-color-solid;
+ }
+ }
+
+ .table-dark {
+ color: inherit;
+
+ th,
+ td,
+ thead th,
+ tbody + tbody {
+ border-color: $border-color-solid;
+ }
+ }
+
+ .table .thead-dark th {
+ border-color: $border-color-solid;
+ color: inherit;
+ }
+
+ // ADDITIONS
+
+ .card {
+ border: $border-width solid $border-color-solid;
+ page-break-inside: avoid;
}
.dropdown-menu {
@@ -99,40 +141,8 @@
border-bottom: $border-width solid $border-color-solid;
}
- .navbar {
- display: none;
- }
-
.popover {
border: $border-width solid $border-color-solid;
}
-
- .table {
- td,
- th {
- background-color: $white !important;
- }
- }
-
- .table-bordered {
- border: $border-width solid $border-color-solid;
- }
-
- .table-dark {
- color: inherit;
-
- td,
- th,
- .table {
- border-color: $border-color-solid;
- }
- }
-
- .table .thead-dark {
- td,
- th {
- color: inherit;
- }
- }
}
}
diff --git a/assets/scss/_theme.scss b/assets/scss/_theme.scss
new file mode 100644
index 000000000..b734591ea
--- /dev/null
+++ b/assets/scss/_theme.scss
@@ -0,0 +1,15 @@
+@if $material-theme == 'material2' {
+ // _spacer
+ $border-radius: 4px;
+ $border-radius-sm: 2px;
+ $border-radius-lg: $border-radius * 4;
+
+ // Chip
+ $chip-border-radius: $border-radius-lg;
+ $chip-icon-size: 1.25rem;
+ $chip-padding-x: 0.75rem;
+
+ // Tooltip
+ $tooltip-bg: #6d6d6d;
+ $tooltip-border-radius: $border-radius;
+}
diff --git a/assets/scss/_utilities.scss b/assets/scss/_utilities.scss
index 576075365..7ca9324ee 100644
--- a/assets/scss/_utilities.scss
+++ b/assets/scss/_utilities.scss
@@ -1,20 +1,26 @@
// Bootstrap
@import 'utilities/align';
-@import 'utilities/border';
@import 'utilities/background';
+@import 'utilities/borders';
@import 'utilities/clearfix';
@import 'utilities/display';
+@import 'utilities/embed';
@import 'utilities/flex';
@import 'utilities/float';
+@import 'utilities/interactions';
+@import 'utilities/overflow';
@import 'utilities/position';
-@import 'utilities/screenreader';
+@import 'utilities/ripple';
+@import 'utilities/screenreaders';
@import 'utilities/shadows';
@import 'utilities/sizing';
@import 'utilities/spacing';
+@import 'utilities/stretched-link';
@import 'utilities/text';
@import 'utilities/visibility';
// Material
-
@import 'utilities/material-icons';
+@import 'utilities/scrollbars';
+@import 'utilities/webkit-custom';
diff --git a/assets/scss/_variables.scss b/assets/scss/_variables.scss
index 1fa543eb4..f8331ae17 100644
--- a/assets/scss/_variables.scss
+++ b/assets/scss/_variables.scss
@@ -1,7 +1,22 @@
-// Sass option
+// Options
+//
+// Quickly modify global styling by enabling or disabling optional features.
$enable-grid-classes: true !default;
+$enable-pointer-cursor-for-buttons: true !default;
$enable-print-styles: true !default;
+//$enable-responsive-font-sizes: false !default; // TODO
+$enable-validation-icons: true !default;
+$enable-deprecation-messages: true !default;
+$enable-dark-theme-media-query: false !default; // If true, Material's Dark theme will be auto applied when user has set Dark mode to be default's browser theme.
+
+//$enable-negative-margins: true !default; // Include negative margin/padding utilities
+$enable-validation-valid: true !default; // Apply Success color to valid inputs (not recommended)
+$secondary-color-for-controls: false !default; // Use secondary color for selection/inputs (primary color otherwise, not recommended)
+$enable-form-ripple: true !default; // Animate bottom line of inputs/forms
+$enable-ripple: true !default; // Enable ripple effect on components (Buttons, menus)
+
+$material-theme: 'material3' !default; // Set a theme. Available are material2, Material 3 (aka Material You, default)
// Variables
diff --git a/assets/scss/base/_base.scss b/assets/scss/base/_base.scss
index 80dd8d6bb..f7e70cc19 100644
--- a/assets/scss/base/_base.scss
+++ b/assets/scss/base/_base.scss
@@ -1,25 +1,32 @@
:root {
- @each $bp, $value in $grid-breakpoints {
- --breakpoint-#{$bp}: #{$value};
- }
+ // Custom variable values only support SassScript inside `#{}`.
@each $color, $value in $colors {
--#{$color}: #{$value};
}
@each $color, $values in $theme-colors {
@each $level, $value in $values {
- @if $level == 'color' {
+ @if $level=='color' {
--#{$color}: #{$value};
- } @else {
+ }
+
+ @else {
--#{$color}-#{$level}: #{$value};
}
}
}
- --font-family-monospace: #{inspect($font-family-monospace)};
+ @each $bp, $value in $grid-breakpoints {
+ --breakpoint-#{$bp}: #{$value};
+ }
+
+ // Use `inspect` for lists so that quoted items keep the quotes.
+ // See https://github.com/sass/sass/issues/2383#issuecomment-336349172
+
--font-family-sans-serif: #{inspect($font-family-sans-serif)};
- --font-family-serif: #{inspect($font-family-serif)};
+ --font-family-monospace: #{inspect($font-family-monospace)};
+ --font-family-material-icons: #{inspect($material-icon-font-family)};
}
// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
@@ -27,19 +34,30 @@
// Box sizing
*,
-*::after,
-*::before {
- box-sizing: inherit;
+*::before,
+*::after {
+ box-sizing: border-box;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
-@at-root {
- // stylelint-disable-next-line at-rule-no-vendor-prefix
- @-ms-viewport {
- width: device-width;
+// Thanks to https://www.belter.io/prefers-reduced-motion/
+@media (prefers-reduced-motion: reduce) {
+ * {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
}
}
-// Document
+html {
+ font-family: sans-serif;
+ line-height: 1.15;
+ scroll-behavior: smooth;
+ text-size-adjust: 100%;
+ -webkit-tap-highlight-color: $webkit-tap-highlight-color;
+}
article,
aside,
@@ -60,347 +78,402 @@ body {
background-color: $body-bg;
color: $body-color;
font-family: $font-family-base;
- font-size: $font-size-base;
- -moz-osx-font-smoothing: grayscale;
- -webkit-font-smoothing: antialiased;
+ font-size: ($font-size-base * 0.875);
font-weight: $font-weight-base;
line-height: $line-height-base;
margin: 0;
}
-html {
- box-sizing: border-box;
- font-family: sans-serif;
- line-height: 1.15;
- text-size-adjust: 100%;
- -ms-overflow-style: scrollbar;
- -webkit-tap-highlight-color: $webkit-tap-highlight-color;
+[tabindex='-1']:focus:not(:focus-visible) {
+ outline: 0 !important;
}
-[tabindex='-1']:focus {
- outline: 0 !important;
+[id] {
+ // Leave a margin above scroll target
+ scroll-margin-top: 2ex;
}
-// Code
+hr {
+ box-sizing: content-box;
+ height: 0;
+ overflow: visible;
+}
-code,
-kbd,
-pre,
-samp {
- font-family: $font-family-monospace;
- font-size: 1em;
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin-top: 0;
+ margin-bottom: $headings-margin-y;
}
-pre {
+p {
margin-top: 0;
- margin-bottom: $pre-margin-y;
- overflow: auto;
- -ms-overflow-style: scrollbar;
+ margin-bottom: $paragraph-margin-y;
}
-// Content grouping
+abbr[title],
+abbr[data-original-title] {
+ border-bottom: 0;
+ cursor: help;
+ text-decoration: underline;
+ text-decoration: underline dotted;
+ text-decoration-skip-ink: none;
+}
-figure {
- margin: 0 0 $paragraph-margin-y;
+address {
+ font-style: normal;
+ line-height: inherit;
}
-hr {
- box-sizing: content-box;
- height: 0;
- overflow: visible;
+address,
+dd,
+ol,
+ul {
+ margin-top: 0;
+ margin-bottom: $paragraph-margin-y;
+}
+
+dt {
+ font-weight: $dt-font-weight;
}
-// Form
+dd {
+ margin: $paragraph-margin-y 0;
-button,
-input,
-optgroup,
-select,
-textarea {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- margin: 0;
+ &:not([class*='col']) {
+ padding-left: 2.5rem;
+
+ > ol,
+ > ul {
+ padding-left: 0;
+ }
+ }
}
-button,
-html [type='button'],
-[type='reset'],
-[type='submit'] {
- -webkit-appearance: button;
+blockquote {
+ margin: 0 0 $paragraph-margin-y;
}
-button::-moz-focus-inner,
-[type='button']::-moz-focus-inner,
-[type='reset']::-moz-focus-inner,
-[type='submit']::-moz-focus-inner {
- border-style: none;
- padding: 0;
+b,
+strong {
+ font-weight: $font-weight-bold;
}
-button,
-input {
- overflow: visible;
+small {
+ font-size: 75%;
}
-button,
-select {
- text-transform: none;
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
}
-button:focus {
- outline: 1px dotted;
- outline: 5px auto -webkit-focus-ring-color;
+sub {
+ bottom: -0.25em;
}
-fieldset {
- border: 0;
- margin: 0;
- min-width: 0;
- padding: 0;
+sup {
+ top: -0.5em;
}
-input {
- &[type='checkbox'],
- &[type='radio'] {
- box-sizing: border-box;
- padding: 0;
+//
+// Links
+//
+
+a {
+ background-color: transparent;
+ color: $link-color;
+ text-decoration: $link-decoration;
+
+ &:hover {
+ color: $link-color-hover;
+ // text-decoration: $link-decoration-hover;
}
+}
- &[type='date'],
- &[type='datetime-local'],
- &[type='month'],
- &[type='time'] {
- -webkit-appearance: listbox;
+a:not([href]):not([class]) {
+ &,
+ &:hover {
+ color: inherit;
+ text-decoration: none;
}
}
-label {
- @include typography-caption;
+//
+// Code
+//
- color: $textfield-hint-color;
- display: inline-block;
+pre,
+code,
+kbd,
+samp {
+ font-family: $font-family-monospace;
+ font-size: 1em;
}
-legend {
- @include typography-headline;
-
- color: inherit;
+pre {
display: block;
- margin-bottom: $headings-margin-y;
- max-width: 100%;
- padding: 0;
- white-space: normal;
- width: 100%;
+ margin-top: 0;
+ margin-bottom: $pre-margin-y;
+ overflow: auto;
+ -ms-overflow-style: scrollbar;
+ user-select: all;
}
-output {
- display: inline-block;
+figure {
+ margin: 0 0 $paragraph-margin-y;
}
-progress {
- vertical-align: baseline;
+// Images
+
+img {
+ border-style: none;
+ vertical-align: middle;
}
-select {
- &[multiple],
- &[size] {
- overflow: auto;
- }
+svg {
+ overflow: hidden;
+ vertical-align: middle;
}
-textarea {
- overflow: auto;
- resize: vertical;
+// Tables
+
+table {
+ border-collapse: collapse;
}
-[type='number']::-webkit-inner-spin-button,
-[type='number']::-webkit-outer-spin-button {
- height: auto;
+caption {
+ @include text-align(left);
+
+ border-top: $table-border-width solid $table-border-color;
+ caption-side: bottom;
+ color: $table-caption-color;
+ font-size: $font-size-subtitle-2;
+ letter-spacing: $letter-spacing-subtitle-2;
+ line-height: $line-height-subtitle-2;
+ padding: $table-thead-padding-y $table-cell-padding-x;
}
-[type='search'] {
- -webkit-appearance: none;
- outline-offset: -2px;
+// 1. Removes font-weight bold by inheriting
+// 2. Matches default `
` alignment by inheriting `text-align`.
+// 3. Fix alignment for Safari
+
+th {
+ font-weight: $table-th-font-weight; // 1
+ text-align: inherit; // 2
+ text-align: -webkit-match-parent; // 3
}
-[type='search']::-webkit-search-cancel-button,
-[type='search']::-webkit-search-decoration {
- -webkit-appearance: none;
+//
+// Forms
+//
+
+label {
+ @include typography-caption;
+
+ color: $textfield-caption-color;
+ display: inline-block;
+ user-select: none;
}
-::-webkit-file-upload-button {
- -webkit-appearance: button;
- font: inherit;
+button {
+ border-radius: 0;
}
-// Hidden
+// Explicitly remove focus outline in Chromium when it shouldn't be
+// visible (e.g. as result of mouse click or touch tap). It already
+// should be doing this automatically, but seems to currently be
+// confused and applies its very visible two-tone outline anyway.
-[hidden] {
- display: none !important;
+button:focus:not(:focus-visible) {
+ outline: 0;
}
-// Images
-
-img {
- border-style: none;
- vertical-align: middle;
+input,
+button,
+select,
+optgroup,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+ margin: 0;
}
-svg:not(:root) {
- overflow: hidden;
+button,
+input {
+ overflow: visible;
}
-// Interactive
+button,
+select {
+ text-transform: none;
+}
-summary {
+[role='button'] {
cursor: pointer;
- display: list-item;
}
-// Link
-
-a {
- background-color: transparent;
- color: $link-color;
- text-decoration: $link-decoration;
- -webkit-text-decoration-skip: objects;
+select {
+ word-wrap: normal;
- @include active-focus-hover {
- color: $link-color-hover;
- text-decoration: $link-decoration-hover;
+ &[multiple],
+ &[size] {
+ overflow: auto;
}
}
-a:not([href]):not([tabindex]) {
- color: inherit;
- text-decoration: none;
+button,
+[type='button'],
+[type='reset'],
+[type='submit'] {
+ -webkit-appearance: button;
+}
- @include active-focus-hover {
- color: inherit;
- text-decoration: none;
+@if $enable-pointer-cursor-for-buttons {
+ button,
+ [type='button'],
+ [type='reset'],
+ [type='submit'] {
+ &:not(:disabled) {
+ cursor: pointer;
+ }
}
- &:focus {
- outline: 0;
+ .btn:not(.disabled):not(:disabled),
+ input:enabled + label:hover {
+ cursor: pointer;
}
}
-// Scripting
+button::-moz-focus-inner,
+[type='button']::-moz-focus-inner,
+[type='reset']::-moz-focus-inner,
+[type='submit']::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
+}
-template {
- display: none;
+input[type='radio'],
+input[type='checkbox'] {
+ box-sizing: border-box;
+ padding: 0;
}
-// Table
+textarea {
+ resize: vertical;
+}
-caption {
- @include text-align(left);
+fieldset {
+ border: 0;
+ margin: 0;
+ min-width: 0;
+ padding: 0;
+}
+
+legend {
@include typography-caption;
- caption-side: bottom;
- color: $table-caption-color;
- min-height: $table-thead-cell-height;
- padding: $table-thead-padding-y $table-cell-padding-x-alt;
-}
+ float: left;
+ margin-bottom: $headings-margin-y;
+ padding: 0;
+ width: 100%;
-table {
- border-collapse: collapse;
+ + * {
+ clear: left;
+ }
}
-th {
- @include text-align(left);
+::-webkit-datetime-edit-fields-wrapper,
+::-webkit-datetime-edit-text,
+::-webkit-datetime-edit-minute,
+::-webkit-datetime-edit-hour-field,
+::-webkit-datetime-edit-day-field,
+::-webkit-datetime-edit-month-field,
+::-webkit-datetime-edit-year-field {
+ padding: 0;
}
-// Typography
-
-abbr {
- &[data-original-title],
- &[title] {
- border-bottom: 0;
- cursor: help;
- text-decoration: underline dotted;
- }
+::-webkit-inner-spin-button {
+ height: auto;
}
-address {
- font-style: normal;
- line-height: inherit;
- margin-bottom: $paragraph-margin-y;
+[type='search'] {
+ -webkit-appearance: textfield;
+ outline-offset: -2px;
}
-b,
-strong {
- font-weight: bolder;
+::-webkit-search-decoration {
+ -webkit-appearance: none;
}
-blockquote {
- margin: 0 0 $paragraph-margin-y;
+::-webkit-color-swatch-wrapper {
+ padding: 0;
}
-dd {
- margin-bottom: $headings-margin-y;
- margin-left: 0;
+::file-selector-button {
+ font: inherit;
}
-dfn {
- font-style: italic;
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit;
}
-dl,
-ol,
-ul {
- margin-top: 0;
- margin-bottom: $paragraph-margin-y;
+//
+// Correct element displays
+//
+
+output {
+ display: inline-block;
}
-dt {
- font-weight: $dt-font-weight;
+iframe {
+ border: 0;
}
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- margin-top: 0;
- margin-bottom: $headings-margin-y;
+summary {
+ cursor: pointer;
+ display: list-item;
}
-mark {
- background-color: $mark-bg;
- color: $mark-color;
+template {
+ display: none;
}
-ol ol,
-ol ul,
-ul ol,
-ul ul {
- margin-bottom: 0;
+progress {
+ vertical-align: baseline;
}
-p {
- margin-top: 0;
- margin-bottom: $paragraph-margin-y;
+[hidden] {
+ display: none !important;
}
-small {
- font-size: 80%;
+// Additions
+
+@at-root {
+
+ // stylelint-disable-next-line at-rule-no-vendor-prefix
+ @-ms-viewport {
+ width: device-width;
+ }
}
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
+dfn {
+ font-style: italic;
}
-sub {
- bottom: -0.25em;
+::selection {
+ background-color: rgba(theme-color('primary'), $overlay-selected-white-opacity); // Material Addition
}
-sup {
- top: -0.5em;
+.disabled:hover,
+:disabled:hover {
+ cursor: default;
}
diff --git a/assets/scss/base/_grid.scss b/assets/scss/base/_grid.scss
index d8a4da5cd..54578c1c2 100644
--- a/assets/scss/base/_grid.scss
+++ b/assets/scss/base/_grid.scss
@@ -1,31 +1,57 @@
-// Column
+// Container widths
+//
+// Set the container width, and override it for fixed navbars in media queries.
+// stylelint-disable
@if $enable-grid-classes {
- @include make-grid-columns;
-}
+ // Single container class with breakpoint max-widths
+ .container,
+ // 100% wide container at all breakpoints
+ .container-fluid {
+ @include make-container();
+ }
-// Container
+ // Responsive containers that are 100% wide until a breakpoint
+ @each $breakpoint, $container-max-width in $container-max-widths {
+ .container-#{$breakpoint} {
+ @extend .container-fluid;
+ }
-@if $enable-grid-classes {
- .container {
- @include make-container;
- @include make-container-max-widths;
- }
-}
+ @include media-breakpoint-up($breakpoint, $grid-breakpoints) {
+ %responsive-container-#{$breakpoint} {
+ max-width: $container-max-width;
+ }
-@if $enable-grid-classes {
- .container-fluid {
- @include make-container;
+ // Extend each breakpoint which is smaller or equal to the current breakpoint
+ $extend-breakpoint: true;
+
+ @each $name, $width in $grid-breakpoints {
+ @if ($extend-breakpoint) {
+ .container#{breakpoint-infix($name, $grid-breakpoints)} {
+ @extend %responsive-container-#{$breakpoint};
+ }
+
+ // Once the current breakpoint is reached, stop extending
+ @if ($breakpoint == $name) {
+ $extend-breakpoint: false;
+ }
+ }
+ }
+ }
}
}
// Row
+//
+// Rows contain your columns.
@if $enable-grid-classes {
.row {
- @include make-row;
+ @include make-row();
}
+ // Remove the negative margin from default .row, then the horizontal padding
+ // from all immediate children columns (to prevent runaway style inheritance).
.no-gutters {
margin-right: 0;
margin-left: 0;
@@ -37,3 +63,11 @@
}
}
}
+
+// Columns
+//
+// Common styles for small and large grid columns
+
+@if $enable-grid-classes {
+ @include make-grid-columns();
+}
diff --git a/assets/scss/base/_typography.scss b/assets/scss/base/_typography.scss
index 8f3d5ac2e..1ad737e92 100644
--- a/assets/scss/base/_typography.scss
+++ b/assets/scss/base/_typography.scss
@@ -1,89 +1,6 @@
-// Blockquote
-
-.blockquote {
- @include typography-title;
-
- border-left: $blockquote-border-width solid $blockquote-border-color;
- margin-bottom: $paragraph-margin-y;
- padding: 0 $spacer;
-}
-
-.blockquote-footer {
- @include typography-caption;
-
- color: $blockquote-small-color;
- display: block;
- margin-top: $spacer-xs;
-
- &::before {
- content: '\2014 \00A0';
- }
-}
-
-// Emphasis
-
-mark,
-.mark {
- background-color: $mark-bg;
- color: $mark-color;
- padding: $mark-padding;
-}
-
-small,
-.small {
- font-size: $small-font-size;
- font-weight: $font-weight-regular;
-}
-
-.initialism {
- font-size: 90%;
- text-transform: uppercase;
-}
-
-// Headings
-
-.typography-display-4 {
- @include typography-display-4;
-}
-
-.typography-display-3 {
- @include typography-display-3;
-}
-
-.typography-display-2 {
- @include typography-display-2;
-}
-
-.typography-display-1 {
- @include typography-display-1;
-}
-
-.typography-headline {
- @include typography-headline;
-}
-
-.typography-title {
- @include typography-title;
-}
-
-.typography-subheading {
- @include typography-subheading;
-}
-
-.typography-body-2 {
- @include typography-body-2;
-}
-
-.typography-body-1 {
- @include typography-body-1;
-}
-
-.typography-caption {
- @include typography-caption;
-}
// Headings - bootstrap classes
-
+// Keep compatibility for Material UI v1
h1,
h2,
h3,
@@ -102,56 +19,70 @@ h6,
}
h1,
-.h1 {
- @include typography-display-2;
-}
+.h1,
+.display-1,
+.typography-display-4,
+.typography-headline-1 { @include typography-headline-1; }
h2,
-.h2 {
- @include typography-display-1;
-}
+.h2,
+.display-2,
+.typography-display-3,
+.typography-headline-2 { @include typography-headline-2; }
h3,
-.h3 {
- @include typography-headline;
-}
+.h3,
+.display-3,
+.typography-display-2,
+.typography-headline-3 { @include typography-headline-3; }
h4,
-.h4 {
- @include typography-title;
-}
+.h4,
+.display-4,
+.typography-display-1,
+.typography-headline-4 { @include typography-headline-4; }
h5,
-.h5 {
- @include typography-subheading;
-}
+.h5,
+.typography-headline,
+.typography-headline-5 { @include typography-headline-5; }
h6,
-.h6 {
- @include typography-body-2;
+.h6,
+.lead,
+.typography-headline-6,
+.typography-title { @include typography-headline-6; }
+
+.typography-subheading,
+.typography-subtitle-1 {
+ @include typography-subtitle-1;
}
-.display-1 {
- @include typography-display-4;
+.typography-subtitle-2 {
+ @include typography-subtitle-2;
}
-.display-2 {
- @include typography-display-3;
+.typography-body-1 {
+ @include typography-body-1;
}
-.display-3 {
- @include typography-display-2;
+.typography-body-2 {
+ @include typography-body-2;
}
-.display-4 {
- @include typography-display-1;
+.typography-caption {
+ @include typography-caption;
}
-.lead {
- @include typography-title;
+.typography-overline {
+ @include typography-overline;
}
-// Hr
+p { font-size: 1rem; } // djibe addition
+
+//
+// Horizontal rules
+//
hr {
border: 0;
@@ -160,7 +91,57 @@ hr {
margin-bottom: $paragraph-margin-y;
}
-// List
+//
+// Emphasis
+//
+
+small,
+.small {
+ font-size: $small-font-size;
+ font-weight: $font-weight-regular;
+}
+
+mark,
+.mark {
+ background-color: $mark-bg;
+ color: $mark-color;
+ padding: $mark-padding;
+}
+
+//
+// Lists
+//
+
+ol {
+ list-style: decimal outside;
+
+ ol {
+ list-style-type: lower-alpha;
+ }
+}
+
+// djibe addition looks like https://developers.google.com/style/lists
+ul {
+ list-style: disc outside;
+
+ &:not([class]) {
+ padding-left: 2.5rem;
+
+ li {
+ font-size: inherit;
+ margin: 0.75rem 0;
+ padding: 0;
+ }
+ }
+}
+
+li > ul > li { // stylelint-disable-line selector-max-type
+ list-style-type: circle;
+}
+
+.list-unstyled {
+ @include list-unstyled;
+}
.list-inline {
@include list-unstyled;
@@ -174,6 +155,32 @@ hr {
}
}
-.list-unstyled {
- @include list-unstyled;
+//
+// Misc
+//
+
+.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+// Blockquotes
+.blockquote {
+ @include typography-body-1;
+
+ border-left: $blockquote-border-width solid $blockquote-border-color;
+ margin-bottom: $paragraph-margin-y;
+ padding: 0 $spacer;
+}
+
+.blockquote-footer {
+ @include typography-caption;
+
+ color: $blockquote-small-color;
+ display: block;
+ margin-top: $spacer-xs;
+
+ &::before {
+ content: '\2014 \00A0'; // —
+ }
}
diff --git a/assets/scss/bootstrap/_alert.scss b/assets/scss/bootstrap/_alert.scss
index 48ca6460f..c494ecb17 100644
--- a/assets/scss/bootstrap/_alert.scss
+++ b/assets/scss/bootstrap/_alert.scss
@@ -1,45 +1,56 @@
+//
+// Base styles
+//
+// Not sure it is OK to look like : https://material.io/design/components/banners.html#specs
+
.alert {
@include border-radius($alert-border-radius);
border: 0;
+ // border: 1px solid $black-divider;
+ color: $black-primary;
display: block;
margin-bottom: $alert-margin-y;
padding: $alert-padding-y $alert-padding-x;
position: relative;
}
-@each $color, $values in $theme-colors {
- .alert-#{$color} {
- background-color: theme-color-light($color);
- color: color-yiq(theme-color-light($color));
+// Headings for larger alerts
+.alert-link {
+ color: inherit;
+ font-weight: $alert-link-font-weight;
+
+ @include hover-focus-active {
+ color: inherit;
}
}
-// Dismissible
+// Dismissible alerts
+//
+// Expand the right padding and account for the close button's positioning.
.alert-dismissible {
- padding-right: ($alert-padding-x * 2 + $close-font-size);
+ padding-right: $close-font-size + $alert-padding-x * 2;
+ // Adjust close link position
.close {
- color: inherit;
- padding: ($alert-padding-y - ($close-font-size - $font-size-base * $line-height-base) / 2) $alert-padding-x;
+ color: $black-hint;
+ padding: ($alert-padding-y - ($close-font-size - $font-size-base * $line-height-base) * 0.5) $alert-padding-x;
position: absolute;
top: 0;
right: 0;
+ z-index: 2;
}
}
-// Misc
-
-.alert-heading {
- color: inherit;
-}
-
-.alert-link {
- color: inherit;
- font-weight: $alert-link-font-weight;
-
- @include active-focus-hover {
- color: inherit;
+// Alternate styles
+//
+// Generate contextual modifier classes for colorizing the alert.
+@each $color, $values in $theme-colors {
+ .alert-#{$color} {
+ background-color: rgba(theme-color($color), $overlay-selected-colored-opacity);
+ color: darken(theme-color($color), 15%);
}
}
+
+// @mixin alert-variant not used
diff --git a/assets/scss/bootstrap/_badge.scss b/assets/scss/bootstrap/_badge.scss
index 20193554b..1581fa7b4 100644
--- a/assets/scss/bootstrap/_badge.scss
+++ b/assets/scss/bootstrap/_badge.scss
@@ -1,36 +1,83 @@
+// Base class
+//
+// Requires one of the contextual, color modifier classes for `color` and
+// `background-color`.
+
.badge {
@include border-radius($badge-border-radius);
+ //@include transition($badge-transition);
align-items: center;
display: inline-flex;
- font-size: inherit;
+ font-size: inherit; //@include font-size($badge-font-size);
font-weight: $badge-font-weight;
+ justify-content: center;
line-height: inherit;
padding-right: $badge-padding-x;
padding-left: $badge-padding-x;
- text-align: center;
- vertical-align: baseline;
+ //text-align: center;
white-space: nowrap;
+ @at-root a#{&} {
+ @include hover-focus {
+ text-decoration: none;
+ }
+ }
+
+ // Empty badges collapse automatically
&:empty {
display: none;
}
- .btn & {
- margin-top: -1px;
- margin-bottom: -1px;
- padding-top: 1px;
- padding-bottom: 1px;
+ // Material addition : https://material.angular.io/components/badge/examples
+ .btn > &,
+ .position-relative > & {
+ border-radius: $badge-width * 0.5;
+ // display: inline-block;
+ font-family: Roboto, sans-serif;
+ font-size: $font-size-caption;
+ font-weight: $badge-btn-font-weight;
+ height: $badge-width;
+ letter-spacing: initial;
+ // line-height: $badge-width;
+ min-width: $badge-width;
+ position: absolute;
+ top: -$badge-width * 0.5;
+ }
+
+ .btn > &,
+ i > &,
+ [class*='material-icons'] > & {
+ top: 0;
+ right: 0;
+ transform: translate(50%, -50%);
+ transform-origin: 100% 0%;
+
+ &.badge-before {
+ right: auto;
+ left: 0;
+ transform: translate(-50%, -50%);
+ transform-origin: 0% 100%;
+ }
}
}
+// Pill badges with extra rounded corners
+
+.badge-pill {
+ @include border-radius(1em);
+
+ //padding-right: $badge-pill-padding-x;
+ //padding-left: $badge-pill-padding-x;
+}
+
@each $color, $values in $theme-colors {
.badge-#{$color} {
background-color: theme-color($color);
color: color-yiq(theme-color($color));
&[href] {
- @include active-focus-hover {
+ @include hover-focus-active {
background-color: theme-color-dark($color);
color: color-yiq(theme-color-dark($color));
text-decoration: none;
@@ -39,8 +86,4 @@
}
}
-// Pill badges with extra rounded corners
-
-.badge-pill {
- @include border-radius(1em);
-}
+// @mixin badge-variant not used
diff --git a/assets/scss/bootstrap/_breadcrumb.scss b/assets/scss/bootstrap/_breadcrumb.scss
index 2fb3f8b13..909bd7854 100644
--- a/assets/scss/bootstrap/_breadcrumb.scss
+++ b/assets/scss/bootstrap/_breadcrumb.scss
@@ -1,35 +1,37 @@
.breadcrumb {
- @include border-radius($breadcrumb-border-radius);
-
align-items: center;
- background-color: $breadcrumb-bg;
+ //background-color: $breadcrumb-bg;
display: flex;
flex-wrap: wrap;
list-style: none;
- margin-bottom: $breadcrumb-margin-y;
- min-height: $breadcrumb-height;
- padding: $breadcrumb-padding-y $breadcrumb-padding-x;
+ padding: 0; // reset Firefox
}
.breadcrumb-item {
- @include transition-standard(color);
-
align-items: center;
color: $breadcrumb-item-color;
display: flex;
+ font-size: $breadcrumb-font-size;
- @include active-focus-hover {
- color: $breadcrumb-item-color-hover;
+ &.active {
+ cursor: default;
}
- &.active {
- color: $breadcrumb-item-color-hover;
- font-weight: bolder;
+ &:only-child {
+ padding: $breadcrumb-padding-y $breadcrumb-padding-x;
}
a {
+ @include transition-standard(background-color);
+
+ border-radius: $spacer-sm;
color: inherit;
+ padding: $breadcrumb-padding-y $breadcrumb-padding-x;
text-decoration: none;
+
+ &:hover {
+ background-color: $breadcrumb-bg-hover;
+ }
}
+ .breadcrumb-item {
@@ -38,10 +40,17 @@
&::before {
@include set-material-icons;
- color: $breadcrumb-item-color;
- content: $breadcrumb-item-icon;
+ color: $black-secondary;
+ content: $breadcrumb-divider;
display: inline-block;
+ // float: left; // Suppress inline spacings and underlining of the separator
margin-right: $breadcrumb-inner-spacer-x;
}
}
+
+ // stylelint-disable
+ &.active::before {
+ margin-right: $breadcrumb-padding-x;
+ }
+ // stylelint-enable
}
diff --git a/assets/scss/bootstrap/_carousel.scss b/assets/scss/bootstrap/_carousel.scss
index b67131814..30ddef09d 100644
--- a/assets/scss/bootstrap/_carousel.scss
+++ b/assets/scss/bootstrap/_carousel.scss
@@ -1,7 +1,7 @@
.carousel {
position: relative;
- @include hover {
+ &:hover {
.carousel-control-next,
.carousel-control-prev {
opacity: 1;
@@ -113,14 +113,14 @@
height: $carousel-control-size;
justify-content: center;
line-height: 1;
- margin-top: ($carousel-control-size / -2);
+ margin-top: ($carousel-control-size * -0.5);
opacity: 0;
position: absolute;
top: 50%;
user-select: none;
width: $carousel-control-size;
- @include active-focus-hover {
+ @include hover-focus-active {
background-color: $carousel-control-bg-hover;
color: $carousel-control-color;
text-decoration: none;
@@ -137,11 +137,11 @@
}
.carousel-control-next {
- right: ($carousel-control-size / 2);
+ right: ($carousel-control-size * 0.5);
}
.carousel-control-prev {
- left: ($carousel-control-size / 2);
+ left: ($carousel-control-size * 0.5);
}
.carousel-control-next-icon,
@@ -162,9 +162,9 @@
.carousel-caption {
color: $carousel-caption-color;
position: absolute;
- right: ((100% - $carousel-caption-width) / 2);
+ right: ((100% - $carousel-caption-width) * 0.5);
bottom: ($carousel-indicator-size * 3);
- left: ((100% - $carousel-caption-width) / 2);
+ left: ((100% - $carousel-caption-width) * 0.5);
text-align: center;
z-index: 1;
}
diff --git a/assets/scss/bootstrap/_close.scss b/assets/scss/bootstrap/_close.scss
index 1680ad725..6666fcfcc 100644
--- a/assets/scss/bootstrap/_close.scss
+++ b/assets/scss/bootstrap/_close.scss
@@ -10,9 +10,10 @@
font-size: $close-font-size;
font-weight: $close-font-weight;
line-height: 1;
+ // opacity: .5;
padding: 0;
- @include active-focus-hover {
+ @include hover-focus-active {
color: $close-color-hover;
text-decoration: none;
}
@@ -25,3 +26,15 @@
cursor: pointer;
}
}
+
+// stylelint-disable
+button.close {
+ background-color: transparent;
+ border: 0;
+ padding: 0;
+}
+
+a.close.disabled {
+ pointer-events: none;
+}
+// stylelint-enable
diff --git a/assets/scss/bootstrap/_code.scss b/assets/scss/bootstrap/_code.scss
index 8a265ca1b..c5b6fef70 100644
--- a/assets/scss/bootstrap/_code.scss
+++ b/assets/scss/bootstrap/_code.scss
@@ -5,7 +5,7 @@ code {
color: $code-color;
font-size: $code-font-size;
padding: $code-padding-y $code-padding-x;
- word-break: break-word;
+ word-wrap: break-word;
a > & {
color: inherit;
@@ -22,7 +22,7 @@ kbd {
kbd {
font-size: 100%;
- font-weight: bolder;
+ font-weight: $font-weight-bolder;
padding: 0;
}
}
diff --git a/assets/scss/bootstrap/_form.scss b/assets/scss/bootstrap/_form.scss
deleted file mode 100644
index 494c43dce..000000000
--- a/assets/scss/bootstrap/_form.scss
+++ /dev/null
@@ -1,173 +0,0 @@
-// Checkbox and radio button
-
-.form-check {
- display: block;
- margin-bottom: $textfield-margin-y;
- padding-left: $form-check-input-gutter;
- position: relative;
-}
-
-.form-check-inline {
- display: inline-block;
- margin-right: $form-check-inline-margin-x;
- margin-bottom: 0;
-}
-
-.form-check-input {
- margin-top: (($font-size-base * $line-height-base - $font-size-base) / 3 * 2);
- margin-left: ($form-check-input-gutter * -1);
- position: absolute;
-
- &:disabled ~ .form-check-label {
- color: $textfield-color-disabled;
- }
-}
-
-.form-check-label {
- color: inherit;
- font-size: inherit;
- line-height: inherit;
-}
-
-// Form group
-
-.form-group {
- margin-bottom: $form-group-margin-y;
-}
-
-.form-row {
- display: flex;
- flex-wrap: wrap;
- margin-right: ($textfield-margin-x / -2);
- margin-left: ($textfield-margin-x / -2);
-
- > .col,
- > [class*='col-'] {
- padding-right: ($textfield-margin-x / 2);
- padding-left: ($textfield-margin-x / 2);
- }
-}
-
-// Inline
-
-.form-inline {
- align-items: center;
- display: flex;
- flex-flow: row wrap;
-
- .custom-file,
- .custom-select {
- width: auto;
- }
-
- .form-check {
- margin-bottom: 0;
- width: auto;
- }
-
- .form-control,
- .form-control-file {
- display: inline-block;
- vertical-align: middle;
- width: auto;
- }
-
- .form-control-plaintext {
- display: inline-block;
- }
-
- .form-group {
- align-items: center;
- display: flex;
- flex: 0 0 auto;
- flex-flow: row wrap;
- margin-bottom: 0;
- }
-
- .input-group {
- width: auto;
- }
-}
-
-// Label
-
-.col-form-label {
- color: inherit;
- font-size: $font-size-base;
- line-height: ($textfield-font-size * $textfield-line-height / $font-size-base);
- padding-top: $textfield-padding-y;
- padding-bottom: $textfield-padding-y;
-}
-
-.col-form-label-lg {
- font-size: ($font-size-base / $textfield-font-size * $textfield-font-size-lg);
- line-height: ($textfield-line-height-lg / ($font-size-base / $textfield-font-size));
- padding-top: $textfield-padding-y-lg;
- padding-bottom: $textfield-padding-y-lg;
-}
-
-.col-form-label-sm {
- font-size: ($font-size-base / $textfield-font-size * $textfield-font-size-sm);
- line-height: ($textfield-line-height-sm / ($font-size-base / $textfield-font-size));
- padding-top: $textfield-padding-y-sm;
- padding-bottom: $textfield-padding-y-sm;
-}
-
-// Misc
-
-.form-text {
- @include typography-caption;
-
- color: $textfield-hint-color;
- display: block;
- margin-top: $textfield-margin-y;
-
- .custom-select-lg + &,
- .floating-label-lg + &,
- .floating-label-lg .custom-select + &,
- .floating-label-lg .form-control + &,
- .floating-label-lg .form-control-file + &,
- .form-control-lg + &,
- .textfield-box-lg + &,
- .textfield-box-lg .custom-select + &,
- .textfield-box-lg .form-control + &,
- .textfield-box-lg .form-control-file + & {
- margin-top: $textfield-margin-y-lg;
- }
-
- .custom-select-sm + &,
- .floating-label-sm + &,
- .floating-label-sm .custom-select + &,
- .floating-label-sm .form-control + &,
- .floating-label-sm .form-control-file + &,
- .form-control-sm + &,
- .textfield-box-sm + &,
- .textfield-box-sm .custom-select + &,
- .textfield-box-sm .form-control + &,
- .textfield-box-sm .form-control-file + & {
- margin-top: $textfield-margin-y-sm;
- }
-}
-
-// Readonly control as plain text
-
-.form-control-plaintext {
- background-color: transparent;
- border-color: transparent;
- border-radius: 0;
- border-style: solid;
- border-width: 0 0 $textfield-border-width;
- box-shadow: none;
- color: $textfield-plaintext-color;
- display: block;
- font-size: $textfield-font-size;
- line-height: $textfield-line-height;
- padding: $textfield-padding-y 0 calc(#{$textfield-padding-y} - #{$textfield-border-width});
- width: 100%;
-
- &.form-control-sm,
- &.form-control-lg {
- padding-right: 0;
- padding-left: 0;
- }
-}
diff --git a/assets/scss/bootstrap/_forms.scss b/assets/scss/bootstrap/_forms.scss
new file mode 100644
index 000000000..bcb38cb71
--- /dev/null
+++ b/assets/scss/bootstrap/_forms.scss
@@ -0,0 +1,211 @@
+// Checkbox and radio button
+
+.form-check {
+ display: block;
+ margin-bottom: $textfield-margin-y;
+ padding-left: $form-check-input-gutter;
+ position: relative;
+}
+
+.form-check-input {
+ margin-top: ($font-size-base * $line-height-base - $font-size-base) / 3 * 2; //$form-check-input-margin-y;
+ margin-left: -$form-check-input-gutter;
+ position: absolute;
+
+ // Use disabled attribute instead of :disabled pseudo-class
+ // Workaround for: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11295231
+ &[disabled] ~ .form-check-label {
+ color: $textfield-color-disabled;
+ }
+}
+
+.form-check-label {
+ color: inherit;
+ font-size: inherit;
+ line-height: inherit;
+ vertical-align: middle;
+}
+
+.form-check-inline {
+ align-items: center;
+ display: inline-flex;
+ margin-right: $form-check-inline-margin-x;
+ margin-bottom: 0;
+
+ .form-check-input {
+ margin-top: 0;
+ margin-right: $form-check-inline-input-margin-x;
+ margin-left: 0;
+ position: static;
+ }
+}
+
+// Form group
+
+.form-group {
+ margin-bottom: $form-group-margin-y;
+}
+
+.form-row {
+ display: flex;
+ flex-wrap: wrap;
+ margin-right: ($textfield-margin-x * -0.5);
+ margin-left: ($textfield-margin-x * -0.5);
+
+ > .col,
+ > [class*='col-'] {
+ padding-right: ($textfield-margin-x * 0.5);
+ padding-left: ($textfield-margin-x * 0.5);
+ }
+}
+
+// Inline
+
+.form-inline {
+ align-items: center;
+ display: flex;
+ flex-flow: row wrap;
+
+ .form-check {
+ margin-bottom: 0;
+ width: 100%; //auto
+ }
+
+ // stylelint-disable
+ @include media-breakpoint-up(sm) {
+ label {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ margin-bottom: 0;
+ }
+
+ // Inline-block all the things for 'inline'
+ .form-group {
+ align-items: center;
+ display: flex;
+ flex: 0 0 auto;
+ flex-flow: row wrap;
+ margin-bottom: 0;
+ }
+
+ // Allow folks to *not* use `.form-group`
+ .form-control {
+ display: inline-block;
+ vertical-align: middle;
+ width: auto; // Prevent labels from stacking above inputs in `.form-group`
+ }
+
+ // Make static controls behave like regular ones
+ .form-control-plaintext {
+ display: inline-block;
+
+ &:focus {
+ outline: 0;
+ }
+ }
+
+ .input-group,
+ .custom-select {
+ width: auto;
+ }
+
+ .form-check {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ padding-left: 0;
+ width: auto;
+ }
+
+ .form-check-input {
+ flex-shrink: 0;
+ margin-top: 0;
+ margin-right: $form-check-input-gutter;
+ margin-left: 0;
+ position: relative;
+ }
+
+ .custom-control {
+ align-items: center;
+ justify-content: center;
+ }
+
+ .custom-control-label {
+ margin-bottom: 0;
+ }
+ }
+ // stylelint-enable
+}
+
+// Label
+
+.col-form-label {
+ color: inherit;
+ font-size: $font-size-base; // todo
+ line-height: ($textfield-font-size * $textfield-line-height / $font-size-base); //$input-line-height
+ // margin-bottom: 0;
+ padding-top: $textfield-padding-y;
+ padding-bottom: $textfield-padding-y;
+}
+
+.col-form-label-lg {
+ font-size: ($font-size-base / $textfield-font-size * $textfield-font-size-lg); //@include font-size($input-font-size-lg)
+ line-height: ($textfield-line-height-lg / ($font-size-base / $textfield-font-size)); //$input-line-height-lg;
+ padding-top: $textfield-padding-y-lg;
+ padding-bottom: $textfield-padding-y-lg;
+}
+
+.col-form-label-sm {
+ font-size: ($font-size-base / $textfield-font-size * $textfield-font-size-sm); //@include font-size($input-font-size-sm);
+ line-height: ($textfield-line-height-sm / ($font-size-base / $textfield-font-size)); //$input-line-height-sm;
+ padding-top: $textfield-padding-y-sm;
+ padding-bottom: $textfield-padding-y-sm;
+}
+
+// Misc
+
+.form-text {
+ color: $textfield-caption-color;
+ display: block;
+ font-size: $font-size-caption;
+ font-weight: $font-weight-caption;
+ letter-spacing: $letter-spacing-caption;
+ line-height: normal;
+ // padding-left: $textfield-box-padding-x;
+
+ &::before {
+ content: '';
+ display: inline-block;
+ height: 1rem;
+ vertical-align: 0;
+ width: 0;
+ }
+
+ [class~='textfield-box'] &,
+ [class~='textfield-box'] ~ & {
+ padding: 0 $textfield-box-padding-x;
+ }
+}
+
+// Readonly control as plain text
+
+.form-control-plaintext {
+ background-color: transparent;
+ border: solid transparent;
+ border-radius: 0;
+ border-width: 0 0 $textfield-border-width;
+ box-shadow: none;
+ color: $textfield-plaintext-color;
+ display: block;
+ font-size: $textfield-font-size;
+ line-height: $textfield-line-height;
+ padding: $textfield-padding-y 0 calc(#{$textfield-padding-y} - #{$textfield-border-width});
+ width: 100%;
+
+ &.form-control-sm,
+ &.form-control-lg {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
diff --git a/assets/scss/bootstrap/_image.scss b/assets/scss/bootstrap/_images.scss
similarity index 56%
rename from assets/scss/bootstrap/_image.scss
rename to assets/scss/bootstrap/_images.scss
index 7c75650d3..f8e29035b 100644
--- a/assets/scss/bootstrap/_image.scss
+++ b/assets/scss/bootstrap/_images.scss
@@ -1,11 +1,21 @@
-.figure {
- display: inline-block;
+.img-fluid {
+ @include img-fluid;
}
-.figure-caption {
- @include typography-caption;
+.img-thumbnail {
+ /* padding: $thumbnail-padding;
+ background-color: $thumbnail-bg;
+ border: $thumbnail-border-width solid $thumbnail-border-color;
+ @include border-radius($thumbnail-border-radius);
+ @include box-shadow($thumbnail-box-shadow);
+ */
+ @include img-fluid;
- color: $figure-caption-color;
+ box-shadow: $thumbnail-box-shadow;
+}
+
+.figure {
+ display: inline-block;
}
.figure-img {
@@ -13,12 +23,8 @@
margin-bottom: $figure-img-margin-y;
}
-.img-fluid {
- @include img-fluid;
-}
-
-.img-thumbnail {
- @include img-fluid;
+.figure-caption {
+ @include typography-caption;
- box-shadow: $thumbnail-box-shadow;
+ color: $figure-caption-color;
}
diff --git a/assets/scss/bootstrap/_jumbotron.scss b/assets/scss/bootstrap/_jumbotron.scss
index ec7cf72c7..6c635c997 100644
--- a/assets/scss/bootstrap/_jumbotron.scss
+++ b/assets/scss/bootstrap/_jumbotron.scss
@@ -4,6 +4,7 @@
background-color: $jumbotron-bg;
box-shadow: map-get($jumbotron-elevation-shadow, shadow);
color: $jumbotron-color;
+ margin-bottom: $jumbotron-padding-y;
padding: $jumbotron-padding-y $jumbotron-padding-x;
}
diff --git a/assets/scss/bootstrap/_nav.scss b/assets/scss/bootstrap/_nav.scss
index df3774869..de95aaf6e 100644
--- a/assets/scss/bootstrap/_nav.scss
+++ b/assets/scss/bootstrap/_nav.scss
@@ -7,16 +7,24 @@
}
.nav-link {
+ color: selection-theme-color();
display: block;
padding: $nav-link-padding-y $nav-link-padding-x;
- @include active-focus-hover {
+ @include hover-focus {
text-decoration: none;
}
+ // Disabled state lightens text
&.disabled {
color: $nav-link-color-disabled;
cursor: default;
+ pointer-events: none;
+ }
+
+ &:hover,
+ &.active {
+ color: darken(selection-theme-color(), 16%);
}
}
@@ -31,9 +39,13 @@
.nav-justified {
.nav-item {
- flex-basis: 0;
- flex-grow: 1;
- text-align: center;
+ @include text-truncate;
+
+ display: flex;
+ flex: 1;
+ //flex-basis: 0;
+ //flex-grow: 1;
+ //text-align: center;
}
}
@@ -44,10 +56,12 @@
@include border-radius($nav-pills-border-radius);
@include transition-standard(background-color, color, opacity);
+ background-color: transparent;
+ border: none;
color: $nav-pills-color;
opacity: $nav-pills-link-opacity;
- @include active-focus-hover {
+ @include hover-focus-active {
background-color: $nav-pills-bg-hover;
}
diff --git a/assets/scss/bootstrap/_pagination.scss b/assets/scss/bootstrap/_pagination.scss
index 1c1fb5655..dd26e22bc 100644
--- a/assets/scss/bootstrap/_pagination.scss
+++ b/assets/scss/bootstrap/_pagination.scss
@@ -2,69 +2,83 @@
background-color: $pagination-bg;
display: flex;
list-style: none;
- padding: $pagination-padding-y $pagination-padding-x;
+ margin: $pagination-margin-x;
}
.page-link {
@include border-radius($pagination-border-radius);
- @include transition-standard(color);
+ @include transition-standard(all);
+ align-items: center;
color: $pagination-color;
- display: block;
- font-size: $btn-font-size;
- font-weight: $btn-font-weight;
- line-height: $btn-line-height;
+ display: flex;
+ font-size: $pagination-font-size;
+ font-weight: $pagination-font-weight;
+ justify-content: center;
+ line-height: $pagination-line-height;
margin-left: $pagination-inner-spacer-x;
- padding: $btn-padding-y $btn-padding-x;
+ min-width: $pagination-line-height * $pagination-font-size;
+ padding: 0 10px;
position: relative;
text-align: center;
white-space: nowrap;
- @include active-focus-hover {
+ @include hover-focus-active {
+ background-color: rgba($black, $overlay-hover-white-opacity);
color: $pagination-color;
text-decoration: none;
+ z-index: 3;
}
- @include focus-hover {
- background-image: linear-gradient(to bottom, $btn-overlay, $btn-overlay);
+ &:focus {
+ background-color: rgba($black, $overlay-focus-white-opacity);
+ outline: 0;
}
- &.active,
&:active {
- background-color: $btn-bg-active;
- background-image: none;
- }
-
- &:focus {
- outline: 0;
+ background-color: rgba($black, $overlay-pressed-white-opacity);
}
&:not(:disabled):not(.disabled) {
cursor: pointer;
}
+}
- .page-item:first-child & {
- margin-left: 0;
+.page-item {
+ &:first-child {
+ .page-link {
+ margin-left: 0;
+ }
}
- .page-item.active & {
- background-color: $btn-bg-active;
+ // stylelint-disable
+ &.active .page-link {
+ background-color: theme-color(primary);
+ color: $white;
+ z-index: 3;
}
- .page-item.disabled & {
+ &.disabled .page-link {
background-color: transparent;
color: $pagination-color-disabled;
cursor: auto;
pointer-events: none;
}
+ // stylelint-enable
}
+//
+// Sizing
+//
+
.pagination-lg .page-link {
- font-size: $btn-font-size-lg;
- padding: $btn-padding-y-lg $btn-padding-x-lg;
+ border-radius: ($pagination-line-height * $pagination-font-size-lg) * 0.5;
+ font-size: $pagination-font-size-lg;
+ width: $pagination-line-height * $pagination-font-size-lg;
}
.pagination-sm .page-link {
- font-size: $btn-font-size-sm;
- padding: $btn-padding-y-sm $btn-padding-x-sm;
+ font-size: $pagination-font-size-sm;
+ min-width: 0;
+ width: $pagination-line-height * $pagination-font-size-sm;
}
diff --git a/assets/scss/bootstrap/_popover.scss b/assets/scss/bootstrap/_popover.scss
index 9320afda9..705c48e72 100644
--- a/assets/scss/bootstrap/_popover.scss
+++ b/assets/scss/bootstrap/_popover.scss
@@ -3,31 +3,23 @@
// Therefore, popovers are styled as Material design's dialogs
.popover {
- @include reset-text;
+ @include reset-text();
@include border-radius($popover-border-radius);
background-color: $popover-bg;
- box-shadow: map-get($popover-elevation-shadow, shadow);
- display: block;
+ box-shadow: $popover-box-shadow;
font-size: $popover-font-size;
margin: $popover-margin;
max-width: $popover-max-width;
position: absolute;
top: 0;
left: 0;
+ word-wrap: break-word;
z-index: map-get($popover-elevation-shadow, elevation);
}
-.popover-body {
- padding: $popover-padding-y $popover-padding-x;
-
- > :last-child {
- margin-bottom: 0;
- }
-}
-
.popover-header {
- @include typography-title;
+ @include typography-headline-6;
margin-bottom: 0;
padding: $popover-padding-y $popover-padding-x 0;
@@ -41,6 +33,15 @@
}
}
+.popover-body {
+ padding: $popover-padding-y $popover-padding-x;
+ // color: $popover-body-color;
+
+ > :last-child {
+ margin-bottom: 0;
+ }
+}
+
// Desktop
@include media-breakpoint-up($popover-breakpoint) {
diff --git a/assets/scss/bootstrap/_transition.scss b/assets/scss/bootstrap/_transitions.scss
similarity index 54%
rename from assets/scss/bootstrap/_transition.scss
rename to assets/scss/bootstrap/_transitions.scss
index 9b7943244..f296e4c10 100644
--- a/assets/scss/bootstrap/_transition.scss
+++ b/assets/scss/bootstrap/_transitions.scss
@@ -1,19 +1,16 @@
-.collapse {
- display: none;
+.fade {
+ //@include transition-standard(opacity);
+ transition: opacity $transition-duration-desktop-complex $transition-timing-function-standard;
- &.show {
- display: block;
+ &:not(.show) {
+ opacity: 0;
}
}
-// stylelint-disable-next-line selector-no-qualifying-type
-tbody.collapse.show {
- display: table-row-group;
-}
-
-// stylelint-disable-next-line selector-no-qualifying-type
-tr.collapse.show {
- display: table-row;
+.collapse {
+ &:not(.show) {
+ display: none;
+ }
}
.collapsing {
@@ -22,14 +19,21 @@ tr.collapse.show {
height: 0;
overflow: hidden;
position: relative;
-}
-.fade {
- @include transition-standard(opacity);
-
- opacity: 0;
+ &.width {
+ @include transition-standard(width);
- &.show {
- opacity: 1;
+ height: auto;
+ width: 0;
}
}
+
+// stylelint-disable-next-line selector-no-qualifying-type
+tbody.collapse.show {
+ display: table-row-group;
+}
+
+// stylelint-disable-next-line selector-no-qualifying-type
+tr.collapse.show {
+ display: table-row;
+}
diff --git a/assets/scss/material-plugins.scss b/assets/scss/material-plugins.scss
new file mode 100644
index 000000000..a625b7ff7
--- /dev/null
+++ b/assets/scss/material-plugins.scss
@@ -0,0 +1,12 @@
+/*!
+ * Material themes by djibe for various plugins (standalone)
+ */
+
+@import 'colors';
+@import 'functions';
+@import 'variables';
+@import 'mixins';
+
+// Plugins
+
+@import 'plugins';
diff --git a/assets/scss/material.scss b/assets/scss/material.scss
index 4af436bb6..2afa44890 100644
--- a/assets/scss/material.scss
+++ b/assets/scss/material.scss
@@ -1,13 +1,22 @@
-@import 'colors';
+/*!
+ * Daemonite Material UI 4.6.2 - 2.0 (https://djibe.github.io/material/)
+ * Copyright 2011-2023 The Bootstrap Authors
+ * Copyright 2011-2023 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * Material UI by djibe, Maya, Geoff Bowers and Alex Skinner
+ */
+
@import 'functions';
+@import 'colors';
@import 'mixins';
@import 'variables';
+@import 'theme';
// Base CSS
-@import 'base/base';
+@import 'base/base'; // root + reboot
@import 'base/grid';
-@import 'base/typography';
+@import 'base/typography'; // type
// Bootstrap components
// Components covered in Bootstrap's css but not in Material design
@@ -18,43 +27,44 @@
@import 'bootstrap/carousel';
@import 'bootstrap/close';
@import 'bootstrap/code';
-@import 'bootstrap/form';
-@import 'bootstrap/image';
+@import 'bootstrap/forms';
+@import 'bootstrap/images';
@import 'bootstrap/jumbotron';
@import 'bootstrap/media';
@import 'bootstrap/nav';
@import 'bootstrap/pagination';
@import 'bootstrap/popover';
@import 'bootstrap/responsive-embed';
-@import 'bootstrap/transition';
+@import 'bootstrap/transitions';
// Material components
// Components covered in Material design (https://material.google.com/components)
-@import 'material/button';
+@import 'material/buttons';
@import 'material/button-flat';
@import 'material/button-float';
@import 'material/button-group';
@import 'material/card';
@import 'material/chip';
-@import 'material/data-table';
-@import 'material/dialog';
-@import 'material/expansion-panel';
-@import 'material/menu';
+@import 'material/dark-theme';
+@import 'material/data-table'; // tables
+@import 'material/dialog'; // modal
+@import 'material/expansion-panel'; // list-group
+@import 'material/menu'; // dropdown
@import 'material/navdrawer';
@import 'material/picker';
@import 'material/progress';
-@import 'material/progress-circular';
-@import 'material/selection-control';
-@import 'material/slider';
-@import 'material/snackbar';
+@import 'material/progress-circular'; // spinners
+@import 'material/selection-control'; // custom-forms
+@import 'material/sliders';
+@import 'material/snackbars'; // toasts
@import 'material/stepper';
@import 'material/tab';
@import 'material/text-field';
@import 'material/text-field-box';
@import 'material/text-field-floating-label';
-@import 'material/text-field-input-group';
-@import 'material/toolbar';
+@import 'material/text-field-input-group'; // input-group
+@import 'material/toolbar'; // navbar
@import 'material/tooltip';
// Utilities
diff --git a/assets/scss/material/_button-flat.scss b/assets/scss/material/_button-flat.scss
index cd7f3f5a2..d64a1ae30 100644
--- a/assets/scss/material/_button-flat.scss
+++ b/assets/scss/material/_button-flat.scss
@@ -1,36 +1,81 @@
+// Btn flat and outlined
+// Material guidelines : https://material.io/design/components/buttons.html#specs
+// Material Web component : https://material-components.github.io/material-components-web-catalog/#/component/button?type=text
+
[class*='btn-flat'],
+.btn-link,
+.card-link,
+.modal .btn {
+ padding: $btn-padding-y $btn-flat-padding-x;
+}
+
[class*='btn-outline'] {
- background-color: transparent;
- box-shadow: none;
+ border: 1px solid currentColor;
+ padding: $btn-padding-y calc(#{$btn-padding-x} - 1px);
- &.active,
- &:active {
- box-shadow: none;
+ &:disabled,
+ &.disabled {
+ border-color: $btn-color-disabled;
}
+}
- &.disabled,
- &:disabled {
- background-color: transparent;
+[class*='btn-flat'],
+[class*='btn-outline'],
+.btn-link,
+.card-link,
+.modal .btn {
+ background-color: transparent;
+ box-shadow: none;
+
+ @include hover-focus-active {
+ box-shadow: inherit;
}
}
-@each $color, $values in $theme-colors {
+@each $color,
+ $values in $theme-colors {
.btn-flat-#{$color},
- .btn-outline-#{$color} {
- @include plain-active-focus-hover {
- color: theme-color($color);
+ .btn-outline-#{$color},
+ .modal .btn-#{$color} {
+ @if ($color !='dark') {
+ @include plain-hover-focus {
+ color: theme-color($color);
+ }
+ }
+
+ @if ($color !='dark' and $color !='light') {
+ &:hover {
+ background-image: linear-gradient(to bottom, rgba(theme-color($color), $overlay-hover-white-opacity), rgba(theme-color($color), $overlay-hover-white-opacity));
+ }
+
+ &:focus {
+ background-image: linear-gradient(to bottom, rgba(theme-color($color), $overlay-focus-white-opacity), rgba(theme-color($color), $overlay-focus-white-opacity));
+ }
+
+ // stylelint-disable-next-line
+ @if not $enable-ripple {
+ &:active {
+ background-image: linear-gradient(to bottom, rgba(theme-color($color), $overlay-pressed-white-opacity), rgba(theme-color($color), $overlay-pressed-white-opacity));
+ }
+ }
}
- &.disabled,
- &:disabled {
+ &:disabled,
+ &.disabled {
color: $btn-color-disabled;
}
}
}
+.btn-link,
+.card-link {
+ @extend .btn-flat-primary;
+}
+
+/*
.btn-flat-light,
.btn-outline-light {
- @include focus-hover {
+ @include hover-focus {
background-image: linear-gradient(to bottom, $btn-overlay-inverse, $btn-overlay-inverse);
}
@@ -39,3 +84,35 @@
background-color: $btn-bg-active-inverse;
}
}
+*/
+
+// Btn-icon addition
+.btn-icon {
+ border-radius: 50%;
+ box-shadow: none;
+ color: initial;
+ fill: currentColor;
+ font-size: 1.5rem;
+ height: $btn-icon-width;
+ min-width: 0;
+ padding: 0;
+ transition: background-color 15ms linear;
+ width: $btn-icon-width;
+
+ &.btn-sm {
+ height: $btn-icon-width-sm;
+ width: $btn-icon-width-sm;
+ }
+
+ &.btn-xs {
+ height: $btn-icon-width-xs;
+ width: $btn-icon-width-xs;
+ }
+
+ &:hover,
+ &:focus,
+ &:active {
+ box-shadow: none;
+ color: initial;
+ }
+}
diff --git a/assets/scss/material/_button-float.scss b/assets/scss/material/_button-float.scss
index b91500432..e855f6c0d 100644
--- a/assets/scss/material/_button-float.scss
+++ b/assets/scss/material/_button-float.scss
@@ -1,22 +1,55 @@
+// https://material-components.github.io/material-components-web-catalog/#/component/fab
+
.btn-float {
border-radius: 50%;
box-shadow: map-get($btn-float-elevation-shadow, shadow);
height: $btn-float-size;
- line-height: $btn-float-size;
+ //line-height: $btn-float-size;
min-width: 0;
padding: 0;
width: $btn-float-size;
- &.active,
- &:active {
+ &:hover {
+ box-shadow: map-get($btn-float-elevation-shadow-hover, shadow);
+ }
+
+ &:active,
+ &.active {
box-shadow: map-get($btn-float-elevation-shadow-active, shadow);
}
- &.disabled,
- &:disabled {
+ &:disabled,
+ &.disabled {
box-shadow: none;
}
+ svg {
+ fill: currentColor;
+ }
+
+ // Extended FAB
+ // stylelint-disable order/order, selector-no-qualifying-type
+ &-extended {
+ border-radius: $btn-float-extended-border-radius;
+ height: $btn-float-extended-height;
+ line-height: $btn-float-extended-line-height;
+ padding: 0 $btn-float-extended-padding-x;
+ width: auto;
+
+ i,
+ svg,
+ [class*='material-icons'] {
+ margin-right: 0.75rem;
+ margin-left: -$spacer-sm;
+
+ &[class*='order-'] {
+ margin-right: -$spacer-sm;
+ margin-left: 0.75rem;
+ }
+ }
+ }
+ // stylelint-enable order/order, selector-no-qualifying-type
+
&.btn-sm {
height: $btn-float-size-sm;
line-height: $btn-float-size-sm;
@@ -45,3 +78,23 @@
}
}
}
+
+.fab-actions {
+ align-items: flex-end;
+ display: flex;
+ flex-direction: column;
+ position: fixed;
+ right: $spacer-lg;
+ bottom: $spacer-lg;
+ z-index: map-get(map-get($elevation-shadows, 12), elevation);
+
+ @media print {
+ & {
+ display: none;
+ }
+ }
+
+ & > .btn {
+ margin-top: 1.25rem;
+ }
+}
diff --git a/assets/scss/material/_button-group.scss b/assets/scss/material/_button-group.scss
index 993f30fd9..6d1625fe3 100644
--- a/assets/scss/material/_button-group.scss
+++ b/assets/scss/material/_button-group.scss
@@ -1,14 +1,18 @@
+// TODO : btn-group disabled
+
.btn-group,
.btn-group-vertical {
@include border-radius($btn-border-radius);
background-color: $btn-group-bg;
+ //border: 1px solid $black-divider;
box-shadow: map-get($btn-elevation-shadow, shadow);
display: inline-flex;
position: relative;
- vertical-align: middle;
+ //vertical-align: middle;
- @each $color, $values in $theme-colors {
+ @each $color,
+ $values in $theme-colors {
> .btn-#{$color} {
&.disabled,
&:disabled {
@@ -19,35 +23,49 @@
}
> .btn {
- @include transition-standard(border-color, opacity);
+ // @include transition-standard(opacity);
box-shadow: none;
- flex: 0 1 auto;
+ flex: 1 1 auto;
min-width: 0;
+ padding-right: $btn-group-padding-x;
+ padding-left: $btn-group-padding-x;
+ position: relative;
+
+ &:hover,
+ &:focus,
+ &:active,
+ &.active {
+ z-index: 1;
+ }
- &.active,
- &:active {
- box-shadow: none;
+ &:active,
+ &.active {
+ background-color: rgba($black, $overlay-activated-white-opacity);
}
- &.disabled,
- &:disabled {
+ &:disabled,
+ &.disabled {
opacity: $btn-group-toggle-opacity;
}
+ // stylelint-disable
&[class*='btn-outline'] {
- opacity: $btn-group-toggle-opacity;
+ border: 0;
+ //opacity: $btn-group-toggle-opacity;
&.active,
&:active {
- opacity: 1;
+ background-color: rgba($black, $overlay-activated-white-opacity);
+ //opacity: 1;
}
&.disabled,
&:disabled {
- opacity: 1;
+ //opacity: 1;
}
}
+ // stylelint-enable
}
> .btn-group,
@@ -60,7 +78,7 @@
}
.btn-group {
- &.show > .btn.dropdown-toggle {
+ &.show > .dropdown-toggle {
box-shadow: none;
}
@@ -103,6 +121,7 @@
margin-top: 0;
}
+ // Reset rounded corners
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
@@ -115,19 +134,19 @@
}
}
-.btn-group-fluid {
+/* .btn-group-fluid {
background-color: transparent;
box-shadow: none;
+} */
+
+.btn-group-sm > .btn {
+ @extend %btn-sm;
}
.btn-group-lg > .btn {
@extend %btn-lg;
}
-.btn-group-sm > .btn {
- @extend %btn-sm;
-}
-
// Checkbox and radio options
[data-toggle='buttons'] {
@@ -144,25 +163,16 @@
}
}
-// Split button dropdown
-
-.dropdown-toggle.dropdown-toggle-split {
- padding-right: $caret-spacer-x;
- padding-left: $caret-spacer-x;
-
- &::after {
- margin-right: 0;
- margin-left: 0;
- }
-
- .dropleft & {
- &::before {
- margin-right: 0;
- margin-left: 0;
- }
- }
+/* .btn-sm + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-sm * .75;
+ padding-left: $btn-padding-x-sm * .75;
}
+.btn-lg + .dropdown-toggle-split {
+ padding-right: $btn-padding-x-lg * .75;
+ padding-left: $btn-padding-x-lg * .75;
+} */
+
// Toolbar
.btn-toolbar {
@@ -174,3 +184,19 @@
width: auto;
}
}
+
+// Checkbox and radio options
+
+.btn-group-toggle {
+ > .btn,
+ > .btn-group > .btn {
+ margin-bottom: 0; // Override default ` |