Pantrix UI

Tag

A short label on a piece of data: a status, a category, a version.

import com.pantrixui.components.data.tag.PantrixTag

Examples

Tones and variants

One variant to a row, six tones in each: Soft, Solid and Outline. Each tag's words say what its tone means; the colour only backs them up.

Column(verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md)) {
    TagVariant.entries.forEach { variant ->
        FlowRow(
            horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
            verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
        ) {
            TONE_WORDS.forEach { (tone, words) ->
                PantrixTag(text = words, tone = tone, variant = variant, tagKey = "${variant.name}_${tone.name}")
            }
        }
    }
}

private val TONE_WORDS = listOf(
    TagTone.Primary to "Featured",
    TagTone.Info to "Info",
    TagTone.Success to "Paid",
    TagTone.Warning to "Expiring",
    TagTone.Danger to "Overdue",
    TagTone.Neutral to "Draft"
)

Icon and dot

The icon stands before the words, in their colour, and says nothing to a screen reader. The dot is in the role's full colour and tells a state: online, outage, offline. Where both are given, the icon is drawn.

Column(verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md)) {
    FlowRow(
        horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
        verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
    ) {
        PantrixTag(text = "Verified", tone = TagTone.Success, icon = PantrixIcons.Check)
        PantrixTag(text = "Beta", tone = TagTone.Info, icon = PantrixIcons.Info)
        PantrixTag(text = "Low stock", tone = TagTone.Warning, icon = PantrixIcons.Warning)
        PantrixTag(text = "Featured", tone = TagTone.Primary, variant = TagVariant.Solid, icon = PantrixIcons.Star)
    }
    FlowRow(
        horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
        verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
    ) {
        PantrixTag(text = "Online", tone = TagTone.Success, dot = true, tagKey = "online")
        PantrixTag(text = "Outage", tone = TagTone.Danger, variant = TagVariant.Solid, dot = true)
        PantrixTag(text = "Offline", dot = true)
        PantrixTag(text = "Active", tone = TagTone.Success, variant = TagVariant.Outline, dot = true)
    }
}

The state of a row

A tag's own place is at the end of a row: an invoice's state. The row does not shrink to the tag; the tag stands inside it without taking it over, and is not pressed. Where a press on the row does something, the row does it.

Column(verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md)) {
    INVOICES.forEach { invoice ->
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md),
            verticalAlignment = Alignment.CenterVertically
        ) {
            PantrixText(text = invoice.number, modifier = Modifier.weight(1f), maxLines = 1)
            PantrixText(text = invoice.amount, color = PantrixTheme.colors.textSecondary, maxLines = 1)
            PantrixTag(
                text = invoice.state.words,
                tone = invoice.state.tone,
                dot = true,
                tagKey = "state_${invoice.key}"
            )
        }
    }
}

private val INVOICES = listOf(
    Invoice("1042", "Invoice #1042", "1 240 ₺", InvoiceState.Paid),
    Invoice("1043", "Invoice #1043", "860 ₺", InvoiceState.Due),
    Invoice("1044", "Invoice #1044", "3 125 ₺", InvoiceState.Overdue),
    Invoice("1045", "Invoice #1045", "410 ₺", InvoiceState.Draft)
)

private enum class InvoiceState(val words: String, val tone: TagTone) {
    Paid("Paid", TagTone.Success),
    Due("Due soon", TagTone.Warning),
    Overdue("Overdue", TagTone.Danger),
    Draft("Draft", TagTone.Neutral)
}

private class Invoice(val key: String, val number: String, val amount: String, val state: InvoiceState)

Beside a title

An article's topics, beside its title: tags with no fill, which do not shout on a page in colour. The tags that do not fit go to the next line; FlowRow does that, not the tag. The last tag has little room, and its words are cut with "…".

Column(verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md)) {
    FlowRow(
        horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
        verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
        itemVerticalAlignment = Alignment.CenterVertically
    ) {
        PantrixText(text = "Theming in Compose Multiplatform", style = PantrixTheme.typography.title)
        TOPICS.forEach { topic -> PantrixTag(text = topic, variant = TagVariant.Outline) }
    }
    PantrixTag(
        text = "Three changes are waiting for review",
        modifier = Modifier.widthIn(max = NARROW_WIDTH.dp),
        tone = TagTone.Warning,
        tagKey = "narrow"
    )
}

private val TOPICS = listOf("Kotlin", "Design", "Accessibility")

private const val NARROW_WIDTH = 160

On a fill

On a fill that is not the theme's ground, here the primary role's full colour: Soft and Solid bring their own grounds and are drawn in their role's colours. The Outline, with no fill, is written in what is written there, white here: the role's own colour may not read on that fill.

