Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions src/mdx/CodeTabs.astro
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,14 @@ parsedHtml.childNodes.forEach((tabContent, index) => {
---
<div class="codetabs_wrapper">
<div class="codetabs_tabs">
{items.map((item, index) => <div class={index === 0 ? "codetabs_tab--active" : "codetabs_tab"} data-change-code-tab-btn>{item}</div>)}
{items.map((item, index) => <div class={index === 0 ? "codetabs_tab--active" : "codetabs_tab"} data-change-code-tab-btn data-tab-label={item}>{item}</div>)}
</div>
<div class="code codetabs_codeBlock">
<Fragment set:html={parsedHtml.toString()} />
</div>
</div>
<script>
document.addEventListener("astro:page-load", () => {
document.querySelectorAll('[data-change-code-tab-btn]').forEach((button) => {
button.addEventListener('click', (e) => {
const target = e.target as Element;
const parent = target.parentElement as Element;
const index = Array.from(parent?.children || []).indexOf(target);
const code = parent.nextElementSibling as Element;
import { setupSyncedTabs } from "@/utils-client";

if (code) {
Array.from(code.children).forEach((child, codeIndex) => {
child.classList.toggle('hidden', codeIndex !== index);
});
}
Array.from(parent.children).forEach((child, codeIndex) => {
child.classList.toggle('codetabs_tab', codeIndex !== index);
child.classList.toggle('codetabs_tab--active', codeIndex === index);
});
});
});
})
document.addEventListener("astro:page-load", setupSyncedTabs);
</script>
23 changes: 3 additions & 20 deletions src/mdx/Tabs.astro
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ parsedHtml.querySelectorAll('.tab__content').forEach((tabContent, index) => {
<div
class={index === 0 ? "tabs__button--active" : "tabs__button"}
data-change-tab-btn
data-tab-label={item}
>
{item}
</div>
Expand All @@ -32,25 +33,7 @@ parsedHtml.querySelectorAll('.tab__content').forEach((tabContent, index) => {
</div>
</div>
<script>
document.addEventListener("astro:page-load", () => {
document.querySelectorAll('[data-change-tab-btn]').forEach((button) => {
button.addEventListener('click', (e) => {
const target = e.target as Element;
const parent = target.parentElement as Element;
const index = Array.from(parent?.children || []).indexOf(target);
const code = parent.nextElementSibling as Element;

if (code) {
Array.from(code.children).forEach((child, codeIndex) => {
child.classList.toggle('hidden', codeIndex !== index);
});
}
Array.from(parent.children).forEach((child, codeIndex) => {
child.classList.toggle('tabs__button', codeIndex !== index);
child.classList.toggle('tabs__button--active', codeIndex === index);
});
});
});
})
import { setupSyncedTabs } from "@/utils-client";

document.addEventListener("astro:page-load", setupSyncedTabs);
</script>
113 changes: 112 additions & 1 deletion src/utils-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,115 @@ export const updateDialectLinks = () => {
const href = (link as HTMLAnchorElement).dataset.href;
(link as HTMLAnchorElement).href = `${href}/${savedDialect}`;
});
};
};

const dialectParam = "dialect";

const dialectAliases: Record<string, string> = {
postgresql: "postgresql",
postgres: "postgresql",
pg: "postgresql",
mysql: "mysql",
sqlite: "sqlite",
sqllite: "sqlite",
singlestore: "singlestore",
"single store": "singlestore",
mssql: "mssql",
"ms sql": "mssql",
cockroachdb: "cockroachdb",
cockroach: "cockroachdb",
turso: "turso",
};

const normalizeDialectValue = (value: string | undefined | null) => {
if (!value) return;

const normalized = value
.trim()
.toLowerCase()
.replace(/\s*\(wip\)\s*$/u, "")
.replace(/[-_]+/gu, " ")
.replace(/\s+/gu, " ");

return dialectAliases[normalized];
};

const getTabButtonDialect = (button: HTMLElement) => {
return normalizeDialectValue(button.dataset.tabLabel ?? button.textContent);
};

const activateTabButton = (button: HTMLElement) => {
const parent = button.parentElement;
if (!parent) return;

const index = Array.from(parent.children).indexOf(button);
const content = parent.nextElementSibling;
const isCodeTab = button.hasAttribute("data-change-code-tab-btn");
const activeClass = isCodeTab ? "codetabs_tab--active" : "tabs__button--active";
const inactiveClass = isCodeTab ? "codetabs_tab" : "tabs__button";

if (content) {
Array.from(content.children).forEach((child, contentIndex) => {
child.classList.toggle("hidden", contentIndex !== index);
});
}

Array.from(parent.children).forEach((child, buttonIndex) => {
child.classList.toggle(inactiveClass, buttonIndex !== index);
child.classList.toggle(activeClass, buttonIndex === index);
});
};

const updateDialectQueryParam = (dialect: string) => {
const url = new URL(window.location.href);
url.searchParams.set(dialectParam, dialect);
window.history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
};

const activateDialectTabs = (dialect: string) => {
const tabGroups = new Set<Element>();
const selector = "[data-change-tab-btn], [data-change-code-tab-btn]";

document.querySelectorAll<HTMLElement>(selector).forEach((button) => {
const parent = button.parentElement;
if (!parent || tabGroups.has(parent)) return;

const matchingButton = Array.from(parent.children).find((child) => {
return getTabButtonDialect(child as HTMLElement) === dialect;
}) as HTMLElement | undefined;

if (matchingButton) {
activateTabButton(matchingButton);
tabGroups.add(parent);
Comment on lines +247 to +253
}
});
};

export const setupSyncedTabs = () => {
const selector = "[data-change-tab-btn], [data-change-code-tab-btn]";

document.querySelectorAll<HTMLElement>(selector).forEach((button) => {
if (button.dataset.syncedTabBound === "true") return;

button.dataset.syncedTabBound = "true";
button.addEventListener("click", () => {
const dialect = getTabButtonDialect(button);

if (dialect) {
activateDialectTabs(dialect);
updateDialectQueryParam(dialect);
return;
}

activateTabButton(button);
});
});

const urlDialect = normalizeDialectValue(
new URLSearchParams(window.location.search).get(dialectParam),
);

if (urlDialect) {
activateDialectTabs(urlDialect);
}
};
Loading