Şablonlar
Giriş
Kullanıcı adı ve parola ile giriş ekranı; satır içi hatalar, tek genel kimlik hatası ve büyük harf uyarısı.
Giriş bloğu AuthShell içinde iki alanlı bir form kurar. Kodu kopyalayıp kendi kimlik doğrulama çağrınızı onSignIn ile bağlayın.
Önizleme
Bölüm başlığı “Önizleme”Boş formu gönderin: odak ilk boş alana gider. İki alanı doldurup gönderince örnek çağrı reddedilir ve genel hata görünür. Sayfa başlığındaki marka ve mod seçimi önizlemeyi de değiştirir.
pnpm add @bigbang/ui| Veri | Tür | Not |
|---|---|---|
onSignIn |
(values) => Promise<boolean> |
false dönerse genel kimlik hatası gösterilir. |
initialError |
boolean |
Sunucu yönlendirmesiyle gelen ret durumunu gösterir. |
lang |
'tr' | 'en' |
Metinler ve kütüphane dizgileri. |
import { Button, Checkbox, IconButton, Inline, InlineAlert, Link, Stack, TextInput } from '@bigbang/ui';import { useRef, useState, type FormEvent, type KeyboardEvent } from 'react';import type { Lang } from '../../patterns/lang';import { AuthShell } from '../../templates/auth-shell/AuthShell';
const copy = { tr: { title: 'Giriş yapın', description: 'Devam etmek için hesabınıza giriş yapın.', username: 'Kullanıcı adı', password: 'Parola', show: 'Parolayı göster', remember: 'Bu cihazı hatırla', submit: 'Giriş yap', signingIn: 'Giriş yapılıyor', forgot: 'Parolamı unuttum', usernameEmpty: 'Kullanıcı adınızı girin.', passwordEmpty: 'Parolanızı girin.', credentials: 'Kullanıcı adı veya parola hatalı.', capsLock: 'Büyük harf kilidi açık.', }, en: { title: 'Sign in', description: 'Sign in to your account to continue.', username: 'Username', password: 'Password', show: 'Show password', remember: 'Remember this device', submit: 'Sign in', signingIn: 'Signing in', forgot: 'Forgot password', usernameEmpty: 'Enter your username.', passwordEmpty: 'Enter your password.', credentials: 'The username or password is wrong.', capsLock: 'Caps Lock is on.', },};
type Errors = { username?: string; password?: string };
export type LoginBlockProps = { lang?: Lang; /** Shows the credential error, as after a rejected attempt. */ initialError?: boolean; /** Called with the entered values once both are filled in. Resolve `false` to show the credential error. */ onSignIn?: (values: { username: string; password: string; remember: boolean }) => Promise<boolean>;};
const demoSignIn = () => new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 1200));
/** Sign-in screen: two fields, inline errors, one generic credential error and a Caps Lock hint. */export function LoginBlock({ lang = 'tr', initialError = false, onSignIn = demoSignIn }: LoginBlockProps) { const t = copy[lang]; const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [remember, setRemember] = useState(false); const [visible, setVisible] = useState(false); const [capsLock, setCapsLock] = useState(false); const [errors, setErrors] = useState<Errors>({}); const [rejected, setRejected] = useState(initialError); const [pending, setPending] = useState(false); const formRef = useRef<HTMLFormElement>(null);
const onSubmit = async (event: FormEvent) => { event.preventDefault(); const found: Errors = {}; if (!username.trim()) found.username = t.usernameEmpty; if (!password) found.password = t.passwordEmpty; setErrors(found); setRejected(false); const first = (['username', 'password'] as const).find((key) => found[key]); if (first) { formRef.current?.querySelector<HTMLInputElement>(`input[name="${first}"]`)?.focus(); return; } setPending(true); const accepted = await onSignIn({ username, password, remember }); setPending(false); // The message never says which value was wrong. if (!accepted) setRejected(true); };
const onKey = (event: KeyboardEvent<HTMLInputElement>) => setCapsLock(event.getModifierState('CapsLock'));
return ( <AuthShell lang={lang} title={t.title} description={t.description}> <form ref={formRef} noValidate onSubmit={onSubmit} aria-labelledby={`auth-title-${lang}`}> <Stack gap="lg"> <TextInput label={t.username} name="username" autoComplete="username" required value={username} onValueChange={(value) => setUsername(value)} {...(errors.username ? { error: errors.username } : {})} /> <TextInput label={t.password} name="password" type={visible ? 'text' : 'password'} autoComplete="current-password" required value={password} onValueChange={(value) => setPassword(value)} onKeyUp={onKey} onKeyDown={onKey} {...(errors.password ? { error: errors.password } : capsLock ? { description: t.capsLock } : {})} endContent={<IconButton icon={visible ? 'eye-off' : 'eye'} label={t.show} variant="tertiary" size="sm" aria-pressed={visible} onClick={() => setVisible((value) => !value)} />} /> <Inline justify="between" align="center" wrap> <Checkbox label={t.remember} name="remember" checked={remember} onCheckedChange={setRemember} /> <Link href="#" size="sm"> {t.forgot} </Link> </Inline> {rejected ? ( <InlineAlert tone="danger" announce> {t.credentials} </InlineAlert> ) : null} <Button type="submit" fullWidth loading={pending} loadingLabel={t.signingIn}> {t.submit} </Button> </Stack> </form> </AuthShell> );}- Marka ve
mainiçindeh1“Giriş yapın” (AuthShell). - Kullanıcı adı alanı (TextInput,
autoComplete="username"). - Parola alanı; sonunda göster/gizle IconButton (
aria-pressed). - “Bu cihazı hatırla” Checkbox ve “Parolamı unuttum” Link.
- Genel hata: reddedilen girişten sonra görünen
dangertonlu InlineAlert (announce). - Tam genişlikte birincil Button; bekleme sırasında yükleniyor durumu.
Erişilebilirlik
Bölüm başlığı “Erişilebilirlik”- Boş gönderimde odak ilk hatalı alana gider; iki alan için özet kutusu gerekmez (Formlar ve doğrulama).
- Kimlik hatası hangi değerin yanlış olduğunu söylemez; InlineAlert
announceilerole="alert"alır ve bir kez okunur; ton ekran okuyucuya “Hata:” ön ekiyle de söylenir. - Büyük harf kilidi açıkken parola alanının açıklaması “Büyük harf kilidi açık.” olur ve alana bağlı okunur.
- Göster/gizle düğmesi adını korur, durumunu
aria-pressedile bildirir. - Parola alanı
autoComplete="current-password"taşır; parola yöneticileri çalışır (WCAG 3.3.8).
Kullanılan bileşenler
Bölüm başlığı “Kullanılan bileşenler”TextInput, IconButton, Checkbox, Link, Button, InlineAlert. Kalıplar: Formlar ve doğrulama, Yükleme durumları, Oturum süresi ve tek kullanımlık kod.