1
0
mirror of https://github.com/locomotivemtl/locomotive-boilerplate.git synced 2026-01-15 00:55:08 +08:00

6 Commits

Author SHA1 Message Date
Deven Caron
8f3034d54a Run precommit 2023-02-01 09:49:25 -05:00
Deven Caron
3fa1de473c Sort config alphabetically 2023-02-01 09:12:48 -05:00
Deven Caron
ecf60ee507 Convert config tabs to spaces
Co-authored-by: Chauncey McAskill <chauncey@locomotive.ca>
2023-02-01 09:10:40 -05:00
Deven Caron
9632d6270e Format all styles & scripts files with prettier command 2023-01-31 16:29:44 -05:00
Deven Caron
bc3a1a6934 Add module class aliases 2023-01-31 16:26:01 -05:00
Deven Caron
2f6b353616 Add prettier & precommit command 2023-01-31 11:44:00 -05:00
42 changed files with 1282 additions and 1305 deletions

7
.prettierrc.json Normal file
View File

@@ -0,0 +1,7 @@
{
"semi": false,
"singleQuote": true,
"tabWidth": 4,
"trailingComma": "es5",
"useTabs": false
}

View File

@@ -1,60 +1,79 @@
import modular from 'modujs'; import modular from 'modujs'
import * as modules from './modules'; import * as modules from './modules'
import globals from './globals'; import globals from './globals'
import { html } from './utils/environment'; import { html } from './utils/environment'
import config from './config' import config from './config'
import { isFontLoadingAPIAvailable, loadFonts } from './utils/fonts'; import { isFontLoadingAPIAvailable, loadFonts } from './utils/fonts'
const app = new modular({ const app = new modular({
modules: modules, modules: modules,
}); })
window.onload = (event) => { window.onload = (event) => {
const $style = document.getElementById('main-css'); const $style = document.getElementById('main-css')
if ($style) { if ($style) {
if ($style.isLoaded) { if ($style.isLoaded) {
init(); init()
} else { } else {
$style.addEventListener('load', (event) => { $style.addEventListener('load', (event) => {
init(); init()
}); })
} }
} else { } else {
console.warn('The "main-css" stylesheet not found'); console.warn('The "main-css" stylesheet not found')
} }
}; }
export const EAGER_FONTS = [ export const EAGER_FONTS = [
{ family: 'Source Sans', style: 'normal', weight: 400 }, { family: 'Source Sans', style: 'normal', weight: 400 },
{ family: 'Source Sans', style: 'normal', weight: 700 }, { family: 'Source Sans', style: 'normal', weight: 700 },
]; ]
function init() { function init() {
globals(); globals()
app.init(app); app.init(app)
html.classList.add('is-loaded'); html.classList.add('is-loaded')
html.classList.add('is-ready'); html.classList.add('is-ready')
html.classList.remove('is-loading'); html.classList.remove('is-loading')
/** /**
* Eagerly load the following fonts. * Eagerly load the following fonts.
*/ */
if (isFontLoadingAPIAvailable) { if (isFontLoadingAPIAvailable) {
loadFonts(EAGER_FONTS, config.IS_DEV).then((eagerFonts) => { loadFonts(EAGER_FONTS, config.IS_DEV).then((eagerFonts) => {
html.classList.add('fonts-loaded'); html.classList.add('fonts-loaded')
if (config.IS_DEV) { if (config.IS_DEV) {
console.group('Eager fonts loaded!', eagerFonts.length, '/', document.fonts.size); console.group(
'Eager fonts loaded!',
eagerFonts.length,
'/',
document.fonts.size
)
console.group('State of eager fonts:') console.group('State of eager fonts:')
eagerFonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/)) eagerFonts.forEach((font) =>
console.log(
font.family,
font.style,
font.weight,
font.status /*, font*/
)
)
console.groupEnd() console.groupEnd()
console.group('State of all fonts:') console.group('State of all fonts:')
document.fonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/)) document.fonts.forEach((font) =>
console.log(
font.family,
font.style,
font.weight,
font.status /*, font*/
)
)
console.groupEnd() console.groupEnd()
} }
}); })
} }
} }

View File

@@ -1,23 +1,23 @@
import svg4everybody from 'svg4everybody'; import svg4everybody from 'svg4everybody'
import config from './config'; import config from './config'
// Dynamic imports for development mode only // Dynamic imports for development mode only
let gridHelper; let gridHelper
(async () => { ;(async () => {
if (config.IS_DEV) { if (config.IS_DEV) {
const gridHelperModule = await import('./utils/grid-helper'); const gridHelperModule = await import('./utils/grid-helper')
gridHelper = gridHelperModule?.gridHelper; gridHelper = gridHelperModule?.gridHelper
} }
})(); })()
export default function () { export default function () {
/** /**
* Use external SVG spritemaps * Use external SVG spritemaps
*/ */
svg4everybody(); svg4everybody()
/** /**
* Add grid helper * Add grid helper
*/ */
gridHelper?.(); gridHelper?.()
} }

View File

@@ -1,3 +1,3 @@
export {default as Example} from './modules/Example'; export { default as Example } from './modules/Example'
export {default as Load} from './modules/Load'; export { default as Load } from './modules/Load'
export {default as Scroll} from './modules/Scroll'; export { default as Scroll } from './modules/Scroll'

View File

