Files
windwiderstand/src/lib/ui/TabBar.svelte
T
Peter Meier da57ad1ac8
Deploy / verify (push) Successful in 43s
Deploy / deploy (push) Successful in 59s
fix: update styling and structure in various components
- Changed margin class from `my-6` to `mb-6` in ContentRows.svelte for consistent spacing.
- Updated PostCard.svelte to use `$derived` for post properties, enhancing reactivity.
- Refined DeadlineBannerBlock.svelte by removing unnecessary border classes and improving layout for better content alignment.
- Modified Button.svelte to support rendering children directly, enhancing flexibility.
- Added `tabindex="0"` to TabBar.svelte for improved accessibility.
- Fixed textarea closing tag in Textarea.svelte for proper HTML structure.
- Corrected span closing tag in Toggle.svelte for valid markup.
2026-04-19 12:42:37 +02:00

53 lines
1.3 KiB
Svelte

<script lang="ts">
/** @type {{ id: string; label: string }[]} */
let {
tabs = [],
selectedId = $bindable(''),
labelledBy = '',
} = $props();
$effect(() => {
if (tabs.length && !selectedId) selectedId = tabs[0].id;
});
function selectTab(id: string) {
selectedId = id;
}
function handleKeydown(e: KeyboardEvent) {
const idx = tabs.findIndex((t) => t.id === selectedId);
if (e.key === 'ArrowRight' && idx < tabs.length - 1) {
e.preventDefault();
selectedId = tabs[idx + 1].id;
} else if (e.key === 'ArrowLeft' && idx > 0) {
e.preventDefault();
selectedId = tabs[idx - 1].id;
}
}
</script>
<div
role="tablist"
aria-label={labelledBy || 'Tabs'}
class="flex h-12 border-b border-stein-200"
tabindex="0"
onkeydown={handleKeydown}
>
{#each tabs as tab}
<button
type="button"
role="tab"
aria-selected={selectedId === tab.id}
aria-controls="panel-{tab.id}"
id="tab-{tab.id}"
class="border-b-2 px-4 text-sm font-medium transition-colors {selectedId === tab.id
? 'border-wald-500 text-wald-600 font-semibold'
: 'border-transparent text-stein-500 hover:text-stein-700'}"
tabindex={selectedId === tab.id ? 0 : -1}
onclick={() => selectTab(tab.id)}
>
{tab.label}
</button>
{/each}
</div>