# Radio-Button-Group

Component of the SBB design system Lyne.

- Package: `@sbb-esta/lyne-elements` (Angular: `@sbb-esta/lyne-angular`)
- Structure: one element
- Categories: Form
- Status: Design guidelines complete

## Links

- Page on digital.sbb.ch: https://digital.sbb.ch/en/design-system/lyne/components/radio-button-group/
- Storybook: https://lyne-elements.app.sbb.ch/?path=/docs/elements-radio-button-group--docs
- Angular (`@sbb-esta/lyne-angular`): https://lyne-angular.app.sbb.ch/angular/components/radio-button-group/overview (API: https://lyne-angular.app.sbb.ch/angular/components/radio-button-group/api)
- Figma: https://www.figma.com/design/mWknI2rC5DJmOgRO61WKai/Lyne-Components?node-id=31104-609907
- GitHub: https://github.com/sbb-design-systems/lyne-components/tree/v5.12.0/src/elements/radio-button-group

## Elements

- `sbb-radio-button-group`: It can be used as a container for radio button elements.

## Overview

### What does the component do?
The radio button group combines [radio buttons](https://digital.sbb.ch/en/design-system/lyne/components/radio-button/) (also [radio button panels](https://digital.sbb.ch/en/design-system/lyne/components/radio-button-panel/) or [selection expansion panels](https://digital.sbb.ch/en/design-system/lyne/components/selection-expansion-panel/)) into one group. Only one entry can be selected at a time. It defines arrangement, name and states (e.g. required, disabled) for all entries.

### When should the component be used?
* Whenever radio buttons are used.
* For selecting several options at once, use the [checkbox group](https://digital.sbb.ch/en/design-system/lyne/components/checkbox-group/) instead.

### Rules.
* A radio button group only combines radio buttons that belong to the same question. The group needs a clear label, also for screen readers (`aria-label`).
* For many or long options, radio buttons are arranged one below the other (`orientation="vertical"`). Side by side only for a few short options. `horizontalFrom` defines from which width they are placed side by side.
* All radio buttons in a group have the same size.
* If a selection is required and none is made, an error message is shown for the whole group.

## Implementation (web components)

The `<sbb-radio-button-group>` is a component which can be used as a wrapper for
a collection of either [sbb-radio-button](https://lyne-elements.app.sbb.ch/?path=/docs/elements-radio-button--docs)s, [sbb-radio-button-panel](https://lyne-elements.app.sbb.ch/?path=/docs/elements-radio-button-panel--docs)s,
or [sbb-selection-expansion-panel](https://lyne-elements.app.sbb.ch/?path=/docs/elements-selection-expansion-panel--docs)s.
Individual radio-buttons inside a radio-group will inherit the `name` of the group.

```html
<!-- The first option will be selected by default -->
<sbb-radio-button-group name="radio-group" value="Value one" aria-label="Radio group label">
  <sbb-radio-button value="Value one">Option one</sbb-radio-button>
  <sbb-radio-button value="Value two">Option two</sbb-radio-button>
  <sbb-radio-button value="Value three">Option three</sbb-radio-button>
</sbb-radio-button-group>
```

Pressing a `<sbb-radio-button>` checks it and unchecks the previously selected one, if any.
They can also be controlled programmatically by setting the value property of the parent radio group to the value of the radio.

Please note that within a `<sbb-radio-button-group>`, only one `<sbb-radio-button>` can be selected at a time;
if you need to select more than one item, it is recommended to use the `<sbb-checkbox-group>` component.

### States

The radio group can have different states:

- can be completely disabled by setting the property `disabled`;
- can be required by setting the property `required`.

```html
<!-- All child radio buttons will be disabled -->
<sbb-radio-button-group value="Value one" aria-label="Radio group label" disabled>
  ...
</sbb-radio-button-group>

<!-- The radio group and all child radio buttons will be marked as required -->
<sbb-radio-button-group value="Value one" aria-label="Radio group label" required>
  ...
</sbb-radio-button-group>
```

In order to deselect a `<sbb-radio-button>` inside the `<sbb-radio-button-group>`,
you can use the `allowEmptySelection` property, which will be proxied to the inner `<sbb-radio-button>`
enabling their deselection (by default, a selected `<sbb-radio-button>` cannot be deselected).

```html
<sbb-radio-button-group allow-empty-selection> ... </sbb-radio-button-group>
```

### Style

The `orientation` property is used to set item orientation. Possible values are `horizontal` (default) and `vertical`.
The optional property `horizontalFrom` can be used in combination with `orientation='vertical'` to
indicate the minimum breakpoint from which the orientation changes to `horizontal`.

```html
<sbb-radio-button-group orientation="vertical" horizontal-from="large">
  ...
</sbb-radio-button-group>
```

### Events

Consumers can listen to the native `change`/`input` event on the `<sbb-radio-button-group>` component
to intercept the selection's change; the current value can be read from `event.detail.value`.

### Accessibility

In order to ensure readability for screen-readers, please provide an `aria-label` attribute for the `<sbb-radio-button-group>`.

### Complex Values

This component supports any types of values, including complex objects.
The type can be specified using the generic type parameter `T` of `SbbRadioButtonGroup<T>`.

```ts
const values = [
  { value: 'value1', name: 'Option 1' },
  { value: 'value2', name: 'Option 2' },
];
```

```html
<sbb-radio-button-group .value="${values[0]}" name="name">
  <sbb-radio-button .value="${values[0]}">Option 1</sbb-radio-button>
  <sbb-radio-button .value="${values[1]}">Option 2</sbb-radio-button>
</sbb-radio-button-group>
```

When using complex objects, it is possible to provide a custom `compareWith` function to control how values are matched:

```ts
const complexValues = [
  { id: 1, name: 'Option 1' },
  { id: 2, name: 'Option 2' },
  { id: 3, name: 'Option 3' },
];
```

```html
<sbb-radio-button-group
  .compareWith="${(v1, v2) => v1?.id === v2?.id}"
  .value="${complexValues[0]}"
>
  <sbb-radio-button .value="${complexValues[0]}">${complexValues[0].name}</sbb-radio-button>
  <sbb-radio-button .value="${complexValues[1]}">${complexValues[1].name}</sbb-radio-button>
  <sbb-radio-button .value="${complexValues[2]}">${complexValues[2].name}</sbb-radio-button>
</sbb-radio-button-group>
```

## API (web components)

Full API tables (attributes, events, slots, CSS properties): https://digital.sbb.ch/en/design-system/lyne/components/radio-button-group/api.md
