71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
import type { FlatTemplatable } from "tempstream";
|
|
import { TempstreamJSX } from "tempstream";
|
|
|
|
const ids = (function* () {
|
|
let i = 0;
|
|
while (true) {
|
|
yield i++;
|
|
}
|
|
})();
|
|
|
|
export function tabs({
|
|
tabs,
|
|
default_tab,
|
|
tab_bar,
|
|
remember_tab = false,
|
|
active_navbar_tab_style = "",
|
|
}: {
|
|
tabs: { id: string; label?: string; content: FlatTemplatable }[];
|
|
default_tab: string;
|
|
tab_bar?: FlatTemplatable;
|
|
remember_tab?: boolean;
|
|
active_navbar_tab_style?: string;
|
|
}) {
|
|
const tab_section_id = ids.next().value;
|
|
return (
|
|
<section class={`tabs tabs__${tab_section_id}`}>
|
|
{tab_bar || (
|
|
<nav>
|
|
{tabs.map(({ id, label }) => (
|
|
<div class="tabs__tab-label">
|
|
<label>
|
|
<input
|
|
type="radio"
|
|
id={`tabs__${tab_section_id}__tab__${id}`}
|
|
name={`tabs__${tab_section_id}`}
|
|
checked={id == default_tab}
|
|
autocomplete={remember_tab ? false : "off"}
|
|
/>
|
|
{label || id}
|
|
{
|
|
/* HTML */ `<style>
|
|
.tabs__${tab_section_id} nav label:has(input:checked) {
|
|
${active_navbar_tab_style}
|
|
}
|
|
</style>`
|
|
}
|
|
</label>
|
|
</div>
|
|
))}
|
|
</nav>
|
|
)}
|
|
{tabs.map(({ id, content }) => {
|
|
const tab_id = `tabs__${tab_section_id}__tab__${id}`;
|
|
return (
|
|
<div class={`tabs__tab tabs__${tab_section_id}__tab ` + tab_id}>
|
|
{
|
|
/* HTML */ `<style>
|
|
body:has(#tabs__${tab_section_id}__tab__${id}:checked)
|
|
.${tab_id} {
|
|
display: block;
|
|
}
|
|
</style>`
|
|
}
|
|
{content}
|
|
</div>
|
|
);
|
|
})}
|
|
</section>
|
|
);
|
|
}
|