Skip to content

Early previewhamur is not on npm yet. The components are being built in the open, follow along on GitHub.

InputsReact

Radio

One radio button of a RadioGroup.

Rendered by React 19.3.1

import * as React from 'react'
import { Radio } from '@hamur/react/radio'
import { RadioGroup } from '@hamur/react/radio-group'

export default function RadioExample() {
  const [size, setSize] = React.useState('medium')
  return (
    <div className="stack">
      <RadioGroup className="stack" defaultValue="medium" onValueChange={setSize}>
        <label className="row">
          <Radio.Root className="radio" value="small">
            <Radio.Indicator className="radio-indicator" />
          </Radio.Root>
          Small
        </label>
        <label className="row">
          <Radio.Root className="radio" value="medium">
            <Radio.Indicator className="radio-indicator" />
          </Radio.Root>
          Medium
        </label>
        <label className="row">
          <Radio.Root className="radio" value="large" disabled>
            <Radio.Indicator className="radio-indicator" />
          </Radio.Root>
          Large (sold out)
        </label>
      </RadioGroup>
      <p className="muted">Size: {size}</p>
    </div>
  )
}
91Tests passing in React · 0 failing
9.9 KiBSize
Not measured yetMemory
Not measured yetSpeed
productdevbook and 18 upstream authors8 commits · last

Installation

npm i @hamur/react

Not on npm yet. The package goes out under the chosen name.

Anatomy

Import the component and assemble its parts:

<Radio.Root>
  <Radio.Indicator />
</Radio.Root>

Examples

Radio is shown in RadioGroup's examples; it has no demo of its own.

API reference

7 props across 2 parts, in React syntax. className, style, render are listed once, under Shared props.

IndicatorRadio.Indicator

Indicates whether the radio button is selected. Renders a <span>.

Indicator props
PropTypeDefault
keepMountedWhether to keep the HTML element in the DOM when the radio button is inactive.booleanfalse
Indicator data attributes
Data attributeDescription
data-checkedPresent when the radio is checked.
data-uncheckedPresent when the radio is not checked.
data-disabledPresent when the radio is disabled.
data-readonlyPresent when the radio is readonly.
data-requiredPresent when the radio is required.
data-starting-stylePresent when the radio indicator begins animating in.
data-ending-stylePresent when the radio indicator is animating out.
data-validPresent when the radio is in a valid state (when wrapped in Field.Root).
data-invalidPresent when the radio is in an invalid state (when wrapped in Field.Root).
data-touchedPresent when the radio has been touched (when wrapped in Field.Root).
data-dirtyPresent when the radio's value has changed (when wrapped in Field.Root).
data-filledPresent when the radio is checked (when wrapped in Field.Root).
data-focusedPresent when the radio is focused (when wrapped in Field.Root).

RootRadio.Root

Represents the radio button itself. and a hidden <input> beside. Renders a <span>.

Root props
PropTypeDefault
valuerequiredThe unique identifying value of the radio in a group.TValue—
nativeButtonWhether the component renders a native <button> element when replacing itbooleanfalse
disabledWhether the component should ignore user interaction.boolean—
readOnlyWhether the user should be unable to select the radio button.boolean—
requiredWhether the user must choose a value before submitting a form.boolean—
inputRefA ref to access the hidden input element.React.Ref<HTMLInputElement>—
Root data attributes
Data attributeDescription
data-checkedPresent when the radio is checked.
data-uncheckedPresent when the radio is not checked.
data-disabledPresent when the radio is disabled.
data-readonlyPresent when the radio is readonly.
data-requiredPresent when the radio is required.
data-validPresent when the radio is in a valid state (when wrapped in Field.Root).
data-invalidPresent when the radio is in an invalid state (when wrapped in Field.Root).
data-touchedPresent when the radio has been touched (when wrapped in Field.Root).
data-dirtyPresent when the radio's value has changed (when wrapped in Field.Root).
data-filledPresent when the radio is checked (when wrapped in Field.Root).
data-focusedPresent when the radio is focused (when wrapped in Field.Root).

Shared props

Every part that renders an element takes these.

Shared props
PropType
classNameCSS class applied to the element, or a function that returns a class based on the component's state.string | ((state: State) => string | undefined)
styleStyle applied to the element, or a function that returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>

Keyboard and accessibility

Keyboard

Keyboard
KeysDoesPart
ArrowDownArrowUpArrowLeftArrowRightSelects the next or previous radio of the groupRoot

Accessibility

What the parts set
PartSetsSo that
Rootrole="radio", aria-checkeda screen reader reads it as a radio button and whether it is chosen
Rootaria-labelledby to an associated labela <label> or Field label names the radio
Roota hidden <input type="radio"> with aria-hidden="true" and tabindex="-1"the form gets the value without a second control to read or tab to
Indicatorrenders a <span> with your markthe dot is decoration; the state is on Root

Focus order

  1. The group is one tab stop: the checked radio, or the first one.
  2. Arrow keys move to and select the other radios.