Pantrix UI

Chip

Bir çip: küçük bir eylem, ya da kullanıcının eklediği ve geri çıkarabildiği bir öğe, örneğin bir alıcı, bir etiket ya da uygulanmış bir süzgeç.

import com.pantrixui.components.elements.chip.PantrixChip

Örnekler

Eylem çipi

İlk biçim: onClick alan çip basılınca bir iş yapan bir düğmedir ve adı etiketidir. En az yazılan hâli ilk çiptir: bir etiket ve bir onClick. İkincisinde leadingIcon etiketin önünde durur. Üçüncüsü enabled = false ile devre dışıdır: soluk çizilir ve basış almaz.

Bir çipe bas: altındaki satır en son hangisine basıldığını söyler.

var last by rememberSaveable { mutableStateOf<String?>(null) }
FlowRow(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
    PantrixChip(label = "Paylaş", onClick = { last = "Paylaş" }, tagKey = "share")
    PantrixChip(
        label = "Takvime ekle",
        onClick = { last = "Takvime ekle" },
        leadingIcon = PantrixIcons.Calendar,
        tagKey = "calendar"
    )
    PantrixChip(label = "Arşivle", onClick = { last = "Arşivle" }, enabled = false, tagKey = "archive")
}
PantrixText(
    text = last?.let { "Son eylem: $it" } ?: "Henüz bir eyleme basılmadı",
    style = PantrixTheme.typography.footnote,
    color = PantrixTheme.colors.textSecondary,
    tagKey = "last_action"
)

Seçilebilir çip: süzgeçler

İkinci biçim: selected ve onSelectedChange alan çip açılıp kapanan bir süzgeçtir. Çip kendiliğinden bir şey değiştirmez: onSelectedChange kullanıcının istediği değeri bildirir, açık süzgeçlerin anahtarlarını burada ekranın durumu saklar.

Açık olan dolgulu çizilir ve başında bir onay işareti taşır; açık olduğu yalnızca renkten anlaşılmaz. Simgesi olan süzgeçte, "Favoriler"de, işaret simgenin yerini alır ve çipin genişliği değişmez. Süzgeçler yana kayan bir satırdadır; altındaki satır kaçının açık olduğunu söyler.

var on by rememberSaveable { mutableStateOf(listOf("stock")) }
Row(
    modifier = Modifier.horizontalScroll(rememberScrollState()),
    horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
) {
    FILTERS.forEach { filter ->
        PantrixChip(
            label = filter.label,
            selected = filter.key in on,
            onSelectedChange = { selected -> on = if (selected) on + filter.key else on - filter.key },
            leadingIcon = filter.icon,
            tagKey = "filter_${filter.key}"
        )
    }
}
PantrixText(
    text = if (on.isEmpty()) "Süzgeç yok" else "${on.size} süzgeç açık",
    style = PantrixTheme.typography.footnote,
    color = PantrixTheme.colors.textSecondary,
    tagKey = "filters_on"
)

private class ChipFilter(
    val key: String,
    val label: String,
    val icon: ImageVector? = null
)

private val FILTERS = listOf(
    ChipFilter("stock", "Stokta"),
    ChipFilter("sale", "İndirimde"),
    ChipFilter("starred", "Favoriler", PantrixIcons.Star),
    ChipFilter("shipping", "Ücretsiz kargo"),
    ChipFilter("new", "Yeni gelenler"),
    ChipFilter("pickup", "Mağazadan teslim")
)

Çıkarılabilen çipler: alıcılar

onRemove çipin sonuna bir çarpı koyar. Çarpı kendi başına bir düğmedir: ekran okuyucu "Ayşe Yılmaz öğesini kaldır" der, yani bir satır çarpı birbirinden ayırt edilir. Çip kendini kaldırmaz; alıcıyı listeden çıkaran buradaki koddur.

Çipin kendisine basmak alıcıyı açar, çarpıya basmak açmaz. Alıcılar satıra sığmayınca alt satıra geçer. "Geri getir" hepsini geri koyar.