PantrixSurface(color = PantrixTheme.colors.primary.color) {
    FlowRow(
        modifier = Modifier.padding(PantrixTheme.spacing.md),
        horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
        verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
    ) {
        PantrixTag(text = "New", tone = TagTone.Success)
        PantrixTag(text = "Limited", tone = TagTone.Warning, variant = TagVariant.Solid)
        PantrixTag(text = "Version 2.4", variant = TagVariant.Outline, tagKey = "outline_on_fill")
        PantrixTag(text = "Live", variant = TagVariant.Outline, dot = true)
    }
}

Colours of its own and a description of its own

colors gives a colour none of the theme's roles has: here the app's own violet. The colours not given stay the tone's. The last tag has a contentDescription: a screen reader says "Payment status: overdue" in place of "Overdue".

val own = ownColors()
FlowRow(
    horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
    verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
) {
    PantrixTag(
        text = "Campaign",
        colors = TagColors(container = own.container, content = own.onContainer, dot = own.color),
        dot = true,
        tagKey = "own"
    )
    PantrixTag(
        text = "Campaign",
        variant = TagVariant.Outline,
        colors = TagColors(content = own.onContainer, border = own.color)
    )
    PantrixTag(
        text = "Overdue",
        tone = TagTone.Danger,
        contentDescription = "Payment status: overdue",
        tagKey = "described"
    )
}

In its own style

In its own style: TagStyle gives a tag's height, its padding, its corners and its dot. Here the tags are pill-shaped, 32dp high, with a 10dp dot; every field not given is the platform's preset. textStyle gives the type of the words: here the theme's label, in bold.

val style = TagStyle(shape = ShapeRole.Full, height = 32.dp, horizontalPadding = 14.dp, dotSize = 10.dp)
val words = PantrixTheme.typography.label.copy(fontWeight = FontWeight.Bold)
FlowRow(
    horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm),
    verticalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.sm)
) {
    PantrixTag(
        text = "Online",
        tone = TagTone.Success,
        dot = true,
        style = style,
        tagKey = "online_pill",
        textStyle = words
    )
    PantrixTag(
        text = "Under maintenance",
        tone = TagTone.Warning,
        dot = true,
        style = style,
        tagKey = "maintenance_pill",
        textStyle = words
    )
}

API

text

A short label on a piece of data: a status, a category, a version.

ParameterTypeDefaultWhat it is
textStringwhat the tag says: a word or two.
modifierModifierModifierthe tag's modifier.
toneTagToneTagTone.Neutralthe colour role the tag is drawn in.
variantTagVariantTagVariant.Softhow much of the role the tag wears.
iconImageVector?nulldrawn before the words, in their colour. It says nothing to a screen reader.
dotBooleanfalsewhether a small disc in the role's full colour stands before the words, where there is no icon: a status a row is in.
contentDescriptionString?nullwhat a screen reader says for the tag in place of its words, or null for the words.
styleTagStyle?nullthis call's own style: over every enclosing one and under the density. Only the fields it sets change, on every platform.
colorsTagColors?nullthis tag's own colours, in place of its tone's: the ones it sets, with the tone's for the rest.
tagKeyString?nullthe tag's automation key: it is Tag_<tagKey>, and is tagged only when given one.
textStyleTextStylePantrixTheme.typography.footnotethe type the words are set in: the theme's footnote unless given. Their colour is the tag's.

TagStyle

PantrixTag's geometry: a label small enough to stand inside a row without taking it over.

ParameterTypeDefaultWhat it is
shapeShapeSpecShapeSpec.UnspecifiedThe tag's corners: a step of the brand's shape scale, or a fixed shape.
heightDpDp.UnspecifiedThe least height of a tag. A larger type makes it taller.
horizontalPaddingDpDp.UnspecifiedThe room between the tag's sides and what it holds.
iconPaddingDpDp.UnspecifiedBetween the icon or the dot and the words.
iconSizeDpDp.UnspecifiedThe width and height of the icon.
borderWidthDpDp.UnspecifiedThe width of the edge of TagVariant.Outline, and of an edge given in TagColors.
dotSizeDpDp.UnspecifiedThe width and height of the dot.

TagColors

What a PantrixTag is painted with, in place of its tone's colours: a colour that is set is used, and one that is left out stays the tone's.

ParameterTypeDefaultWhat it is
containerColorColor.UnspecifiedThe tag's fill. The role's container in TagVariant.Soft, its color in TagVariant.Solid, and none in TagVariant.Outline.
contentColorColor.UnspecifiedThe words and the icon: the colour that reads on container. The role's onContainer in TagVariant.Soft, its onColor in TagVariant.Solid, and its color in TagVariant.Outline, which reads on the theme's grounds. An outlined tag on a fill that is not the theme's ground is written in what is written there.
borderColorColor.UnspecifiedThe tag's edge: that of TagVariant.Outline, in content. A tag of another variant has one where it is given here.
dotColorColor.UnspecifiedThe dot: the role's color, and on the role's full colour its onColor. On a fill that is not the theme's ground, an outlined tag's dot is in content.