Cleaned up and refactored tabs implementation

This commit is contained in:
squidfunk 2017-01-27 22:41:55 +01:00
parent fc900aa4b5
commit 4c4edff9cb
16 changed files with 281 additions and 61 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -45,7 +45,7 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-5ea1192909.css">
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-cfcead01e1.css">
{% if config.extra.palette %}
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-02ce7adcc2.palette.css">
{% endif %}
@ -128,7 +128,7 @@
{% endblock %}
</div>
{% block scripts %}
<script src="{{ base_url }}/assets/javascripts/application-adb933686d.js"></script>
<script src="{{ base_url }}/assets/javascripts/application-5964b4977f.js"></script>
<script>var config={url:{base:"{{ base_url }}"}},app=new Application(config);app.initialize()</script>
{% for path in extra_javascript %}
<script src="{{ path }}"></script>

View File

@ -1,4 +1,4 @@
<nav class="md-tabs">
<nav class="md-tabs" data-md-component="tabs">
<div class="md-tabs__inner md-grid">
<ul class="md-tabs__list">
{% for nav_item in nav %}

View File

@ -44,22 +44,6 @@ export default class Application {
*/
initialize() {
// TODO: just a proof of concept
window.addEventListener("scroll", () => {
if (window.pageYOffset > 5) {
document.body.classList.add("bigger5")
} else {
document.body.classList.remove("bigger5")
}
if (window.pageYOffset > 48) {
document.body.classList.add("bigger48")
} else {
document.body.classList.remove("bigger48")
}
})
/* Initialize Modernizr and FastClick */
new Material.Event.Listener(document, "DOMContentLoaded", () => {
@ -109,6 +93,16 @@ export default class Application {
}
}).listen()
/* Component: header shadow toggle */
new Material.Event.Listener(window, [
"scroll", "resize", "orientationchange"
], new Material.Header.Shadow("[data-md-component=container]")).listen()
/* Component: tabs visibility toggle */
new Material.Event.Listener(window, [
"scroll", "resize", "orientationchange"
], new Material.Tabs.Toggle("[data-md-component=tabs]")).listen()
/* Component: sidebar container */
if (!Modernizr.csscalc)
new Material.Event.MatchMedia("(min-width: 960px)",
@ -131,7 +125,7 @@ export default class Application {
/* Component: link blurring for table of contents */
new Material.Event.MatchMedia("(min-width: 960px)",
new Material.Event.Listener(window, "scroll",
new Material.Nav.Blur("[data-md-component=toc] .md-nav__link")))
new Material.Nav.Blur("[data-md-component=toc] [href]")))
/* Component: collapsible elements for navigation */
const collapsibles =

View File

@ -21,10 +21,12 @@
*/
import Event from "./Material/Event"
import Header from "./Material/Header"
import Nav from "./Material/Nav"
import Search from "./Material/Search"
import Sidebar from "./Material/Sidebar"
import Source from "./Material/Source"
import Tabs from "./Material/tabs"
/* ----------------------------------------------------------------------------
* Module
@ -32,8 +34,10 @@ import Source from "./Material/Source"
export default {
Event,
Header,
Nav,
Search,
Sidebar,
Source
Source,
Tabs
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
import Shadow from "./Header/Shadow"
/* ----------------------------------------------------------------------------
* Module
* ------------------------------------------------------------------------- */
export default {
Shadow
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/* ----------------------------------------------------------------------------
* Class
* ------------------------------------------------------------------------- */
export default class Shadow {
/**
* Show the header shadow depending on scroll offset
*
* @constructor
* @param {(string|HTMLElement)} el - Selector or HTML element
*/
constructor(el) {
this.el_ = (typeof el === "string")
? document.querySelector(el)
: el
/* Grab parent and header */
this.el_ = this.el_.parentNode
this.header_ = this.el_.parentNode.previousElementSibling
/* Initialize height and state */
this.height_ = 0
this.active_ = false
}
/**
* Calculate total height of previous nodes
*/
setup() {
let current = this.el_
while ((current = current.previousElementSibling))
this.height_ += current.offsetHeight
}
/**
* Update shadow state
*/
update() {
const active = window.pageYOffset >= this.height_
if (active !== this.active_)
this.header_.dataset.mdState = (this.active_ = active) ? "shadow" : ""
}
/**
* Reset shadow state
*/
reset() {
this.header_.dataset.mdState = ""
this.height_ = 0
this.active_ = false
}
}

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
import Toggle from "./Tabs/Toggle"
/* ----------------------------------------------------------------------------
* Module
* ------------------------------------------------------------------------- */
export default {
Toggle
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/* ----------------------------------------------------------------------------
* Class
* ------------------------------------------------------------------------- */
export default class Toggle {
/**
* Show tabs depending on scroll offset
*
* @constructor
* @param {(string|HTMLElement)} el - Selector or HTML element
*/
constructor(el) {
this.el_ = (typeof el === "string")
? document.querySelector(el)
: el
/* Initialize height and state */
this.height_ = 5
this.active_ = false
}
/**
* Update visibility
*/
update() {
const active = window.pageYOffset >= this.height_
if (active !== this.active_)
this.el_.dataset.mdState = (this.active_ = active) ? "hidden" : ""
}
/**
* Reset visibility
*/
reset() {
this.el_.dataset.mdState = ""
this.active_ = false
}
}

View File

@ -23,21 +23,3 @@
// ----------------------------------------------------------------------------
// Nothing to see here, move along
// ----------------------------------------------------------------------------
.md-tabs__list {
transition: opacity 0.1s;
}
.bigger5 {
.md-tabs__list {
opacity: 0;
}
}
.bigger48 {
.md-header {
@include z-depth(2);
transition: box-shadow 0.25s;
}
}

View File

@ -41,6 +41,15 @@
@include z-depth(2);
}
// Show and animate shadow
&[data-md-state="shadow"] {
@include z-depth(3);
transition:
background-color 0.25s,
box-shadow 0.25s;
}
// Hide for print
@media print {
display: none;

View File

@ -129,18 +129,18 @@
}
}
// Blurred item
// Blurred link
&[data-md-state="blur"] {
color: $md-color-black--light;
}
// Active item
// Active link
&:active,
&--active {
color: $md-color-primary;
}
// Hovered item
// Hovered link
&:hover {
color: $md-color-accent;
}

View File

@ -1,39 +1,72 @@
// TODO: proof of concept - needs refactor
////
/// Copyright (c) 2016-2017 Martin Donath <martin.donath@squidfunk.com>
///
/// Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS
////
// ----------------------------------------------------------------------------
// Rules
// ----------------------------------------------------------------------------
// Tabs with outline
.md-tabs {
width: 100%;
background: $md-color-primary; //mix($md-color-primary, $md-color-black, 75%);
overflow: scroll;
background: $md-color-primary;
overflow-x: scroll;
// List of items
&__list {
margin: 0;
margin-left: 6rem;
margin-left: 0.4rem;
padding: 0;
transition:
transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1),
opacity 0.1s;
list-style: none;
white-space: nowrap;
}
// List item
&__item {
display: inline-block;
// text-transform: uppercase;
}
// Link inside item
&__link {
display: block;
padding-right: 1.2rem;
padding-left: 1.2rem;
transition: color 0.25s;
color: $md-color-white--light;
font-size: 1.4rem; // TODO: somehow centralize
font-size: 1.4rem;
line-height: 4.8rem;
// Active or hovered link
&--active,
&:hover {
color: $md-color-white;
}
&--active {
box-shadow: 0 -0.2rem 0 mix($md-color-accent, $md-color-white, 25) inset;
}
// Hide tabs upon scrolling
&[data-md-state="hidden"] .md-tabs__list {
transform: translateY(10%);
opacity: 0;
}
}

View File

@ -21,7 +21,7 @@
-->
<!-- Tabs with outline -->
<nav class="md-tabs">
<nav class="md-tabs" data-md-component="tabs">
<div class="md-tabs__inner md-grid">
<ul class="md-tabs__list">
{% for nav_item in nav %}