diff --git a/bookwyrm/static/css/bookwyrm.css b/bookwyrm/static/css/bookwyrm.css index ed03aa7b1..303bc031c 100644 --- a/bookwyrm/static/css/bookwyrm.css +++ b/bookwyrm/static/css/bookwyrm.css @@ -301,6 +301,183 @@ details.dropdown .dropdown-menu a:focus-visible { } } +/** Bookwyrm Tabs + ******************************************************************************/ + +.bw-tabs { + -webkit-overflow-scrolling: touch; + -webkit-touch-callout: none; + position: relative; + align-items: center; + display: flex; + font-size: 1rem; + justify-content: flex-start; + overflow-x: auto; + overflow-y: hidden; + user-select: none; + white-space: nowrap; +} + +.bw-tabs::before { + border-bottom-color: #dbdbdb; + border-bottom-style: solid; + border-bottom-width: 1px; + bottom: 0; + content: ""; + position: absolute; + width: 100%; +} + +.bw-tabs:not(:last-child) { + margin-bottom: 1.5rem; +} + +.bw-tabs a { + align-items: center; + border-bottom-color: #dbdbdb; + border-bottom-style: solid; + border-bottom-width: 1px; + color: #4a4a4a; + display: flex; + justify-content: center; + margin-bottom: -1px; + padding: 0.5em 1em; + position: relative; +} + +.bw-tabs a:hover { + border-bottom-color: transparent; + color: #363636; +} + +.bw-tabs a.is-active { + border-bottom-color: transparent; + color: #3273dc; +} + +.bw-tabs.is-left { + padding-right: 0.75em; +} + +.bw-tabs.is-center { + flex: none; + justify-content: center; + padding-left: 0.75em; + padding-right: 0.75em; +} + +.bw-tabs.is-right { + justify-content: flex-end; + padding-left: 0.75em; +} + +.bw-tabs .icon:first-child { + margin-right: 0.5em; +} + +.bw-tabs .icon:last-child { + margin-left: 0.5em; +} + +.bw-tabs.is-centered { + justify-content: center; +} + +.bw-tabs.is-boxed a { + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.bw-tabs.is-boxed a:hover { + background-color: #f5f5f5; + border-bottom-color: #dbdbdb; +} + +.bw-tabs.is-boxed a.is-active { + background-color: #fff; + border-color: #dbdbdb; + border-bottom-color: #fff !important; +} + +.bw-tabs.is-fullwidth a { + flex-grow: 1; + flex-shrink: 0; +} + +.bw-tabs.is-toggle a { + border-color: #dbdbdb; + border-style: solid; + border-width: 1px; + margin-bottom: 0; + position: relative; +} + +.bw-tabs.is-toggle a:hover { + background-color: #f5f5f5; + border-color: #b5b5b5; + z-index: 2; +} + +.bw-tabs.is-toggle a + a { + margin-left: -1px; +} + +.bw-tabs.is-toggle a:first-child { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.bw-tabs.is-toggle a:last-child { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.bw-tabs.is-toggle a.is-active { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; + z-index: 1; +} + +.bw-tabs.is-toggle { + border-bottom: none; +} + +.bw-tabs.is-toggle.is-toggle-rounded a:first-child { + border-bottom-left-radius: 290486px; + border-top-left-radius: 290486px; + padding-left: 1.25em; +} + +.bw-tabs.is-toggle.is-toggle-rounded a:last-child { + border-bottom-right-radius: 290486px; + border-top-right-radius: 290486px; + padding-right: 1.25em; +} + +.bw-tabs.is-small { + font-size: 0.75rem; +} + +.bw-tabs.is-medium { + font-size: 1.25rem; +} + +.bw-tabs.is-large { + font-size: 1.5rem; +} + +.bw-tabs.has-aside-text a { + margin-top: 1.5rem; +} + +.bw-tabs a .aside-text { + position: absolute; + top: calc(-0.75rem - 0.75rem); + left: 0; + color: #4a4a4a; +} + /** Details panel ******************************************************************************/ diff --git a/bookwyrm/static/js/vendor/tabs.js b/bookwyrm/static/js/vendor/tabs.js index f9568b29f..0535cc869 100644 --- a/bookwyrm/static/js/vendor/tabs.js +++ b/bookwyrm/static/js/vendor/tabs.js @@ -11,17 +11,17 @@ class TabGroup { this.container = container; this.tablist = this.container.querySelector('[role="tablist"]'); - this.buttons = this.tablist.querySelectorAll('[role="tab"]'); + this.tabs = this.tablist.querySelectorAll('[role="tab"]'); this.panels = this.container.querySelectorAll(':scope > [role="tabpanel"]'); this.delay = this.determineDelay(); - if(!this.tablist || !this.buttons.length || !this.panels.length) { + if(!this.tablist || !this.tabs.length || !this.panels.length) { return; } this.keys = this.keys(); this.direction = this.direction(); - this.initButtons(); + this.initTabs(); this.initPanels(); } @@ -46,17 +46,21 @@ class TabGroup { }; } - initButtons() { + initTabs() { let count = 0; - for(let button of this.buttons) { - let isSelected = button.getAttribute("aria-selected") === "true"; - button.setAttribute("tabindex", isSelected ? "0" : "-1"); + for(let tab of this.tabs) { + let isSelected = tab.getAttribute("aria-selected") === "true"; + tab.setAttribute("tabindex", isSelected ? "0" : "-1"); - button.addEventListener('click', this.clickEventListener.bind(this)); - button.addEventListener('keydown', this.keydownEventListener.bind(this)); - button.addEventListener('keyup', this.keyupEventListener.bind(this)); + tab.addEventListener('click', this.clickEventListener.bind(this)); + tab.addEventListener('keydown', this.keydownEventListener.bind(this)); + tab.addEventListener('keyup', this.keyupEventListener.bind(this)); - button.index = count++; + if (isSelected) { + tab.scrollIntoView(); + } + + tab.index = count++; } } @@ -73,11 +77,11 @@ class TabGroup { } clickEventListener(event) { - let button = event.target.closest('a'); + let tab = event.target.closest('[role="tab"]'); event.preventDefault(); - this.activateTab(button, false); + this.activateTab(tab, false); } // Handle keydown on tabs @@ -88,12 +92,12 @@ class TabGroup { case this.keys.end: event.preventDefault(); // Activate last tab - this.activateTab(this.buttons[this.buttons.length - 1]); + this.activateTab(this.tabs[this.tabs.length - 1]); break; case this.keys.home: event.preventDefault(); // Activate first tab - this.activateTab(this.buttons[0]); + this.activateTab(this.tabs[0]); break; // Up and down are in keydown @@ -147,15 +151,15 @@ class TabGroup { switchTabOnArrowPress(event) { var pressed = event.keyCode; - for (let button of this.buttons) { - button.addEventListener('focus', this.focusEventHandler.bind(this)); + for (let tab of this.tabs) { + tab.addEventListener('focus', this.focusEventHandler.bind(this)); } if (this.direction[pressed]) { var target = event.target; if (target.index !== undefined) { - if (this.buttons[target.index + this.direction[pressed]]) { - this.buttons[target.index + this.direction[pressed]].focus(); + if (this.tabs[target.index + this.direction[pressed]]) { + this.tabs[target.index + this.direction[pressed]].focus(); } else if (pressed === this.keys.left || pressed === this.keys.up) { this.focusLastTab(); @@ -184,8 +188,8 @@ class TabGroup { // Set the tab as selected tab.setAttribute('aria-selected', 'true'); - // Give the tab parent an is-active class - tab.parentNode.classList.add('is-active'); + // Give the tab is-active class + tab.classList.add('is-active'); // Get the value of aria-controls (which is an ID) var controls = tab.getAttribute('aria-controls'); @@ -201,11 +205,11 @@ class TabGroup { // Deactivate all tabs and tab panels deactivateTabs() { - for (let button of this.buttons) { - button.parentNode.classList.remove('is-active'); - button.setAttribute('tabindex', '-1'); - button.setAttribute('aria-selected', 'false'); - button.removeEventListener('focus', this.focusEventHandler.bind(this)); + for (let tab of this.tabs) { + tab.classList.remove('is-active'); + tab.setAttribute('tabindex', '-1'); + tab.setAttribute('aria-selected', 'false'); + tab.removeEventListener('focus', this.focusEventHandler.bind(this)); } for (let panel of this.panels) { @@ -214,11 +218,11 @@ class TabGroup { } focusFirstTab() { - this.buttons[0].focus(); + this.tabs[0].focus(); } focusLastTab() { - this.buttons[this.buttons.length - 1].focus(); + this.tabs[this.tabs.length - 1].focus(); } // Determine whether there should be a delay diff --git a/bookwyrm/templates/discover/large-book.html b/bookwyrm/templates/discover/large-book.html index a6ff0aca0..d227502e2 100644 --- a/bookwyrm/templates/discover/large-book.html +++ b/bookwyrm/templates/discover/large-book.html @@ -30,7 +30,7 @@
+