mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
Merge pull request #187 from squidfunk/refactor/sidebar-height-spacing
Added tabs navigation feature (optional)
This commit is contained in:
commit
ca4b8aa94b
15
CHANGELOG
15
CHANGELOG
@ -1,3 +1,18 @@
|
||||
mkdocs-material-1.1.0 (2017-xx-xx)
|
||||
|
||||
* Added tabs navigation feature (optional)
|
||||
* Added Disqus integration (optional)
|
||||
* Added a high resolution Favicon with the new logo
|
||||
* Added static type checking using Facebook's Flow
|
||||
* Fixed #175: Tables cannot be set to 100% width
|
||||
* Fixed #173: Dictionary elements have no bottom spacing
|
||||
* Fixed race conditions in build related to asset revisioning
|
||||
* Fixed accidentally re-introduced Permalink on top-level headline
|
||||
* Fixed alignment of logo in drawer on IE11
|
||||
* Refactored styles related to tables
|
||||
* Refactored and automated Docker build and PyPI release
|
||||
* Refactored build scripts
|
||||
|
||||
mkdocs-material-1.0.5 (2017-02-18)
|
||||
|
||||
* Fixed #153: Sidebar flows out of constrained area in Chrome 56
|
||||
|
@ -101,6 +101,10 @@ gulp.src = (...glob) => {
|
||||
|
||||
/*
|
||||
* Helper function to load a task
|
||||
*
|
||||
* This function returns a callback that will require the task with the given
|
||||
* name and execute the function that is returned by this task. It omits the
|
||||
* need to load all tasks upfront, speeding up the build a gazillion times.
|
||||
*/
|
||||
const load = task => {
|
||||
return done => {
|
||||
@ -116,26 +120,26 @@ const load = task => {
|
||||
/*
|
||||
* Copy favicon
|
||||
*/
|
||||
gulp.task("assets:images:build:ico",
|
||||
gulp.task("assets:images:build:ico", [
|
||||
args.clean ? "assets:images:clean" : false
|
||||
].filter(t => t),
|
||||
load("assets/images/build/ico"))
|
||||
|
||||
/*
|
||||
* Copy and minify vector graphics
|
||||
*/
|
||||
gulp.task("assets:images:build:svg",
|
||||
gulp.task("assets:images:build:svg", [
|
||||
args.clean ? "assets:images:clean" : false
|
||||
].filter(t => t),
|
||||
load("assets/images/build/svg"))
|
||||
|
||||
/*
|
||||
* Copy images
|
||||
*/
|
||||
gulp.task("assets:images:build", args.clean ? [
|
||||
"assets:images:clean"
|
||||
] : [], () => {
|
||||
return gulp.start([
|
||||
gulp.task("assets:images:build", [
|
||||
"assets:images:build:ico",
|
||||
"assets:images:build:svg"
|
||||
])
|
||||
})
|
||||
])
|
||||
|
||||
/*
|
||||
* Clean images generated by build
|
||||
@ -150,38 +154,38 @@ gulp.task("assets:images:clean",
|
||||
/*
|
||||
* Build application logic
|
||||
*
|
||||
* When revisioning, the build must be serialized due to race conditions
|
||||
* happening when two tasks try to write manifest.json simultaneously
|
||||
* When revisioning assets, the build must be serialized due to possible race
|
||||
* conditions when two tasks try to write manifest.json simultaneously
|
||||
*/
|
||||
gulp.task("assets:javascripts:build:application", args.revision ? [
|
||||
"assets:stylesheets:build"
|
||||
] : [], load("assets/javascripts/build/application"))
|
||||
|
||||
gulp.task("assets:javascripts:build:application", [
|
||||
args.clean ? "assets:javascripts:clean" : false,
|
||||
args.lint ? "assets:javascripts:lint" : false,
|
||||
args.revision ? "assets:stylesheets:build" : false
|
||||
].filter(t => t),
|
||||
load("assets/javascripts/build/application"))
|
||||
|
||||
/*
|
||||
* Build custom modernizr
|
||||
*
|
||||
* When revisioning, the build must be serialized due to race conditions
|
||||
* happening when two tasks try to write manifest.json simultaneously
|
||||
* When revisioning assets, the build must be serialized due to possible race
|
||||
* conditions when two tasks try to write manifest.json simultaneously
|
||||
*/
|
||||
gulp.task("assets:javascripts:build:modernizr", [
|
||||
"assets:stylesheets:build"
|
||||
].concat(args.revision ? [
|
||||
"assets:javascripts:build:application"
|
||||
] : []), load("assets/javascripts/build/modernizr"))
|
||||
"assets:stylesheets:build",
|
||||
args.clean ? "assets:javascripts:clean" : false,
|
||||
args.lint ? "assets:javascripts:lint" : false,
|
||||
args.revision ? "assets:javascripts:build:application" : false
|
||||
].filter(t => t),
|
||||
load("assets/javascripts/build/modernizr"))
|
||||
|
||||
/*
|
||||
* Build application logic and Modernizr
|
||||
*/
|
||||
gulp.task("assets:javascripts:build", (args.clean ? [
|
||||
"assets:javascripts:clean"
|
||||
] : []).concat(args.lint ? [
|
||||
"assets:javascripts:lint"
|
||||
] : []), () => {
|
||||
return gulp.start([
|
||||
gulp.task("assets:javascripts:build", [
|
||||
"assets:javascripts:build:application",
|
||||
"assets:javascripts:build:modernizr"
|
||||
])
|
||||
})
|
||||
])
|
||||
|
||||
/*
|
||||
* Clean JavaScript generated by build
|
||||
@ -208,11 +212,10 @@ gulp.task("assets:javascripts:lint",
|
||||
/*
|
||||
* Build stylesheets from SASS source
|
||||
*/
|
||||
gulp.task("assets:stylesheets:build", (args.clean ? [
|
||||
"assets:stylesheets:clean"
|
||||
] : []).concat(args.lint ? [
|
||||
"assets:stylesheets:lint"
|
||||
] : []),
|
||||
gulp.task("assets:stylesheets:build", [
|
||||
args.clean ? "assets:stylesheets:clean" : false,
|
||||
args.lint ? "assets:stylesheets:lint" : false
|
||||
].filter(t => t),
|
||||
load("assets/stylesheets/build"))
|
||||
|
||||
/*
|
||||
@ -256,11 +259,13 @@ gulp.task("assets:clean", [
|
||||
/*
|
||||
* Minify views
|
||||
*/
|
||||
gulp.task("views:build", (args.revision ? [
|
||||
"assets:build"
|
||||
] : []).concat(args.clean ? [
|
||||
"views:clean"
|
||||
] : []),
|
||||
|
||||
gulp.task("views:build", [
|
||||
args.clean ? "views:clean" : false,
|
||||
args.revision ? "assets:images:build" : false,
|
||||
args.revision ? "assets:stylesheets:build" : false,
|
||||
args.revision ? "assets:javascripts:build" : false
|
||||
].filter(t => t),
|
||||
load("views/build"))
|
||||
|
||||
/*
|
||||
@ -302,11 +307,10 @@ gulp.task("mkdocs:serve",
|
||||
* Generate visual tests
|
||||
*/
|
||||
gulp.task("tests:visual:generate", [
|
||||
].concat(args.clean ? [
|
||||
"tests:visual:clean",
|
||||
"assets:build",
|
||||
"views:build"
|
||||
] : []),
|
||||
args.clean ? "tests:visual:clean" : false,
|
||||
args.clean ? "assets:build" : false,
|
||||
args.clean ? "views:build" : false
|
||||
].filter(t => t),
|
||||
load("tests/visual/generate"))
|
||||
|
||||
/*
|
||||
@ -344,10 +348,9 @@ gulp.task("tests:visual:session", [
|
||||
*/
|
||||
gulp.task("build", [
|
||||
"assets:build",
|
||||
"views:build"
|
||||
].concat(args.mkdocs ? [
|
||||
"mkdocs:build"
|
||||
] : []))
|
||||
"views:build",
|
||||
args.mkdocs ? "mkdocs:build" : false
|
||||
].filter(f => f))
|
||||
|
||||
/*
|
||||
* Clean assets and documentation
|
||||
@ -371,10 +374,6 @@ gulp.task("watch", [
|
||||
if (args.mkdocs)
|
||||
gulp.start("mkdocs:serve")
|
||||
|
||||
/* Start karma test runner */
|
||||
// if (args.karma)
|
||||
// gulp.start("tests:unit:watch")
|
||||
|
||||
/* Rebuild stylesheets */
|
||||
gulp.watch([
|
||||
`${config.assets.src}/stylesheets/**/*.scss`
|
||||
|
@ -28,7 +28,7 @@ import changed from "gulp-changed"
|
||||
|
||||
export default (gulp, config) => {
|
||||
return () => {
|
||||
return gulp.src(`${config.assets.src}/images/**/*.ico`)
|
||||
return gulp.src(`${config.assets.src}/images/**/favicon.*`)
|
||||
.pipe(changed(`${config.assets.build}/images`))
|
||||
.pipe(gulp.dest(`${config.assets.build}/images`))
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ import vinyl from "vinyl-paths"
|
||||
|
||||
export default (gulp, config) => {
|
||||
return () => {
|
||||
return gulp.src(`${config.views.build}/**/*.html`)
|
||||
return gulp.src(`${config.views.build}/**/*.{html,py}`)
|
||||
.pipe(vinyl(clean))
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{% extends "main.html" %}
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1>404 - Not found</h1>
|
||||
{% endblock %}
|
||||
|
BIN
material/assets/images/favicon.png
Normal file
BIN
material/assets/images/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
3
material/assets/javascripts/application-30ac6a1727.js
Normal file
3
material/assets/javascripts/application-30ac6a1727.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
material/assets/stylesheets/application-45f91e8d31.css
Normal file
1
material/assets/stylesheets/application-45f91e8d31.css
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -17,15 +17,13 @@
|
||||
{% if config.site_favicon %}
|
||||
<link rel="shortcut icon" href="{{ base_url }}/{{ config.site_favicon }}">
|
||||
{% else %}
|
||||
<link rel="shortcut icon" href="{{ base_url }}/assets/images/favicon.ico">
|
||||
<link rel="shortcut icon" href="{{ base_url }}/assets/images/favicon.png">
|
||||
{% endif %}
|
||||
<meta name="generator" content="mkdocs-{{ mkdocs_version }}, mkdocs-material-1.0.5">
|
||||
{% endblock %}
|
||||
{% block htmltitle %}
|
||||
{% if page.title %}
|
||||
{% if page.title and not page.is_homepage %}
|
||||
<title>{{ page.title }} - {{ config.site_name }}</title>
|
||||
{% elif config.site_description %}
|
||||
<title>{{ config.site_name }} - {{ config.site_description }}</title>
|
||||
{% else %}
|
||||
<title>{{ config.site_name }}</title>
|
||||
{% endif %}
|
||||
@ -34,9 +32,9 @@
|
||||
<script src="{{ base_url }}/assets/javascripts/modernizr-56ade86843.js"></script>
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-a7dac97dbb.css">
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-45f91e8d31.css">
|
||||
{% if config.extra.palette %}
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-02ce7adcc2.palette.css">
|
||||
<link rel="stylesheet" href="{{ base_url }}/assets/stylesheets/application-49c4a440b6.palette.css">
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block fonts %}
|
||||
@ -82,6 +80,10 @@
|
||||
{% include "partials/header.html" %}
|
||||
{% endblock %}
|
||||
<div class="md-container">
|
||||
{% set feature = config.extra.get("feature", {}) %}
|
||||
{% if feature.tabs %}
|
||||
{% include "partials/tabs.html" %}
|
||||
{% endif %}
|
||||
<main class="md-main">
|
||||
<div class="md-main__inner md-grid" data-md-component="container">
|
||||
{% block site_nav %}
|
||||
@ -141,7 +143,7 @@
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% block scripts %}
|
||||
<script src="{{ base_url }}/assets/javascripts/application-8dc3dfc020.js"></script>
|
||||
<script src="{{ base_url }}/assets/javascripts/application-30ac6a1727.js"></script>
|
||||
<script>app.initialize({url:{base:"{{ base_url }}"}})</script>
|
||||
{% for path in extra_javascript %}
|
||||
<script src="{{ path }}"></script>
|
||||
|
@ -2,11 +2,14 @@
|
||||
<nav class="md-header-nav md-grid">
|
||||
<div class="md-flex">
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}" class="{% if config.extra.logo %} md-logo {% else %} md-icon md-icon--home {% endif %} md-header-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}" class="md-logo md-header-nav__button">
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}" width="24" height="24">
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}" class="md-icon md-icon--home md-header-nav__button">
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
<label class="md-icon md-icon--menu md-header-nav__button" for="drawer"></label>
|
||||
|
@ -8,14 +8,15 @@
|
||||
<label class="md-nav__link" for="{{ path }}">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
<nav class="md-nav" data-md-component="collapsible">
|
||||
<nav class="md-nav" data-md-component="collapsible" data-md-level="{{ level }}">
|
||||
<label class="md-nav__title" for="{{ path }}">
|
||||
{{ nav_item.title}}
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
<ul class="md-nav__list" data-md-scrollfix>
|
||||
{% set base = path %}
|
||||
{% for nav_item in nav_item.children %}
|
||||
{% set path = base + "-" + loop.index | string %}
|
||||
{% set level = level + 1 %}
|
||||
{% include "partials/nav-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
@ -1,10 +1,12 @@
|
||||
<nav class="md-nav md-nav--primary">
|
||||
<nav class="md-nav md-nav--primary" data-md-level="0">
|
||||
<label class="md-nav__title md-nav__title--site" for="drawer">
|
||||
<i class="{% if config.extra.logo %} md-logo {% else %} md-icon md-icon--home {% endif %} md-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
<i class="md-logo md-nav__button">
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}">
|
||||
{% endif %}
|
||||
</i>
|
||||
{% else %}
|
||||
<i class="md-icon md-icon--home md-nav__button"></i>
|
||||
{% endif %}
|
||||
{{ config.site_name }}
|
||||
</label>
|
||||
{% if config.repo_url %}
|
||||
@ -15,6 +17,7 @@
|
||||
<ul class="md-nav__list" data-md-scrollfix>
|
||||
{% for nav_item in nav %}
|
||||
{% set path = "nav-" + loop.index | string %}
|
||||
{% set level = 1 %}
|
||||
{% include "partials/nav-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
25
material/partials/tabs-item.html
Normal file
25
material/partials/tabs-item.html
Normal file
@ -0,0 +1,25 @@
|
||||
{% if nav_item.is_homepage %}
|
||||
<li class="md-tabs__item">
|
||||
{% if not page.ancestors | length and nav | selectattr("url", page.url) %}
|
||||
<a href="{{ nav_item.url }}" title="{{ nav_item.title }}" class="md-tabs__link md-tabs__link--active">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ nav_item.url }}" title="{{ nav_item.title }}" class="md-tabs__link">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% elif nav_item.children and nav_item.children | length > 0 %}
|
||||
<li class="md-tabs__item">
|
||||
{% if nav_item.active %}
|
||||
<a href="{{ (nav_item.children | first).url }}" title="{{ nav_item.title }}" class="md-tabs__link md-tabs__link--active">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ (nav_item.children | first).url }}" title="{{ nav_item.title }}" class="md-tabs__link">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
13
material/partials/tabs.html
Normal file
13
material/partials/tabs.html
Normal file
@ -0,0 +1,13 @@
|
||||
{% set class = "md-tabs" %}
|
||||
{% if page.ancestors | length > 0 %}
|
||||
{% set class = "md-tabs md-tabs--active" %}
|
||||
{% endif %}
|
||||
<nav class="{{ class }}" data-md-component="tabs">
|
||||
<div class="md-tabs__inner md-grid">
|
||||
<ul class="md-tabs__list">
|
||||
{% for nav_item in nav %}
|
||||
{% include "partials/tabs-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
@ -28,4 +28,5 @@ if [[ ! -d `npm bin` ]]; then
|
||||
fi
|
||||
|
||||
# Run command
|
||||
`npm bin`/gulp clean && \
|
||||
`npm bin`/gulp watch --no-lint "$@"
|
||||
|
@ -20,7 +20,7 @@
|
||||
IN THE SOFTWARE.
|
||||
-->
|
||||
|
||||
{% extends "main.html" %}
|
||||
{% extends "base.html" %}
|
||||
|
||||
<!-- Content block -->
|
||||
{% block content %}
|
||||
|
BIN
src/assets/images/favicon.png
Normal file
BIN
src/assets/images/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -83,14 +83,31 @@ function initialize(config) { // eslint-disable-line func-style
|
||||
}
|
||||
}).listen()
|
||||
|
||||
/* Component: header shadow toggle */
|
||||
new Material.Event.MatchMedia("(min-width: 1220px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Header.Shadow("[data-md-component=container]")))
|
||||
|
||||
/* Component: tabs visibility toggle */
|
||||
if (document.querySelector("[data-md-component=tabs]"))
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Tabs.Toggle("[data-md-component=tabs]")).listen()
|
||||
|
||||
/* Component: sidebar with navigation */
|
||||
new Material.Event.MatchMedia("(min-width: 1220px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Sidebar.Position("[data-md-component=navigation]")))
|
||||
|
||||
/* Component: sidebar with table of contents */
|
||||
new Material.Event.MatchMedia("(min-width: 960px)",
|
||||
/* Component: sidebar with table of contents - register two separate
|
||||
listeners, as the offset at the top might change */
|
||||
new Material.Event.MatchMedia("(min-width: 960px) and (max-width: 1219px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Sidebar.Position("[data-md-component=toc]")))
|
||||
new Material.Event.MatchMedia("(min-width: 1220px)",
|
||||
new Material.Event.Listener(window, [
|
||||
"scroll", "resize", "orientationchange"
|
||||
], new Material.Sidebar.Position("[data-md-component=toc]")))
|
||||
@ -98,7 +115,7 @@ function initialize(config) { // eslint-disable-line func-style
|
||||
/* 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 =
|
||||
|
@ -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
|
||||
}
|
||||
|
31
src/assets/javascripts/components/Material/Header.js
Normal file
31
src/assets/javascripts/components/Material/Header.js
Normal 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
|
||||
}
|
91
src/assets/javascripts/components/Material/Header/Shadow.js
Normal file
91
src/assets/javascripts/components/Material/Header/Shadow.js
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 or hide header shadow depending on page y-offset
|
||||
*
|
||||
* @constructor
|
||||
*
|
||||
* @property {HTMLElement} el_ - Content container
|
||||
* @property {HTMLElement} header_ - Header
|
||||
* @property {number} height_ - Offset height of previous nodes
|
||||
* @property {boolean} active_ - Header shadow state
|
||||
*
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
*/
|
||||
constructor(el) {
|
||||
const ref = (typeof el === "string")
|
||||
? document.querySelector(el)
|
||||
: el
|
||||
if (!(ref instanceof HTMLElement) ||
|
||||
!(ref.parentNode instanceof HTMLElement))
|
||||
throw new ReferenceError
|
||||
|
||||
/* Grab parent and header */
|
||||
this.el_ = ref.parentNode
|
||||
if (!(this.el_.parentNode instanceof HTMLElement) ||
|
||||
!(this.el_.parentNode.previousElementSibling instanceof HTMLElement))
|
||||
throw new ReferenceError
|
||||
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)) {
|
||||
if (!(current instanceof HTMLElement))
|
||||
throw new ReferenceError
|
||||
this.height_ += current.offsetHeight
|
||||
}
|
||||
this.update()
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@ export default class Position {
|
||||
* Initialize sidebar state
|
||||
*/
|
||||
setup() {
|
||||
this.offset_ = this.el_.offsetTop - this.parent_.offsetTop
|
||||
this.offset_ = this.el_.offsetTop - 56
|
||||
this.update()
|
||||
}
|
||||
|
||||
@ -65,18 +65,18 @@ export default class Position {
|
||||
*
|
||||
* The inner height of the window (= the visible area) is the maximum
|
||||
* possible height for the stretching sidebar. This height must be deducted
|
||||
* by the top offset of the parent container, which accounts for the fixed
|
||||
* header, setting the baseline. Depending on the page y-offset, the top
|
||||
* offset of the sidebar must be taken into account, as well as the case
|
||||
* where the window is scrolled beyond the sidebar container.
|
||||
* by the height of the fixed header (56px). Depending on the page y-offset,
|
||||
* the top offset of the sidebar must be taken into account, as well as the
|
||||
* case where the window is scrolled beyond the sidebar container.
|
||||
*/
|
||||
update() {
|
||||
const offset = window.pageYOffset
|
||||
const visible = window.innerHeight
|
||||
|
||||
/* Calculate bounds of sidebar container */
|
||||
/* Set bounds of sidebar container - must be calculated on every run, as
|
||||
the height of the content might change due to loading images etc. */
|
||||
const bounds = {
|
||||
top: this.parent_.offsetTop,
|
||||
top: 56,
|
||||
bottom: this.parent_.offsetTop + this.parent_.offsetHeight
|
||||
}
|
||||
|
||||
|
31
src/assets/javascripts/components/Material/Tabs.js
Normal file
31
src/assets/javascripts/components/Material/Tabs.js
Normal 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
|
||||
}
|
69
src/assets/javascripts/components/Material/Tabs/Toggle.js
Normal file
69
src/assets/javascripts/components/Material/Tabs/Toggle.js
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Toggle tabs visibility depending on page y-offset
|
||||
*
|
||||
* @constructor
|
||||
*
|
||||
* @property {HTMLElement} el_ - Content container
|
||||
* @property {number} offset_ - Toggle page-y offset
|
||||
* @property {boolean} active_ - Tabs visibility
|
||||
*
|
||||
* @param {(string|HTMLElement)} el - Selector or HTML element
|
||||
*/
|
||||
constructor(el) {
|
||||
const ref = (typeof el === "string")
|
||||
? document.querySelector(el)
|
||||
: el
|
||||
if (!(ref instanceof Node))
|
||||
throw new ReferenceError
|
||||
this.el_ = ref
|
||||
|
||||
/* Initialize offset and state */
|
||||
this.offset_ = 5
|
||||
this.active_ = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Update visibility
|
||||
*/
|
||||
update() {
|
||||
const active = window.pageYOffset >= this.offset_
|
||||
if (active !== this.active_)
|
||||
this.el_.dataset.mdState = (this.active_ = active) ? "hidden" : ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset visibility
|
||||
*/
|
||||
reset() {
|
||||
this.el_.dataset.mdState = ""
|
||||
this.active_ = false
|
||||
}
|
||||
}
|
@ -135,6 +135,20 @@ button[data-md-color-accent] {
|
||||
border-left: 0.4rem solid $color;
|
||||
}
|
||||
}
|
||||
|
||||
// [screen +]: Set background color for tabs
|
||||
@include break-from-device(screen) {
|
||||
|
||||
// Tabs with outline
|
||||
.md-tabs {
|
||||
background: mix($color, $md-color-black, 75%);
|
||||
|
||||
// Fade-out tabs background upon scrolling
|
||||
&[data-md-state="hidden"] {
|
||||
background: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
||||
@import "layout/search";
|
||||
@import "layout/sidebar";
|
||||
@import "layout/source";
|
||||
@import "layout/tabs";
|
||||
|
||||
@import "extensions/admonition";
|
||||
@import "extensions/codehilite";
|
||||
|
@ -85,7 +85,7 @@
|
||||
padding-top: 0.8rem;
|
||||
|
||||
// Hide anchor for top-level heading, as it makes no sense
|
||||
&.headerlink {
|
||||
.headerlink {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,21 @@
|
||||
color: $md-color-white;
|
||||
z-index: 1;
|
||||
|
||||
// Always show shadow, in case JavaScript is not available
|
||||
.no-js & {
|
||||
@include z-depth(2);
|
||||
}
|
||||
|
||||
// [screen +]: Show shadow depending on scroll offset
|
||||
@include break-from-device(screen) {
|
||||
box-shadow: none;
|
||||
|
||||
// Show and animate shadow
|
||||
&[data-md-state="shadow"] {
|
||||
@include z-depth(2);
|
||||
}
|
||||
}
|
||||
|
||||
// Hide for print
|
||||
@media print {
|
||||
display: none;
|
||||
|
@ -66,7 +66,7 @@
|
||||
|
||||
// List item
|
||||
&__item {
|
||||
padding: 0.625em 1.2rem 0;
|
||||
padding: 0 1.2rem;
|
||||
|
||||
// Add bottom spacing to last item
|
||||
&:last-child {
|
||||
@ -98,6 +98,7 @@
|
||||
// Link inside item
|
||||
&__link {
|
||||
display: block;
|
||||
margin-top: 0.625em;
|
||||
transition: color 0.125s;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
@ -283,6 +284,7 @@
|
||||
// Link inside item
|
||||
.md-nav__link {
|
||||
position: relative;
|
||||
margin-top: 0;
|
||||
padding: 1.6rem;
|
||||
|
||||
// Rotate icon
|
||||
@ -424,7 +426,8 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Link inside item
|
||||
// Link inside item - ideally the link display method would be set to
|
||||
// inline on screen, but this doesn't work with text ellipsis
|
||||
&__link {
|
||||
|
||||
// Item contains a nested list
|
||||
|
@ -112,6 +112,9 @@
|
||||
max-height: 100%;
|
||||
margin: 0 0.4rem;
|
||||
overflow-y: auto;
|
||||
// Hack: putting the scroll wrapper on the GPU massively reduces jitter
|
||||
// when locking the sidebars into place
|
||||
backface-visibility: hidden;
|
||||
|
||||
// [tablet -]: Adjust margins
|
||||
@include break-to-device(tablet) {
|
||||
|
153
src/assets/stylesheets/layout/_tabs.scss
Normal file
153
src/assets/stylesheets/layout/_tabs.scss
Normal file
@ -0,0 +1,153 @@
|
||||
////
|
||||
/// 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%;
|
||||
transition: background 0.25s;
|
||||
background: mix($md-color-primary, $md-color-black, 75%);
|
||||
overflow: auto;
|
||||
|
||||
// [tablet -]: Hide tabs for tablet and below, as they don't make any sense
|
||||
@include break-to-device(tablet) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// List of items
|
||||
&__list {
|
||||
margin: 0;
|
||||
margin-left: 0.4rem;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// List item
|
||||
&__item {
|
||||
display: inline-block;
|
||||
height: 4.8rem;
|
||||
padding-right: 1.2rem;
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
|
||||
// Link inside item - could be defined as block elements and aligned via
|
||||
// line height, but this would imply more repaints when scrolling
|
||||
&__link {
|
||||
display: block;
|
||||
margin-top: 1.6rem;
|
||||
transition:
|
||||
color 0.25s,
|
||||
transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1),
|
||||
opacity 0.1s;
|
||||
color: $md-color-white--light;
|
||||
font-size: 1.4rem;
|
||||
|
||||
// Active or hovered link
|
||||
&--active,
|
||||
&:hover {
|
||||
color: $md-color-white;
|
||||
}
|
||||
|
||||
// Delay transitions by a small amount
|
||||
@for $i from 2 through 16 {
|
||||
.md-tabs__item:nth-child(#{$i}) & {
|
||||
transition-delay: 0.02s * ($i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fade-out tabs background upon scrolling
|
||||
&[data-md-state="hidden"] {
|
||||
background: $md-color-primary;
|
||||
|
||||
// Hide tabs upon scrolling - disable transition to minimizes repaints whilte
|
||||
// scrolling down, while scrolling up seems to be okay
|
||||
.md-tabs__link {
|
||||
transform: translateY(50%);
|
||||
transition:
|
||||
color 0.25s,
|
||||
transform 0s 0.4s,
|
||||
opacity 0.1s;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// [screen +]: Adjust main navigation styles
|
||||
@include break-from-device(screen) {
|
||||
|
||||
// Hide 1st level nested items, as they are listed in the tabs by setting
|
||||
// font-size to zero, as we need to preserve bottom padding
|
||||
~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
// We're on the 2nd+ level
|
||||
&--active ~ .md-main {
|
||||
|
||||
// Adjust 1st level styles
|
||||
.md-nav--primary {
|
||||
|
||||
// Hide site title
|
||||
.md-nav__title--site {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Hide 1st level normal items
|
||||
& > .md-nav__list > .md-nav__item {
|
||||
font-size: 0;
|
||||
|
||||
// Show 1st level nested items and induce margin collapse
|
||||
&--nested {
|
||||
font-size: 1.4rem;
|
||||
overflow: auto;
|
||||
|
||||
// Render link same as main navigation title
|
||||
> .md-nav__link {
|
||||
margin-top: 1.2rem;
|
||||
font-weight: 700;
|
||||
pointer-events: none;
|
||||
|
||||
// Hide icon for expansion
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Always expand nested navigation on 2nd level
|
||||
.md-nav[data-md-level="1"] {
|
||||
max-height: initial;
|
||||
|
||||
// Remove left spacing on 2nd level items
|
||||
> .md-nav__list > .md-nav__item {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -52,7 +52,7 @@
|
||||
href="{{ base_url }}/{{ config.site_favicon }}">
|
||||
{% else %}
|
||||
<link rel="shortcut icon"
|
||||
href="{{ base_url }}/assets/images/favicon.ico">
|
||||
href="{{ base_url }}/assets/images/favicon.png">
|
||||
{% endif %}
|
||||
|
||||
<!-- Generator banner -->
|
||||
@ -62,10 +62,8 @@
|
||||
|
||||
<!-- Block: site title -->
|
||||
{% block htmltitle %}
|
||||
{% if page.title %}
|
||||
{% if page.title and not page.is_homepage %}
|
||||
<title>{{ page.title }} - {{ config.site_name }}</title>
|
||||
{% elif config.site_description %}
|
||||
<title>{{ config.site_name }} - {{ config.site_description }}</title>
|
||||
{% else %}
|
||||
<title>{{ config.site_name }}</title>
|
||||
{% endif %}
|
||||
@ -171,6 +169,10 @@
|
||||
|
||||
<!-- Container, necessary for web-application context -->
|
||||
<div class="md-container">
|
||||
{% set feature = config.extra.get("feature", {}) %}
|
||||
{% if feature.tabs %}
|
||||
{% include "partials/tabs.html" %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Main container -->
|
||||
<main class="md-main">
|
||||
|
@ -29,18 +29,17 @@
|
||||
|
||||
<!-- Link to home -->
|
||||
<div class="md-flex__cell md-flex__cell--shrink">
|
||||
{% if config.extra.logo %}
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}"
|
||||
class="
|
||||
{% if config.extra.logo %}
|
||||
md-logo
|
||||
{% else %}
|
||||
md-icon md-icon--home
|
||||
{% endif %} md-header-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
class="md-logo md-header-nav__button">
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}"
|
||||
width="24" height="24" />
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ nav.homepage.url }}" title="{{ config.site_name }}"
|
||||
class="md-icon md-icon--home md-header-nav__button">
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Button to toggle drawer -->
|
||||
|
@ -37,9 +37,10 @@
|
||||
<label class="md-nav__link" for="{{ path }}">
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
<nav class="md-nav" data-md-component="collapsible">
|
||||
<nav class="md-nav" data-md-component="collapsible"
|
||||
data-md-level="{{ level }}">
|
||||
<label class="md-nav__title" for="{{ path }}">
|
||||
{{ nav_item.title}}
|
||||
{{ nav_item.title }}
|
||||
</label>
|
||||
<ul class="md-nav__list" data-md-scrollfix>
|
||||
|
||||
@ -47,6 +48,7 @@
|
||||
{% set base = path %}
|
||||
{% for nav_item in nav_item.children %}
|
||||
{% set path = base + "-" + loop.index | string %}
|
||||
{% set level = level + 1 %}
|
||||
{% include "partials/nav-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
@ -21,28 +21,32 @@
|
||||
-->
|
||||
|
||||
<!-- Main navigation -->
|
||||
<nav class="md-nav md-nav--primary">
|
||||
<nav class="md-nav md-nav--primary" data-md-level="0">
|
||||
|
||||
<!-- Site title -->
|
||||
<label class="md-nav__title md-nav__title--site" for="drawer">
|
||||
<i class="
|
||||
{% if config.extra.logo %}
|
||||
md-logo
|
||||
{% else %}
|
||||
md-icon md-icon--home
|
||||
{% endif %} md-nav__button">
|
||||
{% if config.extra.logo %}
|
||||
<i class="md-logo md-nav__button">
|
||||
<img src="{{ base_url }}/{{ config.extra.logo }}" />
|
||||
{% endif %}
|
||||
</i>
|
||||
{% else %}
|
||||
<i class="md-icon md-icon--home md-nav__button"></i>
|
||||
{% endif %}
|
||||
{{ config.site_name }}
|
||||
</label>
|
||||
|
||||
<!-- Repository containing source -->
|
||||
{% if config.repo_url %}
|
||||
<div class="md-nav__source">
|
||||
{% include "partials/source.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Render item list -->
|
||||
<ul class="md-nav__list" data-md-scrollfix>
|
||||
{% for nav_item in nav %}
|
||||
{% set path = "nav-" + loop.index | string %}
|
||||
{% set level = 1 %}
|
||||
{% include "partials/nav-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
55
src/partials/tabs-item.html
Normal file
55
src/partials/tabs-item.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- Home page -->
|
||||
{% if nav_item.is_homepage %}
|
||||
<li class="md-tabs__item">
|
||||
{% if not page.ancestors | length and nav | selectattr("url", page.url) %}
|
||||
<a href="{{ nav_item.url }}" title="{{ nav_item.title }}"
|
||||
class="md-tabs__link md-tabs__link--active">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ nav_item.url }}" title="{{ nav_item.title }}"
|
||||
class="md-tabs__link">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
|
||||
<!-- Main navigation item with nested items -->
|
||||
{% elif nav_item.children and nav_item.children | length > 0 %}
|
||||
<li class="md-tabs__item">
|
||||
{% if nav_item.active %}
|
||||
<a href="{{ (nav_item.children | first).url }}"
|
||||
title="{{ nav_item.title }}"
|
||||
class="md-tabs__link md-tabs__link--active">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ (nav_item.children | first).url }}"
|
||||
title="{{ nav_item.title }}" class="md-tabs__link">
|
||||
{{ nav_item.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
38
src/partials/tabs.html
Normal file
38
src/partials/tabs.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- Determine class according to level -->
|
||||
{% set class = "md-tabs" %}
|
||||
{% if page.ancestors | length > 0 %}
|
||||
{% set class = "md-tabs md-tabs--active" %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Tabs with outline -->
|
||||
<nav class="{{ class }}" data-md-component="tabs">
|
||||
<div class="md-tabs__inner md-grid">
|
||||
<ul class="md-tabs__list">
|
||||
{% for nav_item in nav %}
|
||||
{% include "partials/tabs-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
Loading…
Reference in New Issue
Block a user