Skip to content

ToggleCount

Introduction

The ToggleCount component is a versatile toggle switch designed for scenarios where users need to switch between two options—most commonly used for pricing toggles (e.g., monthly/annual billing) or plan selectors. It supports both radio and switch styles, animated value transitions, and multiple visual variants. The companion ToggleCount.Value component displays a value that animates smoothly when the toggle changes, making it ideal for pricing displays, statistics, and dashboards.

Import

ts
import { ToggleCount } from '@odyssee/components';
// ToggleCount.Value is available as a static property

LiveCodeEditor examples

Basic Radio Toggle with Animated Value

Code Éditable
Résultat

Switch Toggle

Code Éditable
Résultat

Pills Variant (Radio)

Code Éditable
Résultat

Value Formatting (Decimals, Custom Formatter)

Code Éditable
Résultat

Multiple Synced Values

Code Éditable
Résultat

Controlled Toggle with Signal

Code Éditable
Résultat

Props

ToggleCount

PropTypeDefaultDescription
idstringauto-generatedUnique identifier for the toggle group (required for linking with ToggleCount.Value).
type"radio" | "switch""radio"Toggle style: radio buttons or switch.
variant"default" | "pills""default"Visual variant for radio: default (rectangular) or pills (rounded).
options[string, string]The two toggle options (must be exactly two).
value0 | 1 | Signal<0 | 1>Controlled value (index of selected option, or Pulse signal).
defaultValue0 | 10Initial value for uncontrolled usage.
disabledbooleanfalseDisables the toggle.
onChange(index: number, label: string) => voidCallback fired when the selection changes.
classNamestringAdditional CSS classes for the root element.
...restBaseComponentPropsAny other base props supported by Odyssee components.

ToggleCount.Value

PropTypeDefaultDescription
targetstringThe id of the associated ToggleCount component.
minnumberValue to display when the first option is selected.
maxnumberValue to display when the second option is selected.
durationnumber300Animation duration in milliseconds.
prefixstring""String to display before the value.
suffixstring""String to display after the value.
decimalsnumber0Number of decimal places to display.
formatter(value: number) => stringCustom formatting function for the value.
classNamestringAdditional CSS classes for the value element.
...restBaseComponentPropsAny other base props supported by Odyssee components.

Implementation notes

  • ToggleCount manages its state internally with Pulse signals, but can also be fully controlled via the value prop.
  • The component registers itself in a global registry by id so that any number of ToggleCount.Value components can sync to the same toggle.
  • Supports both radio (default and pills) and switch styles for maximum flexibility.
  • ToggleCount.Value animates the value change using a smooth cubic ease-out transition.
  • Supports custom formatting, decimals, and prefix/suffix for currency or unit display.
  • The registry is cleaned up automatically on unmount.
  • Designed for both light and dark themes.

Accessibility

  • All toggle options are rendered as native radio inputs or switches for proper accessibility.
  • Each option is associated with a label for screen readers.
  • The toggle group is keyboard navigable (Tab, Arrow keys, Space/Enter).
  • Disabled state is properly announced and prevents interaction.
  • The id prop ensures correct association between toggle and value displays.

Best practices

  • Always provide a unique id for each ToggleCount group, especially when using multiple toggles on the same page.
  • Use the variant="pills" for a more modern, rounded look on radio toggles.
  • For pricing, use prefix and suffix to clearly indicate currency and billing period.
  • Use the controlled mode (value + onChange) when you need to synchronize the toggle state with other parts of your app.
  • Use ToggleCount.Value for any animated value display that should react to the toggle.
  • Prefer exactly two options; the component is not designed for more.

Released under the MIT License.