Skip to content

Commit

Permalink
add back in scrolling source tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
greggman committed Mar 13, 2024
1 parent 5b3756c commit 9dc8bbb
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 1 deletion.
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ <h1 id="title"></h1>
<div class="sampleContainer"></div>
</div>
<nav id="code" class="sourceFileNav">
<div class="sourceFileScrollContainer">
<div class="sourceLR" id="sourceL">&lt;</div>
<div id="sourceTabs" class="sourceFileScrollContainer">
<ul id="codeTabs"></ul>
</div>
<div class="sourceLR" id="sourceR">&gt;</div>
</nav>
<div id="sources"></div>
</main>
Expand Down
53 changes: 53 additions & 0 deletions public/css/SampleLayout.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,18 @@
transform: translateY(0.25em);
}

nav.sourceFileNav {
display: flex;
align-items: center;
}

nav.sourceFileNav ul {
box-sizing: border-box;
list-style-type: none;
padding: 0;
margin: 0;
margin-top: 15px;
position: relative;
}

nav.sourceFileNav li {
Expand Down Expand Up @@ -97,12 +103,59 @@ nav.sourceFileNav[data-right=true]::after {
background: linear-gradient(270deg, rgba(0, 0, 0, 0.35), transparent);
}

.sourceLR {
display: none;
cursor: pointer;
width: 5em;
padding: 10px;
margin-top: 15px;
text-align: center;
color: var(--source-tab-color);
background-color: var(--source-tab-background);
border-left: 1px solid rgba(0, 0, 0, 0.5);
border-right: 1px solid rgba(0, 0, 0, 0.5);
}
.sourceLR:hover {
text-decoration: underline;
}
.sourceLRShow .sourceLR {
display: block;
}

nav.sourceFileNav div.sourceFileScrollContainer {
white-space: nowrap;
overflow-x: auto;
scrollbar-width: thin;
}

nav.sourceFileNav div.sourceFileScrollContainer::-webkit-scrollbar {
display: inline;
margin-top: 10px;
margin-bottom: 10px;
height: 11px;
width: 10px;
}

nav.sourceFileNav div.sourceFileScrollContainer::-webkit-scrollbar-thumb {
background: rgb(200, 200, 200);
height: 4px;
border-radius: 20px;
-webkit-box-shadow: inset 0px 0px 10px rgb(45, 33, 33);
border: 0.5px solid transparent;
background-clip: content-box;
}

nav.sourceFileNav div.sourceFileScrollContainer::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0);
}

nav.sourceFileNav li a {
display: block;
margin: 0;
padding: 10px;
color: var(--source-tab-color);
background-color: var(--source-tab-background);
border-right: 1px solid rgba(0, 0, 0, 0.5);
}

nav.sourceFileNav li:hover {
Expand Down
71 changes: 71 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ const sampleContainerElem = getElem('.sampleContainer', sampleElem);
const titleElem = getElem('#title', sampleElem);
const descriptionElem = getElem('#description', sampleElem);
const menuToggleElem = getElem('#menuToggle') as HTMLInputElement;
const codeElem = getElem('#code');
const sourceTabsElem = getElem('#sourceTabs');
const sourceLElem = getElem('#sourceL');
const sourceRElem = getElem('#sourceR');

// Get the parts of a string past the last `/`
const basename = (name: string) => name.substring(name.lastIndexOf('/') + 1);
Expand Down Expand Up @@ -66,6 +70,35 @@ function setURL(url: string) {
// Handle when the URL changes (browser back / forward)
window.addEventListener('popstate', parseURL);

/**
* Scrolls the current tab into view.
*/
function moveIntoView(parent: HTMLElement, element: HTMLElement) {
const parentLeft = parent.scrollLeft;
const parentRight = parentLeft + parent.clientWidth;

const elemLeft = element.offsetLeft;
const elemRight = elemLeft + element.clientWidth;

if (elemLeft < parentLeft) {
parent.scrollLeft -= parentLeft - elemLeft;
} else if (elemRight > parentRight) {
parent.scrollLeft += elemRight - parentRight;
}
}

/**
* Switches to a tab relative to the current tab
*/
function switchToRelativeTab(direction: number) {
const tabs = [...sourceTabsElem.querySelectorAll('a')];
const activeNdx = tabs.findIndex((tab) => tab.dataset.active === 'true');
const newNdx = (activeNdx + tabs.length + direction) % tabs.length;
const tab = tabs[newNdx];
moveIntoView(sourceTabsElem, tab.parentElement!);
tab.click();
}

/**
* Show/hide source tabs
*/
Expand All @@ -75,6 +108,7 @@ function setSourceTab(sourceInfo: SourceInfo) {
const elem = e as HTMLElement;
elem.dataset.active = (elem.dataset.name === name).toString();
});
switchToRelativeTab(0);
}

/**
Expand Down Expand Up @@ -241,6 +275,43 @@ for (const { title, description, samples } of pageCategories) {
);
}

sourceLElem.addEventListener('click', () => switchToRelativeTab(-1));
sourceRElem.addEventListener('click', () => switchToRelativeTab(1));

function checkIfSourceTabsFit() {
const parentWidth = sourceTabsElem.clientWidth;
const childWidth = [...sourceTabsElem.querySelectorAll('li')].reduce(
(sum, elem) => sum + elem.clientWidth,
0
);
const showLR = childWidth > parentWidth;
codeElem.classList.toggle('sourceLRShow', showLR);
}

const registerResizeCallback = (() => {
const elemToResizeCallback = new Map<
Element,
(entry: ResizeObserverEntry) => void
>();
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const cb = elemToResizeCallback.get(entry.target);
if (cb) {
cb(entry);
}
}
});
return function (
elem: Element,
callback: (entry: ResizeObserverEntry) => void
) {
elemToResizeCallback.set(elem, callback);
observer.observe(elem);
};
})();

registerResizeCallback(sourceTabsElem, checkIfSourceTabsFit);

/**
* Parse the page's current URL and then set the iframe appropriately.
*/
Expand Down

0 comments on commit 9dc8bbb

Please sign in to comment.