Tag and TagGroup
Use CTagGroup for a labelled collection of compact categories, filters, or keywords. A descriptive group renders list semantics. Selection, actions, or removal switch it to one keyboard-operable grid.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class TagGlance(Component):
template = """
<c-CStack gap="lg">
<c-CTagGroup label="Topics">
<c-CTag value="css">CSS</c-CTag>
<c-CTag value="html">HTML</c-CTag>
<c-CTag value="accessibility">Accessibility</c-CTag>
</c-CTagGroup>
<c-CTagGroup label="Amenities" selection_mode="multiple" c-value="['wifi']">
<c-CTag value="wifi">Wi-Fi</c-CTag>
<c-CTag value="parking">Parking</c-CTag>
<c-CTag value="pool">Pool</c-CTag>
</c-CTagGroup>
</c-CStack>
"""
preview = TagGlance()
preview # noqa: B018
<c-CTagGroup label="Topics">
<c-CTag value="css">CSS</c-CTag>
<c-CTag value="html">HTML</c-CTag>
</c-CTagGroup>
Select Tags
Choose a selection mode and give every Tag a unique value.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class TagSelection(Component):
template = """
<div x-data="{chosen: ['quiet']}" class="citry-ui-demo-stack">
<c-CTagGroup
label="Workspace qualities"
selection_mode="multiple"
$c-props="{value: chosen, onValueChange: (value) => chosen = value}"
>
<c-CTag value="quiet">Quiet</c-CTag>
<c-CTag value="bright">Bright</c-CTag>
<c-CTag value="central">Central</c-CTag>
</c-CTagGroup>
<output x-text="chosen.join(', ')"></output>
</div>
"""
preview = TagSelection()
preview # noqa: B018
<c-CTagGroup
label="Amenities"
selection_mode="multiple"
c-value="['wifi']"
$c-props="{
value: selectedAmenities,
onValueChange: (value) => selectedAmenities = value
}"
>
<c-CTag value="wifi">Wi-Fi</c-CTag>
<c-CTag value="parking">Parking</c-CTag>
<c-CTag value="pool">Pool</c-CTag>
</c-CTagGroup>
A supplied client value is authoritative. The callback requests the next selection; it does not mutate a controlled group. Omit the prop to release control while preserving the last effective selection. mandatory=True prevents user activation from clearing the final selection.
Actions and removal
actionable=True reports enabled Tag activation through onAction. removable=True adds one form-safe remove Button and enables Delete and Backspace. Removal is a request: update your collection to remove the values.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class TagRemoval(Component):
template = """
<div x-data="{last: 'None'}" class="citry-ui-demo-stack">
<c-CTagGroup
label="Project topics"
removable
$c-props="{onRemove: (values) => last = values.join(', ')}"
>
<c-CTag value="Design">Design</c-CTag>
<c-CTag value="Research">Research</c-CTag>
<c-CTag value="Delivery">Delivery</c-CTag>
</c-CTagGroup>
<output x-text="`Requested removal: ${last}`"></output>
</div>
"""
preview = TagRemoval()
preview # noqa: B018
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class TagActions(Component):
template = """
<div x-data="{last: 'None'}" class="citry-ui-demo-stack">
<c-CTagGroup
label="Open view"
actionable
$c-props="{onAction: (value) => last = value}"
>
<c-CTag value="overview">Overview</c-CTag>
<c-CTag value="activity">Activity</c-CTag>
<c-CTag value="settings">Settings</c-CTag>
</c-CTagGroup>
<output x-text="`Last action: ${last}`"></output>
</div>
"""
preview = TagActions()
preview # noqa: B018
<c-CTagGroup
label="Saved filters"
removable
$c-props="{
onRemove: (values) => removeSavedFilters(values)
}"
>
<c-CTag value="open">Open</c-CTag>
<c-CTag value="assigned">Assigned to me</c-CTag>
</c-CTagGroup>
When a selected Tag in multiple mode receives Delete, the request includes all selected removable values. Focus follows retained values across reorder and moves to the nearest following Tag after removal.
Content
The default slot is the Tag label. start accepts decorative noninteractive phrasing content such as an Icon or Avatar.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class TagContent(Component):
template = """
<div style="max-inline-size: 22rem">
<c-CTagGroup label="People">
<c-CTag value="ava">
<c-fill name="start"><c-CAvatar alt="Ava" size="sm">A</c-CAvatar></c-fill>
<c-fill name="default">Ava, accessibility research</c-fill>
</c-CTag>
<c-CTag value="leo">
<c-fill name="start"><c-CAvatar alt="Leo" size="sm">L</c-CAvatar></c-fill>
<c-fill name="default">Leo, design systems</c-fill>
</c-CTag>
</c-CTagGroup>
</div>
"""
preview = TagContent()
preview # noqa: B018
<c-CTagGroup label="People">
<c-CTag value="ava">
<c-fill name="start"><c-CAvatar alt="Ava" size="sm">A</c-CAvatar></c-fill>
<c-fill name="default">Ava</c-fill>
</c-CTag>
</c-CTagGroup>
Tag content must not contain links, Buttons, form controls, focusable content, or nested Tags. Use a native anchor outside TagGroup when the job is navigation. Free-form entry and editing belong to CTagsInput.
Keyboard behavior
- Arrow keys move through enabled Tags and wrap.
- Home and End move to the first and last enabled Tag.
- Typing moves to the next matching Tag label or
text_value. - Enter and Space activate selection and actions.
- Delete and Backspace request removal.
- Tab from a removable Tag reaches its remove Button; Shift+Tab returns.
The group has one page-tab entry. Descriptive groups remain ordinary lists and do not add keyboard stops.
Disabledness and forms
Group disabledness, item disabledness, CForm.disabled, and native disabled fieldsets all dominate interaction. TagGroup is not a form control and adds no FormData. Owned remove Buttons always use type="button".
Presentation and customization
Variants are soft, solid, and outline. Sizes are sm, md, and lg. Customize through public variables or stable part selectors:
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class TagVariants(Component):
template = """
<c-CStack gap="lg">
<c-CTagGroup
c-for="variant in ['soft', 'solid', 'outline']"
c-label="variant"
c-variant="variant"
selection_mode="single"
value="one"
>
<c-CTag value="one">Selected</c-CTag><c-CTag value="two">Available</c-CTag>
</c-CTagGroup>
<c-CTagGroup c-for="size in ['sm', 'md', 'lg']" c-label="size" c-size="size">
<c-CTag value="sample">Sample</c-CTag>
</c-CTagGroup>
</c-CStack>
"""
preview = TagVariants()
preview # noqa: B018
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class TagCustomization(Component):
css = """
:where(.forest-tags) {
--cui-tag-selected-background: #176b4d;
--cui-tag-selected-foreground: #fff;
--cui-tag-radius: 0.45rem;
}
"""
template = """
<c-CTagGroup label="Forest filters" class_="forest-tags" selection_mode="multiple" c-value="['fern']">
<c-CTag value="fern">Fern</c-CTag>
<c-CTag value="moss">Moss</c-CTag>
<c-CTag value="river">River</c-CTag>
</c-CTagGroup>
"""
preview = TagCustomization()
preview # noqa: B018
.brand-tags {
--cui-tag-selected-background: #176b4d;
--cui-tag-selected-foreground: #fff;
--cui-tag-radius: 0.5rem;
}
See api.yml for the exhaustive inputs, callbacks, variables, attributes, selectors, slots, and public interfaces.
API reference
Inputs
CTagGroup server inputs
Server inputs are passed in a template through <c-CTagGroup ... /> or in Python through CTagGroup(...).
| Input | Type | Default | Effect |
|---|---|---|---|
label | str | required | Supplies the visible fallback label and accessible group name. |
id | str | None | None | Supplies the exact root and relationship prefix. |
value | str | Sequence[str] | None (CTagValue) | None | Sets initial single or multiple selection. |
selection_mode | "none" | "single" | "multiple" (CTagSelectionMode) | "none" | Selects descriptive or selectable behavior. |
mandatory | bool | False | Prevents activation from clearing the final selection. |
actionable | bool | False | Enables Tag action callbacks. |
removable | bool | False | Adds form-safe remove Buttons and deletion keys. |
remove_label | str | "Remove" | Supplies the translated remove action label. |
disabled | bool | False | Disables the owned collection; Form and fieldset disabledness remain dominant. |
variant | "soft" | "solid" | "outline" (CTagVariant) | "soft" | Selects visual treatment. |
size | "sm" | "md" | "lg" (CTagSize) | "md" | Selects Tag geometry. |
class_ | CClassValue | None (CClassValue) | None | Adds root classes. |
style | CStyleValue | None (CStyleValue) | None | Adds root inline styles. |
attrs | Mapping[str, object] | None | None | Adds trusted root attributes without replacing owned semantics. |
CTagGroup client inputs
Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CTagGroup />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
value | string | null | string[] | undefined | Releases control and preserves the last effective selection. | Controls selection while supplied. |
disabled | boolean | undefined | Uses the server fallback. | Overrides local disabledness while valid. |
variant | "soft" | "solid" | "outline" | undefined | Uses the server fallback. | Overrides visual treatment while valid. |
size | "sm" | "md" | "lg" | undefined | Uses the server fallback. | Overrides geometry while valid. |
onValueChange | ((value, detail) => void) | undefined | No selection notification. | Receives selection requests. |
onAction | ((value, detail) => void) | undefined | No action notification. | Receives enabled actionable Tag activation. |
onRemove | ((values, detail) => void) | undefined | No removal notification. | Receives remove Button or deletion-key requests. |
CTag server inputs
Server inputs are passed in a template through <c-CTag ... /> or in Python through CTag(...).
| Input | Type | Default | Effect |
|---|---|---|---|
value | str | required | Supplies unique canonical identity within the group. |
disabled | bool | False | Disables this Tag. |
text_value | str | None | None | Supplies typeahead text instead of current label text. |
class_ | CClassValue | None (CClassValue) | None | Adds Tag-root classes. |
style | CStyleValue | None (CStyleValue) | None | Adds Tag-root inline styles. |
attrs | Mapping[str, object] | None | None | Adds trusted Tag-root attributes without replacing owned semantics. |
CTag client inputs
Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CTag />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
disabled | boolean | undefined | Uses the server fallback. | Overrides item-local disabledness while valid. |
textValue | string | null | undefined | Uses server text or current label text. | Overrides typeahead text while valid. |
Slots
Slots are passed as nested content or <c-fill> tags in a template, or through the slots={...} argument in Python.
CTagGroup slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {} (CTagGroupDefaultSlotData) | None. |
label | no | {} (CTagGroupLabelSlotData) | Escaped label input. |
description | no | {} (CTagGroupDescriptionSlotData) | Wrapper omitted. |
CTag slots
| Slot | Required | Data | Fallback |
|---|---|---|---|
default | yes | {} (CTagDefaultSlotData) | None. |
start | no | {} (CTagStartSlotData) | Wrapper omitted. |
Events
Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.
CTagGroup events
| Event | Signature | Trigger and timing | Detail | Controlled and cancellation behavior |
|---|---|---|---|---|
onValueChange | (value, detail: CTagValueChangeDetail) => void (CTagValueChangeDetail) | Enabled selectable Tag proposes a different value. | {value, previousValue, tagValue, source, controlled, nativeEvent} (CTagValueChangeDetail) | Runs before onAction; supplied client value remains authoritative. |
onAction | (value: str, detail: CTagActionDetail) => void (CTagActionDetail) | Enabled actionable Tag activates. | {value, source, nativeEvent} (CTagActionDetail) | Runs after a selection request. |
onRemove | (values: list[str], detail: CTagRemoveDetail) => void (CTagRemoveDetail) | Remove Button or Delete and Backspace. | {values, tagValue, source, nativeEvent} (CTagRemoveDetail) | Requests owner collection removal without changing structure. |
Methods
-
CSS
CSS variables to theme the components. Set them on an ancestor or the component itself.
CTagGroup CSS variables
Apply these variables to CTagGroup or one of its ancestors.
| Variable | Type | Purpose | Default |
|---|---|---|---|
--cui-tag-gap | length | Inline gap between Tags. | 0.5rem |
--cui-tag-row-gap | length | Gap between wrapped rows. | 0.5rem |
--cui-tag-background | color | Unselected fill. | Variant and scheme derived. |
--cui-tag-foreground | color | Unselected text. | Variant and scheme derived. |
--cui-tag-border-color | color | Tag border. | Scheme-derived neutral. |
--cui-tag-selected-background | color | Selected fill. | Scheme-derived primary. |
--cui-tag-selected-foreground | color | Selected text. | White. |
--cui-tag-selected-border-color | color | Selected border. | Selected background. |
--cui-tag-focus-color | color | Focus outline. | Highlight |
--cui-tag-radius | length | Tag corner radius. | 999px |
--cui-tag-min-height | length | Minimum Tag block size. | Size derived. |
--cui-tag-padding-inline | length | Tag inline padding. | Size derived. |
--cui-tag-internal-gap | length | Gap between internal parts. | Size derived. |
--cui-tag-font-size | length | Tag label size. | Size derived. |
--cui-tag-label-color | color | Group-label foreground. | CanvasText |
--cui-tag-description-color | color | Description foreground. | Scheme-derived muted text. |
Attributes
HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.
CTagGroup attributes
| Attribute | Element | Type | Meaning |
|---|---|---|---|
data-selection-mode | Group root | "none" | "single" | "multiple" | Reflects collection behavior. |
data-actionable | Group root | present-or-absent | Present when action callbacks are enabled. |
data-removable | Group root | present-or-absent | Present when removal is enabled. |
data-disabled | Group root | present-or-absent | Mirrors effective group disabledness. |
data-variant | Group root and Tag | "soft" | "solid" | "outline" | Reflects visual treatment. |
data-size | Group root and Tag | "sm" | "md" | "lg" | Reflects geometry. |
CTag attributes
| Attribute | Element | Type | Meaning |
|---|---|---|---|
data-value | Tag root | string | Exposes canonical identity. |
data-selected | Tag root | present-or-absent | Mirrors effective selection. |
data-disabled | Tag root | present-or-absent | Mirrors effective item disabledness. |
data-removable | Tag root | present-or-absent | Present when the remove affordance exists. |
aria-selected | Selectable Tag row | boolean | Exposes selection to assistive technology. |
aria-disabled | Interactive Tag row | boolean | Exposes effective disabledness. |
Selectors
Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.
CTagGroup selectors
| Selector | Element | Purpose |
|---|---|---|
[data-citry-ui-part="tag-group"] | Group root | Stable group and attrs destination. |
[data-citry-ui-part="group-label"] | Visible group label | Names the collection. |
[data-citry-ui-part="list"] | List or grid | Stable direct collection surface. |
[data-citry-ui-part="description"] | Optional description | Describes the collection. |
[data-citry-ui-part="tag"] | Tag root | Stable Tag and attrs destination. |
[data-citry-ui-part="indicator"] | Selection indicator | Exposes selected state visually. |
[data-citry-ui-part="start"] | Decorative start wrapper | Positions composed decoration. |
[data-citry-ui-part="tag-label"] | Tag label | Supplies the accessible Tag name. |
[data-citry-ui-part="remove"] | Native Button | Requests removal. |
Interfaces
Aliases and data shapes referenced above.
Input type aliases
| Interface | Definition |
|---|---|
CClassValue | str | Mapping[str, bool] | Sequence[CClassValue] |
CStyleValue | str | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue] |
CTagSelectionMode | Literal["none", "single", "multiple"] |
CTagVariant | Literal["soft", "solid", "outline"] |
CTagSize | Literal["sm", "md", "lg"] |
CTagValue | str | None | Sequence[str] |
CTagValueChangeDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
value | str | list[str] | None | - | Requested selection. |
previousValue | str | list[str] | None | - | Selection before activation. |
tagValue | str | - | Activated Tag identity. |
source | "activation" | - | Change origin. |
controlled | bool | - | Whether client value controls selection. |
nativeEvent | Event | - | Triggering native event. |
CTagActionDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
value | str | - | Activated Tag identity. |
source | "activation" | - | Action origin. |
nativeEvent | Event | - | Triggering native event. |
CTagRemoveDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
values | list[str] | - | Requested removal identities. |
tagValue | str | - | Tag that received the removal action. |
source | "remove-button" | "delete-key" | - | Removal origin. |
nativeEvent | Event | - | Triggering native event. |
CTagGroupDefaultSlotData
Empty dataclass: {}.
CTagGroupLabelSlotData
Empty dataclass: {}.
CTagGroupDescriptionSlotData
Empty dataclass: {}.
CTagDefaultSlotData
Empty dataclass: {}.
CTagStartSlotData
Empty dataclass: {}.
Translation keys
Catalog keys used by this family. An explicit component input or slot listed in Override takes precedence over the catalog for that instance.
CTagGroup translation keys
| Key | Purpose | Variables | Override | Browser updates |
|---|---|---|---|---|
citry-ui-tag-remove | Supplies hidden accessible text for every remove control. | None | remove_label input | $c-tr updates text content. |