Theme
Version
GitHub PyPI Discord
On this page

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.

TagGroup at a glance
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.

Select Tags
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.

Request Tag removal
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
Run Tag actions
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.

Compose Tag content
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:

Compare Tag variants and sizes
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
Customize Tags
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(...).

InputTypeDefaultEffect
labelstrrequiredSupplies the visible fallback label and accessible group name.
idstr | NoneNoneSupplies the exact root and relationship prefix.
valuestr | Sequence[str] | None (CTagValue)NoneSets initial single or multiple selection.
selection_mode"none" | "single" | "multiple" (CTagSelectionMode)"none"Selects descriptive or selectable behavior.
mandatoryboolFalsePrevents activation from clearing the final selection.
actionableboolFalseEnables Tag action callbacks.
removableboolFalseAdds form-safe remove Buttons and deletion keys.
remove_labelstr"Remove"Supplies the translated remove action label.
disabledboolFalseDisables 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)NoneAdds root classes.
styleCStyleValue | None (CStyleValue)NoneAdds root inline styles.
attrsMapping[str, object] | NoneNoneAdds 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 />.

InputTypeOmitted behaviorEffect
valuestring | null | string[] | undefinedReleases control and preserves the last effective selection.Controls selection while supplied.
disabledboolean | undefinedUses the server fallback.Overrides local disabledness while valid.
variant"soft" | "solid" | "outline" | undefinedUses the server fallback.Overrides visual treatment while valid.
size"sm" | "md" | "lg" | undefinedUses the server fallback.Overrides geometry while valid.
onValueChange((value, detail) => void) | undefinedNo selection notification.Receives selection requests.
onAction((value, detail) => void) | undefinedNo action notification.Receives enabled actionable Tag activation.
onRemove((values, detail) => void) | undefinedNo 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(...).

InputTypeDefaultEffect
valuestrrequiredSupplies unique canonical identity within the group.
disabledboolFalseDisables this Tag.
text_valuestr | NoneNoneSupplies typeahead text instead of current label text.
class_CClassValue | None (CClassValue)NoneAdds Tag-root classes.
styleCStyleValue | None (CStyleValue)NoneAdds Tag-root inline styles.
attrsMapping[str, object] | NoneNoneAdds 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 />.

InputTypeOmitted behaviorEffect
disabledboolean | undefinedUses the server fallback.Overrides item-local disabledness while valid.
textValuestring | null | undefinedUses 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

SlotRequiredDataFallback
defaultyes{} (CTagGroupDefaultSlotData)None.
labelno{} (CTagGroupLabelSlotData)Escaped label input.
descriptionno{} (CTagGroupDescriptionSlotData)Wrapper omitted.

CTag slots

SlotRequiredDataFallback
defaultyes{} (CTagDefaultSlotData)None.
startno{} (CTagStartSlotData)Wrapper omitted.

Events

Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.

CTagGroup events

EventSignatureTrigger and timingDetailControlled 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.

VariableTypePurposeDefault
--cui-tag-gaplengthInline gap between Tags.0.5rem
--cui-tag-row-gaplengthGap between wrapped rows.0.5rem
--cui-tag-backgroundcolorUnselected fill.Variant and scheme derived.
--cui-tag-foregroundcolorUnselected text.Variant and scheme derived.
--cui-tag-border-colorcolorTag border.Scheme-derived neutral.
--cui-tag-selected-backgroundcolorSelected fill.Scheme-derived primary.
--cui-tag-selected-foregroundcolorSelected text.White.
--cui-tag-selected-border-colorcolorSelected border.Selected background.
--cui-tag-focus-colorcolorFocus outline.Highlight
--cui-tag-radiuslengthTag corner radius.999px
--cui-tag-min-heightlengthMinimum Tag block size.Size derived.
--cui-tag-padding-inlinelengthTag inline padding.Size derived.
--cui-tag-internal-gaplengthGap between internal parts.Size derived.
--cui-tag-font-sizelengthTag label size.Size derived.
--cui-tag-label-colorcolorGroup-label foreground.CanvasText
--cui-tag-description-colorcolorDescription 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

AttributeElementTypeMeaning
data-selection-modeGroup root"none" | "single" | "multiple"Reflects collection behavior.
data-actionableGroup rootpresent-or-absentPresent when action callbacks are enabled.
data-removableGroup rootpresent-or-absentPresent when removal is enabled.
data-disabledGroup rootpresent-or-absentMirrors effective group disabledness.
data-variantGroup root and Tag"soft" | "solid" | "outline"Reflects visual treatment.
data-sizeGroup root and Tag"sm" | "md" | "lg"Reflects geometry.

CTag attributes

AttributeElementTypeMeaning
data-valueTag rootstringExposes canonical identity.
data-selectedTag rootpresent-or-absentMirrors effective selection.
data-disabledTag rootpresent-or-absentMirrors effective item disabledness.
data-removableTag rootpresent-or-absentPresent when the remove affordance exists.
aria-selectedSelectable Tag rowbooleanExposes selection to assistive technology.
aria-disabledInteractive Tag rowbooleanExposes effective disabledness.

Selectors

Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.

CTagGroup selectors

SelectorElementPurpose
[data-citry-ui-part="tag-group"]Group rootStable group and attrs destination.
[data-citry-ui-part="group-label"]Visible group labelNames the collection.
[data-citry-ui-part="list"]List or gridStable direct collection surface.
[data-citry-ui-part="description"]Optional descriptionDescribes the collection.
[data-citry-ui-part="tag"]Tag rootStable Tag and attrs destination.
[data-citry-ui-part="indicator"]Selection indicatorExposes selected state visually.
[data-citry-ui-part="start"]Decorative start wrapperPositions composed decoration.
[data-citry-ui-part="tag-label"]Tag labelSupplies the accessible Tag name.
[data-citry-ui-part="remove"]Native ButtonRequests removal.

Interfaces

Aliases and data shapes referenced above.

Input type aliases

InterfaceDefinition
CClassValuestr | Mapping[str, bool] | Sequence[CClassValue]
CStyleValuestr | Mapping[str, str | int | float | bool | None] | Sequence[CStyleValue]
CTagSelectionModeLiteral["none", "single", "multiple"]
CTagVariantLiteral["soft", "solid", "outline"]
CTagSizeLiteral["sm", "md", "lg"]
CTagValuestr | None | Sequence[str]

CTagValueChangeDetail

FieldTypeDefaultMeaning
valuestr | list[str] | None-Requested selection.
previousValuestr | list[str] | None-Selection before activation.
tagValuestr-Activated Tag identity.
source"activation"-Change origin.
controlledbool-Whether client value controls selection.
nativeEventEvent-Triggering native event.

CTagActionDetail

FieldTypeDefaultMeaning
valuestr-Activated Tag identity.
source"activation"-Action origin.
nativeEventEvent-Triggering native event.

CTagRemoveDetail

FieldTypeDefaultMeaning
valueslist[str]-Requested removal identities.
tagValuestr-Tag that received the removal action.
source"remove-button" | "delete-key"-Removal origin.
nativeEventEvent-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

KeyPurposeVariablesOverrideBrowser updates
citry-ui-tag-removeSupplies hidden accessible text for every remove control.Noneremove_label input$c-tr updates text content.