var kept by rememberSaveable { mutableStateOf(PEOPLE.map { it.key }) }
var opened by rememberSaveable { mutableStateOf<String?>(null) }
FlowRow(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
    PEOPLE.filter { it.key in kept }.forEach { person ->
        PantrixChip(
            label = person.name,
            onClick = { opened = person.name },
            leadingIcon = PantrixIcons.Person,
            onRemove = {
                kept = kept - person.key
                if (opened == person.name) opened = null
            },
            tagKey = "recipient_${person.key}"
        )
    }
}
Row(
    horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
    verticalAlignment = Alignment.CenterVertically
) {
    PantrixText(
        text = opened?.let { "Açılan: $it" } ?: "${kept.size} alıcı",
        style = PantrixTheme.typography.footnote,
        color = PantrixTheme.colors.textSecondary,
        tagKey = "recipients"
    )
    PantrixButton(
        text = "Geri getir",
        onClick = { kept = PEOPLE.map { it.key } },
        variant = ButtonVariant.Text,
        size = ButtonSize.Small,
        enabled = kept.size < PEOPLE.size,
        tagKey = "restore"
    )
}

private class ChipRecipient(
    val key: String,
    val name: String
)

private val PEOPLE = listOf(
    ChipRecipient("ayse", "Ayşe Yılmaz"),
    ChipRecipient("ibrahim", "İbrahim Öztürk"),
    ChipRecipient("ilker", "İlker Kaya"),
    ChipRecipient("selin", "Selin Çağlar")
)

Yalnızca gösteren çipler

Basılamayan iki çip. "Yalnızca üyeler" bir süzgeçtir ve onSelectedChange = null verildi: salt okunurdur, basış ve odak almaz, ama adını ve açık olduğunu ekran okuyucuya yine söyler. "Taslak" onClick = null ile yalnızca bir değeri gösterir: ekran okuyucu için tek bir öğedir.

İkisi de devre dışı değildir: kendi renkleriyle çizilirler, yalnızca basılacak bir şeyleri yoktur.

Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
    PantrixChip(label = "Yalnızca üyeler", selected = true, onSelectedChange = null, tagKey = "locked")
    PantrixChip(label = "Taslak", onClick = null, tagKey = "draft")
}

Uzun etiket ve geniş çip

Yerine sığmayan etiket üç noktayla biter. İkon ve çarpı yerlerini önce alır, etikete kalan verilir: uzun etiket kısalır, simgesiyle çarpısı bütün kalır. İlk çip basılamaz ama çıkarılabilir: onClick = null verilen çip onRemove verilince çarpısını yine taşır.

İkinci çip gereğinden geniştir, 220dp: simgesi ve etiketi bir düğmedeki gibi ortada, çarpısı sonda durur.

PantrixChip(
    label = "Üçüncü çeyreğin kurula gönderildiği hâliyle raporları ve bütün ekleri",
    onClick = null,
    leadingIcon = PantrixIcons.Folder,
    onRemove = {},
    tagKey = "long"
)
PantrixChip(
    label = "Kotlin",
    onClick = null,
    modifier = Modifier.width(220.dp),
    leadingIcon = PantrixIcons.Star,
    onRemove = {},
    tagKey = "wide"
)

Devre dışı çipler

enabled = false çipi basılamaz yapar ve bunu ekran okuyucuya da söyler. Devre dışı çip temanın devre dışı renkleriyle çizilir: açık bir süzgeç devre dışı dolguyu alır; dolgusu olmayan çip dolgusuz kalır ve etiketi soluklaşır. Çarpı da çiple birlikte basılamaz olur.

Son çipe colors verildi, ama o da ötekiler gibi çizildi: devre dışı bir çip, bir üründe her yerde aynı görünsün diye, kendi renklerini değil temanınkileri kullanır.

val own = ownColors()
FlowRow(
    horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
    verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
) {
    PantrixChip(label = "Stokta", selected = true, onSelectedChange = {}, enabled = false, tagKey = "disabled_on")
    PantrixChip(label = "İndirimde", selected = false, onSelectedChange = {}, enabled = false, tagKey = "disabled_off")
    PantrixChip(
        label = "Selin Çağlar",
        onClick = {},
        leadingIcon = PantrixIcons.Person,
        onRemove = {},
        enabled = false,
        tagKey = "disabled_recipient"
    )
    PantrixChip(
        label = "Koleksiyonum",
        selected = true,
        onSelectedChange = {},
        enabled = false,
        colors = ChipColors(selectedContainer = own.color, selectedContent = own.onColor),
        tagKey = "disabled_own_colors"
    )
}

