Skip to content
Snippets Groups Projects
Unverified Commit b4289e4b authored by Fredrik Jonsson's avatar Fredrik Jonsson Committed by GitHub
Browse files

Merge pull request #556 from OpenTechFund/feature/improved-front-end-stack

Rebuilding the front end stack with gulp 4.
parents 537ad169 0ccc95e7
No related branches found
No related tags found
No related merge requests found
Showing
with 193 additions and 382 deletions
class DeterminationCopy {
static selector(){
return '#id_outcome';
}
constructor(node) {
this.node = node[0];
this.bindEventListeners();
}
bindEventListeners(){
this.node.addEventListener('change', (e) => {
this.getMatchingCopy(e.target.value);
}, false);
}
getMatchingCopy(value) {
if (value === '0'){
this.text = document.querySelector('div[data-type="rejected"]').textContent;
} else if (value === '1') {
this.text = document.querySelector('div[data-type="more_info"]').textContent;
} else {
this.text = document.querySelector('div[data-type="accepted"]').textContent;
}
this.updateTextArea(this.text);
}
updateTextArea(text) {
window.tinyMCE.get('id_message').setContent(text);
}
}
export default DeterminationCopy;
import $ from './../globals';
export default function listInputFiles() {
$('input[type=file]').change(function() {
// remove any existing files first
$(this).siblings('.form__file').remove();
for (let i = 0; i < $(this)[0].files.length; ++i) {
$(this).parents('.form__item').prepend(`
<p class="form__file">${$(this)[0].files[i].name}</p>
`);
}
});
}
import $ from './../globals';
export default () => {
// Close the message
$('.js-close-message').click((e) => {
e.preventDefault();
var message = e.target.closest('.js-message');
message.classList.add('messages__text--hide');
});
};
import $ from './../globals';
export default function mobileFilterPadding (element) {
const expanded = 'expanded-filter-element';
const dropdown = $(element).closest('.select2');
const openDropdown = $('.select2 .' + expanded);
let dropdownMargin = 0;
if(openDropdown.length > 0 && !openDropdown.hasClass('select2-container--open')){
// reset the margin of the select we previously worked
openDropdown.removeClass(expanded);
// store the offset to adjust the new select box (elements above the old dropdown unaffected)
if (dropdown.position().top > openDropdown.position().top ){
dropdownMargin = parseInt(openDropdown.css('marginBottom'));
}
openDropdown.css('margin-bottom', '0px');
}
if(dropdown.hasClass('select2-container--open')){
dropdown.addClass(expanded);
const dropdownID = $(element).closest('.select2-selection').attr('aria-owns');
// Element which has the height of the select dropdown
const match = $(`ul#${dropdownID}`);
const dropdownHeight = match.outerHeight(true);
// Element which has the position of the dropdown
const positionalMatch = match.closest('.select2-container');
// Pad the bottom of the select box
dropdown.css('margin-bottom', `${dropdownHeight}px`);
// bump up the dropdown options by height of closed elements
positionalMatch.css('top', positionalMatch.position().top - dropdownMargin);
}
}
class MobileMenu {
static selector() {
return '.js-mobile-menu-toggle';
}
constructor(node, closeButton, mobileMenu, search) {
this.node = node;
this.closeButton = closeButton;
this.mobileMenu = mobileMenu;
this.search = search;
this.bindEventListeners();
}
bindEventListeners() {
this.node.click(this.toggle.bind(this));
this.closeButton.click(this.toggle.bind(this));
}
toggle() {
// toggle mobile menu
this.mobileMenu[0].classList.toggle('is-visible');
// check if search exists
if (document.body.contains(this.search[0])) {
// reset the search whenever the mobile menu is toggled
if(this.search[0].classList.contains('is-visible')){
this.search[0].classList.toggle('is-visible');
document.querySelector('.header__inner--menu-open').classList.toggle('header__inner--search-open');
}
}
// reset the search show/hide icons
if(this.mobileMenu[0].classList.contains('is-visible') && document.body.contains(this.search[0])){
document.querySelector('.header__icon--open-search-menu-closed').classList.remove('is-hidden');
document.querySelector('.header__icon--close-search-menu-closed').classList.remove('is-unhidden');
}
}
}
export default MobileMenu;
class MobileSearch {
static selector() {
return '.js-mobile-search-toggle';
}
constructor(node, mobileMenu, searchForm, searchToggleButton) {
this.node = node;
this.mobileMenu = mobileMenu[0];
this.searchForm = searchForm[0];
this.searchToggleButton = searchToggleButton[0];
this.bindEventListeners();
}
bindEventListeners() {
this.node.click(this.toggle.bind(this));
}
toggle() {
// hide the mobile menu
this.mobileMenu.classList.remove('is-visible');
// wait for the mobile menu to close
setTimeout(() => {
// open the search
this.searchForm.classList.add('is-visible');
// swap the icons
this.searchToggleButton.querySelector('.header__icon--open-search').classList.add('is-hidden');
this.searchToggleButton.querySelector('.header__icon--close-search').classList.add('is-unhidden');
}, 250);
}
}
export default MobileSearch;
class Search {
static selector() {
return '.js-search-toggle';
}
constructor(node, searchForm) {
this.node = node;
this.searchForm = searchForm;
this.bindEventListeners();
}
bindEventListeners() {
this.node.click(this.toggle.bind(this));
}
toggle() {
// show the search
this.searchForm[0].classList.toggle('is-visible');
// swap the icons
this.node[0].querySelector('.header__icon--open-search').classList.toggle('is-hidden');
this.node[0].querySelector('.header__icon--close-search').classList.toggle('is-unhidden');
// add modifier to header to be able to change header icon colours
document.querySelector('.header').classList.toggle('search-open');
}
}
export default Search;
export default function generateTooltips(){
// get the submisttions titles
const titles = Array.prototype.slice.call(document.querySelectorAll('.js-title'));
// if the tile has been truncated...
titles.forEach(function(title){
if (title.textContent.indexOf('...') >= 0) {
addToolTip(title);
}
});
// ...add a tooltip class
function addToolTip(title){
title.classList.add('has-tooltip');
}
}
class Tabs {
static selector() {
return '.js-tabs';
}
constructor() {
// The tabs
this.tabItems = Array.prototype.slice.call(document.querySelectorAll('.tab__item:not(.js-tabs-off)'));
// The tabs content
this.tabsContents = Array.prototype.slice.call(document.querySelectorAll('.tabs__content'));
// Active classes
this.tabActiveClass = 'tab__item--active';
this.tabContentActiveClass = 'tabs__content--current';
this.defaultSelectedTab = 'tab-1';
this.bindEvents();
}
bindEvents() {
this.updateTabOnLoad();
this.tabItems.forEach((el) => {
el.addEventListener('click', (e) => {
// prevent the page jumping
e.preventDefault();
this.tabs(e);
});
});
}
findTab(href) {
return document.querySelector(`a[href="#${href}"]`);
}
updateTabOnLoad() {
// Find tab with matching hash and activate
const url = document.location.toString();
const match = this.findTab(url.split('#')[1]);
this.addTabClasses(match);
}
tabs(e) {
// Find current tab
const tab = e.currentTarget;
this.stripTabClasses();
this.addTabClasses(tab);
this.updateUrl(tab);
}
stripTabClasses(){
// remove active classes from all tabs and tab contents
this.tabItems.forEach(tabItem => tabItem.classList.remove(this.tabActiveClass));
this.tabsContents.forEach(tabsContent => tabsContent.classList.remove(this.tabContentActiveClass));
}
addTabClasses(tab){
if(tab === null) {
tab = document.querySelector(`[data-tab=${this.defaultSelectedTab}]`);
}
const tabId = tab.getAttribute('data-tab');
// add active classes to tabs and their respecitve content
tab.classList.add(this.tabActiveClass);
document.querySelector(`#${tabId}`).classList.add(this.tabContentActiveClass);
}
updateUrl(tab){
window.location.hash = tab.getAttribute('href');
}
}
export default Tabs;
import $ from './../globals';
export default function toggleActionsPanel(){
$('.js-actions-toggle').click(function(e) {
e.preventDefault();
this.classList.toggle('is-active');
this.nextElementSibling.classList.toggle('is-visible');
});
}
import jQuery from './vendor/jquery';
// We have to manually make jQuery a global variable.
// By default it will be in a closure and renamed to lowercase.
window.jQuery = jQuery;
export default jQuery;
import jQuery from './globals';
import MobileMenu from './components/mobile-menu';
import Search from './components/search';
import MobileSearch from './components/mobile-search';
import Tabs from './components/tabs';
import listInputFiles from './components/list-input-files';
import toggleActionsPanel from './components/toggle-actions-panel';
import activityFeed from './components/activity-feed';
import messages from './components/messages';
import fancyboxGlobal from './components/fancybox-global';
import allSubmissions from './components/all-submissions-table';
import allReviews from './components/all-reviews-table';
import submissionFilters from './components/submission-filters';
import mobileFilterPadding from './components/mobile-filter-padding';
import generateTooltips from './components/submission-tooltips';
import DeterminationCopy from './components/determination-template';
import toggleReviewers from './components/toggle-reviewers';
(function ($) {
$(document).ready(function(){
// remove no-js class if js is enabled
document.querySelector('html').classList.remove('no-js');
$(MobileMenu.selector()).each((index, el) => {
new MobileMenu($(el), $('.js-mobile-menu-close'), $('.header__menus--mobile'), $('.header__search'));
});
'use strict';
$(Search.selector()).each((index, el) => {
new Search($(el), $('.header__search'));
});
let Search = class {
static selector() {
return '.js-search-toggle';
}
$(MobileSearch.selector()).each((index, el) => {
new MobileSearch($(el), $('.header__menus--mobile'), $('.header__search'), $('.js-search-toggle'));
});
constructor(node, searchForm) {
this.node = node;
this.searchForm = searchForm;
this.bindEventListeners();
}
$(Tabs.selector()).each((index, el) => {
new Tabs($(el));
});
bindEventListeners() {
this.node.click(this.toggle.bind(this));
}
toggle() {
// show the search
this.searchForm[0].classList.toggle('is-visible');
// swap the icons
this.node[0].querySelector('.header__icon--open-search').classList.toggle('is-hidden');
this.node[0].querySelector('.header__icon--close-search').classList.toggle('is-unhidden');
// add modifier to header to be able to change header icon colours
document.querySelector('.header').classList.toggle('search-open');
}
};
let MobileMenu = class {
static selector() {
return '.js-mobile-menu-toggle';
}
constructor(node, closeButton, mobileMenu, search) {
this.node = node;
this.closeButton = closeButton;
this.mobileMenu = mobileMenu;
this.search = search;
this.bindEventListeners();
}
bindEventListeners() {
this.node.click(this.toggle.bind(this));
this.closeButton.click(this.toggle.bind(this));
}
// $(DeterminationCopy.selector()).each((index, el) => {
// new DeterminationCopy($(el));
// });
toggle() {
// toggle mobile menu
this.mobileMenu[0].classList.toggle('is-visible');
// check if search exists
if (document.body.contains(this.search[0])) {
// reset the search whenever the mobile menu is toggled
if (this.search[0].classList.contains('is-visible')) {
this.search[0].classList.toggle('is-visible');
document.querySelector('.header__inner--menu-open').classList.toggle('header__inner--search-open');
}
}
// reset the search show/hide icons
if (this.mobileMenu[0].classList.contains('is-visible') && document.body.contains(this.search[0])) {
document.querySelector('.header__icon--open-search-menu-closed').classList.remove('is-hidden');
document.querySelector('.header__icon--close-search-menu-closed').classList.remove('is-unhidden');
}
}
};
// Add tooltips to truncated titles on submissions overview table
generateTooltips();
let MobileSearch = class {
static selector() {
return '.js-mobile-search-toggle';
}
// Show list of selected files for upload on input[type=file]
listInputFiles();
constructor(node, mobileMenu, searchForm, searchToggleButton) {
this.node = node;
this.mobileMenu = mobileMenu[0];
this.searchForm = searchForm[0];
this.searchToggleButton = searchToggleButton[0];
this.bindEventListeners();
}
// Show actions sidebar on mobile
toggleActionsPanel();
bindEventListeners() {
this.node.click(this.toggle.bind(this));
}
// Global fancybox options
fancyboxGlobal();
toggle() {
// hide the mobile menu
this.mobileMenu.classList.remove('is-visible');
// Activity feed logic
activityFeed();
// wait for the mobile menu to close
setTimeout(() => {
// open the search
this.searchForm.classList.add('is-visible');
// messages logic
messages();
// swap the icons
this.searchToggleButton.querySelector('.header__icon--open-search').classList.add('is-hidden');
this.searchToggleButton.querySelector('.header__icon--close-search').classList.add('is-unhidden');
}, 250);
}
};
// Submissions overview table logic
allSubmissions();
// Replace no-js with js class if js is enabled.
document.querySelector('html').classList.replace('no-js', 'js');
// All reviews table logic
// allReviews();
$(MobileMenu.selector()).each((index, el) => {
new MobileMenu($(el), $('.js-mobile-menu-close'), $('.header__menus--mobile'), $('.header__search'));
});
$(Search.selector()).each((index, el) => {
new Search($(el), $('.header__search'));
});
// Submission filters logic
submissionFilters();
$(MobileSearch.selector()).each((index, el) => {
new MobileSearch($(el), $('.header__menus--mobile'), $('.header__search'), $('.js-search-toggle'));
});
// Toggle all reviewers in the sidebar
toggleReviewers();
// Close the message
$('.js-close-message').click((e) => {
e.preventDefault();
var message = e.target.closest('.js-message');
message.classList.add('messages__text--hide');
});
// Add active class to select2 checkboxes after page has been filtered
......@@ -82,12 +136,13 @@ import toggleReviewers from './components/toggle-reviewers';
});
// reset mobile filters if they're open past the tablet breakpoint
$(window).resize(function resize(){
$(window).resize(function resize() {
if ($(window).width() < 768) {
$('.select2').on('click', (e) => {
mobileFilterPadding(e.target);
});
} else {
}
else {
$('body').removeClass('no-scroll');
$('.js-filter-wrapper').removeClass('is-open');
$('.js-filter-list').removeClass('form__filters--mobile');
......@@ -96,4 +151,39 @@ import toggleReviewers from './components/toggle-reviewers';
$('.tr--parent.is-expanded').removeClass('is-expanded');
}
}).trigger('resize');
function mobileFilterPadding(element) {
const expanded = 'expanded-filter-element';
const dropdown = $(element).closest('.select2');
const openDropdown = $('.select2 .' + expanded);
let dropdownMargin = 0;
if (openDropdown.length > 0 && !openDropdown.hasClass('select2-container--open')) {
// reset the margin of the select we previously worked
openDropdown.removeClass(expanded);
// store the offset to adjust the new select box (elements above the old dropdown unaffected)
if (dropdown.position().top > openDropdown.position().top) {
dropdownMargin = parseInt(openDropdown.css('marginBottom'));
}
openDropdown.css('margin-bottom', '0px');
}
if (dropdown.hasClass('select2-container--open')) {
dropdown.addClass(expanded);
const dropdownID = $(element).closest('.select2-selection').attr('aria-owns');
// Element which has the height of the select dropdown
const match = $(`ul#${dropdownID}`);
const dropdownHeight = match.outerHeight(true);
// Element which has the position of the dropdown
const positionalMatch = match.closest('.select2-container');
// Pad the bottom of the select box
dropdown.css('margin-bottom', `${dropdownHeight}px`);
// bump up the dropdown options by height of closed elements
positionalMatch.css('top', positionalMatch.position().top - dropdownMargin);
}
}
})(jQuery);
This diff is collapsed.
......@@ -18,7 +18,8 @@
@if map-has-key($direction-map, $direction) {
$opposite-directions: append($opposite-directions, unquote(map-get($direction-map, $direction)));
} @else {
}
@else {
@warn 'No opposite direction can be found for `#{$direction}`. Direction omitted.';
}
}
......
......@@ -51,7 +51,8 @@
@if $value == 0 or $value == auto or $value == inherit {
$px: append($px, $value);
$rem: append($rem, $value);
} @else {
}
@else {
$px: append($px, $value);
$rem: append($rem, rem(strip-unit($value)));
}
......@@ -73,7 +74,8 @@
@if $size == null {
@warn 'Font size ‘#{$keyword}’ does not exist';
} @else {
}
@else {
@include rem-font-size($size);
}
}
......@@ -113,7 +115,7 @@
// Viewport sized typography mixin that takes a min and max pixel-based value
@mixin responsive-font-sizes($min, $max) {
$vw-context: (1260 * 0.1) * 1px;
$vw-context: (1260 * .1) * 1px;
$responsive: ($max / $vw-context) * 10vw;
$responsive-unitless: $responsive / ($responsive - $responsive + 1);
......@@ -152,7 +154,8 @@
@if $direction == top or $direction == bottom {
border-right: $perpendicular-borders;
border-left: $perpendicular-borders;
} @else if $direction == right or $direction == left {
}
@else if $direction == right or $direction == left {
border-top: $perpendicular-borders;
border-bottom: $perpendicular-borders;
}
......
// sass-lint:disable no-color-keywords; no-color-hex
// Default
$color--white: #fff;
$color--black: #141414;
$color--dark-grey: #404041;
$color--light-grey: #f7f7f7;
$color--light-mid-grey: #e8e8e8;
$color--mid-grey: #cfcfcf;
......@@ -32,12 +35,18 @@ $color--linkedin: #137ab8;
$color--facebook: #396ab5;
// Transparent
$color--black-50: rgba(0, 0, 0, 0.5);
$color--black-40: rgba(0, 0, 0, 0.4);
$color--black-20: rgba(0, 0, 0, 0.2);
$color--black-10: rgba(0, 0, 0, 0.1);
$color--black-50: rgba(0, 0, 0, .5);
$color--black-40: rgba(0, 0, 0, .4);
$color--black-25: rgba(0, 0, 0, .25);
$color--black-20: rgba(0, 0, 0, .2);
$color--black-10: rgba(0, 0, 0, .1);
$color--white-50: rgba(255, 255, 255, .5);
$color--white-40: rgba(255, 255, 255, .4);
$color--white-25: rgba(255, 255, 255, .25);
$color--white-20: rgba(255, 255, 255, .2);
$color--white-10: rgba(255, 255, 255, .1);
$color--light-blue-90: transparentize($color--light-blue, 0.9);
$color--light-blue-90: transparentize($color--light-blue, .9);
// Assignment
$color--default: $color--dark-grey;
......@@ -85,8 +94,8 @@ $breakpoints: (
);
// Transition
$transition: 0.25s ease-out;
$quick-transition: 0.15s ease;
$transition: .25s ease-out;
$quick-transition: .15s ease;
// Spacing
$mobile-gutter: 20px;
......@@ -80,6 +80,20 @@ ol {
display: none;
}
.js-hidden,
%js-hidden {
html.js & {
@extend %is-hidden;
}
}
.no-js-hidden,
%no-js-hidden {
html.nojs & {
@extend %is-hidden;
}
}
.is-unhidden,
%is-unhidden {
display: block;
......
......@@ -70,7 +70,7 @@ small, .milli { @include font-size(milli); }
font-family: 'proxima-nova';
font-style: normal;
font-weight: 200;
src: url('./../../fonts/proxima-nova/proxima-nova-thin.woff') format('woff');
src: url('../../fonts/proxima-nova/proxima-nova-thin.woff') format('woff');
text-rendering: optimizeLegibility;
}
......@@ -79,7 +79,7 @@ small, .milli { @include font-size(milli); }
font-family: 'proxima-nova';
font-style: normal;
font-weight: 400;
src: url('./../../fonts/proxima-nova/proxima-nova-regular.woff') format('woff');
src: url('../../fonts/proxima-nova/proxima-nova-regular.woff') format('woff');
text-rendering: optimizeLegibility;
}
......@@ -88,7 +88,7 @@ small, .milli { @include font-size(milli); }
font-family: 'proxima-nova';
font-style: normal;
font-weight: 600;
src: url('./../../fonts/proxima-nova/proxima-nova-semibold.woff') format('woff');
src: url('../../fonts/proxima-nova/proxima-nova-semibold.woff') format('woff');
text-rendering: optimizeLegibility;
}
......@@ -97,7 +97,7 @@ small, .milli { @include font-size(milli); }
font-family: 'proxima-nova';
font-style: normal;
font-weight: 700;
src: url('./../../fonts/proxima-nova/proxima-nova-bold.woff') format('woff');
src: url('../../fonts/proxima-nova/proxima-nova-bold.woff') format('woff');
text-rendering: optimizeLegibility;
}
......@@ -106,6 +106,6 @@ small, .milli { @include font-size(milli); }
font-family: 'proxima-nova';
font-style: normal;
font-weight: 800;
src: url('./../../fonts/proxima-nova/proxima-nova-black.woff') format('woff');
src: url('../../fonts/proxima-nova/proxima-nova-black.woff') format('woff');
text-rendering: optimizeLegibility;
}
......@@ -3,7 +3,7 @@
top: 100vh;
right: 0;
left: 0;
transition: top 0.3s cubic-bezier(0, 0.52, 0.58, 1);
transition: top .3s cubic-bezier(0, .52, .58, 1);
&.is-open {
top: 0;
......
......@@ -161,7 +161,7 @@
&.is-disabled {
pointer-events: none;
opacity: 0.5;
opacity: .5;
}
&--top-space {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment