mirror of
https://github.com/locomotivemtl/locomotive-boilerplate.git
synced 2026-01-15 00:55:08 +08:00
Merge pull request #112 from locomotivemtl/feature/grid-helper
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ node_modules
|
||||
Thumbs.db
|
||||
loconfig.*.json
|
||||
!loconfig.example.json
|
||||
.prettierrc
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": 1665079086854
|
||||
"version": 1667240825414
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import config from './config'
|
||||
import { isFontLoadingAPIAvailable, loadFonts } from './utils/fonts';
|
||||
|
||||
const app = new modular({
|
||||
modules: modules
|
||||
modules: modules,
|
||||
});
|
||||
|
||||
window.onload = (event) => {
|
||||
@@ -35,24 +35,26 @@ function init() {
|
||||
|
||||
app.init(app);
|
||||
|
||||
html.classList.add(config.CSS_CLASS.LOADED);
|
||||
html.classList.add(config.CSS_CLASS.READY);
|
||||
html.classList.remove(config.CSS_CLASS.LOADING);
|
||||
html.classList.add('is-loaded');
|
||||
html.classList.add('is-ready');
|
||||
html.classList.remove('is-loading');
|
||||
|
||||
/**
|
||||
* Eagerly load the following fonts.
|
||||
*/
|
||||
if (isFontLoadingAPIAvailable) {
|
||||
loadFonts(EAGER_FONTS).then((eagerFonts) => {
|
||||
loadFonts(EAGER_FONTS, config.IS_DEV).then((eagerFonts) => {
|
||||
html.classList.add('fonts-loaded');
|
||||
// console.group('Eager fonts loaded!', eagerFonts.length, '/', document.fonts.size);
|
||||
// console.group('State of eager fonts:')
|
||||
// eagerFonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/))
|
||||
// console.groupEnd()
|
||||
// console.group('State of all fonts:')
|
||||
// document.fonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/))
|
||||
// console.groupEnd()
|
||||
|
||||
if (config.IS_DEV) {
|
||||
console.group('Eager fonts loaded!', eagerFonts.length, '/', document.fonts.size);
|
||||
console.group('State of eager fonts:')
|
||||
eagerFonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/))
|
||||
console.groupEnd()
|
||||
console.group('State of all fonts:')
|
||||
document.fonts.forEach((font) => console.log(font.family, font.style, font.weight, font.status/*, font*/))
|
||||
console.groupEnd()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
import svg4everybody from 'svg4everybody';
|
||||
import config from './config';
|
||||
|
||||
export default function() {
|
||||
// Dynamic imports for development mode only
|
||||
let gridHelper;
|
||||
(async () => {
|
||||
if (config.IS_DEV) {
|
||||
const gridHelperModule = await import('./utils/grid-helper');
|
||||
gridHelper = gridHelperModule?.gridHelper;
|
||||
}
|
||||
})();
|
||||
|
||||
export default function () {
|
||||
/**
|
||||
* Use external SVG spritemaps
|
||||
*/
|
||||
svg4everybody();
|
||||
|
||||
/**
|
||||
* Add grid helper
|
||||
*/
|
||||
gridHelper?.();
|
||||
}
|
||||
|
||||
138
assets/scripts/utils/grid-helper.js
Normal file
138
assets/scripts/utils/grid-helper.js
Normal file
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Grid Helper
|
||||
*
|
||||
* Provides a grid based on the design guidelines and is helpful for web integration.
|
||||
*
|
||||
* - `Control + g` to toggle the grid
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} GridHelperReference
|
||||
*
|
||||
* @property {string} [gutterCssVar=GRID_HELPER_GUTTER_CSS_VAR] - CSS variable used to define grid gutters.
|
||||
* @property {string} [marginCssVar=GRID_HELPER_MARGIN_CSS_VAR] - CSS variable used to define grid margins.
|
||||
* @property {string} [rgbaColor=GRID_HELPER_RGBA_COLOR] - RGBA color for the grid appearence.
|
||||
*/
|
||||
|
||||
const GRID_HELPER_GUTTER_CSS_VAR = '--grid-gutter';
|
||||
const GRID_HELPER_MARGIN_CSS_VAR = '--grid-margin';
|
||||
const GRID_HELPER_RGBA_COLOR = 'rgba(255, 0, 0, .1)';
|
||||
|
||||
/**
|
||||
* Create a grid helper
|
||||
*
|
||||
* @param {GridHelperReference}
|
||||
*
|
||||
*/
|
||||
function gridHelper({
|
||||
gutterCssVar = GRID_HELPER_GUTTER_CSS_VAR,
|
||||
marginCssVar = GRID_HELPER_MARGIN_CSS_VAR,
|
||||
rgbaColor = GRID_HELPER_RGBA_COLOR,
|
||||
} = {}) {
|
||||
// Set grid container
|
||||
const $gridContainer = document.createElement('div');
|
||||
document.body.append($gridContainer);
|
||||
|
||||
// Set grid appearence
|
||||
setGridHelperColumns($gridContainer, rgbaColor);
|
||||
setGridHelperStyles($gridContainer, gutterCssVar, marginCssVar);
|
||||
|
||||
// Set grid interactivity
|
||||
setGridEvents($gridContainer, rgbaColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grid container styles
|
||||
*
|
||||
* @param {HTMLElement} $container - DOM Element that contains a list of generated columns
|
||||
* @param {string} gutterCssVar - CSS variable used to define grid gutters.
|
||||
* @param {string} marginCssVar - CSS variable used to define grid margins.
|
||||
*
|
||||
*/
|
||||
function setGridHelperStyles($container, gutterCssVar, marginCssVar) {
|
||||
const elStyles = $container.style;
|
||||
elStyles.zIndex = '10000';
|
||||
elStyles.position = 'fixed';
|
||||
elStyles.top = '0';
|
||||
elStyles.left = '0';
|
||||
elStyles.display = 'flex';
|
||||
elStyles.width = '100%';
|
||||
elStyles.height = '100%';
|
||||
elStyles.columnGap = `var(${gutterCssVar}, 0)`;
|
||||
elStyles.paddingLeft = `var(${marginCssVar}, 0)`;
|
||||
elStyles.paddingRight = `var(${marginCssVar}, 0)`;
|
||||
elStyles.pointerEvents = 'none';
|
||||
elStyles.visibility = 'hidden';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grid columns
|
||||
*
|
||||
* @param {HTMLElement} $container - DOM Element that will contain a list of generated columns
|
||||
* @param {string} rgbaColor - RGBA color to stylize the generated columns
|
||||
*
|
||||
*/
|
||||
function setGridHelperColumns($container, rgbaColor) {
|
||||
// Clear columns
|
||||
$container.innerHTML = '';
|
||||
|
||||
// Loop through columns
|
||||
const columns = Number(
|
||||
window.getComputedStyle($container).getPropertyValue('--grid-columns')
|
||||
);
|
||||
|
||||
let $col;
|
||||
for (var i = 0; i < columns; i++) {
|
||||
$col = document.createElement('div');
|
||||
$col.style.flex = '1 1 0';
|
||||
$col.style.backgroundColor = rgbaColor;
|
||||
$container.appendChild($col);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grid events
|
||||
*
|
||||
* Resize to rebuild columns
|
||||
* Keydown/Keyup to toggle the grid display
|
||||
*
|
||||
* @param {HTMLElement} $container - DOM Element that contains a list of generated columns
|
||||
* @param {string} rgbaColor - RGBA color to stylize the generated columns
|
||||
*
|
||||
*/
|
||||
function setGridEvents($container, rgbaColor) {
|
||||
// Handle resize
|
||||
window.addEventListener(
|
||||
'resize',
|
||||
setGridHelperColumns($container, rgbaColor)
|
||||
);
|
||||
|
||||
// Toggle grid
|
||||
let ctrlDown = false;
|
||||
let isActive = false;
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key == 'Control') {
|
||||
ctrlDown = true;
|
||||
} else {
|
||||
if (ctrlDown && e.key == 'g') {
|
||||
if (isActive) {
|
||||
$container.style.visibility = 'visible';
|
||||
} else {
|
||||
$container.style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
isActive = !isActive;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', (e) => {
|
||||
if (e.key == 'Control') {
|
||||
ctrlDown = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export { gridHelper };
|
||||
@@ -2,6 +2,22 @@
|
||||
// Elements / Document
|
||||
// ==========================================================================
|
||||
|
||||
:root {
|
||||
|
||||
// Grid
|
||||
--grid-columns : 4;
|
||||
--grid-gutter : #{rem(10px)};
|
||||
--grid-gutter-half : calc(0.5 * var(--grid-gutter));
|
||||
--grid-margin : 0px;
|
||||
|
||||
@media (min-width: $from-small) {
|
||||
--grid-columns : 12;
|
||||
--grid-gutter : #{rem(16px)};
|
||||
--grid-margin : #{rem(20px)};
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Simple page-level setup.
|
||||
//
|
||||
// 1. Include web fonts
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// ==========================================================================
|
||||
// Main
|
||||
// ==========================================================================
|
||||
$app-env: app-env();
|
||||
|
||||
// Settings
|
||||
// ==========================================================================
|
||||
@@ -69,4 +70,4 @@
|
||||
// @import "utilities/helpers";
|
||||
// @import "utilities/states";
|
||||
// @import "utilities/spacing";
|
||||
// @import "utilities/print";
|
||||
// @import "utilities/print";
|
||||
@@ -6,7 +6,7 @@ import resolve from '../utils/template.js';
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
import { basename } from 'node:path';
|
||||
import { promisify } from 'node:util';
|
||||
import sass from 'node-sass';
|
||||
import sass, { types } from 'node-sass';
|
||||
import { PurgeCSS } from 'purgecss';
|
||||
|
||||
const sassRender = promisify(sass.render);
|
||||
@@ -23,8 +23,14 @@ export const defaultSassOptions = {
|
||||
sourceMap: true,
|
||||
sourceMapContents: true,
|
||||
};
|
||||
|
||||
export const developmentSassOptions = Object.assign({}, defaultSassOptions, {
|
||||
outputStyle: 'expanded',
|
||||
functions: {
|
||||
'app-env()': function () {
|
||||
return (new types.String('development'))
|
||||
}
|
||||
}
|
||||
});
|
||||
export const productionSassOptions = Object.assign({}, defaultSassOptions, {
|
||||
outputStyle: 'compressed',
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -41,8 +41,6 @@
|
||||
|
||||
<body data-module-load>
|
||||
|
||||
<!-- <p aria-hidden="true" class="u-screen-reader-text" style="font-family: 'Webfont';"> </p> -->
|
||||
|
||||
<div data-load-container>
|
||||
<div class="o-scroll" data-module-scroll="main">
|
||||
<header data-scroll-section>
|
||||
|
||||
Reference in New Issue
Block a user