İçeriğe geç
BigBang

Sık açılanlar

    ↑↓Gezin↵AçEscKapat
    EN

    Ş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.

    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.

    Canlı örnek, StorybookStorybook'ta aç
    Canlı örnek, StorybookStorybook'ta aç
    Terminal window
    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>
    );
    }
    1. Marka ve main içinde h1 “Giriş yapın” (AuthShell).
    2. Kullanıcı adı alanı (TextInput, autoComplete="username").
    3. Parola alanı; sonunda göster/gizle IconButton (aria-pressed).
    4. “Bu cihazı hatırla” Checkbox ve “Parolamı unuttum” Link.
    5. Genel hata: reddedilen girişten sonra görünen danger tonlu InlineAlert (announce).
    6. Tam genişlikte birincil Button; bekleme sırasında yükleniyor durumu.
    • 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 announce ile role="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-pressed ile bildirir.
    • Parola alanı autoComplete="current-password" taşır; parola yöneticileri çalışır (WCAG 3.3.8).

    TextInput, IconButton, Checkbox, Link, Button, InlineAlert. Kalıplar: Formlar ve doğrulama, Yükleme durumları, Oturum süresi ve tek kullanımlık kod.