mirror of
https://github.com/locomotivemtl/locomotive-boilerplate.git
synced 2026-01-15 00:55:08 +08:00
Compare commits
45 Commits
feature/sw
...
feature/11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
171aa29a12 | ||
|
|
375b54150e | ||
|
|
0a4da30696 | ||
|
|
ec55037dfe | ||
|
|
795be38edb | ||
|
|
f52d2bc61e | ||
|
|
6cef7be291 | ||
|
|
e97cf527b8 | ||
|
|
a1801c8bc8 | ||
|
|
d6abf2b4ca | ||
|
|
09217c17e5 | ||
|
|
a66cb193d0 | ||
|
|
6d37049989 | ||
|
|
bc3fd3a492 | ||
|
|
45d8be5525 | ||
|
|
ea8f98a52d | ||
|
|
56bbd9e3c5 | ||
|
|
dcb7e91b91 | ||
|
|
2b1eb8e0dd | ||
|
|
f4afd9c6b2 | ||
|
|
7578397a8e | ||
|
|
27effb470d | ||
|
|
7a91cbce61 | ||
|
|
65a265c0ea | ||
|
|
afb3a4aa6a | ||
|
|
40521c3f2b | ||
|
|
2d395cf73a | ||
|
|
81d47b88b8 | ||
|
|
c16407c8c1 | ||
|
|
522c9c0bcb | ||
|
|
ddd12ffc38 | ||
|
|
9e6d7ae182 | ||
|
|
d5bff3ab50 | ||
|
|
962ba66b96 | ||
|
|
5b6bca6ce3 | ||
|
|
4ae90a5821 | ||
|
|
31061daf60 | ||
|
|
ceefeb554e | ||
|
|
276b5eebc0 | ||
|
|
0af2be4599 | ||
|
|
98ba8c4972 | ||
|
|
3f7077b488 | ||
|
|
a674a16c4b | ||
|
|
dd2c783938 | ||
|
|
7021666c46 |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -5,3 +5,14 @@ loconfig.*.json
|
||||
!loconfig.example.json
|
||||
.prettierrc
|
||||
www/**/*.html
|
||||
|
||||
www/assets/scripts/app.js
|
||||
www/assets/scripts/app.js.map
|
||||
www/assets/scripts/vendors.js
|
||||
|
||||
www/assets/styles/main.css
|
||||
www/assets/styles/main.css.map
|
||||
www/assets/styles/critical.css
|
||||
www/assets/styles/critical.css.map
|
||||
|
||||
assets.json
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"version": 1705616220986
|
||||
}
|
||||
@@ -1,48 +1,34 @@
|
||||
import modular from 'modujs';
|
||||
import * as modules from './modules';
|
||||
import globals from './globals';
|
||||
import { debounce } from './utils/tickers'
|
||||
import { debounce } from './utils/tickers';
|
||||
import { $html } from './utils/dom';
|
||||
import { ENV, FONT, CUSTOM_EVENT, CSS_CLASS } from './config'
|
||||
import { isFontLoadingAPIAvailable, loadFonts } from './utils/fonts';
|
||||
|
||||
const app = new modular({
|
||||
modules: modules,
|
||||
});
|
||||
|
||||
window.addEventListener('load', (event) => {
|
||||
const $style = document.getElementById('main-css');
|
||||
|
||||
if ($style) {
|
||||
if ($style.isLoaded) {
|
||||
init();
|
||||
} else {
|
||||
$style.addEventListener('load', (event) => {
|
||||
init();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.warn('The "main-css" stylesheet not found');
|
||||
}
|
||||
modules,
|
||||
});
|
||||
|
||||
function init() {
|
||||
bindEvents();
|
||||
globals();
|
||||
setViewportSizes();
|
||||
|
||||
app.init(app);
|
||||
|
||||
$html.classList.add(CSS_CLASS.LOADED);
|
||||
$html.classList.add(CSS_CLASS.READY);
|
||||
$html.classList.add(CSS_CLASS.LOADED, CSS_CLASS.READY);
|
||||
$html.classList.remove(CSS_CLASS.LOADING);
|
||||
|
||||
// Bind window resize event with default vars
|
||||
const resizeEndEvent = new CustomEvent(CUSTOM_EVENT.RESIZE_END)
|
||||
window.addEventListener('resize', () => {
|
||||
$html.style.setProperty('--vw', `${document.documentElement.clientWidth * 0.01}px`)
|
||||
debounce(() => {
|
||||
window.dispatchEvent(resizeEndEvent)
|
||||
}, 200, false)
|
||||
})
|
||||
/**
|
||||
* Debug focus
|
||||
*/
|
||||
// document.addEventListener(
|
||||
// "focusin",
|
||||
// function () {
|
||||
// console.log('focused: ', document.activeElement)
|
||||
// }, true
|
||||
// );
|
||||
|
||||
/**
|
||||
* Eagerly load the following fonts.
|
||||
@@ -51,15 +37,101 @@ function init() {
|
||||
loadFonts(FONT.EAGER, ENV.IS_DEV).then((eagerFonts) => {
|
||||
$html.classList.add(CSS_CLASS.FONTS_LOADED);
|
||||
|
||||
if (ENV.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()
|
||||
}
|
||||
/**
|
||||
* Debug fonts loading
|
||||
*/
|
||||
// if (ENV.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));
|
||||
// console.groupEnd();
|
||||
// console.group('State of all fonts:');
|
||||
// document.fonts.forEach(font => console.log(font.family, font.style, font.weight, font.status));
|
||||
// console.groupEnd();
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Global events
|
||||
////////////////
|
||||
function bindEvents() {
|
||||
|
||||
// Resize event
|
||||
const resizeEndEvent = new CustomEvent(CUSTOM_EVENT.RESIZE_END)
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
debounce(() => {
|
||||
window.dispatchEvent(resizeEndEvent)
|
||||
}, 200, false)
|
||||
)
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
onResize
|
||||
)
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
setViewportSizes()
|
||||
}
|
||||
|
||||
function setViewportSizes() {
|
||||
|
||||
// Document styles
|
||||
const documentStyles = document.documentElement.style;
|
||||
|
||||
// Viewport width
|
||||
const vw = document.body.clientWidth * 0.01;
|
||||
documentStyles.setProperty('--vw', `${vw}px`);
|
||||
|
||||
// Return if browser supports vh, svh, dvh, & lvh
|
||||
if (ENV.SUPPORTS_VH) {
|
||||
return
|
||||
}
|
||||
|
||||
// Viewport height
|
||||
const svh = document.documentElement.clientHeight * 0.01;
|
||||
documentStyles.setProperty('--svh', `${svh}px`);
|
||||
|
||||
const dvh = window.innerHeight * 0.01;
|
||||
documentStyles.setProperty('--dvh', `${dvh}px`);
|
||||
|
||||
if (document.body) {
|
||||
const fixed = document.createElement('div');
|
||||
fixed.style.width = '1px';
|
||||
fixed.style.height = '100vh';
|
||||
fixed.style.position = 'fixed';
|
||||
fixed.style.left = '0';
|
||||
fixed.style.top = '0';
|
||||
fixed.style.bottom = '0';
|
||||
fixed.style.visibility = 'hidden';
|
||||
|
||||
document.body.appendChild(fixed);
|
||||
|
||||
var fixedHeight = fixed.clientHeight;
|
||||
|
||||
fixed.remove();
|
||||
|
||||
const lvh = fixedHeight * 0.01;
|
||||
|
||||
documentStyles.setProperty('--lvh', `${lvh}px`);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Execute
|
||||
////////////////
|
||||
window.addEventListener('load', () => {
|
||||
const $style = document.getElementById('main-css');
|
||||
|
||||
if ($style) {
|
||||
if ($style.isLoaded) {
|
||||
init();
|
||||
} else {
|
||||
$style.addEventListener('load', init);
|
||||
}
|
||||
} else {
|
||||
console.warn('The "main-css" stylesheet not found');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -21,6 +21,15 @@ const ENV = Object.freeze({
|
||||
// Device
|
||||
IS_MOBILE,
|
||||
IS_DESKTOP: !IS_MOBILE,
|
||||
|
||||
// Supports
|
||||
SUPPORTS_VH: (
|
||||
'CSS' in window
|
||||
&& 'supports' in window.CSS
|
||||
&& window.CSS.supports('height: 100svh')
|
||||
&& window.CSS.supports('height: 100dvh')
|
||||
&& window.CSS.supports('height: 100lvh')
|
||||
)
|
||||
})
|
||||
|
||||
// Main CSS classes used within the project
|
||||
|
||||
@@ -20,34 +20,26 @@ html {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
@media (max-width: $to-small) {
|
||||
@media (max-width: $to-sm) {
|
||||
font-size: $font-size - 2px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-small) and (max-width: $to-medium) {
|
||||
font-size: $font-size - 2px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-medium) and (max-width: $to-large) {
|
||||
@media (min-width: $from-sm) and (max-width: $to-lg) {
|
||||
font-size: $font-size - 1px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-large) and (max-width: $to-huge) {
|
||||
font-size: $font-size; // [1]
|
||||
@media (min-width: $from-lg) and (max-width: $to-2xl) {
|
||||
font-size: $font-size;
|
||||
}
|
||||
|
||||
@media (min-width: $from-huge) and (max-width: $to-gigantic) {
|
||||
@media (min-width: $from-2xl) and (max-width: $to-3xl) {
|
||||
font-size: $font-size + 1px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-gigantic) and (max-width: $to-colossal) {
|
||||
@media (min-width: $from-3xl) {
|
||||
font-size: $font-size + 2px;
|
||||
}
|
||||
|
||||
@media (min-width: $from-colossal) {
|
||||
font-size: $font-size + 4px;
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
124
assets/styles/elements/_normalize.scss
Normal file
124
assets/styles/elements/_normalize.scss
Normal file
@@ -0,0 +1,124 @@
|
||||
// ==========================================================================
|
||||
// Elements / Normalize
|
||||
// ==========================================================================
|
||||
|
||||
// Modern CSS Normalize
|
||||
// Based on the reset by Andy.set with some tweaks.
|
||||
// Original by Andy.set: https://piccalil.li/blog/a-more-modern-css-reset/
|
||||
// Review by Chris collier: https://chriscoyier.net/2023/10/03/being-picky-about-a-css-reset-for-fun-pleasure/
|
||||
|
||||
|
||||
// Box sizing rules
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Prevent font size inflation
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
// Remove default margin in favour of better control in authored CSS
|
||||
p,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
dl,
|
||||
dd,
|
||||
figure,
|
||||
blockquote {
|
||||
margin-block: unset;
|
||||
}
|
||||
|
||||
// Remove list styles on ul, ol elements with a class, which suggests default styling will be removed
|
||||
ul[class],
|
||||
ol[class] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
// Set core defaults
|
||||
html {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: unset;
|
||||
}
|
||||
|
||||
// Set shorter line heights on headings and interactive elements
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
input,
|
||||
label,
|
||||
button {
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
// Balance text wrapping on headings
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
// Remove a elements default styles if they have a class
|
||||
a[class] {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
// Make assets easier to work with
|
||||
img,
|
||||
svg,
|
||||
canvas,
|
||||
picture {
|
||||
display: block;
|
||||
max-inline-size: 100%;
|
||||
block-size: auto;
|
||||
}
|
||||
|
||||
// Inherit fonts for inputs and buttons
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
textarea {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
// Make sure textareas without a rows attribute are not tiny
|
||||
textarea:not([rows]) {
|
||||
min-height: 10em;
|
||||
}
|
||||
|
||||
// Anything that has been anchored to should have extra scroll margin
|
||||
:target {
|
||||
scroll-margin-block: 1rlh;
|
||||
}
|
||||
|
||||
// Reduced mootion preference
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic / Buttons
|
||||
// ==========================================================================
|
||||
|
||||
// 1. Allow us to style box model properties.
|
||||
// 2. Fixes odd inner spacing in IE7.
|
||||
// 3. Reset/normalize some styles.
|
||||
// 4. Line different sized buttons up a little nicer.
|
||||
// 5. Make buttons inherit font styles (often necessary when styling `input`s as buttons).
|
||||
// 6. Force all button-styled elements to appear clickable.
|
||||
|
||||
button,
|
||||
.c-button {
|
||||
@include u-hocus {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
display: inline-block; // [1]
|
||||
overflow: visible; // [2]
|
||||
margin: 0; // [3]
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
background: none transparent;
|
||||
color: inherit;
|
||||
vertical-align: middle; // [4]
|
||||
text-align: center; // [3]
|
||||
text-decoration: none;
|
||||
text-transform: none;
|
||||
font: inherit; // [5]
|
||||
line-height: normal;
|
||||
cursor: pointer; // [6]
|
||||
user-select: none;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic / Forms
|
||||
// ==========================================================================
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: none transparent;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
line-height: normal;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
select {
|
||||
text-transform: none;
|
||||
|
||||
&::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&::-ms-value {
|
||||
background: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
// // Remove Firefox :focus dotted outline, breaks color inherit
|
||||
// // &:-moz-focusring {
|
||||
// // color: transparent;
|
||||
// // text-shadow: 0 0 0 #000000; // Text :focus color
|
||||
// // }
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic
|
||||
// ==========================================================================
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Add the correct display in IE 10-.
|
||||
// 1. Add the correct display in IE.
|
||||
|
||||
template, // [1]
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*,
|
||||
:before,
|
||||
:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
address {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
dfn,
|
||||
cite,
|
||||
em,
|
||||
i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
svg {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
p,
|
||||
figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// 1. Single taps should be dispatched immediately on clickable elements
|
||||
|
||||
a, area, button, input, label, select, textarea, [tabindex] {
|
||||
-ms-touch-action: manipulation; // [1]
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
[hreflang] > abbr[title] {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
hr {
|
||||
display: block;
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
border-top: 1px solid #CCCCCC;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Generic / Media
|
||||
// ==========================================================================
|
||||
|
||||
// 1. Setting `vertical-align` removes the whitespace that appears under `img`
|
||||
// elements when they are dropped into a page as-is. Safer alternative to
|
||||
// using `display: block;`.
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
iframe,
|
||||
img,
|
||||
svg,
|
||||
video {
|
||||
vertical-align: middle; // [1]
|
||||
}
|
||||
|
||||
// Add the correct display in iOS 4-7.
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
// 2. Fluid media for responsive purposes.
|
||||
|
||||
img,
|
||||
svg {
|
||||
max-width: 100%; // [2]
|
||||
height: auto;
|
||||
|
||||
// 4. If a `width` and/or `height` attribute have been explicitly defined,
|
||||
// let’s not make the image fluid.
|
||||
|
||||
&[width], // [4]
|
||||
&[height] {
|
||||
// [4]
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Offset `alt` text from surrounding copy.
|
||||
|
||||
img {
|
||||
font-style: italic; // [4]
|
||||
}
|
||||
|
||||
// 5. SVG elements should fallback to their surrounding text color.
|
||||
|
||||
svg {
|
||||
fill: currentColor; // [5]
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
// ==========================================================================
|
||||
// Main
|
||||
// ==========================================================================
|
||||
|
||||
// Modules
|
||||
// ==========================================================================
|
||||
|
||||
@use "sass:math";
|
||||
|
||||
// ==========================================================================
|
||||
// Tools
|
||||
// ==========================================================================
|
||||
|
||||
@@ -17,25 +20,16 @@
|
||||
// Settings
|
||||
// ==========================================================================
|
||||
|
||||
@import "settings/config";
|
||||
@import "settings/config.breakpoints";
|
||||
@import "settings/config.colors";
|
||||
@import "settings/config.eases";
|
||||
@import "settings/config.fonts";
|
||||
@import "settings/config.spacers";
|
||||
@import "settings/config.timings";
|
||||
@import "settings/config.spacings";
|
||||
@import "settings/config.speeds";
|
||||
@import "settings/config.zindexes";
|
||||
@import "settings/config";
|
||||
@import "settings/config.variables";
|
||||
|
||||
// Generic
|
||||
// ==========================================================================
|
||||
|
||||
@import "node_modules/normalize.css/normalize";
|
||||
@import "generic/generic";
|
||||
@import "generic/media";
|
||||
@import "generic/form";
|
||||
@import "generic/button";
|
||||
|
||||
// Vendors
|
||||
// ==========================================================================
|
||||
@import "node_modules/locomotive-scroll/dist/locomotive-scroll";
|
||||
@@ -43,6 +37,7 @@
|
||||
// Elements
|
||||
// ==========================================================================
|
||||
|
||||
@import "elements/normalize";
|
||||
@import "elements/document";
|
||||
|
||||
// Objects
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
&.-col-#{$base-column-nb}\@from-medium {
|
||||
@media (min-width: $from-medium) {
|
||||
&.-col-#{$base-column-nb}\@from-md {
|
||||
@media (min-width: $from-md) {
|
||||
grid-template-columns: repeat(#{$base-column-nb}, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
// // Logo
|
||||
// .svg-logo {
|
||||
// --icon-width: #{rem(100px)};
|
||||
// --icon-ratio: 20/30; // width/height based on svg viewBox
|
||||
// --icon-ratio: math.div(20, 30); // width/height based on svg viewBox
|
||||
|
||||
// // Sizes
|
||||
// .o-icon.-big & {
|
||||
|
||||
@@ -6,15 +6,16 @@
|
||||
// ==========================================================================
|
||||
|
||||
$breakpoints: (
|
||||
"tiny": 500px,
|
||||
"small": 700px,
|
||||
"medium": 1000px,
|
||||
"large": 1200px,
|
||||
"big": 1400px,
|
||||
"huge": 1600px,
|
||||
"enormous": 1800px,
|
||||
"gigantic": 2000px,
|
||||
"colossal": 2400px
|
||||
"2xs": 340px,
|
||||
"xs": 500px,
|
||||
"sm": 700px,
|
||||
"md": 1000px,
|
||||
"lg": 1200px,
|
||||
"xl": 1400px,
|
||||
"2xl": 1600px,
|
||||
"3xl": 1800px,
|
||||
"4xl": 2000px,
|
||||
"5xl": 2400px
|
||||
);
|
||||
|
||||
// Functions
|
||||
@@ -75,21 +76,17 @@ $breakpoints: (
|
||||
// Legacy
|
||||
// ==========================================================================
|
||||
|
||||
$from-tiny: map-get($breakpoints, "tiny") !default;
|
||||
$to-tiny: map-get($breakpoints, "tiny") - 1 !default;
|
||||
$from-small: map-get($breakpoints, "small") !default;
|
||||
$to-small: map-get($breakpoints, "small") - 1 !default;
|
||||
$from-medium: map-get($breakpoints, "medium") !default;
|
||||
$to-medium: map-get($breakpoints, "medium") - 1 !default;
|
||||
$from-large: map-get($breakpoints, "large") !default;
|
||||
$to-large: map-get($breakpoints, "large") - 1 !default;
|
||||
$from-big: map-get($breakpoints, "big") !default;
|
||||
$to-big: map-get($breakpoints, "big") - 1 !default;
|
||||
$from-huge: map-get($breakpoints, "huge") !default;
|
||||
$to-huge: map-get($breakpoints, "huge") - 1 !default;
|
||||
$from-enormous: map-get($breakpoints, "enormous") !default;
|
||||
$to-enormous: map-get($breakpoints, "enormous") - 1 !default;
|
||||
$from-gigantic: map-get($breakpoints, "gigantic") !default;
|
||||
$to-gigantic: map-get($breakpoints, "gigantic") - 1 !default;
|
||||
$from-colossal: map-get($breakpoints, "colossal") !default;
|
||||
$to-colossal: map-get($breakpoints, "colossal") - 1 !default;
|
||||
$from-xs: map-get($breakpoints, "xs") !default;
|
||||
$to-xs: map-get($breakpoints, "xs") - 1 !default;
|
||||
$from-sm: map-get($breakpoints, "sm") !default;
|
||||
$to-sm: map-get($breakpoints, "sm") - 1 !default;
|
||||
$from-md: map-get($breakpoints, "md") !default;
|
||||
$to-md: map-get($breakpoints, "md") - 1 !default;
|
||||
$from-lg: map-get($breakpoints, "lg") !default;
|
||||
$to-lg: map-get($breakpoints, "lg") - 1 !default;
|
||||
$from-xl: map-get($breakpoints, "xl") !default;
|
||||
$to-xl: map-get($breakpoints, "xl") - 1 !default;
|
||||
$from-2xl: map-get($breakpoints, "2xl") !default;
|
||||
$to-2xl: map-get($breakpoints, "2xl") - 1 !default;
|
||||
$from-3xl: map-get($breakpoints, "3xl") !default;
|
||||
$to-3xl: map-get($breakpoints, "3xl") - 1 !default;
|
||||
|
||||
@@ -32,12 +32,13 @@ $easing: ease("power2.out");
|
||||
|
||||
// Spacing Units
|
||||
// =============================================================================
|
||||
$unit: 60px;
|
||||
$unit-small: 20px;
|
||||
$unit: 60px;
|
||||
$unit-small: 20px;
|
||||
$vw-viewport: 1440;
|
||||
|
||||
// Container
|
||||
// ==========================================================================
|
||||
$padding: $unit;
|
||||
$padding: $unit;
|
||||
|
||||
// Grid
|
||||
// ==========================================================================
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Settings / Config / Spacers
|
||||
// ==========================================================================
|
||||
|
||||
// Spacers
|
||||
// ==========================================================================
|
||||
|
||||
$spacers: (
|
||||
'gutter': var(--grid-gutter),
|
||||
'xs': #{vh(5)},
|
||||
'sm': #{vh(7.5)},
|
||||
'md': #{vh(10)},
|
||||
'lg': #{vh(12.5)},
|
||||
'xl': #{vh(15)},
|
||||
);
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
// Returns spacer.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// margin-top: spacer(gutter);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The spacer key in $spacers.
|
||||
// @param {number} $multiplier - The multiplier of the spacer value.
|
||||
// @return {size}
|
||||
|
||||
@function spacer($spacer: $spacer-default, $multiplier: 1) {
|
||||
@if not map-has-key($spacers, $spacer) {
|
||||
@error "Unknown master spacer: #{$spacer}";
|
||||
}
|
||||
|
||||
$index: map-get($spacers, $spacer);
|
||||
|
||||
@return calc(#{$index} * #{$multiplier});
|
||||
}
|
||||
69
assets/styles/settings/_config.spacings.scss
Normal file
69
assets/styles/settings/_config.spacings.scss
Normal file
@@ -0,0 +1,69 @@
|
||||
// ==========================================================================
|
||||
// Settings / Config / Spacings
|
||||
// ==========================================================================
|
||||
|
||||
:root {
|
||||
--spacing-2xs-mobile: 6;
|
||||
--spacing-2xs-desktop: 10;
|
||||
|
||||
--spacing-xs-mobile: 12;
|
||||
--spacing-xs-desktop: 16;
|
||||
|
||||
--spacing-sm-mobile: 22;
|
||||
--spacing-sm-desktop: 32;
|
||||
|
||||
--spacing-md-mobile: 32;
|
||||
--spacing-md-desktop: 56;
|
||||
|
||||
--spacing-lg-mobile: 48;
|
||||
--spacing-lg-desktop: 96;
|
||||
|
||||
--spacing-xl-mobile: 64;
|
||||
--spacing-xl-desktop: 128;
|
||||
|
||||
--spacing-2xl-mobile: 88;
|
||||
--spacing-2xl-desktop: 176;
|
||||
|
||||
--spacing-3xl-mobile: 122;
|
||||
--spacing-3xl-desktop: 224;
|
||||
}
|
||||
|
||||
// Spacings
|
||||
// ==========================================================================
|
||||
|
||||
$spacings: (
|
||||
'gutter': var(--grid-gutter),
|
||||
'2xs': #{size-clamp('2xs')},
|
||||
'xs': #{size-clamp('xs')},
|
||||
'sm': #{size-clamp('sm')},
|
||||
'md': #{size-clamp('md')},
|
||||
'lg': #{size-clamp('lg')},
|
||||
'xl': #{size-clamp('xl')},
|
||||
'2xl': #{size-clamp('2xl')},
|
||||
'3xl': #{size-clamp('3xl')},
|
||||
);
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
// Returns spacing.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// margin-top: spacing(gutter);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The spacing key in $spacings.
|
||||
// @param {number} $multiplier - The multiplier of the spacing value.
|
||||
// @return {size}
|
||||
|
||||
@function spacing($spacing: 'sm', $multiplier: 1) {
|
||||
@if not map-has-key($spacings, $spacing) {
|
||||
@error "Unknown master spacing: #{$spacing}";
|
||||
}
|
||||
|
||||
$index: map-get($spacings, $spacing);
|
||||
|
||||
@return calc(#{$index} * #{$multiplier});
|
||||
}
|
||||
@@ -1,23 +1,20 @@
|
||||
// ==========================================================================
|
||||
// Settings / Config / Timings
|
||||
// Settings / Config / Speeds
|
||||
// ==========================================================================
|
||||
|
||||
// Timings
|
||||
// Speeds
|
||||
// ==========================================================================
|
||||
|
||||
$timings: (
|
||||
$speeds: (
|
||||
fastest: 0.1s,
|
||||
faster: 0.15s,
|
||||
fast: 0.25s,
|
||||
normal: 0.5s,
|
||||
slow: 0.75s,
|
||||
slower: 1s,
|
||||
slowest: 2s,
|
||||
normal: 0.3s,
|
||||
slow: 0.5s,
|
||||
slower: 0.75s,
|
||||
slowest: 1s,
|
||||
);
|
||||
|
||||
// Default timing for t()
|
||||
$timing-default: "normal" !default;
|
||||
|
||||
// Function
|
||||
// ==========================================================================
|
||||
|
||||
@@ -25,17 +22,17 @@ $timing-default: "normal" !default;
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// transition-duration: t(slow);
|
||||
// transition-duration: speed(slow);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {string} $key - The timing key in $timings.
|
||||
// @param {string} $key - The speed key in $speeds.
|
||||
// @return {duration}
|
||||
|
||||
@function t($key: $timing-default) {
|
||||
@if not map-has-key($timings, $key) {
|
||||
@error "Unknown '#{$key}' in $timings.";
|
||||
@function speed($key: "normal") {
|
||||
@if not map-has-key($speeds, $key) {
|
||||
@error "Unknown '#{$key}' in $speeds.";
|
||||
}
|
||||
|
||||
@return map-get($timings, $key);
|
||||
@return map-get($speeds, $key);
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
// --color-#{"" + $color}: #{$value};
|
||||
// }
|
||||
|
||||
@media (min-width: $from-small) {
|
||||
@media (min-width: $from-sm) {
|
||||
--grid-columns: #{$base-column-nb};
|
||||
--grid-gutter: #{rem(16px)};
|
||||
--grid-margin: #{rem(20px)};
|
||||
|
||||
@@ -48,17 +48,6 @@
|
||||
@return math.div($size, $base) * 1rem;
|
||||
}
|
||||
|
||||
// Converts a number to a percentage.
|
||||
//
|
||||
// @alias percentage()
|
||||
// @link http://sassdoc.com/annotations/#alias
|
||||
// @param {Number} $number - The value to convert.
|
||||
// @return {Number} A percentage.
|
||||
|
||||
@function span($number) {
|
||||
@return percentage($number);
|
||||
}
|
||||
|
||||
// Checks if a list contains a value(s).
|
||||
//
|
||||
// @link https://github.com/thoughtbot/bourbon/blob/master/core/bourbon/validators/_contains.scss
|
||||
@@ -125,25 +114,53 @@ $context: 'frontend' !default;
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage spacer
|
||||
// @param {number} $inset - The grid gutter inset
|
||||
// @param {number} $percentage - The percentage spacer
|
||||
// @param {number} $inset - The grid gutter inset
|
||||
// @return {function<number>}
|
||||
@function grid-space($percentage, $inset: 0) {
|
||||
@return calc(#{$percentage} * (100vw - 2 * var(--grid-margin, 0px)) - (1 - #{$percentage}) * var(--grid-gutter, 0px) + #{$inset} * var(--grid-gutter, 0px));
|
||||
@return calc(#{$percentage} * (#{vw(100)} - 2 * var(--grid-margin, 0px)) - (1 - #{$percentage}) * var(--grid-gutter, 0px) + #{$inset} * var(--grid-gutter, 0px));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport height.
|
||||
// Returns calculation of a percentage of the viewport small height.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// height: vh(100);
|
||||
// height: svh(100);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage number
|
||||
// @return {function<number>} in vh
|
||||
@function vh($number) {
|
||||
@return calc(#{$number} * var(--vh, 1vh));
|
||||
// @return {function<number>} in svh
|
||||
@function svh($number) {
|
||||
@return calc(#{$number} * var(--svh, 1svh));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport large height.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// height: lvh(100);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage number
|
||||
// @return {function<number>} in lvh
|
||||
@function lvh($number) {
|
||||
@return calc(#{$number} * var(--lvh, 1lvh));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport dynamic height.
|
||||
//
|
||||
// ```scss
|
||||
// .c-box {
|
||||
// height: dvh(100);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// @param {number} $number - The percentage number
|
||||
// @return {function<number>} in dvh
|
||||
@function dvh($number) {
|
||||
@return calc(#{$number} * var(--dvh, 1dvh));
|
||||
}
|
||||
|
||||
// Returns calculation of a percentage of the viewport width.
|
||||
@@ -161,6 +178,19 @@ $context: 'frontend' !default;
|
||||
@return calc(#{$number} * var(--vw, 1vw));
|
||||
}
|
||||
|
||||
@function clamp-with-max($min, $size, $max) {
|
||||
$vw-context: $vw-viewport * 0.01;
|
||||
@return clamp(#{$min}, calc(#{$size} / #{$vw-context} * 1vw), #{$max});
|
||||
}
|
||||
|
||||
@function size-clamp($size) {
|
||||
@return clamp-with-max(
|
||||
calc(#{rem(1px)} * var(--spacing-#{$size}-mobile)),
|
||||
var(--spacing-#{$size}-desktop),
|
||||
calc(#{rem(1px)} * var(--spacing-#{$size}-desktop))
|
||||
);
|
||||
}
|
||||
|
||||
// Returns clamp of calculated preferred responsive font size
|
||||
// within a font size and breakpoint range.
|
||||
//
|
||||
@@ -170,7 +200,7 @@ $context: 'frontend' !default;
|
||||
// }
|
||||
//
|
||||
// .c-heading.-h2 {
|
||||
// font-size: responsive-type(20px, 40px, $from-big);
|
||||
// font-size: responsive-type(20px, 40px, $from-xl);
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
|
||||
@@ -8,12 +8,11 @@
|
||||
///
|
||||
/// @example
|
||||
/// .u-margin-top {}
|
||||
/// .u-padding-left-large {}
|
||||
/// .u-margin-right-small {}
|
||||
/// .u-margin-top-xs {}
|
||||
/// .u-padding-left-lg {}
|
||||
/// .u-margin-right-sm {}
|
||||
/// .u-padding {}
|
||||
/// .u-padding-right-none {}
|
||||
/// .u-padding-horizontal {}
|
||||
/// .u-padding-vertical-small {}
|
||||
///
|
||||
/// @link https://github.com/inuitcss/inuitcss/blob/512977a/utilities/_utilities.spacing.scss
|
||||
////
|
||||
@@ -35,7 +34,7 @@ $spacing-properties: (
|
||||
'margin': 'margin',
|
||||
) !default;
|
||||
|
||||
$spacing-sizes: join($spacers, (
|
||||
$spacing-sizes: join($spacings, (
|
||||
null: var(--grid-gutter),
|
||||
'none': 0
|
||||
));
|
||||
@@ -51,8 +50,8 @@ $spacing-sizes: join($spacers, (
|
||||
// Base class
|
||||
$base-class: ".u-" + #{$property-namespace}#{$direction-namespace}#{$size-namespace};
|
||||
|
||||
// Spacer without media query
|
||||
@if $breakpoint == "tiny" {
|
||||
// Spacing without media query
|
||||
@if $breakpoint == "xs" {
|
||||
#{$base-class} {
|
||||
@each $direction in $directions {
|
||||
#{$property}#{$direction}: $size !important;
|
||||
@@ -60,7 +59,7 @@ $spacing-sizes: join($spacers, (
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer min-width breakpoints `@from-*`
|
||||
// Spacing min-width breakpoints `@from-*`
|
||||
#{$base-class}\@from-#{$breakpoint} {
|
||||
@media #{mq-min($breakpoint)} {
|
||||
@each $direction in $directions {
|
||||
@@ -69,7 +68,7 @@ $spacing-sizes: join($spacers, (
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer max-width breakpoints @to-*`
|
||||
// Spacing max-width breakpoints @to-*`
|
||||
#{$base-class}\@to-#{$breakpoint} {
|
||||
@media #{mq-max($breakpoint)} {
|
||||
@each $direction in $directions {
|
||||
|
||||
@@ -46,14 +46,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// .is-hidden\@to-large {
|
||||
// @media (max-width: $to-large) {
|
||||
// .is-hidden\@to-lg {
|
||||
// @media (max-width: $to-lg) {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// .is-hidden\@from-large {
|
||||
// @media (min-width: $from-large) {
|
||||
// .is-hidden\@from-lg {
|
||||
// @media (min-width: $from-lg) {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -21,8 +21,8 @@ $widths-fractions: 1 2 3 4 5 !default;
|
||||
|
||||
@include widths($widths-fractions);
|
||||
|
||||
.u-1\/2\@from-small {
|
||||
@media (min-width: $from-small) {
|
||||
width: span(1/2);
|
||||
.u-1\/2\@from-sm {
|
||||
@media (min-width: $from-sm) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ The first step is to set intial SCSS values in the following files :
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
&.-col-#{$base-column-nb}\@from-medium {
|
||||
@media (min-width: $from-medium) {
|
||||
&.-col-#{$base-column-nb}\@from-md {
|
||||
@media (min-width: $from-md) {
|
||||
grid-template-columns: repeat(#{$base-column-nb}, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,10 +80,10 @@ Learn about [namespacing](https://csswizardry.com/2015/03/more-transparent-ui-co
|
||||
}
|
||||
|
||||
.c-block_heading {
|
||||
@media (max-width: $to-medium) {
|
||||
@media (max-width: $to-md) {
|
||||
.c-block.-large & {
|
||||
margin-bottom: rem(40px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"dest": "./www/assets/scripts"
|
||||
},
|
||||
"svgs": {
|
||||
"src": "./assets/images/sprite",
|
||||
"src": "./assets/svgs",
|
||||
"dest": "./www/assets/images"
|
||||
},
|
||||
"views": {
|
||||
|
||||
9929
package-lock.json
generated
9929
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@@ -6,7 +6,7 @@
|
||||
"author": "Locomotive <info@locomotive.ca>",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=20.1",
|
||||
"node": "20.x",
|
||||
"npm": ">=8.0"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -14,27 +14,27 @@
|
||||
"build": "node --experimental-json-modules --no-warnings build/build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"locomotive-scroll": "^5.0.0-beta.9",
|
||||
"locomotive-scroll": "^5.0.0-beta.11",
|
||||
"modujs": "^1.4.2",
|
||||
"modularload": "^1.2.6",
|
||||
"normalize.css": "^8.0.1",
|
||||
"svg4everybody": "^2.1.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.13",
|
||||
"@11ty/eleventy": "^2.0.1",
|
||||
"@11ty/eleventy-img": "^3.1.8",
|
||||
"@factorial/eleventy-plugin-twig": "^0.1.2",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"browser-sync": "^3.0.2",
|
||||
"concat": "^1.0.3",
|
||||
"esbuild": "^0.17.6",
|
||||
"esbuild": "^0.20.0",
|
||||
"kleur": "^4.1.5",
|
||||
"node-notifier": "^10.0.1",
|
||||
"postcss": "^8.4.21",
|
||||
"purgecss": "^5.0.0",
|
||||
"sass": "^1.69.5",
|
||||
"sass": "^1.70.0",
|
||||
"svg-mixer": "~2.3.14",
|
||||
"tiny-glob": "^0.2.9",
|
||||
"@11ty/eleventy": "^2.0.1",
|
||||
"@factorial/eleventy-plugin-twig": "^0.1.2",
|
||||
"twig": "^1.16.0"
|
||||
"twig": "^1.17.1"
|
||||
},
|
||||
"overrides": {
|
||||
"browser-sync": {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<footer>
|
||||
<p>Made with <a href="https://github.com/locomotivemtl/locomotive-boilerplate" title="Locomotive Boilerplate" target="_blank" rel="noopener">🚂</a></p>
|
||||
<footer class="o-container">
|
||||
<p>Made by Locomotive<br>
|
||||
<a href="https://github.com/locomotivemtl/locomotive-boilerplate" title="Locomotive Boilerplate" target="_blank" rel="noopener">Github</a>
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<header>
|
||||
<a href="/"><h1>Locomotive Boilerplate</h1></a>
|
||||
<header class="o-container">
|
||||
<h1><a href="/">Locomotive Boilerplate</a></h1>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="/images">Images</a></li>
|
||||
<li><a href="/form" data-load="customTransition">Form</a></li>
|
||||
<li><a href="/grid">Grid</a></li>
|
||||
<li><a href="/form" data-load="customTransition">Form</a></li>
|
||||
<li><a href="/wysiwyg">Wysiwyg</a></li>
|
||||
<li><a href="/projects">Projects</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
51
views/snippets/button.twig
Normal file
51
views/snippets/button.twig
Normal file
@@ -0,0 +1,51 @@
|
||||
{# --- Parameters ------------------------- #}
|
||||
|
||||
{% set _tag = tag | default('button') %}
|
||||
{% set _href = href | default(null) %}
|
||||
{% set _external = external ?? false %}
|
||||
{% set _classes = classes | default(null) %}
|
||||
{% set _modifiers = modifiers | default(null) %}
|
||||
{% set _label = label | default(null) %}
|
||||
{% set _icon = icon | default(null) %}
|
||||
{% set _attr = attr | default(null) %}
|
||||
|
||||
{# --- Computed --------------------------- #}
|
||||
|
||||
{% if _href != null %}
|
||||
{% set _tag = 'a' %}
|
||||
{% elseif _tag == 'a' %}
|
||||
{% set _tag = 'span' %}
|
||||
{% endif %}
|
||||
|
||||
{% if _classes != null %}
|
||||
{% set _classes = ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{% if _modifiers != null %}
|
||||
{% set _classes = ' ' ~ _modifiers ~ ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{# ---------------------------------------- #}
|
||||
|
||||
<{{ _tag }}
|
||||
class="c-button{{ _classes }}"
|
||||
{% if _href %}href="{{ _href }}"{% endif %}
|
||||
{% if _external %}target="_blank" rel="noopener noreferrer" data-load="false"{% endif %}
|
||||
{% if _attr %}{{ _attr | raw }}{% endif %}
|
||||
>
|
||||
{% block inner %}
|
||||
<span class="c-button_inner">
|
||||
{% if _label %}
|
||||
<span class="c-button_label">
|
||||
{{ _label }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if _icon %}
|
||||
{% include "@snippets/icon.twig" with {
|
||||
icon: _icon,
|
||||
classes: 'c-button_icon',
|
||||
} only %}
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
</{{ _tag }}>
|
||||
15
views/snippets/icon.twig
Normal file
15
views/snippets/icon.twig
Normal file
@@ -0,0 +1,15 @@
|
||||
{# --- Parameters ------------------------- #}
|
||||
|
||||
{% set _icon = icon %}
|
||||
{% set _classes = classes | default(null) %}
|
||||
{% set _modifiers = modifiers | default(null) %}
|
||||
|
||||
{# ---------------------------------------- #}
|
||||
|
||||
{% if _icon %}
|
||||
<span class="o-icon {{ _classes }} {{ _modifiers }}">
|
||||
<svg class="svg-{{ _icon }}" focusable="false" aria-hidden="true">
|
||||
<use xlink:href="#{{ _icon }}"></use>
|
||||
</svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
95
views/snippets/image.twig
Normal file
95
views/snippets/image.twig
Normal file
@@ -0,0 +1,95 @@
|
||||
{#
|
||||
Image snippet
|
||||
|
||||
The `img` parameter was made to receive formatted data from a CMS.
|
||||
The use case would be to output an image without overriding is dimensions or other properties.
|
||||
|
||||
It needs to be an object with the following keys :
|
||||
-src: String,
|
||||
-width: Int,
|
||||
-height: Int,
|
||||
-alt?: String,
|
||||
-caption?: String
|
||||
|
||||
```twig
|
||||
{% include '@snippets/image.twig' with
|
||||
img: project.featured_image
|
||||
%}
|
||||
```
|
||||
#}
|
||||
|
||||
{# Defaults #}
|
||||
{% set _width = img.width | default(1) %}
|
||||
{% set _height = img.height | default(1) %}
|
||||
{% set _src = img.src | default(null) %}
|
||||
{% set _alt = img.alt | default(null) %}
|
||||
{% set _caption = img.caption | default(null) %}
|
||||
{% set _attr = attr | default(null) %}
|
||||
{% set _has_parallax = has_parallax | default(null) %}
|
||||
{% set _parallax_speed = parallax_speed | default('-0.1') %}
|
||||
|
||||
{# Override properties #}
|
||||
{% set _width = width | default(_width) %}
|
||||
{% set _height = height | default(_height) %}
|
||||
{% set _src = src | default(_src) %}
|
||||
{% set _alt = alt | default(_alt) %}
|
||||
{% set _caption = caption | default(_caption) %}
|
||||
|
||||
{# Misc. #}
|
||||
{% set _is_figure = is_figure | default(false) %}
|
||||
{% set _is_lazy_load = is_lazy_load | default(true) %}
|
||||
{% set _tag = _is_figure ? 'figure' : 'div' %}
|
||||
|
||||
{# Classes & modifiers #}
|
||||
{% set _classes = classes | default(null) %}
|
||||
{% set _modifiers = modifiers | default(null) %}
|
||||
|
||||
{% if _has_parallax %}
|
||||
{% set _modifiers = _modifiers ~ ' -parallax' %}
|
||||
{% endif %}
|
||||
|
||||
{% if _is_lazy_load %}
|
||||
{% set _modifiers = _modifiers ~ ' -lazy-load' %}
|
||||
{% set _loading = 'lazy' %}
|
||||
{% else %}
|
||||
{% set _loading = 'eager' %}
|
||||
{% endif %}
|
||||
|
||||
{% if _classes != null %}
|
||||
{% set _classes = ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{% if _modifiers != null %}
|
||||
{% set _classes = ' ' ~ _modifiers ~ ' ' ~ _classes %}
|
||||
{% endif %}
|
||||
|
||||
{# ---------------------------------------- #}
|
||||
|
||||
<{{_tag}} class="c-image{{ _classes }}" {{_attr}}>
|
||||
<div
|
||||
class="c-image_inner"
|
||||
{% if has_parallax %}
|
||||
data-scroll
|
||||
data-scroll-speed="{{ _parallax_speed }}"
|
||||
{% endif %}
|
||||
>
|
||||
<img
|
||||
class="c-image_img"
|
||||
src="{{ _src }}"
|
||||
alt="{{ _alt }}"
|
||||
width="{{ _width }}"
|
||||
height="{{ _height }}"
|
||||
loading="{{ _loading }}"
|
||||
onload="this.closest('.c-image')?.classList?.add('is-loaded');"
|
||||
>
|
||||
</div>
|
||||
|
||||
{% if _caption %}
|
||||
{% if _is_figure %}
|
||||
<figcaption class="c-image_description">{{ _caption }}</figcaption>
|
||||
{% else %}
|
||||
<div class="c-image_description"><span>{{ _caption }}</span></div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</{{ _tag }}>
|
||||
@@ -4,24 +4,24 @@
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Hello</h1>
|
||||
|
||||
<div class="o-grid -col-4 -col-12@from-medium -gutters">
|
||||
<div class="o-grid_item u-gc-1/8@from-medium" style="background-color: gray;">
|
||||
<h2 class="c-heading -h2">This grid has 4 columns and 12 columns from `medium` MQ</h2>
|
||||
<div class="o-grid -col-4 -col-12@from-md -gutters">
|
||||
<div class="o-grid_item u-gc-1/8@from-md" style="background-color: gray;">
|
||||
<h2 class="c-heading -h2">This grid has 4 columns and 12 columns from `md` MQ</h2>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-1/5@from-medium" style="background-color: yellow;">
|
||||
<div class="o-grid_item u-gc-1/5@from-md" style="background-color: yellow;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-5/9@from-medium" style="background-color: red;">
|
||||
<div class="o-grid_item u-gc-5/9@from-md" style="background-color: red;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-9/13@from-medium" style="background-color: blue;">
|
||||
<div class="o-grid_item u-gc-9/13@from-md" style="background-color: blue;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
|
||||
<div class="o-grid_item u-gc-1/3 u-gc-5/13@from-medium" style="background-color: pink;">
|
||||
<div class="o-grid_item u-gc-1/3 u-gc-5/13@from-md" style="background-color: pink;">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Expedita provident distinctio deleniti eaque cumque doloremque aut quo dicta porro commodi, temporibus totam dolor autem tempore quasi ullam sed suscipit vero?</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,49 @@ title: Home
|
||||
|
||||
{% block content %}
|
||||
<div class="o-container">
|
||||
<h1 class="c-heading -h1">Hello</h1>
|
||||
|
||||
{# ====================== #}
|
||||
{# ====== Headings ====== #}
|
||||
{# ====================== #}
|
||||
|
||||
<h1 class="c-heading -h1">Heading 1</h1>
|
||||
<h1 class="c-heading -h2">Heading 2</h1>
|
||||
<h1 class="c-heading -h3">Heading 3</h1>
|
||||
<h1 class="c-heading -h4">Heading 4</h1>
|
||||
<h1 class="c-heading -h5">Heading 5</h1>
|
||||
<h1 class="c-heading -h6">Heading 6</h1>
|
||||
|
||||
<hr>
|
||||
|
||||
{# ======================= #}
|
||||
{# ======== Texts ======== #}
|
||||
{# ======================= #}
|
||||
|
||||
<p class="c-text -body-regular" style="max-width: 500px">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Totam libero, sit pariatur voluptatum amet magni odio ducimus! Saepe facere iste porro voluptatem. Tenetur perferendis ea a quasi vitae! Ullam, blanditiis.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
{# ======================= #}
|
||||
{# ======= Buttons ======= #}
|
||||
{# ======================= #}
|
||||
|
||||
{% include "@snippets/button.twig" with {
|
||||
label: 'Button'
|
||||
} %}
|
||||
|
||||
<hr>
|
||||
|
||||
{# ====================== #}
|
||||
{# ======= Images ======= #}
|
||||
{# ====================== #}
|
||||
|
||||
{% include "@snippets/image.twig" with {
|
||||
src: 'http://picsum.photos/800/600?v=1',
|
||||
width: 800,
|
||||
height: 600
|
||||
} %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
78
views/templates/wysiwyg.twig
Normal file
78
views/templates/wysiwyg.twig
Normal file
@@ -0,0 +1,78 @@
|
||||
{% extends "@layouts/base.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div data-module-scroll="main">
|
||||
<div class="o-container || c-wysiwyg">
|
||||
<h1>Heading 1</h1>
|
||||
<h2>Heading 2</h2>
|
||||
<h3>Heading 3</h3>
|
||||
<h4>Heading 4</h4>
|
||||
<h5>Heading 5</h5>
|
||||
<h6>Heading 6</h6>
|
||||
<h1>Heading 1</h1>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<h2>Heading 2</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<h3>Heading 3</h3>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<h4>Heading 4</h4>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<h5>Heading 5</h5>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<h6>Heading 6</h6>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p><p><strong>Lorem ipsum dolor sit amet, consectetur</strong> adipiscing elit, sed do eiusmod tempor incididunt u<strong>t labore et dolore magna aliqua</strong>. Ut enim ad minim <em>veniam, quis nostrud exercitation</em> ullamco laboris <em>nisi ut aliquip ex ea</em> commodo consequat. <span style="text-decoration: underline;">Duis aute irure dolor in reprehenderit in voluptate velit</span> esse cillum dolore eu fugiat nulla pariatur. <span style="text-decoration: underline;">Excepteur sint occaecat cupidatat</span> non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
<blockquote>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
</blockquote>
|
||||
<p>Je suis un <a href="https://www.lipsum.com/" target="_blank" title="Un super lien" rel="noopener noreferrer">super lien.</a> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor <a href="https://www.lipsum.com/" title="Lorem Ipsum">incididunt ut labore et dolore magna aliqua</a>. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p>
|
||||
<a href="mailto:example@example.com" title="Test mail">Lien mail.</a><br/>
|
||||
<a href="tel:+0-123-456-7890" title="Test tel">Lien téléphone.</a>
|
||||
</p>
|
||||
<ul>
|
||||
<li>Item 1</li>
|
||||
<li><strong>Item 2</strong></li>
|
||||
<li><em><strong>Item 3</strong></em></li>
|
||||
<li><span style="text-decoration: underline;">Item 4</span></li>
|
||||
<li><a href="https://www.lipsum.com/" title="Lorem ipsum">Item 5</a></li>
|
||||
</ul>
|
||||
<ol>
|
||||
<li>Item 1</li>
|
||||
<li>Item 2</li>
|
||||
<li>Item 3</li>
|
||||
</ol>
|
||||
<p style="padding-left: 60px;">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <br/>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex."</p>
|
||||
<p style="text-align: left;">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p style="text-align: center;">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p style="text-align: right;">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<table width="539" height="90">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 126.55px;"><strong>Last name</strong></td>
|
||||
<td style="width: 261.417px;"><span style="text-decoration: underline;">First name</span></td>
|
||||
<td style="width: 126.533px;"><em>City</em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 126.55px;">Lorem</td>
|
||||
<td style="width: 261.417px;">Ipsum</td>
|
||||
<td style="width: 126.533px;">Montréal</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width: 126.55px;">Dolor</td>
|
||||
<td style="width: 261.417px;">Sit</td>
|
||||
<td style="width: 126.533px;">Paris</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p><img src="https://www.airinuit.com/uploads/destinations/XGR/Mathias_Laroque_MWL.pilot_website_fall_2021_HD.jpg" alt=""/></p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p><img src="https://www.airinuit.com/uploads/destinations/XGR/Mathias_Laroque_MWL.pilot_website_fall_2021_HD.jpg" alt=""/></p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/qt7jSw55N1A" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex.</p>
|
||||
<p><img src="https://www.airinuit.com/uploads/destinations/XGR/Mathias_Laroque_MWL.pilot_website_fall_2021_HD.jpg" alt=""/></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"critical.css"}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user