İçeriğe geç
BigBang

Sık açılanlar

    ↑↓Gezin↵AçEscKapat
    EN

    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.

    Canlı örnek, StorybookStorybook'ta aç

    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>
    );
    }

    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>
    );
    }

    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.

    Öğe listesi
    AdDurumSahibi
    Birinci öğeEtkinKullanıcı 1
    İkinci öğeTaslakKullanıcı 2
    Üçüncü öğeDuraklatıldıKullanıcı 1
    Dördüncü öğeEtkinKullanıcı 2
    Beşinci öğeTaslakKullanıcı 1
    Altıncı öğeEtkinKullanı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>
    );
    }

    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.

    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>
    );
    }