Files
game-kit/template/src/lib/components/About.svelte
T

92 lines
2.2 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" module>
import type { Tab } from './Tabs.svelte';
/** One section of the about panel: a tab and what it shows. */
export type AboutTab = Tab;
</script>
<script lang="ts">
// The about panel: the game's story, its keeping and its company, a tab
// at a time rather than one long page. Opened from the hall's "about this
// game" link (and #about); closes with its button, a click outside it, or
// Escape. The tab last read is the one it reopens on.
import Tabs from './Tabs.svelte';
let { open = $bindable(false), tabs, title }: { open?: boolean; tabs: AboutTab[]; title: string } = $props();
let current = $state('');
function onKey(e: KeyboardEvent) {
if (open && e.key === 'Escape') open = false;
}
</script>
<svelte:window onkeydown={onKey} />
{#if open}
<div class="about-scrim" role="presentation" onclick={(ev) => ev.target === ev.currentTarget && (open = false)}>
<div class="panel" role="dialog" aria-modal="true" aria-labelledby="about-title">
<header>
<h2 id="about-title">{title}</h2>
<button type="button" class="close" aria-label="Close" onclick={() => (open = false)}>×</button>
</header>
<div class="body">
<Tabs {tabs} label="About this game" bind:current />
</div>
</div>
</div>
{/if}
<style>
/* Its own backdrop: not every game has another dialog to share one with. */
.about-scrim {
position: fixed;
inset: 0;
z-index: 20;
background: rgba(0, 0, 0, 0.55);
display: grid;
place-items: center;
padding: 16px;
}
.panel {
width: min(100%, 44rem);
max-height: 100%;
display: flex;
flex-direction: column;
background: var(--slate);
border: 1px solid var(--rule-strong);
border-radius: 6px;
padding: 1rem 1.4rem 1.2rem;
}
header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 1rem;
}
h2 {
font-size: 1.3rem;
margin: 0 0 0.6rem;
}
.close {
background: none;
border: none;
color: inherit;
font-size: 1.5rem;
line-height: 1;
cursor: pointer;
padding: 0.2rem 0.4rem;
}
.body {
overflow: auto;
min-height: 12rem;
}
/* The tab strip stays in view while a long tab scrolls beneath it. */
.body :global([role='tablist']) {
position: sticky;
top: 0;
z-index: 1;
background: var(--slate);
}
</style>