Kalıplar
Bildirimler
Geri bildirimi hangi kanaldan vereceğiniz, önem düzeyleri ve canlı bölgeler.
Ürün kullanıcıya her gün bir şey söyler: bir alan hatalı, bir kayıt tamamlandı, sistem bakımda. Bu kalıp her mesajın hangi kanaldan, hangi önem düzeyi ve hangi canlı bölgeyle verileceğini belirler.
Ne zaman kullanılır
Bölüm başlığı “Ne zaman kullanılır”- Bir eylemin sonucunu, bir uyarıyı veya bir hatayı kullanıcıya bildirirken.
- Mesajın yerine karar verirken: alan altı, bölüm, sayfa, kısa onay veya bildirim merkezi.
- Mesajın ekran okuyucuya nasıl duyurulacağını seçerken.
Canlı örnek
Bölüm başlığı “Canlı örnek”Aynı iletiyi üç kanaldan deneyin: bölüm için InlineAlert, sayfa geneli için Banner, geçici onay için toast. Başarı toast’ı “Geri al” eylemi sunar. Sonradan görünen iletiler duyurulur: hata kesintili, diğerleri nazik.
import { Banner, Button, InlineAlert, Inline, Stack, Text, useToast } from '@bigbang/ui';import { useState } from 'react';import { type Lang, LangProvider } from '../lang';
const copy = { tr: { intro: 'Aynı iletiyi üç kanaldan deneyin: satır içi uyarı, sayfa bandı ve toast. Ekran okuyucu açıkken dinleyin.', inline: 'Satır içi uyarı (bölüm)', banner: 'Banner (sayfa geneli)', toast: 'Toast (geçici onay)', tones: { success: 'Başarı', warning: 'Uyarı', danger: 'Hata' }, kinds: { success: { title: 'Ayarlar kaydedildi', text: 'Ayarlar kaydedildi.' }, warning: { title: 'Depolama dolmak üzere', text: 'Depolama alanının %80 kadarı dolu.' }, danger: { title: 'Rapor gönderilemedi', text: 'Rapor gönderilemedi. Bağlantınızı denetleyip tekrar deneyin.' }, }, undo: 'Geri al', undone: 'Geri alındı', }, en: { intro: 'Try the same message in three channels: inline alert, page banner and toast. Listen with a screen reader on.', inline: 'Inline alert (section)', banner: 'Banner (page-wide)', toast: 'Toast (transient)', tones: { success: 'Success', warning: 'Warning', danger: 'Error' }, kinds: { success: { title: 'Settings saved', text: 'Settings saved.' }, warning: { title: 'Storage almost full', text: 'About 80% of the storage is used.' }, danger: { title: 'Report not sent', text: 'The report was not sent. Check your connection and try again.' }, }, undo: 'Undo', undone: 'Undone', },};
type Tone = 'success' | 'warning' | 'danger';const tones: Tone[] = ['success', 'warning', 'danger'];
function ToneButtons({ label, lang, onPick }: { label: string; lang: Lang; onPick: (tone: Tone) => void }) { const t = copy[lang]; return ( <Stack gap="xs"> <Text size="sm" weight="medium"> {label} </Text> <Inline gap="sm" wrap> {tones.map((tone) => ( <Button key={tone} variant="secondary" size="sm" tone={tone === 'danger' ? 'danger' : 'neutral'} onClick={() => onPick(tone)}> {t.tones[tone]} </Button> ))} </Inline> </Stack> );}
function Lab({ lang }: { lang: Lang }) { const t = copy[lang]; const toast = useToast(); // A new `key` per pick remounts the message, so it is announced again and its own dismissal resets. const [inline, setInline] = useState<{ tone: Tone; key: number } | null>(null); const [banner, setBanner] = useState<{ tone: Tone; key: number } | null>(null);
const showToast = (tone: Tone) => { const { title, text } = t.kinds[tone]; // Only the success toast has an action: a short confirmation of the user's own action may offer undo. if (tone === 'success') { toast.show({ title, tone, action: { label: t.undo, onClick: () => toast.show({ title: t.undone, tone: 'neutral' }) } }); } else { toast.show({ title, description: text, tone }); } };
return ( <Stack gap="lg" className="w-full max-w-xl"> <Text size="sm" tone="subtle"> {t.intro} </Text> <ToneButtons label={t.inline} lang={lang} onPick={(tone) => setInline((prev) => ({ tone, key: (prev?.key ?? 0) + 1 }))} /> <ToneButtons label={t.banner} lang={lang} onPick={(tone) => setBanner((prev) => ({ tone, key: (prev?.key ?? 0) + 1 }))} /> <ToneButtons label={t.toast} lang={lang} onPick={showToast} /> <Stack gap="sm" className="min-h-12"> {banner ? ( <Banner key={`banner-${banner.key}`} tone={banner.tone} announce dismissible onDismiss={() => setBanner(null)} > {t.kinds[banner.tone].text} </Banner> ) : null} {inline ? ( <InlineAlert key={`inline-${inline.key}`} tone={inline.tone} title={t.kinds[inline.tone].title} announce dismissible onDismiss={() => setInline(null)}> {t.kinds[inline.tone].text} </InlineAlert> ) : null} </Stack> </Stack> );}
/** * A feedback lab for the decision matrix: a section message is an `InlineAlert`, a page-wide one a `Banner`, * a short confirmation of the user's own action a toast (the success toast offers "Undo"). * Messages that appear later are announced: errors assertively, the rest politely. */export function FeedbackLab({ lang = 'tr' }: { lang?: Lang }) { return ( <LangProvider lang={lang}> <Lab lang={lang} /> </LangProvider> );}Kurallar
Bölüm başlığı “Kurallar”Karar tablosu, mesajı kapsamına göre kanala eşler.
| Kanal | Kapsam ve kural |
|---|---|
| Alan hatası | Alanın altında; yalnızca o alanla ilgili doğrulama. |
Satır içi uyarı (InlineAlert) |
Bir bölümde; bölümle ilgili bilgi, uyarı veya hata. |
Banner (Banner) |
Sayfa veya sistem genelinde; kalıcıdır, kullanıcı kapatana veya durum bitene kadar kalır. |
Toast (useToast) |
Kullanıcının kendi eyleminin kısa onayı; isteğe bağlı geri al; en az 5000 ms sonra kapanır, üstüne gelince veya odaklanınca durur. Eylem gerektiren hata için kullanılmaz. |
| Bildirim merkezi | Eşzamansız olaylar: kullanıcı başka yerdeyken biten işler, davetler, hatırlatmalar. |
| Önem düzeyi | Simge | Metin |
|---|---|---|
| Bilgi | info |
“Bilgi” |
| Başarı | circle-check |
“Başarılı” |
| Uyarı | triangle-alert |
“Uyarı” |
| Tehlike | circle-x |
“Hata” |
Her düzey simge ve metinle birlikte verilir; renk tek başına anlam taşımaz.
| Canlı bölge | Kullanım |
|---|---|
Nazik (role="status") |
Durum iletileri: başarı, uyarı, ilerleme. |
Kesintili (role="alert") |
Yalnızca engelleyen hatalar. |
Davranış
Bölüm başlığı “Davranış”- Mesajın kapsamını belirleyin: tek alan, bölüm, sayfa, kısa onay veya eşzamansız olay.
- Tabloya göre kanalı seçin; aynı mesajı iki kanaldan vermeyin.
- Önem düzeyini seçin ve simge ile sözcüğü ekleyin.
- Mesaj sayfa yüklendikten sonra görünüyorsa
announceaçın: bileşen hatayı kesintili (role="alert"), diğer düzeyleri nazik (role="status") duyurur. Toast kendi bölgesinde duyurulur. - Kapatılabilir mesajda kapatma düğmesi vardır; kapatınca mesaj solar ve odak sonraki odaklanabilir öğeye geçer.
- Toast kendiliğinden kapanır ve tek başına kritik bilgi taşımaz; sonuç başka bir yerde de görünür.
Hata sonrası kullanıcıyı yönlendirmek için Hatadan kurtarma kalıbına bakın.
Erişilebilirlik
Bölüm başlığı “Erişilebilirlik”- Durum iletileri
role="status"bölgesine yazılır; ekran okuyucu işini bölmeden okur. role="alert"yalnızca engelleyen hatalarda kullanılır; her uyarıyı kesintili yapmak okuyucuyu yorar.InlineAlertveBannerönem düzeyini gizli bir önekle söyler (“Hata:”, “Uyarı:”); toast bildirim bölgesinde (“Bildirimler”) duyurulur. Hata toast’ı kapatılana kadar kalır.- Kapatma düğmesi adlıdır (“Uyarıyı kapat”) ve odak sonraki odaklanabilir öğeye geçer.
- Toast üstüne gelince veya odaklanınca durur; süre en az 5000 ms’dir (WCAG 2.2.1).
- Renk tek başına anlam taşımaz; simge ve sözcük her zaman vardır (WCAG 1.4.1).
İçerik
Bölüm başlığı “İçerik”- Mesaj ne olduğunu söyler; hata ise nasıl çözüleceğini de söyler.
- Önem sözcüğünü bileşen söyler (“Başarılı:”); metinde yinelemeyin: “Ayarlar kaydedildi.”
- Toast tek cümledir ve geri al dışında eylem içermez.
- Suçlayıcı dil ve belirsiz ifadeler (“Bir hata oluştu”) kullanmayın.
Hareket
Bölüm başlığı “Hareket”| Öğe | Hareket | Preset |
|---|---|---|
| Toast | Girişte 240 ms, çıkışta 150 ms, 8 px kayma | motion.toast |
| Alan hata metni | 150 ms solma, 4 px aşağı kayma | motion.fieldMessage |
| Satır içi mesaj ve Banner | Kapanırken solma | motion.collapsible |
Hareketi azaltma tercihinde kaymalar kalkar, yalnızca kısa solma kalır.
Kullanılan bileşenler
Bölüm başlığı “Kullanılan bileşenler”InlineAlert, Banner, Toast, Button, Icon, Text, TextInput. İlgili kalıplar: Formlar ve doğrulama, Hatadan kurtarma.