Skip to content

Commit

Permalink
Replace tabbed UI with columns & navigation
Browse files Browse the repository at this point in the history
Issue #116
  • Loading branch information
TomaszGasior committed Apr 29, 2021
1 parent b7c9e7f commit b4abaaf
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 160 deletions.
144 changes: 58 additions & 86 deletions assets/css/part/tabbed-ui.css
Original file line number Diff line number Diff line change
@@ -1,107 +1,79 @@
.JS .tabbed-ui > div {
background: #FAFFF8;
padding: 0.5em 1.2em 0.8em;
border: 1px solid #D2D2D2;
}
.JS .tabbed-ui > div:not(.tabbed-ui-current) {
display: none;
}
/* wrapper */

.tabbed-ui-navigator {
padding-left: 0;
list-style-type: none;
margin: 0 0 -1px;

vertical-align: bottom;
.tabbed-ui-wrapper {
display: grid;
grid-template-columns: 250px 1fr;
grid-gap: 40px;
}
@supports (-webkit-nbsp-mode: initial)

@media (max-width: 800px)
{
.tabbed-ui-navigator {
/* needed for WebKit, not Blink */
margin-bottom: 0;
.tabbed-ui-wrapper {
display: block;
}
}
.tabbed-ui-navigator li {
display: inline;
}
.tabbed-ui-navigator button {
margin-right: 0.4em;
padding: 0.2em 0.9em;
background: #FAFFF8;
border: 1px solid #D2D2D2;
opacity: 0.63;

white-space: nowrap;
display: inline-block;
outline-style: none;
box-shadow: none;
color: inherit;
transition-property: opacity;
width: auto;
font-weight: normal;
margin-top: 0;
}
.tabbed-ui-navigator button:hover {
background: #fff;
color: inherit;
}
.tabbed-ui-navigator button:focus:not(:hover):not(:active) {
opacity: 1;
outline-style: dashed;
}
.tabbed-ui-navigator button.tabbed-ui-current {
opacity: 1;
border-bottom-color: #FAFFF8;
padding-top: 0.6em;
background: #FAFFF8;
}

/* navigation */

@media (max-width: 800px)
{
.tabbed-ui-navigator {
margin-bottom: 0.4em;
}

.tabbed-ui-navigator button {
margin-bottom: 0.5em;
}
.tabbed-ui-navigator button, .tabbed-ui-navigator button.tabbed-ui-current {
padding: 0.2em 0.9em;
border: 1px solid #D2D2D2;
}
.tabbed-ui-navigator li:last-child button {
margin-right: 0;
}
.tabbed-ui-navigator button.tabbed-ui-current {
font-weight: bold;
border-color: #aaa;
.tabbed-ui-navigation {
display: none;
}
}

.tabbed-ui-navigation ol {
list-style: none;
padding-left: 0;
margin: 0;

position: sticky;
top: 20px;
}
.tabbed-ui-navigation a {
display: block;

/* information paragraph in tabbed UI */
border: 1px solid #eee;
background: #fff;
padding: 10px 20px;

.JS .tabbed-ui .information {
box-shadow: none;
padding-top: 1.5em;
padding-bottom: 1.5em;
position: relative;
overflow: hidden;
}
.tabbed-ui-navigation a:hover, .tabbed-ui-navigation a:focus {
background: #f1f1f1;
}
.tabbed-ui-navigation a::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;

@media (max-width: 800px)
{
.JS .tabbed-ui .information {
padding-top: 0.9em;
padding-bottom: 0.9em;
}
background: #ef7f20;
width: 7px;
transform: translateX(-100%);
transition: transform linear 0.1s;
}
.tabbed-ui-navigation a.active::before {
transform: translateX(0);
}
.tabbed-ui-navigation li + li a {
border-top: none;
}
.tabbed-ui-navigation li:first-child a {
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
.tabbed-ui-navigation li:last-child a {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}


/* button in tabbed UI */
/* content */

.JS .tabbed-ui > div > form > button {
margin-top: 1.5em;
margin-bottom: 0.7em;
}
.JS .tabbed-ui + button {
margin-top: 1.3em;
.tabbed-ui div:first-child h2 {
margin-top: 0;
}
108 changes: 34 additions & 74 deletions assets/js/src/TabbedUI.js
Original file line number Diff line number Diff line change
@@ -1,101 +1,61 @@
import '../../css/part/tabbed-ui.css';
import tocbot from 'tocbot';

export class TabbedUI
{
constructor(container)
{
/** @type {!Element} */
this.container = container;
this.panels = [...container.children];
this.navigator = null;
this.buttons = [];

this.setupNavigator();
this.setupPanels();
}
this.wrapper = null;
this.navigation = null;

get LAST_PANEL_SESSION_KEY()
{
return 'tabbed-ui__' + location.pathname;
this.setupMarkup();
this.setupNavigation();
}

setupNavigator()
setupMarkup()
{
this.navigator = document.createElement('ul');
this.navigator.classList.add('tabbed-ui-navigator');
this.navigator.setAttribute('role', 'tablist');

this.panels.forEach((panel, i) => {
let title = panel.querySelector('h2').innerHTML;
let item = document.createElement('li');
let button = document.createElement('button');

button.innerHTML = title;
button.dataset.panelNumber = i;
button.type = 'button';
button.addEventListener('click', this.onNavigatorButtonClick.bind(this));
this.wrapper = document.createElement('div');
this.wrapper.classList.add('tabbed-ui-wrapper');

this.buttons[i] = button;
this.navigation = document.createElement('nav');
this.navigation.classList.add('tabbed-ui-navigation');

item.appendChild(button);
this.navigator.appendChild(item);
});

this.container.insertBefore(this.navigator, this.panels[0]);
this.container.parentNode.replaceChild(this.wrapper, this.container);
this.wrapper.appendChild(this.navigation);
this.wrapper.appendChild(this.container);
}

setupPanels()
setupNavigation()
{
let defaultPanelNumber = 0;

let currentHash = location.hash.replace('#', '');
let savedPanelNumber = sessionStorage.getItem(this.LAST_PANEL_SESSION_KEY);

if (null != savedPanelNumber) {
defaultPanelNumber = savedPanelNumber;
}

this.panels.forEach((panel, i) => {
panel.setAttribute('role', 'tab');

if (currentHash && panel.id == currentHash) {
defaultPanelNumber = i;

// If default panel was determined by URL hash, scroll to
// the top of the page to prevent default browser behavior.
let scrollToTop = () => {
window.scroll(0, 0);
window.removeEventListener('scroll', scrollToTop);
};
window.addEventListener('scroll', scrollToTop);
}
this.container.querySelectorAll('h2').forEach(node => {
node.id = this.slugify(node.textContent);
});

this.changePanel(defaultPanelNumber);
}
tocbot.init({
tocSelector: '.tabbed-ui-navigation',
contentSelector: '.tabbed-ui',
headingSelector: 'h2',

changePanel(panelNumber)
{
this.panels.forEach((panel, i) => {
panel.classList.remove('tabbed-ui-current');
this.buttons[i].classList.remove('tabbed-ui-current');
activeLinkClass: 'active',

if (i == panelNumber) {
panel.classList.add('tabbed-ui-current');
this.buttons[i].classList.add('tabbed-ui-current');
}
basePath: window.location.pathname,
});
}

onNavigatorButtonClick(event)
slugify(string)
{
event.preventDefault();

let button = event.target;
let panelNumber = button.dataset.panelNumber;

button.blur();

this.changePanel(panelNumber);
sessionStorage.setItem(this.LAST_PANEL_SESSION_KEY, panelNumber);
// https://gist.github.com/codeguy/6684588

return string
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.toLowerCase()
.trim()
.replace(/[^a-z0-9 ]/g, '')
.replace(/\s+/g, '-')
;
}
}
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
"dev": "encore dev",
"watch": "encore dev --watch",
"build": "encore production --progress"
},
"dependencies": {
"tocbot": "^4.12.2"
}
}

0 comments on commit b4abaaf

Please sign in to comment.