Skip to main content
cngx-src documentation

CngxRadio

cngx-radio

ComponentPrimaryOnPushNo encapsulationv0.1.0WCAG AA

projects/common/interactive/radio/radio.component.ts

Import#

import { CngxRadio } from '@cngx/common/interactive'

Description#

Single radio leaf. Injects the parent group via CNGX_RADIO_GROUP (token, never the concrete CngxRadioGroup class) and writes group.value.set(this.value()) when the user picks it. The leaf does not own a value of its own - value is a required input<T> supplied by the consumer; checked-ness is derived from group.value() === this.value().

Composes CngxRovingItem as a host directive with input forwarding ('cngxRovingItemDisabled: disabled') so the consumer's [disabled] binding flows into both the radio's own disabled model AND the roving directive's skip-test - arrow-key navigation in the parent group (driven by CngxRovingTabindex) skips per-radio-disabled leaves automatically. Group-level [disabled] is a separate cascade via radioDisabled = computed(() => group.disabled() || disabled()); it blocks click + Space/Enter + auto-select (consumePendingArrowSelect returns false when the group is disabled) but is NOT forwarded to roving - a fully-disabled group lets focus transit visually while every selection pathway short-circuits.

Selection on click, Space, or Enter (auto-select also fires on arrow nav via consumePendingArrowSelect); Tab and programmatic focus do not select on focus alone (W3C APG variant - the parent group's keyboard contract makes this explicit).

The [attr.name] host binding is cosmetic (parity with native <input type="radio" name="…"> markup expectations); the <div role="radio"> host does not participate in HTML form submission, so the attribute carries no functional weight.

https://cngxjs.github.io/cngx/examples/#/common/interactive/radio/basic-vertical-group https://cngxjs.github.io/cngx/examples/#/common/interactive/radio/custom-dot-glyph https://cngxjs.github.io/cngx/examples/#/common/interactive/radio/disabled-group-cascades-per-radio-overrides https://cngxjs.github.io/cngx/examples/#/common/interactive/radio/orientation-horizontal https://cngxjs.github.io/cngx/examples/#/forms/field/form-primitives/coming-in-a-follow-up https://cngxjs.github.io/cngx/examples/#/forms/field/form-primitives/reactive-forms-same-atom-just-bind-formcontrol https://cngxjs.github.io/cngx/examples/#/forms/field/form-primitives/signal-forms-drop-the-atom-into-cngx-form-field

Metadata#

Host#

Relationships

Index#

Inputs#

disabled#boolean
model()
default false
disabledReason#string
input()
default ''
dotGlyph#TemplateRef | null
default null
value#T
input()Required

Outputs#

disabled#boolean
model()

Instance Properties#

describedId#unknown
ProtectedReadonly
nextUid('cngx-radio-desc')
group#unknown
ProtectedReadonly
inject<CngxRadioGroupContract<T>>(CNGX_RADIO_GROUP)

Methods#

handleFocus#void
Protected
handleKeydown#void
Protected
handleKeydown(event: Event)
@parameventEvent
handleSelect#void
Protected

HostBindings#

BindingExpression
[attr.aria-checked]radioChecked() ? "true" : "false"
[attr.aria-disabled]radioDisabled() ? "true" : null
[attr.aria-describedby]describedById()
[attr.name]group.name()
[class.cngx-radio--checked]radioChecked()
[class.cngx-radio--disabled]radioDisabled()

HostListeners#

EventHandler
(focus)focus()
(click)click()
(keydown.space)keydown.space()
(keydown.enter)keydown.enter()

Default visuals for the interactive shell around <cngx-radio-indicator>. The host carries .cngx-radio and renders the indicator plus a .cngx-radio__label slot for the projected label text and a .cngx-radio__sr-only slot for assistive-only copy. Visual state (filled circle vs ring) lives on the inner indicator; the --cngx-radio-indicator-* namespace is owned by CngxRadioIndicator and shell-specific --cngx-radio-* tokens are registered here without overlap.

State modifiers

  • --checked - unstyled here; exposed as a consumer-theming hook (the indicator paints the filled circle)
  • --disabled - cursor: not-allowed + opacity dim via --cngx-radio-disabled-opacity

Slots

  • .cngx-radio__label - projected label content
  • .cngx-radio__sr-only - visually-hidden copy for AT

Inheritance

Layout and focus tokens cascade through the foundation; the focus-outline default colour matches --cngx-color-primary so the ring stays in step with the foundation reset:

  • --cngx-radio-gap -> --cngx-space-sm
  • --cngx-radio-focus-outline -> --cngx-color-primary
  • --cngx-radio-focus-radius -> --cngx-radius-sm
  • --cngx-radio-color - direct (defaults to currentColor)

Index#

Layout

--cngx-radio-gap#*
Default value 0.5rem

Gap between the indicator and the label slot.

Surface

--cngx-radio-color#*
Default value currentColor

Text color of the host shell. Defaults to currentColor.

State / Disabled

--cngx-radio-disabled-opacity#<number>
Default value 0.5

Opacity multiplier applied by .cngx-radio--disabled.

State / Focus

--cngx-radio-focus-outline#*
Default value 2px solid oklch(0.66 0.19 50)

Focus-ring outline shorthand. Matches the foundation reset's :focus-visible accent so the radio reads consistently with every other focusable atom in the library.

--cngx-radio-focus-offset#*
Default value 3px

Outline offset of the focus ring. Matches the foundation reset's :focus-visible offset so the ring breathes the same against the indicator + label as it does against any other atom.

--cngx-radio-focus-radius#*
Default value 0.25rem

Corner radius applied while focused.