Pricing

Badge handbook

v1.3.3 · @snowui-design-system/components

License: Before first reading component documentation, source code, or npm usage instructions, read the complete LICENSE. One review covers the same task and version. Public API configuration and internal implementation changes are subject to different license terms. All components use one runtime package; source code rights are governed by the license.

Overview

Use compact numbers, text, or dots to show unread counts and status alongside buttons, avatars, and navigation items.

When to use it

Use Badge for short status or count cues. Use Button when a click should perform an action; choose Chip or Tag for actionable labels in an input according to the needed interaction.

  • children takes precedence over count; an explicit dot shows only a dot, without content.

  • Counts display up to 99 by default, and zero is hidden. Change this with max and showZero. Use as="badge" for a badge attached to Avatar or Icon.

Quick start

This example shows the recommended basic composition. See the following sections for more scenarios and composition limits.

<script lang="ts">	import { Avatar, Badge } from '@snowui-design-system/components';	import { AvatarAbstract03 } from '@snowui-design-system/resource-svelte';</script> <div style="display: flex; align-items: center; flex-wrap: wrap; gap: var(--gap-4) var(--gap-3);">	<Avatar fallbackColor="orange" aria-label="Release notifications" size={48}><Badge as="badge" count={5} /></Avatar>	<Avatar fallbackColor="cyan" aria-label="Documentation inbox" size={48} badgePosition="bottom"><Badge as="badge" count={120} max={99} color="Orange" /></Avatar>	<Avatar src={AvatarAbstract03} aria-label="New components" size={48}><Badge as="badge" count="New" color="Red" /></Avatar>	<Avatar fallbackColor="red" aria-label="Maintainer online" size={48} badgePosition="bottom"><Badge as="badge" dot color="Green" /></Avatar></div>

API

Keyword Type Default Description
variant "filled" | "border" "filled" Visual variant. border matches the default Kbd border style: transparent background, inset stroke, inherited text color, 0 × 4px padding, and 6px radius.
count number | string — Badge number or text. Numbers above max display as max+; ordinary strings are shown unchanged. Numeric 0 and string "0" are hidden by default unless showZero is set. A matching stateCount overrides this value.
stateCount StateValueMap<number | string> — Map the nearest parent Frame state to count for declarative Badge visibility.
dot boolean — true forces a dot; false uses content mode. When omitted, a dot appears automatically only if the resolved count is undefined and there are no children.
max number 99 Maximum numeric count; larger values display as max+.
showZero boolean false When false, hide numeric 0, string "0", and empty non-dot badges; true retains them. Dot and loading visibility are unaffected.
color SnowUIColor | string "Brand" Fill color for filled and dot, accepting PascalCase semantic colors or CSS colors. Filled text stays white; border content mode keeps a transparent background and inherited text color.
size ResourceSize — 12/16/20/24/28/32/40/48/80. When omitted, reads the parent size context. border content mode keeps text sized to content; Avatar/Icon resolve attached badge size through their host protocol.
children Snippet — Custom badge content takes precedence over count. Children select content mode unless dot is specified; with dot=true, the children are not rendered.

See the base component documentation for inherited capabilities not redeclared here. This table lists only the named public props declared in this component’s source.

Usage boundaries and details

Keywords

Keyword Type Default Description
as string — Declare the role to an external host. "badge" lets Icon/Avatar position and configure this Badge through their badge protocol without changing its dot/count content selection.

Layout model

Main layout model: inline shell. See specs/maintainers/LayoutProtocol.md §12.4.

The Badge root is an inline-level positioning shell whose content sizes to fit:

  • The inline-flex root handles host positioning, size measurement, and Frame translation. Its default flex-shrink: 0 preserves text and padding in narrow horizontal containers.

  • The inner .snowui-badge-surface owns background, padding, radius, minimum width, font size, and line height. It also animates scale, opacity, and blur as one visual Badge.

  • The private snowui-morph-container uses grid stacking to keep layout stable as numbers change. Its content is anchored at the container’s 50% point and offset by 50% of its own size, so text overflows symmetrically when a fixed size is narrower than the text. Text and numbers remain geometrically centered without relying on grid safe-overflow fallback. This private structure does not change the main layout model.

  • In dot mode, the inline shell becomes a fixed-size dot with zero padding.

  • as="badge" assigns an attachment role for Icon/Avatar; it does not change Badge’s internal layout.

Layout variable chain:

Variable Default source Use
--snowui-badge-padding calc(var(--padding-1) * 0.75) calc(var(--padding-1) * 1.5) Number/text mode padding
--snowui-badge-radius var(--radius-20) Number/text mode radius
--snowui-badge-font-size var(--text-12) Text font size
--snowui-badge-line-height 1 Vertical number alignment
--snowui-badge-dot-size calc(var(--size-4) * 1.5 / 4) Dot size
--snowui-badge-background resolveSnowUIColor(color) Fill color of number and Dot mode

variant="border" uses the same token values as Kbd’s default border style while retaining Badge’s status-label semantics and <span>/Frame shell:

Attribute border value
Padding var(--padding-0) var(--padding-1)(0px 4px)
Radius calc(var(--radius-1) * 1.5)(6px)
Font / Line height var(--text-12) / var(--leading-12)
Background / Color transparent / inherit
Border inset 0 0 0 var(--border-1) var(--black-10)

