Şablonlar
AuthShell
Giriş, tek kullanımlık kod ve parola ekranlarının ortak kabuğu.
AuthShell, oturum açılmadan görülen ekranları tek bir ortalanmış kartta toplar. Gezinme yoktur; kullanıcının dikkati yalnızca forma gider.
Önizleme
Bölüm başlığı “Önizleme”Sayfa başlığındaki marka ve mod seçimi canlı önizlemeyi de değiştirir. İkinci önizleme ikinci markayı koyu modda gösterir.
Bölgeler
Bölüm başlığı “Bölgeler”| Bölge | Öğe | Not |
|---|---|---|
| Marka | brand |
Logo veya ürün adı; verilmezse nötr ürün adı yazılır. |
| İçerik kartı | main |
Sayfanın tek h1 başlığı (title), açıklama ve form. En geniş 400 px. |
| Alt bilgi | footer |
Gizlilik ve yardım bağlantıları; footer ile değiştirilebilir. |
| Yan alan | aside |
Yalnız süs; ekran okuyucudan gizlidir. |
Kırılım noktaları
Bölüm başlığı “Kırılım noktaları”| Genişlik | Düzen |
|---|---|
| 1024 px altı | Tek sütun; kart ortada, yan alan gizli. |
| 1024 px ve üstü | Solda yan alan, sağda 448 px’lik form sütunu. aside={false} ile kart tüm genişlikte ortalanır. |
Kartın iç boşluğu space.2xl, kenarlığı border.subtle, gölgesi shadow.raised token’ından gelir.
Erişilebilirlik
Bölüm başlığı “Erişilebilirlik”- Sayfada tek
mainyer işareti vardır ve başlığıyla adlandırılır (aria-labelledby). - Tek
h1vardır; form içindeki başlıklarh2ile başlar. - Alt bilgi
footer(contentinfo) olarak adlandırılmıştır. - Yan alan
aria-hiddentaşır; içinde odaklanabilir öğe olmaz. - Sayfa açıldığında odak belgenin başında kalır; ilk alan
autoFocusalmaz, böylece ekran okuyucu başlığı önce okur.
import { Heading, Inline, Link, Stack, Text } from '@bigbang/ui';import type { ReactNode } from 'react';import { type Lang, LangProvider } from '../../patterns/lang';
const copy = { tr: { product: 'Ürün adı', privacy: 'Gizlilik', help: 'Yardım', footer: 'Yasal bilgiler', aside: 'Ekibinizin işleri tek yerde.' }, en: { product: 'Product name', privacy: 'Privacy', help: 'Help', footer: 'Legal', aside: "Your team's work in one place." },};
export type AuthShellProps = { /** The page's only h1, such as "Giriş yapın". */ title: string; /** One sentence under the title. */ description?: ReactNode; /** The form. */ children: ReactNode; /** Links under the card; defaults to privacy and help. */ footer?: ReactNode; /** Logo or product name; defaults to a neutral product name. */ brand?: ReactNode; /** Shows the decorative side panel from `lg` up. */ aside?: boolean; lang?: Lang;};
/** * Template for sign-in, one-time code and password screens: one centred card in a `main` landmark, * the brand above it and the footer links below. No navigation, so nothing competes with the form. */export function AuthShell({ title, description, children, footer, brand, aside = true, lang = 'tr' }: AuthShellProps) { const t = copy[lang]; return ( <LangProvider lang={lang}> <div className="grid min-h-[40rem] w-full bg-surface-default lg:grid-cols-[1fr_minmax(0,28rem)]" data-template="auth-shell"> {aside ? ( <div className="hidden items-end bg-surface-layer-1 p-4xl lg:flex" aria-hidden="true"> <Text size="lg" tone="subtle"> {t.aside} </Text> </div> ) : null} <div className={`flex flex-col items-center justify-between gap-3xl px-lg py-3xl ${aside ? '' : 'lg:col-span-2'}`}> <div className="w-full max-w-[25rem]" data-part="brand"> {brand ?? ( <Text weight="medium"> {t.product} </Text> )} </div> <main className="w-full max-w-[25rem] rounded-lg border border-line-subtle bg-surface-raised p-2xl shadow-raised" aria-labelledby={`auth-title-${lang}`}> <Stack gap="xl"> <Stack gap="sm"> <Heading level={1} size="lg" id={`auth-title-${lang}`}> {title} </Heading> {description ? <Text tone="subtle">{description}</Text> : null} </Stack> {children} </Stack> </main> <footer className="w-full max-w-[25rem]" aria-label={t.footer}> {footer ?? ( <Inline gap="lg"> <Link href="#" size="sm"> {t.privacy} </Link> <Link href="#" size="sm"> {t.help} </Link> </Inline> )} </footer> </div> </div> </LangProvider> );}Kullanılan bileşenler
Bölüm başlığı “Kullanılan bileşenler”Heading, Text, Stack, Inline, Link. Bu kabuğu kullanan bloklar: Giriş, Tek kullanımlık kod.