Kendi renkleri

Renkleri dışarıdan verilen iki çip. İlki dolgulu bir eylemdir: dolgusu, etiketi ve simgesi verildi, kenarı Color.Transparent ile kaldırıldı. İkincisi bir süzgeçtir ve yalnızca açıkken çizildiği renkler verildi: kapalıyken temanınkilerle çizilir. Süzgece basıp kapat ve farkı gör.

ChipColors yalnızca verilen renkleri değiştirir; verilmeyeni temanın rolü belirler.

val own = ownColors()
var inCollection by rememberSaveable { mutableStateOf(true) }
Row(horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)) {
    PantrixChip(
        label = "Yeni sezon",
        onClick = {},
        leadingIcon = PantrixIcons.Star,
        colors = ChipColors(
            container = own.container,
            content = own.onContainer,
            icon = own.onContainer,
            border = Color.Transparent
        ),
        tagKey = "new_season"
    )
    PantrixChip(
        label = "Koleksiyonum",
        selected = inCollection,
        onSelectedChange = { inCollection = it },
        colors = ChipColors(selectedContainer = own.color, selectedContent = own.onColor),
        tagKey = "my_collection"
    )
}

Şekil ve stil

style yalnızca bu çipin geometrisini değiştirir; verilmeyen alanlar temanın ve platformun stilinden gelir. İlk çip stilsizdir ve şekli platformunkidir: Android'de orta yuvarlak, ötekilerde tam yuvarlak. İkincisinin köşeleri ShapeRole.Small ile az yuvarlak, üçüncüsününki ShapeRole.Full ile tam yuvarlaktır. Sonuncusu 40dp yüksekliğindedir ve etiketinin iki yanında 20dp boşluk vardır.

FlowRow(
    horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
    verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
    itemVerticalAlignment = Alignment.CenterVertically
) {
    PantrixChip(label = "Stilsiz", onClick = {}, tagKey = "plain")
    PantrixChip(label = "Az yuvarlak", onClick = {}, style = ChipStyle(shape = ShapeRole.Small), tagKey = "rounded")
    PantrixChip(label = "Tam yuvarlak", onClick = {}, style = ChipStyle(shape = ShapeRole.Full), tagKey = "pill")
    PantrixChip(
        label = "Yüksek",
        onClick = {},
        style = ChipStyle(height = 40.dp, horizontalPadding = 20.dp),
        tagKey = "tall"
    )
}

API

label

Bir çip: küçük bir eylem, ya da kullanıcının eklediği ve geri çıkarabildiği bir öğe, örneğin bir alıcı, bir etiket ya da uygulanmış bir süzgeç.

ParametreTürVarsayılanNe olduğu
labelStringÇipin metni ve ekran okuyucu için adı.
onClick(() -> Unit)?Çipe basılınca çağrılır. Null verilirse çip yalnızca bir değeri gösterir.
modifierModifierModifierÇipin modifier'ı. Çipin ayırdığı dokunma hedefinin dışına uygulanır.
leadingIconImageVector?nullEtiketin önündeki ikon. Stilin ikon boyutunda çizilir.
onRemove(() -> Unit)?nullÇıkarma düğmesine basılınca çağrılır. Null verilirse düğme konmaz.
enabledBooleantrueÇipe ve çıkarma düğmesine basılıp basılamayacağı. Basılamayan çip devre dışı renklerle çizilir ve devre dışı olduğunu söyler.
styleChipStyle?nullBu çağrının kendi stili: çevresindeki her stili ezer, yoğunluk ona da uygulanır. Yalnızca verdiği alanlar değişir ve her platformda değişir.
colorsChipColors?nullBu çipin kendi renkleri: verdiği renkler kullanılır, gerisi temanınkilerdir. Devre dışı bir çip temanın renklerinde kalır.
tagKeyString?nullÇipin otomasyon anahtarı: çip Chip_<tagKey>, çıkarma düğmesi ChipRemove_<tagKey>'dir. Bir basış Chip olayı olarak bildirilir: click ya da remove. Olay etiketin metnini hiçbir zaman taşımaz.
interactionSourceMutableInteractionSource?nullÇipin dışarı taşınan etkileşimleri. Null ise çip kendi kaynağını tutar. Çıkarma düğmesinin her zaman kendi kaynağı vardır.

