Merge branch 'v2'
This commit is contained in:
@@ -1,161 +1,15 @@
|
||||
import { APP_NAME, $document, $pjaxWrapper } from './utils/environment';
|
||||
|
||||
import globals from './globals';
|
||||
|
||||
import { arrayContains, removeFromArray } from './utils/array';
|
||||
import { getNodeData } from './utils/html';
|
||||
import { isFunction } from './utils/is';
|
||||
|
||||
// Basic modules
|
||||
import modular from 'modujs';
|
||||
import * as modules from './modules';
|
||||
import globals from './globals';
|
||||
import { html } from './utils/environment';
|
||||
|
||||
const MODULE_NAME = 'App';
|
||||
const EVENT_NAMESPACE = `${APP_NAME}.${MODULE_NAME}`;
|
||||
const app = new modular({
|
||||
modules: modules
|
||||
});
|
||||
|
||||
export const EVENT = {
|
||||
INIT_MODULES: `initModules.${EVENT_NAMESPACE}`,
|
||||
INIT_SCOPED_MODULES: `initScopedModules.${EVENT_NAMESPACE}`,
|
||||
DELETE_SCOPED_MODULES: `deleteScopedModules.${EVENT_NAMESPACE}`
|
||||
};
|
||||
app.init(app);
|
||||
globals();
|
||||
|
||||
class App {
|
||||
constructor() {
|
||||
this.modules = modules;
|
||||
this.currentModules = [];
|
||||
html.classList.add('is-loaded is-ready');
|
||||
html.classList.remove('is-loading');
|
||||
|
||||
$document.on(EVENT.INIT_MODULES, (event) => {
|
||||
this.initGlobals(event.firstBlood)
|
||||
.deleteModules(event)
|
||||
.initModules(event);
|
||||
});
|
||||
|
||||
$document.on(EVENT.INIT_SCOPED_MODULES, (event) => {
|
||||
this.initModules(event);
|
||||
});
|
||||
|
||||
$document.on(EVENT.DELETE_SCOPED_MODULES, (event) => {
|
||||
this.deleteModules(event);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all existing modules or a specific scope of modules
|
||||
* @param {Object} event The event being triggered.
|
||||
* @return {Object} Self (allows chaining)
|
||||
*/
|
||||
deleteModules(event) {
|
||||
let destroyAll = true;
|
||||
let moduleIds = [];
|
||||
|
||||
// Check for scope first
|
||||
if (event.$scope instanceof jQuery && event.$scope.length > 0) {
|
||||
// Modules within scope
|
||||
const $modules = event.$scope.find('[data-module]');
|
||||
|
||||
// Determine their uids
|
||||
moduleIds = $.makeArray($modules.map(function(index) {
|
||||
return $modules.eq(index).data('uid');
|
||||
}));
|
||||
|
||||
if (moduleIds.length > 0) {
|
||||
destroyAll = false;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop modules and destroying all of them, or specific ones
|
||||
let i = this.currentModules.length;
|
||||
|
||||
while (i--) {
|
||||
if (destroyAll || arrayContains(moduleIds, this.currentModules[i].uid)) {
|
||||
removeFromArray(moduleIds, this.currentModules[i].uid);
|
||||
this.currentModules[i].destroy();
|
||||
this.currentModules.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute global functions and settings
|
||||
* Allows you to initialize global modules only once if you need
|
||||
* (ex.: when using Barba.js or SmoothState.js)
|
||||
* @return {Object} Self (allows chaining)
|
||||
*/
|
||||
initGlobals(firstBlood) {
|
||||
globals(firstBlood);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find modules and initialize them
|
||||
* @param {Object} event The event being triggered.
|
||||
* @return {Object} Self (allows chaining)
|
||||
*/
|
||||
initModules(event) {
|
||||
// Elements with module
|
||||
let $moduleEls = [];
|
||||
|
||||
// If first blood, load all modules in the DOM
|
||||
// If scoped, render elements with modules
|
||||
// If Barba, load modules contained in Barba container
|
||||
if (event.firstBlood) {
|
||||
$moduleEls = $document.find('[data-module]');
|
||||
} else if (event.$scope instanceof jQuery && event.$scope.length > 0) {
|
||||
$moduleEls = event.$scope.find('[data-module]');
|
||||
} else if (event.isPjax) {
|
||||
$moduleEls = $pjaxWrapper.find('[data-module]');
|
||||
}
|
||||
|
||||
// Loop through elements
|
||||
let i = 0;
|
||||
const elsLen = $moduleEls.length;
|
||||
|
||||
for (; i < elsLen; i++) {
|
||||
|
||||
// Current element
|
||||
let el = $moduleEls[i];
|
||||
|
||||
// All data- attributes considered as options
|
||||
let options = getNodeData(el);
|
||||
|
||||
// Add current DOM element and jQuery element
|
||||
options.el = el;
|
||||
options.$el = $moduleEls.eq(i);
|
||||
|
||||
// Module does exist at this point
|
||||
let attr = options.module;
|
||||
|
||||
// Splitting modules found in the data-attribute
|
||||
let moduleIdents = attr.split(/[,\s]+/g);
|
||||
|
||||
// Loop modules
|
||||
let j = 0;
|
||||
let modulesLen = moduleIdents.length;
|
||||
|
||||
for (; j < modulesLen; j++) {
|
||||
let moduleAttr = moduleIdents[j];
|
||||
|
||||
if (typeof this.modules[moduleAttr] === 'function') {
|
||||
let module = new this.modules[moduleAttr](options);
|
||||
this.currentModules.push(module);
|
||||
module.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// IIFE for loading the application
|
||||
// ==========================================================================
|
||||
(function() {
|
||||
new App();
|
||||
$document.triggerHandler({
|
||||
type: EVENT.INIT_MODULES,
|
||||
firstBlood: true
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import TransitionManager from './transitions/TransitionManager';
|
||||
import svg4everybody from 'svg4everybody';
|
||||
|
||||
export default function(firstBlood) {
|
||||
export default function() {
|
||||
svg4everybody();
|
||||
|
||||
if (firstBlood) {
|
||||
const transitionManager = new TransitionManager();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export {default as Example} from './modules/Example';
|
||||
export {default as Load} from './modules/Load';
|
||||
export {default as Scroll} from './modules/Scroll';
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
let uid = 0;
|
||||
|
||||
/**
|
||||
* Abstract Module
|
||||
*/
|
||||
export default class {
|
||||
constructor(options) {
|
||||
this.$el = options.$el || null;
|
||||
this.el = options.el || null;
|
||||
|
||||
// Generate a unique module identifier
|
||||
this.uid = 'm-' + uid++;
|
||||
// Use jQuery's data API to "store it in the DOM"
|
||||
this.$el.data('uid', this.uid);
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
destroy() {
|
||||
if (this.$el) {
|
||||
this.$el.removeData('uid')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,11 @@
|
||||
import { APP_NAME } from '../utils/environment';
|
||||
import AbstractModule from './AbstractModule';
|
||||
|
||||
const MODULE_NAME = 'Example';
|
||||
const EVENT_NAMESPACE = `${APP_NAME}.${MODULE_NAME}`;
|
||||
|
||||
const EVENT = {
|
||||
CLICK: `click.${EVENT_NAMESPACE}`
|
||||
};
|
||||
|
||||
export default class extends AbstractModule {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
// Declaration of properties
|
||||
console.log('🔨 [module]:constructor - Example');
|
||||
import { module } from 'modujs';
|
||||
|
||||
export default class extends module {
|
||||
constructor(m) {
|
||||
super(m);
|
||||
}
|
||||
|
||||
init() {
|
||||
// Set events and such
|
||||
|
||||
}
|
||||
|
||||
destroy() {
|
||||
console.log('❌ [module]:destroy - Example');
|
||||
super.destroy();
|
||||
this.$el.off(`.${EVENT_NAMESPACE}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
import { APP_NAME, $document } from '../utils/environment';
|
||||
import AbstractModule from './AbstractModule';
|
||||
import { module } from 'modujs';
|
||||
import { $document } from '../utils/environment'
|
||||
import ScrollManager from '../scroll/vendors/ScrollManager';
|
||||
|
||||
const MODULE_NAME = 'Scroll';
|
||||
const EVENT_NAMESPACE = `${APP_NAME}.${MODULE_NAME}`;
|
||||
|
||||
export default class extends AbstractModule {
|
||||
constructor(options) {
|
||||
super(options);
|
||||
export default class extends module {
|
||||
constructor(m) {
|
||||
super(m);
|
||||
}
|
||||
|
||||
init() {
|
||||
setTimeout(() => {
|
||||
this.scrollManager = new ScrollManager({
|
||||
container: this.$el,
|
||||
selector: '.js-animate',
|
||||
smooth: false,
|
||||
smoothMobile: false,
|
||||
mobileContainer: $document,
|
||||
getWay: false,
|
||||
getSpeed: false
|
||||
});
|
||||
}, 500);
|
||||
this.scroll = new ScrollManager({
|
||||
container: $(this.el),
|
||||
smooth: true,
|
||||
inertia: 1
|
||||
});
|
||||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.scrollManager.destroy();
|
||||
this.scroll.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
22
assets/scripts/modules/load.js
Normal file
22
assets/scripts/modules/load.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { module } from 'modujs';
|
||||
import modularLoad from 'modularload';
|
||||
|
||||
export default class extends module {
|
||||
constructor(m) {
|
||||
super(m);
|
||||
}
|
||||
|
||||
init() {
|
||||
const load = new modularLoad({
|
||||
enterDelay: 0,
|
||||
transitions: {
|
||||
customTransition: {}
|
||||
}
|
||||
});
|
||||
|
||||
load.on('loaded', (transition, oldContainer, newContainer) => {
|
||||
this.call('destroy', oldContainer, 'app');
|
||||
this.call('update', newContainer, 'app');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { APP_NAME, $document, $html, $body, isDebug, $pjaxWrapper } from '../utils/environment';
|
||||
|
||||
import { EVENT as TransitionEvent } from './TransitionManager'
|
||||
|
||||
export default class {
|
||||
constructor(options) {
|
||||
|
||||
this.options = options;
|
||||
this.wrapper = options.wrapper;
|
||||
this.overrideClass = options.overrideClass ? options.overrideClass : '';
|
||||
this.clickedLink = options.clickedLink;
|
||||
|
||||
}
|
||||
|
||||
launch() {
|
||||
if(isDebug) {
|
||||
console.log("---- Launch transition 👊 -----");
|
||||
}
|
||||
|
||||
$html
|
||||
.removeClass('has-dom-loaded has-dom-animated ')
|
||||
.addClass(`has-dom-loading ${this.overrideClass}`);
|
||||
|
||||
}
|
||||
|
||||
hideView(oldView, newView) {
|
||||
if(isDebug) {
|
||||
console.log('----- ❌ [VIEW]:hide - ', oldView.getAttribute('data-template'));
|
||||
}
|
||||
|
||||
// launch it at the end (animations...)
|
||||
$document.triggerHandler({
|
||||
type:TransitionEvent.READYTOAPPEND,
|
||||
oldView: oldView,
|
||||
newView: newView
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
displayView(view) {
|
||||
|
||||
if(isDebug) {
|
||||
console.log('----- ✅ [VIEW]:display :', view.getAttribute('data-template'));
|
||||
}
|
||||
|
||||
$html.attr('data-template', view.getAttribute('data-template'));
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
$html
|
||||
.addClass('has-dom-loaded')
|
||||
.removeClass('has-dom-loading');
|
||||
|
||||
setTimeout(() => {
|
||||
$html
|
||||
.removeClass(this.overrideClass)
|
||||
.addClass('has-dom-animated');
|
||||
}, 1000);
|
||||
|
||||
// launch it at the end (animations...)
|
||||
$document.triggerHandler({
|
||||
type:TransitionEvent.READYTODESTROY
|
||||
});
|
||||
|
||||
},1000);
|
||||
}
|
||||
|
||||
|
||||
destroy() {
|
||||
if(isDebug) {
|
||||
console.log("---- ❌ [transition]:destroy -----");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { APP_NAME, $document, $html, isDebug, $pjaxWrapper } from '../utils/environment';
|
||||
import BaseTransition from './BaseTransition';
|
||||
|
||||
import { EVENT as TransitionEvent } from './TransitionManager'
|
||||
|
||||
export default class extends BaseTransition{
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
this.overrideClass = '-custom-transition';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
import Pjax from 'pjax';
|
||||
import { APP_NAME, $document, $html, isDebug, $pjaxWrapper, $window } from '../utils/environment';
|
||||
import { EVENT as APP_EVENT } from '../app';
|
||||
|
||||
//List here all of your transitions
|
||||
import * as transitions from './transitions';
|
||||
|
||||
const MODULE_NAME = 'Transition';
|
||||
const EVENT_NAMESPACE = `${APP_NAME}.${MODULE_NAME}`;
|
||||
|
||||
export const EVENT = {
|
||||
CLICK: `click.${EVENT_NAMESPACE}`,
|
||||
READYTOAPPEND: `readyToAppend.${EVENT_NAMESPACE}`,
|
||||
READYTODESTROY: `readyToDestroy.${EVENT_NAMESPACE}`,
|
||||
GOTO: `goto.${EVENT_NAMESPACE}`
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@todo :
|
||||
|
||||
- ✅ get data-transition on clicked link -> launch() and add switch(){}
|
||||
- ✅ add goto listener
|
||||
- ✅ add overrideClass system for all transitions
|
||||
- ✅ add base class manager like old DefaultTransition (has-dom-loaded, has-dom-loading etc..)
|
||||
|
||||
|
||||
======= SCHEMA =======
|
||||
|
||||
[] : listener
|
||||
* : trigger event
|
||||
|
||||
[pjax:send] -> (transition) launch()
|
||||
|
||||
[pjax:switch] (= new view is loaded) -> (transition) hideView()-> hide animations & *readyToAppend
|
||||
|
||||
[readyToAppend] -> append() -> delete modules
|
||||
-> remove oldView from the DOM, and innerHTMl newView
|
||||
-> change()
|
||||
|
||||
display() -> (transition) displayView() -> display animations & *readyToDestroy
|
||||
-> init new modules
|
||||
|
||||
[readyToAppend] -> reinit()
|
||||
|
||||
*/
|
||||
|
||||
export default class {
|
||||
constructor() {
|
||||
|
||||
|
||||
// jQuery ondomready
|
||||
$window.on('load',() => {
|
||||
this.load();
|
||||
});
|
||||
|
||||
this.transition = new transitions['BaseTransition']({
|
||||
wrapper: this.wrapper
|
||||
});
|
||||
|
||||
/*
|
||||
===== PJAX CONFIGURATION =====
|
||||
*/
|
||||
|
||||
this.containerClass = '.js-pjax-container';
|
||||
this.wrapperId = 'js-pjax-wrapper';
|
||||
this.noPjaxRequestClass = 'no-transition';
|
||||
this.wrapper = document.getElementById(this.wrapperId);
|
||||
|
||||
this.options = {
|
||||
debug: false,
|
||||
cacheBust: false,
|
||||
elements: [`a:not(.${this.noPjaxRequestClass})`,'form[action]'],
|
||||
selectors: ['title',`${this.containerClass}`],
|
||||
switches: {},
|
||||
requestOptions: {
|
||||
timeout: 2000
|
||||
}
|
||||
};
|
||||
this.options.switches[this.containerClass] = (oldEl, newEl, options) => this.switch(oldEl, newEl, options)
|
||||
this.pjax = new Pjax(this.options);
|
||||
|
||||
/*
|
||||
===== LISTENERS =====
|
||||
*/
|
||||
|
||||
document.addEventListener('pjax:send',(e) => this.send(e));
|
||||
|
||||
|
||||
$document.on(EVENT.READYTOAPPEND,(event) => {
|
||||
this.append(event.oldView, event.newView);
|
||||
});
|
||||
$document.on(EVENT.READYTODESTROY,(event) => {
|
||||
this.reinit();
|
||||
});
|
||||
|
||||
|
||||
/** goto exampe
|
||||
$document.triggerHandler({
|
||||
type: 'goto.Transition',
|
||||
options : {
|
||||
el: {{element clicked?}},
|
||||
link: {{url}}
|
||||
}
|
||||
});
|
||||
*/
|
||||
$document.on(EVENT.GOTO, (e) => {
|
||||
if(e.options.el != undefined) {
|
||||
this.autoEl = e.options.el.get(0);
|
||||
}
|
||||
this.pjax.loadUrl(e.options.link, $.extend({}, this.pjax.options));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* (PJAX) Launch when pjax receive a request
|
||||
* get & manage data-transition,init and launch it
|
||||
* @param {event}
|
||||
* @return void
|
||||
*/
|
||||
send(e) {
|
||||
if(isDebug) {
|
||||
console.log("---- Launch request 🙌 -----");
|
||||
}
|
||||
|
||||
let el,transition;
|
||||
|
||||
if(e.triggerElement != undefined) {
|
||||
|
||||
el = e.triggerElement;
|
||||
|
||||
transition = el.getAttribute('data-transition') ? el.getAttribute('data-transition') : 'BaseTransition';
|
||||
$html.attr('data-transition',transition);
|
||||
|
||||
} else {
|
||||
|
||||
if (this.autoEl != undefined) {
|
||||
el = this.autoEl;
|
||||
} else {
|
||||
el = document;
|
||||
}
|
||||
|
||||
transition = 'BaseTransition';
|
||||
}
|
||||
|
||||
// options available : wrapper, overrideClass
|
||||
this.transition = new transitions[transition]({
|
||||
wrapper: this.wrapper,
|
||||
clickedLink: el
|
||||
});
|
||||
|
||||
this.transition.launch();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* (PJAX) Launch when new page is loaded
|
||||
* @param {js dom element},
|
||||
* @param {js dom element}
|
||||
* @param {options : pjax options}
|
||||
* @return void
|
||||
*/
|
||||
switch(oldView, newView, options) {
|
||||
if(isDebug) {
|
||||
console.log('---- Next view loaded 👌 -----');
|
||||
}
|
||||
this.transition.hideView(oldView, newView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch when you trigger EVENT.READYTOAPPEND in your transition
|
||||
* after newView append, launch this.change()
|
||||
* @param {js dom element},
|
||||
* @param {js dom element}
|
||||
* @return void
|
||||
*/
|
||||
append(oldView, newView) {
|
||||
|
||||
newView.style.opacity = 0;
|
||||
this.wrapper.appendChild(newView);
|
||||
|
||||
// Add these 2 rAF if you want to have the containers overlapped
|
||||
// Useful with a image transition, to prevent flickering
|
||||
// requestAnimationFrame(() => {
|
||||
// requestAnimationFrame(() => {
|
||||
newView.style.opacity = 1;
|
||||
this.change(oldView, newView);
|
||||
// });
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* launch after this.append(), remove modules, remove oldView and set the newView
|
||||
* @param {js dom element},
|
||||
* @return void
|
||||
*/
|
||||
change(oldView, newView) {
|
||||
|
||||
$document.triggerHandler({
|
||||
type: APP_EVENT.DELETE_SCOPED_MODULES,
|
||||
$scope: $pjaxWrapper
|
||||
});
|
||||
|
||||
this.wrapper.innerHTML = newView.outerHTML;
|
||||
|
||||
oldView.remove();
|
||||
|
||||
// Fetch any inline script elements.
|
||||
const scripts = newView.querySelectorAll('script.js-inline');
|
||||
|
||||
if (scripts instanceof window.NodeList) {
|
||||
let i = 0;
|
||||
let len = scripts.length;
|
||||
for (; i < len; i++) {
|
||||
eval(scripts[i].innerHTML);
|
||||
}
|
||||
}
|
||||
|
||||
$document.triggerHandler({
|
||||
type: APP_EVENT.INIT_SCOPED_MODULES,
|
||||
isPjax: true
|
||||
});
|
||||
|
||||
this.pjax.onSwitch();
|
||||
|
||||
this.transition.displayView(newView);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch when you trigger EVENT.READYTODESTROY in your transition -> displayView(), at the end
|
||||
* @return void
|
||||
*/
|
||||
reinit() {
|
||||
this.transition.destroy();
|
||||
$html.attr('data-transition','');
|
||||
this.transition = new transitions['BaseTransition']({
|
||||
wrapper: this.wrapper
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* DOM is loaded
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
load() {
|
||||
$html.addClass('has-dom-loaded');
|
||||
$html.removeClass('has-dom-loading');
|
||||
setTimeout(() => {
|
||||
$html.addClass('has-dom-animated');
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export {default as BaseTransition} from './BaseTransition';
|
||||
export {default as CustomTransition} from './CustomTransition';
|
||||
@@ -3,10 +3,11 @@ const DATA_API_KEY = '.data-api';
|
||||
|
||||
const $document = $(document);
|
||||
const $window = $(window);
|
||||
const html = document.documentElement;
|
||||
const $html = $(document.documentElement).removeClass('has-no-js').addClass('has-js');
|
||||
const $body = $(document.body);
|
||||
const $pjaxWrapper = $('#js-pjax-wrapper');
|
||||
|
||||
const isDebug = !!$html.data('debug');
|
||||
|
||||
export { APP_NAME, DATA_API_KEY, $document, $window, $html, $body, isDebug, $pjaxWrapper };
|
||||
export { APP_NAME, DATA_API_KEY, $document, $window, html, $html, $body, isDebug, $pjaxWrapper };
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
@import "tools/mixins";
|
||||
@import "tools/fonts";
|
||||
@import "tools/layout";
|
||||
// @import "tools/ratio";
|
||||
// @import "tools/widths";
|
||||
@import "tools/widths";
|
||||
// @import "tools/family";
|
||||
|
||||
// Generic
|
||||
@@ -26,23 +25,23 @@
|
||||
@import "generic/form";
|
||||
@import "generic/button";
|
||||
|
||||
// Base
|
||||
// Elements
|
||||
// ==========================================================================
|
||||
@import "base/fonts";
|
||||
@import "base/page";
|
||||
@import "base/headings";
|
||||
@import "elements/fonts";
|
||||
@import "elements/page";
|
||||
@import "elements/headings";
|
||||
|
||||
// Objects
|
||||
// ==========================================================================
|
||||
@import "objects/container";
|
||||
// @import "objects/crop";
|
||||
// @import "objects/ratio";
|
||||
// @import "objects/table";
|
||||
@import "objects/ratio";
|
||||
@import "objects/layout";
|
||||
@import "objects/form";
|
||||
@import "objects/button";
|
||||
@import "objects/pjax";
|
||||
@import "objects/scroll";
|
||||
// @import "objects/crop";
|
||||
// @import "objects/table";
|
||||
|
||||
// Vendors
|
||||
// ==========================================================================
|
||||
@@ -58,10 +57,11 @@
|
||||
|
||||
// Utilities
|
||||
// ==========================================================================
|
||||
@import "utilities/ratio";
|
||||
@import "utilities/widths";
|
||||
// @import "utilities/align";
|
||||
// @import "utilities/helpers";
|
||||
// @import "utilities/states";
|
||||
// @import "utilities/headings";
|
||||
// @import "utilities/spacing";
|
||||
// @import "utilities/widths";
|
||||
// @import "utilities/print";
|
||||
|
||||
@@ -2,20 +2,6 @@
|
||||
// Objects / Ratio
|
||||
// ==========================================================================
|
||||
|
||||
//
|
||||
// @link https://github.com/inuitcss/inuitcss/blob/19d0c7e/objects/_objects.ratio.scss
|
||||
//
|
||||
|
||||
// A list of aspect ratios that get generated as modifier classes.
|
||||
|
||||
$aspect-ratios: (
|
||||
(2:1),
|
||||
(4:3),
|
||||
(16:9),
|
||||
) !default;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create ratio-bound content blocks, to keep media (e.g. images, videos) in
|
||||
* their correct aspect ratios.
|
||||
@@ -38,6 +24,7 @@ $aspect-ratios: (
|
||||
}
|
||||
|
||||
.o-ratio_content,
|
||||
.o-ratio > img,
|
||||
.o-ratio > iframe,
|
||||
.o-ratio > embed,
|
||||
.o-ratio > object {
|
||||
@@ -46,34 +33,5 @@ $aspect-ratios: (
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// height: 100%;
|
||||
}
|
||||
|
||||
/* stylelint-disable */
|
||||
|
||||
//
|
||||
// Generate a series of ratio classes to be used like so:
|
||||
//
|
||||
// @example
|
||||
// <div class="o-ratio -16:9">
|
||||
//
|
||||
//
|
||||
.o-ratio {
|
||||
@each $ratio in $aspect-ratios {
|
||||
@each $antecedent, $consequent in $ratio {
|
||||
@if (type-of($antecedent) != number) {
|
||||
@error "`#{$antecedent}` needs to be a number."
|
||||
}
|
||||
|
||||
@if (type-of($consequent) != number) {
|
||||
@error "`#{$consequent}` needs to be a number."
|
||||
}
|
||||
|
||||
&.-#{$antecedent}\:#{$consequent}::before {
|
||||
padding-bottom: ($consequent/$antecedent) * 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* stylelint-enable */
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Tools / Ratio Constraint
|
||||
// ==========================================================================
|
||||
|
||||
//
|
||||
// A tool to restrain a container to a unitary or fractional proportion.
|
||||
//
|
||||
|
||||
$data-ratios: "1/2" "0.5" 50%,
|
||||
"11/20" "0.55" 55%,
|
||||
"3/5" "0.6" 60%,
|
||||
"13/20" "0.65" 65%,
|
||||
"7/10" "0.7" 70%,
|
||||
"3/4" "0.75" 75%,
|
||||
"4/5" "0.8" 80%,
|
||||
"17/20" "0.85" 85%,
|
||||
"9/10" "0.9" 90%,
|
||||
"19/20" "0.95" 95%,
|
||||
"1/1" "1" 100%,
|
||||
"21/20" "1.05" 105%,
|
||||
"11/10" "1.1" 110%,
|
||||
"23/20" "1.15" 115%,
|
||||
"6/5" "1.2" 120%,
|
||||
"5/4" "1.25" 125% !default;
|
||||
$data-ratio-crops: "top" "bottom" "both" !default;
|
||||
|
||||
@mixin crop($crop) {
|
||||
@if $crop == "top" {
|
||||
bottom: 0;
|
||||
} @else if $crop == "bottom" {
|
||||
top: 0;
|
||||
} @else if $crop == "both" {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.u-ratio {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
display: block;
|
||||
width: 100%;
|
||||
content: "";
|
||||
}
|
||||
|
||||
@each $ratio in $data-ratios {
|
||||
$ratio-1: nth($ratio, 1);
|
||||
$ratio-2: nth($ratio, 2);
|
||||
&[data-ratio="#{$ratio-1}"]::before,
|
||||
&[data-ratio="#{$ratio-2}"]::before {
|
||||
padding-top: nth($ratio, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.u-ratio_content_container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.u-ratio_content {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
@each $crop in $data-ratio-crops {
|
||||
&[data-ratio-crop="#{$crop}"] {
|
||||
@include crop($crop);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
assets/styles/utilities/_ratio.scss
Normal file
42
assets/styles/utilities/_ratio.scss
Normal file
@@ -0,0 +1,42 @@
|
||||
// ==========================================================================
|
||||
// Utilities / Ratio
|
||||
// ==========================================================================
|
||||
|
||||
//
|
||||
// @link https://github.com/inuitcss/inuitcss/blob/19d0c7e/objects/_objects.ratio.scss
|
||||
//
|
||||
|
||||
// A list of aspect ratios that get generated as modifier classes.
|
||||
|
||||
$aspect-ratios: (
|
||||
(2:1),
|
||||
(4:3),
|
||||
(16:9),
|
||||
) !default;
|
||||
|
||||
/* stylelint-disable */
|
||||
|
||||
//
|
||||
// Generate a series of ratio classes to be used like so:
|
||||
//
|
||||
// @example
|
||||
// <div class="o-ratio u-16:9">
|
||||
//
|
||||
//
|
||||
@each $ratio in $aspect-ratios {
|
||||
@each $antecedent, $consequent in $ratio {
|
||||
@if (type-of($antecedent) != number) {
|
||||
@error "`#{$antecedent}` needs to be a number."
|
||||
}
|
||||
|
||||
@if (type-of($consequent) != number) {
|
||||
@error "`#{$consequent}` needs to be a number."
|
||||
}
|
||||
|
||||
&.u-#{$antecedent}\:#{$consequent}::before {
|
||||
padding-bottom: ($consequent/$antecedent) * 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* stylelint-enable */
|
||||
Reference in New Issue
Block a user