A wrapper that decorates any component: the hosted component sits in Slot#1, and up to two decorator slots float a badge, status indicator, icon, or Lottie above it — new features, alerts, counts, special actions.
Overview
DecorateContainer wraps a component and floats a decoration above it without touching the hosted component's own contract — the container never affects the states of what it hosts. It is the DS home for badges on icons, NEW labels on tiles, and status dots on avatars.
-
1
Slot#1
-
2
Slot#2 Decorator
-
3
Two decorators
Decorator
Decorator Slot#3
Decorator
Anatomy
Three slots: the hosted component and up to two independent decorators floating above it.
-
1
Slot#1 — the hosted component .decorate-container__slot1 — wraps the component on all sides: hug width and height.var(--sp-s0) — default paddings and corner radius; instance margins may be negative.
-
2
Slot#2 — the decorator .decorate-container__slot2 — absolute above the content, anchored per Layout; hug, var(--sp-s0) paddings and radius.Expands towards the direction opposite to its offset — it never pushes into adjacent screen content.Predefined content: Indicator (Simple, M), IconContainer (s24), ImageContainer (s24), Tag (Surface), Custom — any DS or local component.
-
3
Slot#3 — the second decorator .decorate-container__slot3 — the same contract as Slot#2; used independently or together with it.
Layout
Slot#1
Decorator
-
Wrapping Slot#1 wraps the component on all sides: height and width — hug.
-
Defaults var(--sp-s0) — the default horizontal and vertical paddings, and the default corner radius.
Margins
Decorator Slot#1 Slot#2
Decorator
-
Instance Margins Horizontal and vertical margins are set per instance — --dc-offset-x / --dc-offset-y on web — and they can be negative: the decorator tucks inside or pokes past the corner.
-
Opposite Expansion The decorator expands towards the direction opposite to its offset, so it never pushes into adjacent screen content.
Anchoring
Decorator Slot#1 Slot#2
Decorator Slot#1 Slot#2
Decorator Slot#1 Slot#2
Decorator Slot#1 Slot#2
Decorator Slot#1 Slot#2
Decorator Slot#1 Slot#2
Decorator Slot#1 Slot#2
Decorator Slot#1 Slot#2
Decorator
-
Horizontally To the right — by default (no modifier).In the center — --h-center.To the left — --h-left.
-
Vertically At the top — by default (no modifier).In the center — --v-center.At the bottom — --v-bottom.
Slot#2 wraps its component on all sides — hug, s0 paddings, s0 radius — and carries the predefined content set; Custom accepts any DS or local component.
Slot#2
-
Predefined Content Indicator — Simple style, M size, by default.IconContainer — var(--sp-s24) by default.ImageContainer — var(--sp-s24) by default. The s24 recipe size-class lands with its first product use.Tag — Surface style, by default.Custom — any component from the design system or a local one.
Slot#3 is the same contract — hug, s0 paddings, s0 radius, the same predefined set — used independently or together with Slot#2; its offset expands opposite too.
Slot#3
-
RTL Both decorator slots mirror their horizontal placement from the document's dir — right becomes left, center remains; vertical never changes. The web anchoring is logical (inset-inline-*), so the mirror needs no extra class.
Animation
The decorator appears and disappears with the Scale Short pattern — scale 0 ↔ 1 from the decorator's own center. The demo loops the honest lifecycle; the animation can be disabled per instance.
-
Enter var(--pattern-scale-short-appear) — 100 ms, standard-ease-in-out; only transform takes part.
-
Exit var(--pattern-scale-short-hide) — 200 ms, the same curve, back to scale 0.
-
Reduced motion Handled at the token: motion.css zeroes every --pattern-* inside prefers-reduced-motion: reduce — the primitive ships no override of its own.
Usage
A decoration floats above a component without touching its contract or the layout flow around it. Related: Indicator and Tag (the default decorator content), ServiceCard (the tile's top-right decoration slot is an instance of this primitive).
-
1
Unread Count An entry point carries how much is waiting behind it: the Indicator rides the host's corner, the host stays untouched.
-
2
Feature Markers A NEW tag and a status dot mark the host at two corners at once — Slot#2 and Slot#3 working together.
Accessibility
The container announces elements according to the hosted component's behaviour — it adds nothing of its own. Slot#1, Slot#2 and Slot#3 are one focus area; the focus rectangle covers the whole construction, decorator overhangs included.
-
1
Single Focus Area The decorator never becomes a separate swipe stop — one stop for the whole construction, and its meaning joins the host's announcement: "Menu, 1 notification".
-
2
Two Decorators, Still One Stop Slot#2 and Slot#3 together add their meaning to the same single announcement — "Profile photo, verified, online". A purely visual decorator adds nothing.
-
VoiceOver The container is the accessibility element (isAccessibilityElement = true on the wrapper, false on the slots); the trait comes from the hosted component — a Button host keeps the Button trait.
-
TalkBack The container is the single focusable node (screenReaderFocusable); the slots are importantForAccessibility="no". A count or status decorator lands in stateDescription — TalkBack reads "Menu, button, 1 notification" and re-announces when the count changes.
-
Web The decorator slots carry aria-hidden="true"; a meaningful decorator's text joins the host's accessible name. The Scale Short enter/exit never announces on its own — a decorator that must be heard is the host's live-region decision.
-
Resizing Size-increase parameters (100 / 130 / 150 %) are set within the hosted components themselves; DecorateContainer does not restrict or affect them.