Skip to content

Commit

Permalink
Refactor tab styles
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianrbz committed Dec 13, 2024
1 parent 242fb47 commit 04c40a8
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 83 deletions.
53 changes: 26 additions & 27 deletions app/_assets/javascripts/components/tabs.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
class TabsComponent {
constructor(elem) {
this.elem = elem;
this.tablistNode = this.elem.querySelector('[role=tablist]');
this.activeTabClasses = ['text-primary', 'font-semibold', 'border-brand'];
this.inactiveTabClasses = ['border-transparent'];
this.tablistNode = this.elem.querySelector("[role=tablist]");
this.activeTabClasses = ["tab-button__horizontal--active"];

this.tabs = Array.from(this.tablistNode.querySelectorAll('[role=tab]'));
this.tabs = Array.from(this.tablistNode.querySelectorAll("[role=tab]"));
this.firstTab = this.tabs[0];
this.lastTab = this.tabs[this.tabs.length - 1];

this.tabs.forEach((tab) => {
tab.addEventListener('keydown', this.onKeydown.bind(this));
tab.addEventListener('click', this.onClick.bind(this));
tab.addEventListener("keydown", this.onKeydown.bind(this));
tab.addEventListener("click", this.onClick.bind(this));
});
// Listen for the custom event to update tabs
document.addEventListener('tabSelected', this.onTabSelected.bind(this));
document.addEventListener("tabSelected", this.onTabSelected.bind(this));

this.setSelectedTab(this.firstTab, false);
}
Expand All @@ -25,22 +24,22 @@ class TabsComponent {
let flag = false;

switch (event.key) {
case 'ArrowLeft':
selectedTab = this.getPreviousTab(tgt)
case "ArrowLeft":
selectedTab = this.getPreviousTab(tgt);
flag = true;
break;

case 'ArrowRight':
selectedTab = this.getNextTab(tgt)
case "ArrowRight":
selectedTab = this.getNextTab(tgt);
flag = true;
break;

case 'Home':
case "Home":
selectedTab = this.firstTab;
flag = true;
break;

case 'End':
case "End":
selectedTab = this.lastTab;
flag = true;
break;
Expand All @@ -67,24 +66,26 @@ class TabsComponent {
}

setSelectedTab(currentTab, setFocus) {
if (typeof setFocus !== 'boolean') {
if (typeof setFocus !== "boolean") {
setFocus = true;
}
this.tabs.forEach((tab) => {
const tabPanel = document.getElementById(tab.getAttribute('aria-controls'));
const tabPanel = document.getElementById(
tab.getAttribute("aria-controls")
);
if (currentTab === tab) {
tab.setAttribute('aria-selected', 'true');
tab.setAttribute("aria-selected", "true");
tab.tabIndex = 0;
this.toggleTabClasses(tab, true);
tabPanel.classList.remove('hidden');
tabPanel.classList.remove("hidden");
if (setFocus) {
tab.focus();
}
} else {
tab.setAttribute('aria-selected', 'false');
tab.setAttribute("aria-selected", "false");
tab.tabIndex = -1;
this.toggleTabClasses(tab, false);
tabPanel.classList.add('hidden');
tabPanel.classList.add("hidden");
}
});
}
Expand All @@ -108,14 +109,14 @@ class TabsComponent {
}

setSelectedTabBySlug(slug, setFocus = true) {
const tab = this.tabs.find(tab => tab.dataset.slug === slug);
const tab = this.tabs.find((tab) => tab.dataset.slug === slug);
if (tab) {
this.setSelectedTab(tab, setFocus);
}
}

dispatchTabSelectedEvent(tabSlug) {
const event = new CustomEvent('tabSelected', { detail: { tabSlug } });
const event = new CustomEvent("tabSelected", { detail: { tabSlug } });
document.dispatchEvent(event);
}

Expand All @@ -127,24 +128,22 @@ class TabsComponent {
toggleTabClasses(tab, isActive) {
if (isActive) {
tab.classList.add(...this.activeTabClasses);
tab.classList.remove(...this.inactiveTabClasses);
} else {
tab.classList.add(...this.inactiveTabClasses);
tab.classList.remove(...this.activeTabClasses);
}
}
}

export default class Tabs {
constructor() {
document.querySelectorAll('.tabs').forEach((elem) => {
document.querySelectorAll(".tabs").forEach((elem) => {
new TabsComponent(elem);
});

// Check if a tab query param exists in the URL
const urlParams = new URLSearchParams(window.location.search);
const tabSlug = urlParams.get('tab');
const formatSlug = urlParams.get('format');
const tabSlug = urlParams.get("tab");
const formatSlug = urlParams.get("format");
if (tabSlug) {
this.selectTabBySlug(tabSlug);
} else if (formatSlug) {
Expand All @@ -153,7 +152,7 @@ export default class Tabs {
}

selectTabBySlug(tabSlug) {
const event = new CustomEvent('tabSelected', { detail: { tabSlug } });
const event = new CustomEvent("tabSelected", { detail: { tabSlug } });
document.dispatchEvent(event);
}
}
63 changes: 30 additions & 33 deletions app/_assets/javascripts/toc.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,46 @@
function toggleTocLinkClasses(link, isActive) {
const activeClasses = ['border-l-2', 'border-brand'];
const activeLinkClasses = ['text-primary', '-ml-0.5'];
const activeClasses = ["tab-button__vertical--active"];

if (isActive) {
link.classList.add(...activeLinkClasses);
link.classList.remove('text-secondary');
link.parentElement.classList.add(...activeClasses);
link.classList.add(...activeClasses);
} else {
link.classList.add('text-secondary');
link.classList.remove(...activeLinkClasses);
link.parentElement.classList.remove(...activeClasses);
link.classList.remove(...activeClasses);
}
}

window.addEventListener("scroll", () => {
const anchors = document.querySelectorAll("a.header-link");
const scrollToLinks = document.querySelectorAll("a.scroll-to");
const navHeight = document.getElementById('header-nav').offsetHeight;
const anchors = document.querySelectorAll("a.header-link");
const scrollToLinks = document.querySelectorAll("a.scroll-to");
const navHeight = document.getElementById("header-nav").offsetHeight;

if (!anchors.length || !scrollToLinks.length) {
return;
}
if (!anchors.length || !scrollToLinks.length) {
return;
}

let activeSet = false;
let activeSet = false;

scrollToLinks.forEach(link => toggleTocLinkClasses(link, false));
scrollToLinks.forEach((link) => toggleTocLinkClasses(link, false));

// Convert NodeList to Array and reverse it
const anchorsArray = Array.from(anchors).reverse();
// Convert NodeList to Array and reverse it
const anchorsArray = Array.from(anchors).reverse();

for (const element of anchorsArray) {
const elementTop = element.getBoundingClientRect().top + window.scrollY;
for (const element of anchorsArray) {
const elementTop = element.getBoundingClientRect().top + window.scrollY;

// window top + header section + extra padding
if (window.scrollY + navHeight + 20 >= elementTop) {
const matchingLink = document.querySelector(`a.scroll-to[href$="${element.getAttribute("href")}"]`);
if (matchingLink) {
toggleTocLinkClasses(matchingLink, true);
activeSet = true;
}
break;
// window top + header section + extra padding
if (window.scrollY + navHeight + 20 >= elementTop) {
const matchingLink = document.querySelector(
`a.scroll-to[href$="${element.getAttribute("href")}"]`
);
if (matchingLink) {
toggleTocLinkClasses(matchingLink, true);
activeSet = true;
}
};

if (!activeSet) {
toggleTocLinkClasses(scrollToLinks[0], true);
break;
}
});
}

if (!activeSet) {
toggleTocLinkClasses(scrollToLinks[0], true);
}
});
32 changes: 32 additions & 0 deletions app/_assets/stylesheets/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,36 @@
.badge.deprecated {
@apply bg-semantic-red-secondary;
}

.tablist {
@apply list-none flex gap-4 text-sm ml-0 flex-row border-b border-primary/5 w-full items-center;
}

.tabcolumn {
@apply list-none flex text-sm ml-0 w-full gap-0;
}

.tab-button {
@apply flex text-sm max-h-11 box-border;
}

.tab-button--active {
@apply text-primary font-semibold border-brand !important;
}

.tab-button__horizontal {
@apply tab-button py-3 text-terciary hover:no-underline items-center;

&.tab-button__horizontal--active {
@apply tab-button--active border-b-2 -mb-0.5 !important;
}
}

.tab-button__vertical {
@apply tab-button py-2 px-5 text-terciary hover:no-underline border-l-2 border-transparent;

&.tab-button__vertical--active {
@apply tab-button--active !important;
}
}
}
4 changes: 2 additions & 2 deletions app/_includes/components/tabs.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% assign tabs = 'navtabs-' | append: navtabs_id %}

<div class="tabs flex flex-col {{ class }} {{ environment['additional_classes'] }}">
<ul class="tablist flex gap-4 text-sm ml-0 flex-row" role="tablist">
<ul class="tablist" role="tablist">
{% for tab in environment[tabs] %}
{% assign slug = tab[1].attributes.slug %}
{% if forloop.first %}
Expand All @@ -11,7 +11,7 @@
{% endif %}
<button
id="navtab-{{ navtabs_id }}-tab-{{ forloop.index }}"
class="py-3 border-b-2"
class="tab-button__horizontal"
aria-controls="navtab-{{ navtabs_id }}-tabpanel-{{ forloop.index }}"
role="tab"
aria-selected="{{ aria_selected }}"
Expand Down
20 changes: 5 additions & 15 deletions app/_includes/layouts/plugins/nav_header.html
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
<header class="w-full">
<div class="flex items-end">
<div class="flex flex-col w-full">
<div class="flex justify-between items-center text-sm">
<ul class="list-none flex align-bottom ml-0 flex-row gap-0">
<li class="px-4 py-3 {% if page.overview? %} border-b-2 border-brand {% endif %}">
<a class="text-primary" href="{{page.overview_url}}">Overview</a>
</li>
<li class="px-4 py-3 {% if page.example? %} border-b-2 border-brand {% endif %}">
<a class="text-primary" href="{{page.get_started_url}}">Get started</a>
</li>
<li class="px-4 py-3 {% if page.reference? %} border-b-2 border-brand {% endif %}">
<a class="text-primary" href="{{page.reference_url}}">Configuration reference</a>
</li>
<li class="px-4 py-3 {% if page.changelog? %} border-b-2 border-brand {% endif %}">
<a class="text-primary" href="{{page.changelog_url}}">Changelog</a>
</li>
</ul>
<div class="tablist">
<a class="tab-button__horizontal{% if page.overview? %} tab-button__horizontal--active{% endif %}" href="{{page.overview_url}}">Overview</a>
<a class="tab-button__horizontal{% if page.example? %} tab-button__horizontal--active{% endif %}" href="{{page.get_started_url}}">Get started</a>
<a class="tab-button__horizontal{% if page.reference? %} tab-button__horizontal--active{% endif %}" href="{{page.reference_url}}">Configuration reference</a>
<a class="tab-button__horizontal{% if page.changelog? %} tab-button__horizontal--active{% endif %}" href="{{page.changelog_url}}">Changelog</a>
</div>
</div>
</div>
Expand Down
7 changes: 3 additions & 4 deletions app/_layouts/plugins/example.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
<nav class="flex gap-8 basis-1/4">
<div class="flex gap-3 flex-col">
<div class="text-sm text-brand font-semibold">Basic use cases</div>
<ul class="flex list-none ml-0">
<ul class="tabcolumn">
{% for example in page.examples %}
{% assign current_page = false %}{% if page.url == example.url %}{% assign current_page = true %}{% endif%}
<li class="flex py-2 px-5 {% if current_page %}border-l-2 border-brand{% endif %}">
<a href="{{ example.url }}" class="text-sm {% if current_page %}text-primary -ml-0.5{% else %}text-secondary{% endif %}">{{ example.title }}</a>
<li>
<a class="tab-button__vertical{% if page.url == example.url %} tab-button__vertical--active{% endif %}" href="{{ example.url }}">{{ example.title }}</a>
</li>
{% endfor %}
</ul>
Expand Down
3 changes: 1 addition & 2 deletions app/_layouts/with_aside.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@

{% if page.toc != false %}
<div class="flex flex-col w-full sticky top-[96px] items-baseline">
{% include toc.html html=content h_min=2 h_max=2 id='toc' item_class='py-2 px-5'
anchor_class='scroll-to text-secondary' class="list-none ml-0" %}
{% include toc.html html=content h_min=2 h_max=2 id='toc' anchor_class='tab-button__vertical scroll-to' class="tabcolumn" %}
</div>
{% endif %}
</aside>
Expand Down

0 comments on commit 04c40a8

Please sign in to comment.