@@ -1,14 +1,14 @@
import { module } from 'modujs'; import { module as Module } from 'modujs'
import { EAGER_FONTS } from '../app'; import { EAGER_FONTS } from '../app'
import { whenReady } from '../utils/fonts'; import { whenReady } from '../utils/fonts'
export default class extends module { export default class extends Module {
constructor(m) { constructor(m) {
super(m); super(m)
} }
init() { init() {
whenReady(EAGER_FONTS).then((fonts) => this.onFontsLoaded(fonts)); whenReady(EAGER_FONTS).then((fonts) => this.onFontsLoaded(fonts))
} }
onFontsLoaded(fonts) { onFontsLoaded(fonts) {

View File

@@ -1,22 +1,22 @@
import { module } from 'modujs'; import { module as Module } from 'modujs'
import modularLoad from 'modularload'; import modularLoad from 'modularload'
export default class extends module { export default class extends Module {
constructor(m) { constructor(m) {
super(m); super(m)
} }
init() { init() {
const load = new modularLoad({ const load = new modularLoad({
enterDelay: 0, enterDelay: 0,
transitions: { transitions: {
customTransition: {} customTransition: {},
} },
}); })
load.on('loaded', (transition, oldContainer, newContainer) => { load.on('loaded', (transition, oldContainer, newContainer) => {
this.call('destroy', oldContainer, 'app'); this.call('destroy', oldContainer, 'app')
this.call('update', newContainer, 'app'); this.call('update', newContainer, 'app')
}); })
} }
} }

View File

@@ -1,22 +1,22 @@
import { module } from 'modujs'; import { module as Module } from 'modujs'
import { lazyLoadImage } from '../utils/image'; import { lazyLoadImage } from '../utils/image'
import LocomotiveScroll from 'locomotive-scroll'; import LocomotiveScroll from 'locomotive-scroll'
export default class extends module { export default class extends Module {
constructor(m) { constructor(m) {
super(m); super(m)
} }
init() { init() {
this.scroll = new LocomotiveScroll({ this.scroll = new LocomotiveScroll({
el: this.el, el: this.el,
smooth: true smooth: true,
}); })
this.scroll.on('call', (func, way, obj, id) => { this.scroll.on('call', (func, way, obj, id) => {
// Using modularJS // Using modularJS
this.call(func[0], { way, obj }, func[1], func[2]); this.call(func[0], { way, obj }, func[1], func[2])
}); })
this.scroll.on('scroll', (args) => { this.scroll.on('scroll', (args) => {
// console.log(args.scroll); // console.log(args.scroll);
@@ -47,6 +47,6 @@ export default class extends module {
} }
destroy() { destroy() {
this.scroll.destroy(); this.scroll.destroy()
} }
} }

View File

@@ -1,9 +1,8 @@
const APP_NAME = 'Boilerplate'; const APP_NAME = 'Boilerplate'
const DATA_API_KEY = '.data-api'; const DATA_API_KEY = '.data-api'
const html = document.documentElement; const html = document.documentElement
const body = document.body; const body = document.body
const isDebug = html.hasAttribute('data-debug'); const isDebug = html.hasAttribute('data-debug')
export { APP_NAME, DATA_API_KEY, html, body, isDebug }
export { APP_NAME, DATA_API_KEY, html, body, isDebug };

View File

@@ -23,7 +23,7 @@
* @property {string} [weight] - The weight used by the font in our CSS. * @property {string} [weight] - The weight used by the font in our CSS.
*/ */
const isFontLoadingAPIAvailable = ('fonts' in document); const isFontLoadingAPIAvailable = 'fonts' in document
/** /**
* Determines if the given font matches the given `FontFaceReference`. * Determines if the given font matches the given `FontFaceReference`.
@@ -33,15 +33,14 @@ const isFontLoadingAPIAvailable = ('fonts' in document);
* *
* @returns {boolean} * @returns {boolean}
*/ */
function conformsToReference(font, criterion) function conformsToReference(font, criterion) {
{ for (const [key, value] of Object.entries(criterion)) {
for (const [ key, value ] of Object.entries(criterion)) {
switch (key) { switch (key) {
case 'family': { case 'family': {
if (trim(font[key]) !== value) { if (trim(font[key]) !== value) {
return false; return false
} }
break; break
} }
case 'weight': { case 'weight': {
@@ -54,21 +53,21 @@ function conformsToReference(font, criterion)
* @link https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#common_weight_name_mapping * @link https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#common_weight_name_mapping
*/ */
if (font[key] != value) { if (font[key] != value) {
return false; return false
} }
break; break
} }
default: { default: {
if (font[key] !== value) { if (font[key] !== value) {
return false; return false
} }
break; break
} }
} }
} }
return true; return true
} }
/** /**
@@ -79,24 +78,21 @@ function conformsToReference(font, criterion)
* *
* @returns {boolean} * @returns {boolean}
*/ */
function conformsToShorthand(font, criterion) function conformsToShorthand(font, criterion) {
{ const family = trim(font.family)
const family = trim(font.family);
if (trim(family) === criterion) { if (trim(family) === criterion) {
return true; return true
} }
if ( if (
criterion.endsWith(trim(family)) && ( criterion.endsWith(trim(family)) &&
criterion.match(font.weight) || (criterion.match(font.weight) || criterion.match(font.style))
criterion.match(font.style)
)
) { ) {
return true; return true
} }
return true; return true
} }
/** /**
@@ -107,15 +103,14 @@ function conformsToShorthand(font, criterion)
* *
* @returns {boolean} * @returns {boolean}
*/ */
function conformsToAnyReference(font, criteria) function conformsToAnyReference(font, criteria) {
{
for (const criterion of criteria) { for (const criterion of criteria) {
if (conformsToReference(font, criterion)) { if (conformsToReference(font, criterion)) {
return true; return true
} }
} }
return false; return false
} }
/** /**
@@ -126,17 +121,16 @@ function conformsToAnyReference(font, criteria)
* *
* @returns {FontFace[]} * @returns {FontFace[]}
*/ */
function findManyByReference(search) function findManyByReference(search) {
{ const found = []
const found = [];
for (const font of document.fonts) { for (const font of document.fonts) {
if (conformsToReference(font, search)) { if (conformsToReference(font, search)) {
found.push(font); found.push(font)
} }
} }
return found; return found
} }
/** /**
@@ -147,17 +141,16 @@ function findManyByReference(search)
* *
* @returns {FontFace[]} * @returns {FontFace[]}
*/ */
function findManyByShorthand(search) function findManyByShorthand(search) {
{ const found = []
const found = [];
for (const font of document.fonts) { for (const font of document.fonts) {
if (conformsToShorthand(font, search)) { if (conformsToShorthand(font, search)) {
found.push(font); found.push(font)
} }
} }
return found; return found
} }
/** /**
@@ -168,15 +161,14 @@ function findManyByShorthand(search)
* *
* @returns {?FontFace} * @returns {?FontFace}
*/ */
function findOneByReference(search) function findOneByReference(search) {
{
for (const font of document.fonts) { for (const font of document.fonts) {
if (conformsToReference(font, criterion)) { if (conformsToReference(font, criterion)) {
return font; return font
} }
} }
return null; return null
} }
/** /**
@@ -192,15 +184,14 @@ function findOneByReference(search)
* *
* @returns {?FontFace} * @returns {?FontFace}
*/ */
function findOneByShorthand(search) function findOneByShorthand(search) {
{
for (const font of document.fonts) { for (const font of document.fonts) {
if (conformsToShorthand(font, search)) { if (conformsToShorthand(font, search)) {
return font; return font
} }
} }
return null; return null
} }
/** /**
@@ -220,16 +211,16 @@ function getAny(search) {
if (search) { if (search) {
switch (typeof search) { switch (typeof search) {
case 'string': case 'string':
return findOneByShorthand(search); return findOneByShorthand(search)
case 'object': case 'object':
return findOneByReference(search); return findOneByReference(search)
} }
} }
throw new TypeError( throw new TypeError(
'Expected font query to be font shorthand or font reference' 'Expected font query to be font shorthand or font reference'
); )
} }
/** /**
@@ -244,30 +235,30 @@ function getAny(search) {
*/ */
function getMany(queries) { function getMany(queries) {
if (!Array.isArray(queries)) { if (!Array.isArray(queries)) {
queries = [ queries ]; queries = [queries]
} }
const found = new Set(); const found = new Set()
queries.forEach((search) => { queries.forEach((search) => {
if (search) { if (search) {
switch (typeof search) { switch (typeof search) {
case 'string': case 'string':
found.add(...findManyByShorthand(search)); found.add(...findManyByShorthand(search))
return; return
case 'object': case 'object':
found.add(...findManyByReference(search)); found.add(...findManyByReference(search))
return; return
} }
} }
throw new TypeError( throw new TypeError(
'Expected font query to be font shorthand or font reference' 'Expected font query to be font shorthand or font reference'
); )
}) })
return [ ...found ]; return [...found]
} }
/** /**
@@ -283,10 +274,10 @@ function getMany(queries) {
*/ */
function hasAny(search) { function hasAny(search) {
if (search instanceof FontFace) { if (search instanceof FontFace) {
return document.fonts.has(search); return document.fonts.has(search)
} }
return getAny(search) != null; return getAny(search) != null
} }
/** /**
@@ -302,15 +293,12 @@ function hasAny(search) {
* *
* @returns {Promise} * @returns {Promise}
*/ */
async function loadFonts(fontsToLoad, debug = false) async function loadFonts(fontsToLoad, debug = false) {
{
if ((fontsToLoad.size ?? fontsToLoad.length) === 0) { if ((fontsToLoad.size ?? fontsToLoad.length) === 0) {
throw new TypeError( throw new TypeError('Expected at least one font')
'Expected at least one font'
);
} }
return await loadFontsWithAPI([ ...fontsToLoad ], debug); return await loadFontsWithAPI([...fontsToLoad], debug)
} }
/** /**
@@ -320,12 +308,11 @@ async function loadFonts(fontsToLoad, debug = false)
* *
* @returns {Promise} * @returns {Promise}
*/ */
async function loadFontFaceWithAPI(font) async function loadFontFaceWithAPI(font) {
{ return await (font.status === 'unloaded' ? font.load() : font.loaded).then(
return await (font.status === 'unloaded' (font) => font,
? font.load() (err) => font
: font.loaded )
).then((font) => font, (err) => font)
} }
/** /**
@@ -336,31 +323,34 @@ async function loadFontFaceWithAPI(font)
* *
* @returns {Promise} * @returns {Promise}
*/ */
async function loadFontsWithAPI(fontsToLoad, debug = false) async function loadFontsWithAPI(fontsToLoad, debug = false) {
{ debug &&
debug && console.group('[loadFonts:API]', fontsToLoad.length, '/', document.fonts.size); console.group(
'[loadFonts:API]',
fontsToLoad.length,
'/',
document.fonts.size
)
const fontsToBeLoaded = []; const fontsToBeLoaded = []
for (const fontToLoad of fontsToLoad) { for (const fontToLoad of fontsToLoad) {
if (fontToLoad instanceof FontFace) { if (fontToLoad instanceof FontFace) {
if (!document.fonts.has(fontToLoad)) { if (!document.fonts.has(fontToLoad)) {
document.fonts.add(fontToLoad); document.fonts.add(fontToLoad)
} }
fontsToBeLoaded.push( fontsToBeLoaded.push(loadFontFaceWithAPI(fontToLoad))
loadFontFaceWithAPI(fontToLoad)
);
} else { } else {
fontsToBeLoaded.push( fontsToBeLoaded.push(
...getMany(fontToLoad).map((font) => loadFontFaceWithAPI(font)) ...getMany(fontToLoad).map((font) => loadFontFaceWithAPI(font))
); )
} }
} }
debug && console.groupEnd(); debug && console.groupEnd()
return await Promise.all(fontsToBeLoaded); return await Promise.all(fontsToBeLoaded)
} }
/** /**
@@ -374,7 +364,7 @@ async function loadFontsWithAPI(fontsToLoad, debug = false)
* @returns {string} * @returns {string}
*/ */
function trim(value) { function trim(value) {
return value.replace(/['"]+/g, ''); return value.replace(/['"]+/g, '')
} }
/** /**
@@ -385,11 +375,10 @@ function trim(value) {
* *
* @returns {Promise} * @returns {Promise}
*/ */
async function whenReady(queries) async function whenReady(queries) {
{ const fonts = getMany(queries)
const fonts = getMany(queries);
return await Promise.all(fonts.map((font) => font.loaded)); return await Promise.all(fonts.map((font) => font.loaded))
} }
export { export {

View File

@@ -15,9 +15,9 @@
* @property {string} [rgbaColor=GRID_HELPER_RGBA_COLOR] - RGBA color for the grid appearence. * @property {string} [rgbaColor=GRID_HELPER_RGBA_COLOR] - RGBA color for the grid appearence.
*/ */
const GRID_HELPER_GUTTER_CSS_VAR = '--grid-gutter'; const GRID_HELPER_GUTTER_CSS_VAR = '--grid-gutter'
const GRID_HELPER_MARGIN_CSS_VAR = '--grid-margin'; const GRID_HELPER_MARGIN_CSS_VAR = '--grid-margin'
const GRID_HELPER_RGBA_COLOR = 'rgba(255, 0, 0, .1)'; const GRID_HELPER_RGBA_COLOR = 'rgba(255, 0, 0, .1)'
/** /**
* Create a grid helper * Create a grid helper
@@ -31,15 +31,15 @@ function gridHelper({
rgbaColor = GRID_HELPER_RGBA_COLOR, rgbaColor = GRID_HELPER_RGBA_COLOR,
} = {}) { } = {}) {
// Set grid container // Set grid container
const $gridContainer = document.createElement('div'); const $gridContainer = document.createElement('div')
document.body.append($gridContainer); document.body.append($gridContainer)
// Set grid appearence // Set grid appearence
setGridHelperColumns($gridContainer, rgbaColor); setGridHelperColumns($gridContainer, rgbaColor)
setGridHelperStyles($gridContainer, gutterCssVar, marginCssVar); setGridHelperStyles($gridContainer, gutterCssVar, marginCssVar)
// Set grid interactivity // Set grid interactivity
setGridEvents($gridContainer, rgbaColor); setGridEvents($gridContainer, rgbaColor)
} }
/** /**
@@ -51,19 +51,19 @@ function gridHelper({
* *
*/ */
function setGridHelperStyles($container, gutterCssVar, marginCssVar) { function setGridHelperStyles($container, gutterCssVar, marginCssVar) {
const elStyles = $container.style; const elStyles = $container.style
elStyles.zIndex = '10000'; elStyles.zIndex = '10000'
elStyles.position = 'fixed'; elStyles.position = 'fixed'
elStyles.top = '0'; elStyles.top = '0'
elStyles.left = '0'; elStyles.left = '0'
elStyles.display = 'flex'; elStyles.display = 'flex'
elStyles.width = '100%'; elStyles.width = '100%'
elStyles.height = '100%'; elStyles.height = '100%'
elStyles.columnGap = `var(${gutterCssVar}, 0)`; elStyles.columnGap = `var(${gutterCssVar}, 0)`
elStyles.paddingLeft = `var(${marginCssVar}, 0)`; elStyles.paddingLeft = `var(${marginCssVar}, 0)`
elStyles.paddingRight = `var(${marginCssVar}, 0)`; elStyles.paddingRight = `var(${marginCssVar}, 0)`
elStyles.pointerEvents = 'none'; elStyles.pointerEvents = 'none'
elStyles.visibility = 'hidden'; elStyles.visibility = 'hidden'
} }
/** /**
@@ -75,19 +75,19 @@ function setGridHelperStyles($container, gutterCssVar, marginCssVar) {
*/ */
function setGridHelperColumns($container, rgbaColor) { function setGridHelperColumns($container, rgbaColor) {
// Clear columns // Clear columns
$container.innerHTML = ''; $container.innerHTML = ''
// Loop through columns // Loop through columns
const columns = Number( const columns = Number(
window.getComputedStyle($container).getPropertyValue('--grid-columns') window.getComputedStyle($container).getPropertyValue('--grid-columns')
); )
let $col; let $col
for (var i = 0; i < columns; i++) { for (var i = 0; i < columns; i++) {
$col = document.createElement('div'); $col = document.createElement('div')
$col.style.flex = '1 1 0'; $col.style.flex = '1 1 0'
$col.style.backgroundColor = rgbaColor; $col.style.backgroundColor = rgbaColor
$container.appendChild($col); $container.appendChild($col)
} }
} }
@@ -106,33 +106,33 @@ function setGridEvents($container, rgbaColor) {
window.addEventListener( window.addEventListener(
'resize', 'resize',
setGridHelperColumns($container, rgbaColor) setGridHelperColumns($container, rgbaColor)
); )
// Toggle grid // Toggle grid
let ctrlDown = false; let ctrlDown = false
let isActive = false; let isActive = false
document.addEventListener('keydown', (e) => { document.addEventListener('keydown', (e) => {
if (e.key == 'Control') { if (e.key == 'Control') {
ctrlDown = true; ctrlDown = true
} else { } else {
if (ctrlDown && e.key == 'g') { if (ctrlDown && e.key == 'g') {
if (isActive) { if (isActive) {
$container.style.visibility = 'hidden'; $container.style.visibility = 'hidden'
} else { } else {
$container.style.visibility = 'visible'; $container.style.visibility = 'visible'
} }
isActive = !isActive; isActive = !isActive
} }
} }
}); })
document.addEventListener('keyup', (e) => { document.addEventListener('keyup', (e) => {
if (e.key == 'Control') { if (e.key == 'Control') {
ctrlDown = false; ctrlDown = false
} }
}); })
} }
export { gridHelper }; export { gridHelper }

View File

@@ -4,15 +4,18 @@
* @return {string} escaped string * @return {string} escaped string
*/ */
const escapeHtml = str => const escapeHtml = (str) =>
str.replace(/[&<>'"]/g, tag => ({ str.replace(
'&': '&amp;', /[&<>'"]/g,
'<': '&lt;', (tag) =>
'>': '&gt;', ({
"'": '&#39;', '&': '&amp;',
'"': '&quot;' '<': '&lt;',
}[tag])) '>': '&gt;',
"'": '&#39;',
'"': '&quot;',
}[tag])
)
/** /**
* Unescape HTML string * Unescape HTML string
@@ -20,22 +23,21 @@ const escapeHtml = str =>
* @return {string} unescaped string * @return {string} unescaped string
*/ */
const unescapeHtml = str => const unescapeHtml = (str) =>
str.replace('&amp;', '&') str
.replace('&amp;', '&')
.replace('&lt;', '<') .replace('&lt;', '<')
.replace('&gt;', '>') .replace('&gt;', '>')
.replace('&#39;', "'") .replace('&#39;', "'")
.replace('&quot;', '"') .replace('&quot;', '"')
/** /**
* Get element data attributes * Get element data attributes
* @param {HTMLElement} node - node element * @param {HTMLElement} node - node element
* @return {array} node data * @return {array} node data
*/ */
const getNodeData = node => { const getNodeData = (node) => {
// All attributes // All attributes
const attributes = node.attributes const attributes = node.attributes
@@ -68,13 +70,9 @@ const getNodeData = node => {
data[match[1]] = getData(node.getAttribute(name)) data[match[1]] = getData(node.getAttribute(name))
} }
return data; return data
} }
/** /**
* Parse value to data type. * Parse value to data type.
* *
@@ -84,7 +82,7 @@ const getNodeData = node => {
*/ */
const rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/ const rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/
const getData = data => { const getData = (data) => {
if (data === 'true') { if (data === 'true') {
return true return true
} }
@@ -98,7 +96,7 @@ const getData = data => {
} }
// Only convert to a number if it doesn't change the string // Only convert to a number if it doesn't change the string
if (data === +data+'') { if (data === +data + '') {
return +data return +data
} }
@@ -109,15 +107,13 @@ const getData = data => {
return data return data
} }
/** /**
* Returns an array containing all the parent nodes of the given node * Returns an array containing all the parent nodes of the given node
* @param {HTMLElement} $el - DOM Element * @param {HTMLElement} $el - DOM Element
* @return {array} parent nodes * @return {array} parent nodes
*/ */
const getParents = $el => { const getParents = ($el) => {
// Set up a parent array // Set up a parent array
let parents = [] let parents = []
@@ -130,11 +126,4 @@ const getParents = $el => {
return parents return parents
} }
export { escapeHtml, unescapeHtml, getNodeData, getData, getParents }
export {
escapeHtml,
unescapeHtml,
getNodeData,
getData,
getParents,
}

View File

@@ -5,14 +5,13 @@
* @return {object} The given image meta data * @return {object} The given image meta data
*/ */
const getImageMetadata = $img => ({ const getImageMetadata = ($img) => ({
url: $img.src, url: $img.src,
width: $img.naturalWidth, width: $img.naturalWidth,
height: $img.naturalHeight, height: $img.naturalHeight,
ratio: $img.naturalWidth / $img.naturalHeight, ratio: $img.naturalWidth / $img.naturalHeight,
}) })
/** /**
* Load the given image. * Load the given image.
* *
@@ -36,11 +35,13 @@ const loadImage = (url, options = {}) => {
}) })
} }
if($img.decode) { if ($img.decode) {
$img.src = url $img.src = url
$img.decode().then(loadCallback).catch(e => { $img.decode()
reject(e) .then(loadCallback)
}) .catch((e) => {
reject(e)
})
} else { } else {
$img.onload = loadCallback $img.onload = loadCallback
$img.onerror = (e) => { $img.onerror = (e) => {
@@ -51,7 +52,6 @@ const loadImage = (url, options = {}) => {
}) })
} }
/** /**
* Lazy load the given image. * Lazy load the given image.
* *
@@ -66,7 +66,7 @@ const LAZY_LOADED_IMAGES = []
const lazyLoadImage = async ($el, url, callback) => { const lazyLoadImage = async ($el, url, callback) => {
let src = url ? url : $el.dataset.src let src = url ? url : $el.dataset.src
let loadedImage = LAZY_LOADED_IMAGES.find(image => image.url === src) let loadedImage = LAZY_LOADED_IMAGES.find((image) => image.url === src)
if (!loadedImage) { if (!loadedImage) {
loadedImage = await loadImage(src) loadedImage = await loadImage(src)
@@ -78,7 +78,7 @@ const lazyLoadImage = async ($el, url, callback) => {
LAZY_LOADED_IMAGES.push(loadedImage) LAZY_LOADED_IMAGES.push(loadedImage)
} }
if($el.src === src) { if ($el.src === src) {
return return
} }
@@ -91,7 +91,7 @@ const lazyLoadImage = async ($el, url, callback) => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
let lazyParent = $el.closest('.c-lazy') let lazyParent = $el.closest('.c-lazy')
if(lazyParent) { if (lazyParent) {
lazyParent.classList.add('-lazy-loaded') lazyParent.classList.add('-lazy-loaded')
lazyParent.style.backgroundImage = '' lazyParent.style.backgroundImage = ''
} }
@@ -102,9 +102,4 @@ const lazyLoadImage = async ($el, url, callback) => {
}) })
} }
export { getImageMetadata, loadImage, lazyLoadImage }
export {
getImageMetadata,
loadImage,
lazyLoadImage
}

View File

@@ -7,7 +7,7 @@
* @return {boolean} * @return {boolean}
*/ */
const isObject = x => (x && typeof x === 'object') const isObject = (x) => x && typeof x === 'object'
/** /**
* Determines if the argument is a function. * Determines if the argument is a function.
@@ -16,10 +16,6 @@ const isObject = x => (x && typeof x === 'object')
* @return {boolean} * @return {boolean}
*/ */
const isFunction = x => typeof x === 'function' const isFunction = (x) => typeof x === 'function'
export { isObject, isFunction }
export {
isObject,
isFunction
}

View File

@@ -8,7 +8,6 @@
const clamp = (min = 0, max = 1, a) => Math.min(max, Math.max(min, a)) const clamp = (min = 0, max = 1, a) => Math.min(max, Math.max(min, a))
/** /**
* Calculate lerp * Calculate lerp
* @param {number} x - start value * @param {number} x - start value
@@ -19,7 +18,6 @@ const clamp = (min = 0, max = 1, a) => Math.min(max, Math.max(min, a))
const lerp = (x, y, a) => x * (1 - a) + y * a const lerp = (x, y, a) => x * (1 - a) + y * a
/** /**
* Calculate inverted lerp * Calculate inverted lerp
* @param {number} x - start value * @param {number} x - start value
@@ -28,8 +26,7 @@ const lerp = (x, y, a) => x * (1 - a) + y * a
* @return {number} inverted lerp value * @return {number} inverted lerp value
*/ */
const invlerp = (x, y, a) => clamp((v - x)/(a - x)) const invlerp = (x, y, a) => clamp((v - x) / (a - x))
/** /**
* Round number to the specified precision. * Round number to the specified precision.
@@ -42,13 +39,7 @@ const invlerp = (x, y, a) => clamp((v - x)/(a - x))
* @return {number} The rounded number. * @return {number} The rounded number.
*/ */
const roundNumber = (number, precision = 2) => { const roundNumber = (number, precision = 2) => {
return Number.parseFloat(number.toPrecision(precision)); return Number.parseFloat(number.toPrecision(precision))
} }
export { clamp, lerp, invlerp, roundNumber }
export {
clamp,
lerp,
invlerp,
roundNumber
}

View File

@@ -39,7 +39,6 @@ const debounce = (callback, delay, immediate = false) => {
} }
} }
/** /**
* Creates a throttled function. * Creates a throttled function.
* *
@@ -71,8 +70,4 @@ const throttle = (callback, delay) => {
} }
} }
export { debounce, throttle }
export {
debounce,
throttle
}

View File

@@ -4,32 +4,32 @@
* @return {number|object} translate value * @return {number|object} translate value
*/ */
const getTranslate = $el => { const getTranslate = ($el) => {
if (!window.getComputedStyle) {
if(!window.getComputedStyle) {
return return
} }
let translate let translate
const style = getComputedStyle($el) const style = getComputedStyle($el)
const transform = style.msTransform || style.webkitTransform || style.MozTransform || style.OTransform || style.transform const transform =
style.msTransform ||
style.webkitTransform ||
style.MozTransform ||
style.OTransform ||
style.transform
const matrix3D = transform.match(/^matrix3d\((.+)\)$/) const matrix3D = transform.match(/^matrix3d\((.+)\)$/)
if(matrix3D) { if (matrix3D) {
translate = parseFloat(matrix3D[1].split(', ')[13]) translate = parseFloat(matrix3D[1].split(', ')[13])
} else { } else {
const matrix = transform.match(/^matrix\((.+)\)$/) const matrix = transform.match(/^matrix\((.+)\)$/)
translate = { translate = {
x: matrix ? parseFloat(matrix[1].split(', ')[4]) : 0 x: matrix ? parseFloat(matrix[1].split(', ')[4]) : 0,
y: matrix ? parseFloat(matrix[1].split(', ')[5]) : 0 y: matrix ? parseFloat(matrix[1].split(', ')[5]) : 0,
} }
} }
return translate return translate
} }
export { transform, getTranslate }
export {
transform,
getTranslate
}

View File

@@ -29,7 +29,7 @@
* - {@link https://www.w3.org/TR/page-visibility/ W3 Specification} * - {@link https://www.w3.org/TR/page-visibility/ W3 Specification}
* - {@link https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API MDN Web Docs} * - {@link https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API MDN Web Docs}
*/ */
export default new class PageVisibility { export default new (class PageVisibility {
/** /**
* Checks if the "visibilitychange" event listener has been registered. * Checks if the "visibilitychange" event listener has been registered.
* *
@@ -37,7 +37,7 @@ export default new class PageVisibility {
* otherwise returns `true`. * otherwise returns `true`.
*/ */
get isEnabled() { get isEnabled() {
return isVisibilityChangeObserved; return isVisibilityChangeObserved
} }
/** /**
@@ -48,12 +48,15 @@ export default new class PageVisibility {
*/ */
disableCustomEvents() { disableCustomEvents() {
if (isVisibilityChangeObserved) { if (isVisibilityChangeObserved) {
isVisibilityChangeObserved = false; isVisibilityChangeObserved = false
document.removeEventListener('visibilitychange', handleCustomVisibilityChange); document.removeEventListener(
return true; 'visibilitychange',
handleCustomVisibilityChange
)
return true
} }
return false; return false
} }
/** /**
@@ -64,14 +67,17 @@ export default new class PageVisibility {
*/ */
enableCustomEvents() { enableCustomEvents() {
if (!isVisibilityChangeObserved) { if (!isVisibilityChangeObserved) {
isVisibilityChangeObserved = true; isVisibilityChangeObserved = true
document.addEventListener('visibilitychange', handleCustomVisibilityChange); document.addEventListener(
return true; 'visibilitychange',
handleCustomVisibilityChange
)
return true
} }
return false; return false
} }
} })()
/** /**
* Tracks whether custom visibility event types * Tracks whether custom visibility event types
@@ -79,7 +85,7 @@ export default new class PageVisibility {
* *
* @type {boolean} * @type {boolean}
*/ */
let isVisibilityChangeObserved = false; let isVisibilityChangeObserved = false
/** /**
* Dispatches a custom visibility event at the document derived * Dispatches a custom visibility event at the document derived
@@ -94,11 +100,13 @@ let isVisibilityChangeObserved = false;
* @return {void} * @return {void}
*/ */
function handleCustomVisibilityChange(event) { function handleCustomVisibilityChange(event) {
document.dispatchEvent(new CustomEvent(`visibility${document.visibilityState}`, { document.dispatchEvent(
detail: { new CustomEvent(`visibility${document.visibilityState}`, {
cause: event detail: {
} cause: event,
})); },
})
)
} }
/** /**

View File

@@ -3,7 +3,6 @@
// ========================================================================== // ==========================================================================
.c-form { .c-form {
} }
.c-form_item { .c-form_item {
@@ -58,7 +57,8 @@ $checkbox-icon-color: $input-icon-color;
padding-left: ($checkbox + rem(10px)); padding-left: ($checkbox + rem(10px));
cursor: pointer; cursor: pointer;
&::before, &::after { &::before,
&::after {
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 0; left: 0;
@@ -67,7 +67,7 @@ $checkbox-icon-color: $input-icon-color;
padding: 0; padding: 0;
width: $checkbox; width: $checkbox;
height: $checkbox; height: $checkbox;
content: ""; content: '';
} }
&::before { &::before {
@@ -78,7 +78,7 @@ $checkbox-icon-color: $input-icon-color;
&::after { &::after {
border-color: transparent; border-color: transparent;
background-color: transparent; background-color: transparent;
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2210.5%22%20viewBox%3D%220%200%2013%2010.5%22%20enable-background%3D%22new%200%200%2013%2010.5%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpath%20fill%3D%22%23#{$checkbox-icon-color}%22%20d%3D%22M4.8%205.8L2.4%203.3%200%205.7l4.8%204.8L13%202.4c0%200-2.4-2.4-2.4-2.4L4.8%205.8z%22%2F%3E%3C%2Fsvg%3E"); background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2210.5%22%20viewBox%3D%220%200%2013%2010.5%22%20enable-background%3D%22new%200%200%2013%2010.5%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpath%20fill%3D%22%23#{$checkbox-icon-color}%22%20d%3D%22M4.8%205.8L2.4%203.3%200%205.7l4.8%204.8L13%202.4c0%200-2.4-2.4-2.4-2.4L4.8%205.8z%22%2F%3E%3C%2Fsvg%3E');
background-position: center; background-position: center;
background-size: rem(12px); background-size: rem(12px);
background-repeat: no-repeat; background-repeat: no-repeat;
@@ -118,12 +118,13 @@ $radio-icon-color: $input-icon-color;
.c-form_radioLabel { .c-form_radioLabel {
@extend .c-form_checkboxLabel; @extend .c-form_checkboxLabel;
&::before, &::after { &::before,
&::after {
border-radius: 50%; border-radius: 50%;
} }
&::after { &::after {
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20enable-background%3D%22new%200%200%2013%2013%22%20xml%3Aspace%3D%22preserve%22%3E%3Ccircle%20fill%3D%22%23#{$radio-icon-color}%22%20cx%3D%226.5%22%20cy%3D%226.5%22%20r%3D%226.5%22%2F%3E%3C%2Fsvg%3E"); background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2213%22%20viewBox%3D%220%200%2013%2013%22%20enable-background%3D%22new%200%200%2013%2013%22%20xml%3Aspace%3D%22preserve%22%3E%3Ccircle%20fill%3D%22%23#{$radio-icon-color}%22%20cx%3D%226.5%22%20cy%3D%226.5%22%20r%3D%226.5%22%2F%3E%3C%2Fsvg%3E');
background-size: rem(6px); background-size: rem(6px);
} }
} }
@@ -149,11 +150,11 @@ $select-icon-color: $input-icon-color;
bottom: 0; bottom: 0;
z-index: 2; z-index: 2;
width: $select-icon; width: $select-icon;
background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2211.3%22%20viewBox%3D%220%200%2013%2011.3%22%20enable-background%3D%22new%200%200%2013%2011.3%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpolygon%20fill%3D%22%23#{$select-icon-color}%22%20points%3D%226.5%2011.3%203.3%205.6%200%200%206.5%200%2013%200%209.8%205.6%20%22%2F%3E%3C%2Fsvg%3E"); background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2213%22%20height%3D%2211.3%22%20viewBox%3D%220%200%2013%2011.3%22%20enable-background%3D%22new%200%200%2013%2011.3%22%20xml%3Aspace%3D%22preserve%22%3E%3Cpolygon%20fill%3D%22%23#{$select-icon-color}%22%20points%3D%226.5%2011.3%203.3%205.6%200%200%206.5%200%2013%200%209.8%205.6%20%22%2F%3E%3C%2Fsvg%3E');
background-position: center; background-position: center;
background-size: rem(8px); background-size: rem(8px);
background-repeat: no-repeat; background-repeat: no-repeat;
content: ""; content: '';
pointer-events: none; pointer-events: none;
} }
} }

View File

@@ -16,7 +16,9 @@
transform: scaleX(1.45); transform: scaleX(1.45);
} }
&:hover, .has-scroll-scrolling &, .has-scroll-dragging & { &:hover,
.has-scroll-scrolling &,
.has-scroll-dragging & {
opacity: 1; opacity: 1;
} }
} }

View File

@@ -2,4 +2,4 @@
// Critical CSS // Critical CSS
// ========================================================================== // ==========================================================================
$assets-path: "assets/"; $assets-path: 'assets/';

View File

@@ -3,17 +3,16 @@
// ========================================================================== // ==========================================================================
:root { :root {
// Grid // Grid
--grid-columns : 4; --grid-columns: 4;
--grid-gutter : #{rem(10px)}; --grid-gutter: #{rem(10px)};
--grid-gutter-half : calc(0.5 * var(--grid-gutter)); --grid-gutter-half: calc(0.5 * var(--grid-gutter));
--grid-margin : 0px; --grid-margin: 0px;
@media (min-width: $from-small) { @media (min-width: $from-small) {
--grid-columns : 12; --grid-columns: 12;
--grid-gutter : #{rem(16px)}; --grid-gutter: #{rem(16px)};
--grid-margin : #{rem(20px)}; --grid-margin: #{rem(20px)};
} }
} }
@@ -30,7 +29,7 @@
html { html {
min-height: 100%; // [2] min-height: 100%; // [2]
line-height: $line-height; // [3] line-height: $line-height; // [3]
font-family: ff("sans"); font-family: ff('sans');
color: $font-color; color: $font-color;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;

View File

@@ -57,13 +57,25 @@ figure {
padding: 0; padding: 0;
} }
h1, h2, h3, h4, h5, h6 { h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0; margin: 0;
} }
// 1. Single taps should be dispatched immediately on clickable elements // 1. Single taps should be dispatched immediately on clickable elements
a, area, button, input, label, select, textarea, [tabindex] { a,
area,
button,
input,
label,
select,
textarea,
[tabindex] {
-ms-touch-action: manipulation; // [1] -ms-touch-action: manipulation; // [1]
touch-action: manipulation; touch-action: manipulation;
} }
@@ -83,5 +95,5 @@ hr {
padding: 0; padding: 0;
height: 1px; height: 1px;
border: 0; border: 0;
border-top: 1px solid #CCCCCC; border-top: 1px solid #cccccc;
} }

View File

@@ -1,23 +1,23 @@
// ========================================================================== // ==========================================================================
// Main // Main
// ========================================================================== // ==========================================================================
$app-env: app-env(); $app-env: app-env();
// Settings // Settings
// ========================================================================== // ==========================================================================
@import "settings/config.eases"; @import 'settings/config.eases';
@import "settings/config.colors"; @import 'settings/config.colors';
@import "settings/config"; @import 'settings/config';
// ========================================================================== // ==========================================================================
// Tools // Tools
// ========================================================================== // ==========================================================================
@import "tools/maths"; @import 'tools/maths';
@import "tools/functions"; @import 'tools/functions';
@import "tools/mixins"; @import 'tools/mixins';
@import "tools/fonts"; @import 'tools/fonts';
// @import "tools/layout"; // @import "tools/layout";
// @import "tools/widths"; // @import "tools/widths";
// @import "tools/family"; // @import "tools/family";
@@ -25,25 +25,25 @@ $app-env: app-env();
// Generic // Generic
// ========================================================================== // ==========================================================================
@import "node_modules/normalize.css/normalize"; @import 'node_modules/normalize.css/normalize';
@import "generic/generic"; @import 'generic/generic';
@import "generic/media"; @import 'generic/media';
@import "generic/form"; @import 'generic/form';
@import "generic/button"; @import 'generic/button';
// Elements // Elements
// ========================================================================== // ==========================================================================
@import "elements/document"; @import 'elements/document';
// Objects // Objects
// ========================================================================== // ==========================================================================
@import "objects/scroll"; @import 'objects/scroll';
@import "objects/container"; @import 'objects/container';
@import "objects/ratio"; @import 'objects/ratio';
@import "objects/icons"; @import 'objects/icons';
@import "objects/grid"; @import 'objects/grid';
// @import "objects/layout"; // @import "objects/layout";
// @import "objects/crop"; // @import "objects/crop";
// @import "objects/table"; // @import "objects/table";
@@ -55,19 +55,19 @@ $app-env: app-env();
// Components // Components
// ========================================================================== // ==========================================================================
@import "components/scrollbar"; @import 'components/scrollbar';
@import "components/heading"; @import 'components/heading';
@import "components/button"; @import 'components/button';
@import "components/form"; @import 'components/form';
// Utilities // Utilities
// ========================================================================== // ==========================================================================
@import "utilities/ratio"; @import 'utilities/ratio';
@import "utilities/grid-column"; @import 'utilities/grid-column';
// @import "utilities/widths"; // @import "utilities/widths";
// @import "utilities/align"; // @import "utilities/align";
// @import "utilities/helpers"; // @import "utilities/helpers";
// @import "utilities/states"; // @import "utilities/states";
// @import "utilities/spacing"; // @import "utilities/spacing";
// @import "utilities/print"; // @import "utilities/print";

View File

@@ -4,13 +4,18 @@
// @link https://github.com/inuitcss/inuitcss/blob/19d0c7e/objects/_objects.crop.scss // @link https://github.com/inuitcss/inuitcss/blob/19d0c7e/objects/_objects.crop.scss
// A list of cropping ratios that get generated as modifier classes. // A list of cropping ratios that get generated as modifier classes.
$crop-ratios: ( $crop-ratios: (
(2:1), (
(4:3), 2: 1,
(16:9), ),
(
4: 3,
),
(
16: 9,
)
) !default; ) !default;
// Provide a cropping container in order to display media (usually images) // Provide a cropping container in order to display media (usually images)

View File

@@ -2,7 +2,6 @@
// Objects / SVG Icons // Objects / SVG Icons
// ========================================================================== // ==========================================================================
// Markup // Markup
// //
// 1. If icon is accessible and has a title // 1. If icon is accessible and has a title
@@ -41,7 +40,6 @@
} }
} }
// SVG sizes // SVG sizes
// ========================================================================== // ==========================================================================
@@ -55,4 +53,3 @@
// --icon-width: #{rem(200px)}; // --icon-width: #{rem(200px)};
// } // }
// } // }

View File

@@ -68,17 +68,17 @@
} }
&.-flex { &.-flex {
display: flex; display: flex;
&.-top { &.-top {
align-items: flex-start; align-items: flex-start;
} }
&.-middle { &.-middle {
align-items: center; align-items: center;
} }
&.-bottom { &.-bottom {
align-items: flex-end; align-items: flex-end;
} }
} }
&.-stretch { &.-stretch {
align-items: stretch; align-items: stretch;

View File

@@ -18,15 +18,15 @@
display: block; display: block;
padding-bottom: 100%; // [1] padding-bottom: 100%; // [1]
width: 100%; width: 100%;
content: ""; content: '';
} }
} }
.o-ratio_content, .o-ratio_content,
.o-ratio > img, .o-ratio > img,
.o-ratio > iframe, .o-ratio > iframe,
.o-ratio > embed, .o-ratio > embed,
.o-ratio > object { .o-ratio > object {
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;

View File

@@ -5,25 +5,25 @@
// Palette // Palette
// ============================================================================= // =============================================================================
$color-lightest: #FFFFFF; $color-lightest: #ffffff;
$color-darkest: #000000; $color-darkest: #000000;
// Specific // Specific
// ============================================================================= // =============================================================================
// Link // Link
$color-link: #1A0DAB; $color-link: #1a0dab;
$color-link-focus: #1A0DAB; $color-link-focus: #1a0dab;
$color-link-hover: darken(#1A0DAB, 10%); $color-link-hover: darken(#1a0dab, 10%);
// Selection // Selection
$selection-text-color: #3297FD; $selection-text-color: #3297fd;
$selection-background-color: #FFFFFF; $selection-background-color: #ffffff;
// Social Colors // Social Colors
// ============================================================================= // =============================================================================
$color-facebook: #3B5998; $color-facebook: #3b5998;
$color-instagram: #E1306C; $color-instagram: #e1306c;
$color-youtube: #CD201F; $color-youtube: #cd201f;
$color-twitter: #1DA1F2; $color-twitter: #1da1f2;

View File

@@ -3,46 +3,46 @@
// ========================================================================== // ==========================================================================
// Power 1 // Power 1
$ease-power1-in: cubic-bezier(0.550, 0.085, 0.680, 0.530); $ease-power1-in: cubic-bezier(0.55, 0.085, 0.68, 0.53);
$ease-power1-out: cubic-bezier(0.250, 0.460, 0.450, 0.940); $ease-power1-out: cubic-bezier(0.25, 0.46, 0.45, 0.94);
$ease-power1-in-out: cubic-bezier(0.455, 0.030, 0.515, 0.955); $ease-power1-in-out: cubic-bezier(0.455, 0.03, 0.515, 0.955);
// Power 2 // Power 2
$ease-power2-in: cubic-bezier(0.550, 0.055, 0.675, 0.190); $ease-power2-in: cubic-bezier(0.55, 0.055, 0.675, 0.19);
$ease-power2-out: cubic-bezier(0.215, 0.610, 0.355, 1.000); $ease-power2-out: cubic-bezier(0.215, 0.61, 0.355, 1);
$ease-power2-in-out: cubic-bezier(0.645, 0.045, 0.355, 1.000); $ease-power2-in-out: cubic-bezier(0.645, 0.045, 0.355, 1);
// Power 3 // Power 3
$ease-power3-in: cubic-bezier(0.895, 0.030, 0.685, 0.220); $ease-power3-in: cubic-bezier(0.895, 0.03, 0.685, 0.22);
$ease-power3-out: cubic-bezier(0.165, 0.840, 0.440, 1.000); $ease-power3-out: cubic-bezier(0.165, 0.84, 0.44, 1);
$ease-power3-in-out: cubic-bezier(0.770, 0.000, 0.175, 1.000); $ease-power3-in-out: cubic-bezier(0.77, 0, 0.175, 1);
// Power 3 // Power 3
$ease-power4-in: cubic-bezier(0.755, 0.050, 0.855, 0.060); $ease-power4-in: cubic-bezier(0.755, 0.05, 0.855, 0.06);
$ease-power4-out: cubic-bezier(0.230, 1.000, 0.320, 1.000); $ease-power4-out: cubic-bezier(0.23, 1, 0.32, 1);
$ease-power4-in-out: cubic-bezier(0.860, 0.000, 0.070, 1.000); $ease-power4-in-out: cubic-bezier(0.86, 0, 0.07, 1);
// Expo // Expo
$ease-expo-in: cubic-bezier(0.950, 0.050, 0.795, 0.035); $ease-expo-in: cubic-bezier(0.95, 0.05, 0.795, 0.035);
$ease-expo-out: cubic-bezier(0.190, 1.000, 0.220, 1.000); $ease-expo-out: cubic-bezier(0.19, 1, 0.22, 1);
$ease-expo-in-out: cubic-bezier(1.000, 0.000, 0.000, 1.000); $ease-expo-in-out: cubic-bezier(1, 0, 0, 1);
// Back // Back
$ease-back-in: cubic-bezier(0.600, -0.280, 0.735, 0.045); $ease-back-in: cubic-bezier(0.6, -0.28, 0.735, 0.045);
$ease-back-out: cubic-bezier(0.175, 00.885, 0.320, 1.275); $ease-back-out: cubic-bezier(0.175, 00.885, 0.32, 1.275);
$ease-back-in-out: cubic-bezier(0.680, -0.550, 0.265, 1.550); $ease-back-in-out: cubic-bezier(0.68, -0.55, 0.265, 1.55);
// Sine // Sine
$ease-sine-in: cubic-bezier(0.470, 0.000, 0.745, 0.715); $ease-sine-in: cubic-bezier(0.47, 0, 0.745, 0.715);
$ease-sine-out: cubic-bezier(0.390, 0.575, 0.565, 1.000); $ease-sine-out: cubic-bezier(0.39, 0.575, 0.565, 1);
$ease-sine-in-out: cubic-bezier(0.445, 0.050, 0.550, 0.950); $ease-sine-in-out: cubic-bezier(0.445, 0.05, 0.55, 0.95);
// Circ // Circ
$ease-circ-in: cubic-bezier(0.600, 0.040, 0.980, 0.335); $ease-circ-in: cubic-bezier(0.6, 0.04, 0.98, 0.335);
$ease-circ-out: cubic-bezier(0.075, 0.820, 0.165, 1.000); $ease-circ-out: cubic-bezier(0.075, 0.82, 0.165, 1);
$ease-circ-in-out: cubic-bezier(0.785, 0.135, 0.150, 0.860); $ease-circ-in-out: cubic-bezier(0.785, 0.135, 0.15, 0.86);
// Misc // Misc
$ease-bounce: cubic-bezier(0.17, 0.67, 0.3, 1.33); $ease-bounce: cubic-bezier(0.17, 0.67, 0.3, 1.33);
$ease-slow-out: cubic-bezier(.04,1.15,0.4,.99); $ease-slow-out: cubic-bezier(0.04, 1.15, 0.4, 0.99);
$ease-smooth: cubic-bezier(0.380, 0.005, 0.215, 1); $ease-smooth: cubic-bezier(0.38, 0.005, 0.215, 1);

View File

@@ -6,21 +6,26 @@
// ============================================================================= // =============================================================================
// The current stylesheet context. Available values: frontend, editor. // The current stylesheet context. Available values: frontend, editor.
$context: frontend !default; $context: frontend !default;
// Path is relative to the stylesheets directory. // Path is relative to the stylesheets directory.
$assets-path: "../" !default; $assets-path: '../' !default;
// Typefaces // Typefaces
// ============================================================================= // =============================================================================
// Font directory // Font directory
$font-dir: "../fonts/"; $font-dir: '../fonts/';
// Font fallbacks (retrieved from systemfontstack.com on 2022-05-31) // Font fallbacks (retrieved from systemfontstack.com on 2022-05-31)
$font-fallback-sans: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; $font-fallback-sans: -apple-system, BlinkMacSystemFont, avenir next, avenir,
$font-fallback-serif: Iowan Old Style, Apple Garamond, Baskerville, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial,
$font-fallback-mono: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace; sans-serif;
$font-fallback-serif: Iowan Old Style, Apple Garamond, Baskerville,
Times New Roman, Droid Serif, Times, Source Serif Pro, serif,
Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
$font-fallback-mono: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
monospace;
// Map of font families. // Map of font families.
// //
@@ -28,7 +33,7 @@ $font-fallback-mono: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console
// <font-id>: (<font-name>, <font-fallbacks>) // <font-id>: (<font-name>, <font-fallbacks>)
// ``` // ```
$font-families: ( $font-families: (
sans: join("Source Sans", $font-fallback-sans, $separator: comma), sans: join('Source Sans', $font-fallback-sans, $separator: comma),
); );
// List of custom font faces as tuples. // List of custom font faces as tuples.
@@ -37,10 +42,10 @@ $font-families: (
// <font-name> <font-file-basename> <font-weight> <font-style> // <font-name> <font-file-basename> <font-weight> <font-style>
// ``` // ```
$font-faces: ( $font-faces: (
("Source Sans", "SourceSans3-Bold", 700, normal), ('Source Sans', 'SourceSans3-Bold', 700, normal),
("Source Sans", "SourceSans3-BoldIt", 700, italic), ('Source Sans', 'SourceSans3-BoldIt', 700, italic),
("Source Sans", "SourceSans3-Regular", 400, normal), ('Source Sans', 'SourceSans3-Regular', 400, normal),
("Source Sans", "SourceSans3-RegularIt", 400, italic), ('Source Sans', 'SourceSans3-RegularIt', 400, italic)
); );
// Typography // Typography
@@ -48,38 +53,38 @@ $font-faces: (
// Base // Base
$font-size: 16px; $font-size: 16px;
$line-height: 24px / $font-size; $line-height: 24px / $font-size;
$font-color: $color-darkest; $font-color: $color-darkest;
// Headings // Headings
$font-size-h1: 36px !default; $font-size-h1: 36px !default;
$font-size-h2: 28px !default; $font-size-h2: 28px !default;
$font-size-h3: 24px !default; $font-size-h3: 24px !default;
$font-size-h4: 20px !default; $font-size-h4: 20px !default;
$font-size-h5: 18px !default; $font-size-h5: 18px !default;
$font-size-h6: 16px !default; $font-size-h6: 16px !default;
$line-height-h: $line-height; $line-height-h: $line-height;
// Weights // Weights
$font-weight-light: 300; $font-weight-light: 300;
$font-weight-normal: 400; $font-weight-normal: 400;
$font-weight-medium: 500; $font-weight-medium: 500;
$font-weight-bold: 700; $font-weight-bold: 700;
// Transitions // Transitions
// ============================================================================= // =============================================================================
$speed: 0.3s; $speed: 0.3s;
$easing: $ease-power2-out; $easing: $ease-power2-out;
// Spacing Units // Spacing Units
// ============================================================================= // =============================================================================
$unit: 60px; $unit: 60px;
$unit-small: 20px; $unit-small: 20px;
// Container // Container
// ========================================================================== // ==========================================================================
$padding: $unit; $padding: $unit;
// Grid // Grid
// ========================================================================== // ==========================================================================
@@ -89,30 +94,30 @@ $base-column-gap: $unit-small;
// Breakpoints // Breakpoints
// ============================================================================= // =============================================================================
$from-tiny: 500px !default; $from-tiny: 500px !default;
$to-tiny: $from-tiny - 1 !default; $to-tiny: $from-tiny - 1 !default;
$from-small: 700px !default; $from-small: 700px !default;
$to-small: $from-small - 1 !default; $to-small: $from-small - 1 !default;
$from-medium: 1000px !default; $from-medium: 1000px !default;
$to-medium: $from-medium - 1 !default; $to-medium: $from-medium - 1 !default;
$from-large: 1200px !default; $from-large: 1200px !default;
$to-large: $from-large - 1 !default; $to-large: $from-large - 1 !default;
$from-big: 1400px !default; $from-big: 1400px !default;
$to-big: $from-big - 1 !default; $to-big: $from-big - 1 !default;
$from-huge: 1600px !default; $from-huge: 1600px !default;
$to-huge: $from-huge - 1 !default; $to-huge: $from-huge - 1 !default;
$from-enormous: 1800px !default; $from-enormous: 1800px !default;
$to-enormous: $from-enormous - 1 !default; $to-enormous: $from-enormous - 1 !default;
$from-gigantic: 2000px !default; $from-gigantic: 2000px !default;
$to-gigantic: $from-gigantic - 1 !default; $to-gigantic: $from-gigantic - 1 !default;
$from-colossal: 2400px !default; $from-colossal: 2400px !default;
$to-colossal: $from-colossal - 1 !default; $to-colossal: $from-colossal - 1 !default;
// Master z-indexe // Master z-indexe
// ============================================================================= // =============================================================================
$z-indexes: ( $z-indexes: (
"header": 200, 'header': 200,
"above": 1, 'above': 1,
"below": -1 'below': -1,
); );

View File

@@ -229,7 +229,8 @@
$child: nth(nth($selector, -1), -1); $child: nth(nth($selector, -1), -1);
&:nth-last-child(n + #{$min}):nth-last-child(-n + #{$max}):first-child, &:nth-last-child(n + #{$min}):nth-last-child(-n + #{$max}):first-child,
&:nth-last-child(n + #{$min}):nth-last-child(-n + #{$max}):first-child ~ #{$child} { &:nth-last-child(n + #{$min}):nth-last-child(-n + #{$max}):first-child
~ #{$child} {
@content; @content;
} }
} }
@@ -240,7 +241,7 @@
@mixin first-child() { @mixin first-child() {
&:first-of-type { &:first-of-type {
@content @content;
} }
} }
@@ -250,7 +251,7 @@
@mixin last-child() { @mixin last-child() {
&:last-of-type { &:last-of-type {
@content @content;
} }
} }

View File

@@ -15,8 +15,8 @@
@font-face { @font-face {
font-display: swap; font-display: swap;
font-family: nth($webfont, 1); font-family: nth($webfont, 1);
src: url("#{$dir}#{nth($webfont, 2)}.woff2") format("woff2"), src: url('#{$dir}#{nth($webfont, 2)}.woff2') format('woff2'),
url("#{$dir}#{nth($webfont, 2)}.woff") format("woff"); url('#{$dir}#{nth($webfont, 2)}.woff') format('woff');
font-weight: #{nth($webfont, 3)}; font-weight: #{nth($webfont, 3)};
font-style: #{nth($webfont, 4)}; font-style: #{nth($webfont, 4)};
} }
@@ -33,7 +33,7 @@
@mixin font-faces($webfonts, $dir) { @mixin font-faces($webfonts, $dir) {
@if (length($webfonts) > 0) { @if (length($webfonts) > 0) {
@if (type-of(nth($webfonts, 1)) == "list") { @if (type-of(nth($webfonts, 1)) == 'list') {
@each $webfont in $webfonts { @each $webfont in $webfonts {
@include font-face($webfont, $dir); @include font-face($webfont, $dir);
} }

View File

@@ -8,7 +8,7 @@
// @return {Boolean} // @return {Boolean}
@function is-pixel-number($number) { @function is-pixel-number($number) {
@return type-of($number) == number and unit($number) == "px"; @return type-of($number) == number and unit($number) == 'px';
} }
// Converts the given pixel value to its EM quivalent. // Converts the given pixel value to its EM quivalent.
@@ -36,7 +36,6 @@
// @return {Number} Scalable pixel value in REMs. // @return {Number} Scalable pixel value in REMs.
@function rem($size, $base: $font-size) { @function rem($size, $base: $font-size) {
@if not is-pixel-number($size) { @if not is-pixel-number($size) {
@error "`#{$size}` needs to be a number in pixel."; @error "`#{$size}` needs to be a number in pixel.";
} }
@@ -92,12 +91,9 @@
// @return {Boolean} // @return {Boolean}
// @access private // @access private
@function list-contains( @function list-contains($list, $values...) {
$list,
$values...
) {
@each $value in $values { @each $value in $values {
@if type-of(index($list, $value)) != "number" { @if type-of(index($list, $value)) != 'number' {
@return false; @return false;
} }
} }

View File

@@ -34,7 +34,7 @@
&::after { &::after {
display: if(list-contains($supports, table), table, block); display: if(list-contains($supports, table), table, block);
clear: both; clear: both;
content: if(list-contains($supports, opera), " ", ""); content: if(list-contains($supports, opera), ' ', '');
} }
} }
@@ -50,11 +50,19 @@
$important: important($important); $important: important($important);
font-size: rem($font-size) $important; font-size: rem($font-size) $important;
@if ($line-height == "auto") { @if ($line-height == 'auto') {
line-height: ceil($font-size / $line-height) * ($line-height / $font-size) $important; line-height: ceil($font-size / $line-height) *
} ($line-height / $font-size)
@else { $important;
@if (type-of($line-height) == number or $line-height == "inherit" or $line-height == "normal") { } @else {
@if (
type-of($line-height) ==
number or
$line-height ==
'inherit' or
$line-height ==
'normal'
) {
line-height: $line-height $important; line-height: $line-height $important;
} }
@elseif ($line-height != "none" and $line-height != false) { @elseif ($line-height != "none" and $line-height != false) {
@@ -77,7 +85,7 @@
&::before { &::before {
display: inline-block; display: inline-block;
height: 100%; height: 100%;
content: ""; content: '';
vertical-align: middle; vertical-align: middle;
} }
@@ -128,7 +136,7 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
word-wrap: normal; // [2] word-wrap: normal; // [2]
@if $width { @if $width {
max-width: $width; // [1] max-width: $width; // [1]
} }
@@ -176,7 +184,7 @@
@mixin u-hidden($important: true) { @mixin u-hidden($important: true) {
$important: important($important); $important: important($important);
display: none $important; display: none $important;
visibility: hidden $important; visibility: hidden $important;
} }
@@ -191,5 +199,5 @@
@mixin u-shown($display: block, $important: true) { @mixin u-shown($display: block, $important: true) {
$important: important($important); $important: important($important);
display: $display $important; display: $display $important;
visibility: visible $important; visibility: visible $important;
} }

View File

@@ -12,12 +12,12 @@
$colsMax: $base-column-nb + 1; $colsMax: $base-column-nb + 1;
$breakpoints: ( $breakpoints: (
"null" null, 'null' null,
"from-tiny" "from-tiny", 'from-tiny' 'from-tiny',
"from-small" "from-small", 'from-small' 'from-small',
"from-medium" "from-medium", 'from-medium' 'from-medium',
"from-large" "from-large", 'from-large' 'from-large',
"from-big" "from-big" 'from-big' 'from-big'
) !default; ) !default;
@each $breakpoint-namespace, $breakpoint in $breakpoints { @each $breakpoint-namespace, $breakpoint in $breakpoints {
@@ -30,27 +30,27 @@ $breakpoints: (
} }
} @else { } @else {
.u-gc-#{$fromIndex}\/#{$toIndex}\@#{$breakpoint} { .u-gc-#{$fromIndex}\/#{$toIndex}\@#{$breakpoint} {
@if $breakpoint-namespace == "from-tiny" { @if $breakpoint-namespace == 'from-tiny' {
@media (min-width: $from-tiny) { @media (min-width: $from-tiny) {
grid-column-start: #{$fromIndex}; grid-column-start: #{$fromIndex};
grid-column-end: #{$toIndex}; grid-column-end: #{$toIndex};
} }
} @else if $breakpoint-namespace == "from-small" { } @else if $breakpoint-namespace == 'from-small' {
@media (min-width: $from-small) { @media (min-width: $from-small) {
grid-column-start: #{$fromIndex}; grid-column-start: #{$fromIndex};
grid-column-end: #{$toIndex}; grid-column-end: #{$toIndex};
} }
} @else if $breakpoint-namespace == "from-medium" { } @else if $breakpoint-namespace == 'from-medium' {
@media (min-width: $from-medium) { @media (min-width: $from-medium) {
grid-column-start: #{$fromIndex}; grid-column-start: #{$fromIndex};
grid-column-end: #{$toIndex}; grid-column-end: #{$toIndex};
} }
} @else if $breakpoint-namespace == "from-large" { } @else if $breakpoint-namespace == 'from-large' {
@media (min-width: $from-large) { @media (min-width: $from-large) {
grid-column-start: #{$fromIndex}; grid-column-start: #{$fromIndex};
grid-column-end: #{$toIndex}; grid-column-end: #{$toIndex};
} }
} @else if $breakpoint-namespace == "from-big" { } @else if $breakpoint-namespace == 'from-big' {
@media (min-width: $from-big) { @media (min-width: $from-big) {
grid-column-start: #{$fromIndex}; grid-column-start: #{$fromIndex};
grid-column-end: #{$toIndex}; grid-column-end: #{$toIndex};

View File

@@ -19,13 +19,13 @@
// Visibility / Display // Visibility / Display
// ========================================================================== // ==========================================================================
[hidden][aria-hidden="false"] { [hidden][aria-hidden='false'] {
position: absolute; position: absolute;
display: inherit; display: inherit;
clip: rect(0, 0, 0, 0); clip: rect(0, 0, 0, 0);
} }
[hidden][aria-hidden="false"]:focus { [hidden][aria-hidden='false']:focus {
clip: auto; clip: auto;
} }

View File

@@ -11,7 +11,6 @@
//// ////
@media print { @media print {
// 1. Black prints faster: http://www.sanbeiji.com/archives/953 // 1. Black prints faster: http://www.sanbeiji.com/archives/953
*, *,
@@ -31,19 +30,19 @@
} }
a[href]:after { a[href]:after {
content: " (" attr(href) ")"; content: ' (' attr(href) ')';
} }
abbr[title]:after { abbr[title]:after {
content: " (" attr(title) ")"; content: ' (' attr(title) ')';
} }
// Don't show links that are fragment identifiers, or use the `javascript:` // Don't show links that are fragment identifiers, or use the `javascript:`
// pseudo protocol. // pseudo protocol.
a[href^="#"]:after, a[href^='#']:after,
a[href^="javascript:"]:after { a[href^='javascript:']:after {
content: ""; content: '';
} }
pre, pre,
@@ -63,7 +62,6 @@
page-break-inside: avoid; page-break-inside: avoid;
} }
img { img {
max-width: 100% !important; max-width: 100% !important;
} }

View File

@@ -6,9 +6,15 @@
// A list of aspect ratios that get generated as modifier classes. // A list of aspect ratios that get generated as modifier classes.
$aspect-ratios: ( $aspect-ratios: (
(2:1), (
(4:3), 2: 1,
(16:9), ),
(
4: 3,
),
(
16: 9,
)
) !default; ) !default;
/* stylelint-disable */ /* stylelint-disable */
@@ -21,11 +27,11 @@ $aspect-ratios: (
@each $ratio in $aspect-ratios { @each $ratio in $aspect-ratios {
@each $antecedent, $consequent in $ratio { @each $antecedent, $consequent in $ratio {
@if (type-of($antecedent) != number) { @if (type-of($antecedent) != number) {
@error "`#{$antecedent}` needs to be a number." @error "`#{$antecedent}` needs to be a number.";
} }
@if (type-of($consequent) != number) { @if (type-of($consequent) != number) {
@error "`#{$consequent}` needs to be a number." @error "`#{$consequent}` needs to be a number.";
} }
&.u-#{$antecedent}\:#{$consequent}::before { &.u-#{$antecedent}\:#{$consequent}::before {

View File

@@ -21,25 +21,25 @@
/* stylelint-disable string-quotes */ /* stylelint-disable string-quotes */
$spacing-directions: ( $spacing-directions: (
null: null, null: null,
'-top': '-top', '-top': '-top',
'-right': '-right', '-right': '-right',
'-bottom': '-bottom', '-bottom': '-bottom',
'-left': '-left', '-left': '-left',
'-horizontal': '-left' '-right', '-horizontal': '-left' '-right',
'-vertical': '-top' '-bottom', '-vertical': '-top' '-bottom',
) !default; ) !default;
$spacing-properties: ( $spacing-properties: (
'padding': 'padding', 'padding': 'padding',
'margin': 'margin', 'margin': 'margin',
) !default; ) !default;
$spacing-sizes: ( $spacing-sizes: (
null: $unit, null: $unit,
'-double': $unit * 2, '-double': $unit * 2,
'-small': $unit-small, '-small': $unit-small,
'-none': 0px '-none': 0px,
) !default; ) !default;
@each $property-namespace, $property in $spacing-properties { @each $property-namespace, $property in $spacing-properties {

View File

@@ -4,7 +4,7 @@
// ARIA roles display visual cursor hints // ARIA roles display visual cursor hints
[aria-busy="true"] { [aria-busy='true'] {
cursor: progress; cursor: progress;
} }

1557
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,8 @@
}, },
"scripts": { "scripts": {
"start": "node --experimental-json-modules --no-warnings build/watch.js", "start": "node --experimental-json-modules --no-warnings build/watch.js",
"build": "node --experimental-json-modules --no-warnings build/build.js" "build": "node --experimental-json-modules --no-warnings build/build.js",
"precommit": "prettier --write 'assets/**/*.{js,scss,json}'"
}, },
"dependencies": { "dependencies": {
"locomotive-scroll": "^4.1.4", "locomotive-scroll": "^4.1.4",
@@ -29,6 +30,7 @@
"node-notifier": "^10.0.1", "node-notifier": "^10.0.1",
"node-sass": "^8.0.0", "node-sass": "^8.0.0",
"postcss": "^8.4.21", "postcss": "^8.4.21",
"prettier": "^2.8.3",
"purgecss": "^5.0.0", "purgecss": "^5.0.0",
"svg-mixer": "~2.3.14", "svg-mixer": "~2.3.14",
"tiny-glob": "^0.2.9" "tiny-glob": "^0.2.9"