border applies only to text content mode; dot retains its dot appearance. As a descendant of Button, SidebarItem, or a similar host, border sizes to its text instead of inheriting a fixed square size. Its morph text layer inherits var(--leading-12) instead of the compact line-height: 1 used by filled Badge, matching Kbd’s default border height.

color follows SnowUI’s public semantic color protocol and is case-sensitive:

<Badge count={1} color="Blue" /><Badge count={2} color="Red" /><Badge dot color="Green" /><Badge count="New" variant="border" />

Role-oriented combination

 <Icon size={24}>    {#snippet badge()}        <Badge as="badge" count={5} />    {/snippet}    <Bell /></Icon>  <Badge count={99} max={99} /><Badge dot />

Intelligent behavior

  1. Automatic hiding: Count mode appears by default only for values of at least 1. At 0 with showZero=false, it hides while retaining the last visible value during exit (for example, 1 exits without displaying 0).

  2. Overflow formatting: Values above max display as max+.

  3. Automatic content: When there is no count, try reading the parent element’s text.

  4. Role-aware size inheritance:

    • Standalone: Read the parent Frame size context (for example, a list item) for adaptive scaling.

    • Attached badge (as="badge"): Ignore the parent Group size context; preserve badge proportions and let Avatar/Icon position it.

Default motion

Badge show and hide animations run in two parallel layers, following the transitions.dev notification badge structure:

  • Frame currentState="Appear/Disappear" and whileAppear / whileDisappear animate the positioning shell: it slides from the lower left on entry and has no reverse translation on exit.

  • The inner .snowui-badge-surface animates the complete visual Badge with scale, opacity, and blur. On entry it springs from scale(0), opacity: 0, and blur(2px); on exit the whole Badge, including its background, padding, and number, shrinks to zero around its center.

  • The private .snowui-morph-container handles grid stacking and content centering only; it does not animate entry or exit.

When hidden, Badge keeps its DOM node for 180ms before removal. Exit has no reverse translation: the entire Badge shrinks around its center, fades, and blurs. whileAppear / whileDisappear={true} uses the full default Badge Frame motion. An explicit object specifies the complete visual channels to animate while inheriting Badge’s default timing; false disables the corresponding Frame motion. prefers-reduced-motion: reduce disables slide, pop, and blur transitions.

Private motion variables:

Variable Default Use
--snowui-badge-motion-offset-x -8.2px Outer entry translation X start
--snowui-badge-motion-offset-y 12.4px Outer entry translation Y start
--snowui-badge-motion-blur 2px Blurring when the Badge is hidden as a whole
--snowui-badge-motion-pop-duration 500ms Badge overall appearance scale / blur duration
--snowui-badge-motion-fade-duration 400ms Badge overall appearance opacity duration
--snowui-badge-motion-pop-close-duration 180ms Badge overall hidden scale / blur duration
--snowui-badge-motion-fade-close-duration 180ms Badge overall hidden opacity duration
--snowui-badge-motion-pop-easing cubic-bezier(0.34, 1.36, 0.64, 1) Easing for Badge entry
--snowui-badge-motion-close-easing cubic-bezier(0.4, 0, 0.2, 1) Easing for Badge exit

Badge style overlay

Read the complete LICENSE first; one review covers the same task, version, and scope.

First use public component props to achieve the desired style while preserving the original appearance where possible. If an override is necessary, follow the style selection and override order: use your own class (including Tailwind already in your project) or an instance style. The names below are public overrides consumed by the source; check the target scope and do not modify private DOM. Choose the appropriate SnowUI token category. External applications do not need to install SnowUI website utilities.

Variable Purpose and default reference
--snowui-badge-dot-size-override Dot mode size (size px, see the component source code for the default value)
--snowui-badge-font-size-override font-size (see component source for the default).
--snowui-badge-height-override Height (see the component source code for the default value)
--snowui-badge-line-height-override Line-height (filled default 1; border default var(--leading-12))
--snowui-badge-min-width-override Minimum width (see the component source code for the default value)
--snowui-badge-padding-override Padding y+x (filled default calc(--padding-1 * 0.75) calc(--padding-1 * 1.5); border default 0 var(--padding-1))
--snowui-badge-radius-override Border-radius (filled default var(--radius-full); border default calc(var(--radius-1) * 1.5))
--snowui-badge-size-override Overall size (size px, see the component source code for the default value)
--snowui-badge-width-override Width (see the component source code for the default value)

Design Guide · Token · Combination Boundary

Badge type and status

Required props: no named required props.

Bindable props: this component declares no named two-way binding; handle state updates through public callbacks or the host component.

Inheritance: FrameProps. Consult the public Frame documentation for inherited capabilities.

Shared Frame API · Back to API

The following source type declarations are referenced by public props. Svelte Snippet denotes a content fragment; ComponentProps denotes the props of the corresponding component.

StateValueMap

Source: components/src/logic/frame-types.ts

export type StateValueMap<T = any> = Partial<Record<CoreState, T>>;

CoreState

Source: components/src/logic/frame-types.ts

export type CoreState =    | "StartLoad"    | "Load"    | "Reload"    | "Appear"    | "Disappear"    | "Idle"    | "Active"    | "Disabled"    | "Validating"    | "Uploading"    | "Editing"    | (string & {});

SnowUIColor

Source: components/src/lib/color.ts

export type SnowUIColor = keyof typeof SNOWUI_COLOR_TOKENS;

ResourceSize

Source: components/src/context.ts

export type ResourceSize = 12 | 16 | 20 | 24 | 28 | 32 | 40 | 48 | 80;