From 5fe7a86151473a12ec82d3756ae3f1dde871f032 Mon Sep 17 00:00:00 2001 From: polandll Date: Thu, 15 Oct 2020 20:50:52 -0700 Subject: [PATCH] add tabs codeblock ui --- src/css/site.css | 1 + src/css/tabs.css | 72 +++++++++++++++++++++++++++++++++++++++++ src/js/06-tabs-block.js | 50 ++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 src/css/tabs.css create mode 100644 src/js/06-tabs-block.js diff --git a/src/css/site.css b/src/css/site.css index 5b02791f..6afd189d 100644 --- a/src/css/site.css +++ b/src/css/site.css @@ -16,3 +16,4 @@ @import "highlight.css"; @import "print.css"; @import "typeface-nunito.css"; +@import "tabs.css"; diff --git a/src/css/tabs.css b/src/css/tabs.css new file mode 100644 index 00000000..69fb118f --- /dev/null +++ b/src/css/tabs.css @@ -0,0 +1,72 @@ +.tabset { + margin-bottom: 20px; + margin-top: 20px; +} + +.tabs ul { + display: flex; + flex-wrap: wrap; + list-style: none; + margin: 0 -0.25rem 0 0; + padding: 0; +} + +.tabs li { + align-items: center; + border-bottom: 0; + border: 1px solid #808080; + cursor: pointer; + display: flex; + font-weight: bold; + height: 2.5rem; + line-height: 1; + margin-right: 0.25rem; + padding: 0 1.5rem; + position: relative; +} + +.tabs.ulist li { + margin-bottom: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +.tabs li + li { + margin-top: 0; +} + +.tabset.is-loading .tabs li:not(:first-child), +.tabset:not(.is-loading) .tabs li:not(.is-active) { + background-color: #fafafa; + color: #8e8e8e; + font-weight: normal; +} + +.tabset.is-loading .tabs li:first-child::after, +.tabs li.is-active::after { + background-color: white; + content: ""; + display: block; + height: 3px; /* Chrome doesn't always paint the line accurately, so add a little extra */ + position: absolute; + bottom: -1.5px; + left: 0; + right: 0; +} + +.tabset > .content { + border: 1px solid gray; + padding: 1.25rem; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} + +.tabset.is-loading .tab-pane:not(:first-child), +.tabset:not(.is-loading) .tab-pane:not(.is-active) { + display: none; +} + +.tab-pane > :first-child { + margin-top: 0; +} diff --git a/src/js/06-tabs-block.js b/src/js/06-tabs-block.js new file mode 100644 index 00000000..2b88fecb --- /dev/null +++ b/src/js/06-tabs-block.js @@ -0,0 +1,50 @@ +;(function () { + 'use strict' + + var hash = window.location.hash + find('.tabset').forEach(function (tabset) { + var active + var tabs = tabset.querySelector('.tabs') + if (tabs) { + var first + find('li', tabs).forEach(function (tab, idx) { + var id = (tab.querySelector('a[id]') || tab).id + if (!id) return + var pane = getPane(id, tabset) + if (!idx) first = { tab: tab, pane: pane } + if (!active && hash === '#' + id && (active = true)) { + tab.classList.add('is-active') + if (pane) pane.classList.add('is-active') + } else if (!idx) { + tab.classList.remove('is-active') + if (pane) pane.classList.remove('is-active') + } + tab.addEventListener('click', activateTab.bind({ tabset: tabset, tab: tab, pane: pane })) + }) + if (!active && first) { + first.tab.classList.add('is-active') + if (first.pane) first.pane.classList.add('is-active') + } + } + tabset.classList.remove('is-loading') + }) + + function activateTab (e) { + var tab = this.tab + var pane = this.pane + find('.tabs li, .tab-pane', this.tabset).forEach(function (it) { + it === tab || it === pane ? it.classList.add('is-active') : it.classList.remove('is-active') + }) + e.preventDefault() + } + + function find (selector, from) { + return Array.prototype.slice.call((from || document).querySelectorAll(selector)) + } + + function getPane (id, tabset) { + return find('.tab-pane', tabset).find(function (it) { + return it.getAttribute('aria-labelledby') === id + }) + } +})()