label

Bir süzgeç: açık ya da kapalı olan bir çip.

ParametreTürVarsayılanNe olduğu
labelStringÇipin metni ve ekran okuyucu için adı.
selectedBooleanSüzgecin açık olup olmadığı.
onSelectedChange((Boolean) -> Unit)?Kullanıcının istediği değerle, yani selected'ın tersiyle çağrılır. Çip kendiliğinden bir şey değiştirmez: selected ne diyorsa odur. Null verilirse çip salt okunur olur.
modifierModifierModifierÇipin modifier'ı. Çipin ayırdığı dokunma hedefinin dışına uygulanır.
leadingIconImageVector?nullEtiketin önündeki ikon. Stilin ikon boyutunda çizilir. Seçili bir çip onun yerinde bir onay işareti gösterir.
enabledBooleantrueÇipe basılıp basılamayacağı. Basılamayan çip devre dışı renklerle çizilir ve devre dışı olduğunu söyler.
styleChipStyle?nullBu çağrının kendi stili: çevresindeki her stili ezer, yoğunluk ona da uygulanır. Yalnızca verdiği alanlar değişir ve her platformda değişir.
colorsChipColors?nullBu çipin kendi renkleri: verdiği renkler kullanılır, gerisi temanınkilerdir. Devre dışı bir çip temanın renklerinde kalır.
tagKeyString?nullÇipin otomasyon anahtarı: çip Chip_<tagKey>'dir. Bir değişiklik Chip olayı olarak bildirilir: toggle. Olay istenen değeri taşır, etiketin metnini hiçbir zaman taşımaz.
interactionSourceMutableInteractionSource?nullÇipin dışarı taşınan etkileşimleri. Null ise çip kendi kaynağını tutar.

ChipStyle

PantrixChip'in geometrisi.

ParametreTürVarsayılanNe olduğu
shapeShapeSpecShapeSpec.UnspecifiedÇipin şekli: markanın şekil ölçeğinin bir adımı ya da sabit bir şekil.
heightDpDp.UnspecifiedÇipin yüksekliği. Büyük bir yazı ölçeğinde bu yüksekliğe sığmayan etiket çipi yükseltir.
horizontalPaddingDpDp.Unspecifiedİkonu olmayan yanda, etiketle çipin kenarı arasındaki boşluk.
iconPaddingDpDp.Unspecifiedİkonla çipin kenarı arasındaki ve ikonla etiket arasındaki boşluk.
iconSizeDpDp.UnspecifiedBaştaki ikonun, seçili bir çipin onay işaretinin ve çıkarma düğmesindeki çarpının genişliği ve yüksekliği.
borderWidthDpDp.UnspecifiedSeçili olmayan bir çipin kenarının kalınlığı. Kenar çipin içine çizilir: çip kenarlıyken de kenarsızken de aynı boyuttadır.

ChipColors

Temanın renklerini almayan bir çip için PantrixChip'in boyandığı renkler: verilen renk kullanılır, verilmeyen temanın rolünde kalır. Bir ürün yalnızca değiştirdiği renkleri verir:

ParametreTürVarsayılanNe olduğu
containerColorColor.UnspecifiedSeçili olmayan çipin dolgusu. Varsayılan olarak yoktur: çip kenarından ve etiketinden ibarettir.
contentColorColor.UnspecifiedSeçili olmayan çipin etiketi. Temanın textPrimary rengi.
iconColorColor.UnspecifiedSeçili olmayan çipte etiketin önündeki ikon ve çıkarma düğmesinin çarpısı. Temanın textSecondary rengi.
borderColorColor.UnspecifiedSeçili olmayan çipin kenarı. Temanın border rengi.
selectedContainerColorColor.UnspecifiedAçık bir süzgecin dolgusu. Primary rolünün container'ı.
selectedContentColorColor.UnspecifiedAçık bir süzgecin etiketi ve onay işareti: selectedContainer'ın üstünde okunan renk. Primary rolünün onContainer'ı.