Bileşenler
FilterBar
Liste ya da tablo için süzme denetimleri: uygulanan filtre çipleri, sonuç sayısı ve tek tıkla temizleme.
- Storybook
- Storybook
- Kaynak kod
- Kaynak kod
Aşağıdaki örnek Storybook’tan canlı yüklenir; denetimleri Storybook’ta açabilirsiniz.
Varsayılan
Bölüm başlığı “Varsayılan”FilterBar, filtreleri tek bir tipli nesne olarak tutar. Siz fields ile denetimleri tanımlarsınız, value ve onValueChange ile değeri yönetirsiniz. Varsayılan instant kipinde her değişiklik hemen uygulanır. Uygulanan filtreler çip olarak görünür; her çipin kendi kaldır düğmesi vardır. “Filtreleri temizle” yalnızca bir filtre uygulandığında görünür.
import { useState } from 'react';import { FilterBar, type FilterField } from '@bigbang/ui';
type Filters = { query: string; status: string | null; category: string[]; mine: boolean };
const empty: Filters = { query: '', status: null, category: [], mine: false };
const fields: ReadonlyArray<FilterField<Filters>> = [ { key: 'query', label: 'Ara', kind: 'search', placeholder: 'Ada göre ara' }, { key: 'status', label: 'Durum', kind: 'select', options: [ { value: 'active', label: 'Etkin' }, { value: 'draft', label: 'Taslak' }, { value: 'paused', label: 'Duraklatıldı' }, ], }, { key: 'category', label: 'Kategori', kind: 'multi-select', options: [ { value: 'a', label: 'Kategori A' }, { value: 'b', label: 'Kategori B' }, { value: 'c', label: 'Kategori C' }, ], }, { key: 'mine', label: 'Yalnızca benim', kind: 'toggle' },];
export default function Default() { const [value, setValue] = useState<Filters>({ ...empty, status: 'active', category: ['a'] }); return ( <div className="w-full"> <FilterBar fields={fields} value={value} onValueChange={setValue} resultCount={12} /> </div> );}Toplu uygulama
Bölüm başlığı “Toplu uygulama”apply="batch" kipinde değişiklikler bir taslakta birikir. Uygula düğmesi yalnızca taslak uygulanan değerden farklıysa etkindir; Sıfırla taslağı geri alır. Arama kutusunda Enter da uygular. Çipler her zaman uygulanan değeri gösterir.
import { useState } from 'react';import { FilterBar, type FilterField } from '@bigbang/ui';
type Filters = { query: string; status: string | null; category: string[]; mine: boolean };
const empty: Filters = { query: '', status: null, category: [], mine: false };
const fields: ReadonlyArray<FilterField<Filters>> = [ { key: 'query', label: 'Ara', kind: 'search', placeholder: 'Ada göre ara' }, { key: 'status', label: 'Durum', kind: 'select', options: [ { value: 'active', label: 'Etkin' }, { value: 'draft', label: 'Taslak' }, { value: 'paused', label: 'Duraklatıldı' }, ], }, { key: 'category', label: 'Kategori', kind: 'multi-select', options: [ { value: 'a', label: 'Kategori A' }, { value: 'b', label: 'Kategori B' }, { value: 'c', label: 'Kategori C' }, ], }, { key: 'mine', label: 'Yalnızca benim', kind: 'toggle' },];
export default function Batch() { const [value, setValue] = useState<Filters>(empty); return ( <div className="w-full"> <FilterBar fields={fields} value={value} onValueChange={setValue} apply="batch" resultCount={12} /> </div> );}Tabloyla birlikte
Bölüm başlığı “Tabloyla birlikte”FilterBar süzme işini yapmaz; yalnızca değeri üretir. Satırları siz süzersiniz ve sonuç sayısını resultCount ile geri verirsiniz. Sayı, filtreler değiştikten 500 ms sonra ekran okuyucuya bir kez duyurulur.
| Ad | Durum | Sahibi |
|---|---|---|
| Birinci öğe | Etkin | Kullanıcı 1 |
| İkinci öğe | Taslak | Kullanıcı 2 |
| Üçüncü öğe | Duraklatıldı | Kullanıcı 1 |
| Dördüncü öğe | Etkin | Kullanıcı 2 |
| Beşinci öğe | Taslak | Kullanıcı 1 |
| Altıncı öğe | Etkin | Kullanıcı 2 |
import { useState } from 'react';import { FilterBar, Table, type FilterField } from '@bigbang/ui';
type Filters = { query: string; status: string | null; category: string[]; mine: boolean };
const empty: Filters = { query: '', status: null, category: [], mine: false };
const fields: ReadonlyArray<FilterField<Filters>> = [ { key: 'query', label: 'Ara', kind: 'search', placeholder: 'Ada göre ara' }, { key: 'status', label: 'Durum', kind: 'select', options: [ { value: 'active', label: 'Etkin' }, { value: 'draft', label: 'Taslak' }, { value: 'paused', label: 'Duraklatıldı' }, ], }, { key: 'category', label: 'Kategori', kind: 'multi-select', options: [ { value: 'a', label: 'Kategori A' }, { value: 'b', label: 'Kategori B' }, { value: 'c', label: 'Kategori C' }, ], }, { key: 'mine', label: 'Yalnızca benim', kind: 'toggle' },];
const rows = [ { name: 'Birinci öğe', status: 'active', category: 'a', mine: true }, { name: 'İkinci öğe', status: 'draft', category: 'b', mine: false }, { name: 'Üçüncü öğe', status: 'paused', category: 'c', mine: true }, { name: 'Dördüncü öğe', status: 'active', category: 'a', mine: false }, { name: 'Beşinci öğe', status: 'draft', category: 'b', mine: true }, { name: 'Altıncı öğe', status: 'active', category: 'c', mine: false },];
export default function WithTable() { const [value, setValue] = useState<Filters>(empty); const shown = rows.filter( (row) => row.name.toLocaleLowerCase().includes(value.query.trim().toLocaleLowerCase()) && (value.status === null || row.status === value.status) && (value.category.length === 0 || value.category.includes(row.category)) && (!value.mine || row.mine), ); return ( <div className="grid w-full gap-xl"> <FilterBar fields={fields} value={value} onValueChange={setValue} resultCount={shown.length} /> <Table caption="Öğe listesi" captionHidden> <Table.Header> <Table.Row> <Table.HeaderCell>Ad</Table.HeaderCell> <Table.HeaderCell>Durum</Table.HeaderCell> <Table.HeaderCell>Sahibi</Table.HeaderCell> </Table.Row> </Table.Header> <Table.Body> {shown.map((row) => ( <Table.Row key={row.name}> <Table.RowHeader>{row.name}</Table.RowHeader> <Table.Cell>{fields[1]?.options?.find((option) => option.value === row.status)?.label}</Table.Cell> <Table.Cell>{row.mine ? 'Kullanıcı 1' : 'Kullanıcı 2'}</Table.Cell> </Table.Row> ))} {shown.length === 0 ? ( <Table.Row> <Table.Cell colSpan={3}>Filtrelere uyan öğe yok</Table.Cell> </Table.Row> ) : null} </Table.Body> </Table> </div> );}Dar ekran
Bölüm başlığı “Dar ekran”1024 px’in altında arama kutusu yerinde kalır; diğer filtreler “Diğer filtreler” düğmesinin açtığı satır içi bir panele geçer. Düğme, uygulanan filtre sayısını rozetle gösterir.
Açık ve koyu mod
Bölüm başlığı “Açık ve koyu mod”FilterBar tüm renklerini token’lardan alır ve ona gömülü denetimler kendi modlarını izler.
import { useState } from 'react';import { FilterBar, type FilterField } from '@bigbang/ui';
type Filters = { query: string; status: string | null; category: string[]; mine: boolean };
const empty: Filters = { query: '', status: null, category: [], mine: false };
const fields: ReadonlyArray<FilterField<Filters>> = [ { key: 'query', label: 'Ara', kind: 'search', placeholder: 'Ada göre ara' }, { key: 'status', label: 'Durum', kind: 'select', options: [ { value: 'active', label: 'Etkin' }, { value: 'draft', label: 'Taslak' }, { value: 'paused', label: 'Duraklatıldı' }, ], }, { key: 'category', label: 'Kategori', kind: 'multi-select', options: [ { value: 'a', label: 'Kategori A' }, { value: 'b', label: 'Kategori B' }, { value: 'c', label: 'Kategori C' }, ], }, { key: 'mine', label: 'Yalnızca benim', kind: 'toggle' },];
export default function Default() { const [value, setValue] = useState<Filters>({ ...empty, status: 'active', category: ['a'] }); return ( <div className="w-full"> <FilterBar fields={fields} value={value} onValueChange={setValue} resultCount={12} /> </div> );}