Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions apps/design-land/src/app/radio/radio.component.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
<h1>Daff Radio</h1>
<design-land-example-viewer-container example="basic-radio"></design-land-example-viewer-container>

<design-land-example-viewer-container example="radio-with-control"></design-land-example-viewer-container>

<design-land-example-viewer-container example="radio-with-hint"></design-land-example-viewer-container>

<design-land-example-viewer-container example="radio-with-error"></design-land-example-viewer-container>

<design-land-example-viewer-container example="radio-orientations"></design-land-example-viewer-container>
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<h2>Basic Radio</h2>
<daff-radio-set [formGroup]="radioGroup" name="race">
<daff-radio formControlName="race" value="Terran">Terran</daff-radio>
<daff-radio formControlName="race" value="Protoss">Protoss</daff-radio>
<daff-radio formControlName="race" value="Zerg">Zerg</daff-radio>
<daff-radio-set name="cc" value="visa" (valueChange)="update($event)">
<daff-form-label>Card Type</daff-form-label>
<daff-radio value="visa">Visa</daff-radio>
<daff-radio value="mastercard">MasterCard</daff-radio>
<daff-radio value="amex">American Express</daff-radio>
</daff-radio-set>
<div>
The best race to play as is: {{this.radioGroup.get('race').value}}
</div>

<div>Selected value: {{ value }}</div>
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ import {
ChangeDetectionStrategy,
Component,
} from '@angular/core';
import {
UntypedFormGroup,
UntypedFormControl,
ReactiveFormsModule,
} from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';

import { DAFF_RADIO_COMPONENTS } from '@daffodil/design/radio';

Expand All @@ -20,9 +16,9 @@ import { DAFF_RADIO_COMPONENTS } from '@daffodil/design/radio';
],
})
export class BasicRadioExampleComponent {
radioGroup = new UntypedFormGroup({
race: new UntypedFormControl('Zerg'),
});
value: any;

constructor() {}
update(val: any) {
this.value = val;
}
}
8 changes: 8 additions & 0 deletions libs/design-examples/radio/src/examples.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { BasicRadioExampleComponent } from './basic-radio/basic-radio.component';
import { RadioOrientationsExampleComponent } from './radio-orientations/radio-orientations.component';
import { RadioWithControlExampleComponent } from './radio-with-control/radio-with-control.component';
import { RadioWithErrorExampleComponent } from './radio-with-error/radio-with-error.component';
import { RadioWithHintExampleComponent } from './radio-with-hint/radio-with-hint.component';

export const RADIO_EXAMPLES = [
BasicRadioExampleComponent,
RadioWithControlExampleComponent,
RadioWithHintExampleComponent,
RadioWithErrorExampleComponent,
RadioOrientationsExampleComponent,
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<daff-radio-set [orientation]="orientationControl.value" [formControl]="giftWrap" name="giftwrap">
<daff-form-label>Gift Wrapping</daff-form-label>
<daff-radio value="none">None</daff-radio>
<daff-radio value="standard">Standard</daff-radio>
<daff-radio value="premium">Premium</daff-radio>
</daff-radio-set>

<select [formControl]="orientationControl">
@for (option of options; track option) {
<option [value]="option.value">{{ option.label }}</option>
}
</select>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
ChangeDetectionStrategy,
Component,
} from '@angular/core';
import {
UntypedFormControl,
ReactiveFormsModule,
} from '@angular/forms';

import { DAFF_RADIO_COMPONENTS } from '@daffodil/design/radio';

@Component({
selector: 'radio-orientations-example',
templateUrl: './radio-orientations.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
DAFF_RADIO_COMPONENTS,
ReactiveFormsModule,
],
})
export class RadioOrientationsExampleComponent {
giftWrap = new UntypedFormControl('none');

orientationControl: UntypedFormControl = new UntypedFormControl('');

options = [
{ value: '', label: 'Default' },
{ value: 'vertical', label: 'Vertical' },
{ value: 'horizontal', label: 'Horizontal' },
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<daff-radio-set [formControl]="ccType" name="cctype">
<daff-form-label>Card Type</daff-form-label>
<daff-radio value="visa">Visa</daff-radio>
<daff-radio value="mastercard">MasterCard</daff-radio>
<daff-radio value="amex">American Express</daff-radio>
</daff-radio-set>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
ChangeDetectionStrategy,
Component,
} from '@angular/core';
import {
UntypedFormControl,
ReactiveFormsModule,
} from '@angular/forms';

import { DAFF_RADIO_COMPONENTS } from '@daffodil/design/radio';

@Component({
selector: 'radio-with-control-example',
templateUrl: './radio-with-control.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
DAFF_RADIO_COMPONENTS,
ReactiveFormsModule,
],
})
export class RadioWithControlExampleComponent {
ccType = new UntypedFormControl('visa');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<daff-radio-set [formControl]="shippingMethod" name="shippingMethod">
<daff-form-label>Shipping Method</daff-form-label>
<daff-radio value="standard">Standard (5-7 business days)</daff-radio>
<daff-radio value="express">Express (2-3 business days)</daff-radio>
<daff-radio value="overnight">Overnight</daff-radio>
<daff-hint>Delivery times may vary during peak seasons</daff-hint>
<daff-error-message>Please select a shipping method to continue</daff-error-message>
</daff-radio-set>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
ChangeDetectionStrategy,
Component,
} from '@angular/core';
import {
UntypedFormControl,
ReactiveFormsModule,
} from '@angular/forms';

import { DAFF_RADIO_COMPONENTS } from '@daffodil/design/radio';

@Component({
selector: 'radio-with-error-example',
templateUrl: './radio-with-error.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
DAFF_RADIO_COMPONENTS,
ReactiveFormsModule,
],
})
export class RadioWithErrorExampleComponent {
shippingMethod = new UntypedFormControl('standard');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<daff-radio-set [formControl]="shippingOptions" name="shippingOptions">
<daff-form-label>Shipping Options</daff-form-label>
<daff-radio value="standard">Standard (5-7 business days)</daff-radio>
<daff-radio value="express">Express (2-3 business days)</daff-radio>
<daff-radio value="overnight">Overnight (next business day)</daff-radio>
<daff-hint>Delivery times may vary during peak seasons</daff-hint>
</daff-radio-set>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
ChangeDetectionStrategy,
Component,
} from '@angular/core';
import {
UntypedFormControl,
ReactiveFormsModule,
} from '@angular/forms';

import { DAFF_RADIO_COMPONENTS } from '@daffodil/design/radio';

@Component({
selector: 'radio-with-hint-example',
templateUrl: './radio-with-hint.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [
DAFF_RADIO_COMPONENTS,
ReactiveFormsModule,
],
})
export class RadioWithHintExampleComponent {
shippingOptions = new UntypedFormControl('standard');
}
45 changes: 41 additions & 4 deletions libs/design/radio/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Radio
Radio is used to select a single value from a selection of values.
Radio allows users to select a single value from a group of options.

## Overview
It can be hooked into Angular's `FormControl` to accomodate custom functionality. The `DaffRadioSetComponent` serves as a wrapper around a logical group of radios to provide styling.
Use radio when you need users to pick exactly one option from a visible list of choices. Radio buttons are ideal when users need to see and compare all available options at once. It **cannot** be used by itself and must be contained within a `<daff-radio-set>`.

<design-land-example-viewer-container example="basic-radio"></design-land-example-viewer-container>

Expand Down Expand Up @@ -46,7 +46,44 @@ import { CustomComponent } from './custom.component';
export class CustomComponentModule { }
```

> Deprecation notice: This method is deprecated. It's recommended to update all custom components to standalone.
> **Warning**
>
> This method is deprecated. It's recommended to update all custom components to standalone.

## Anatomy
Radio must be used inside `<daff-radio-set>` to enable proper state management and grouping. The radio set component manages the selected value and handles the shared `name` attribute for the group.

### Basic structure
Use `<daff-radio-set>` to group related radio buttons and `<daff-radio>` for individual options:

```html
<daff-radio-set name="cardType" value="visa">
Card Type
<daff-radio value="visa">Visa</daff-radio>
<daff-radio value="mastercard">MasterCard</daff-radio>
<daff-radio value="amex">American Express</daff-radio>
</daff-radio-set>
```

## Reactive forms
Radio can be used with Angular's reactive forms by binding a `FormControl` to the radio set:

<design-land-example-viewer-container example="radio-with-control"></design-land-example-viewer-container>

## Accessibility
Radio uses native `<input>` HTML elements to ensure an accesible experience by default. It supports inputs to customize the experience for accessibility by allowing native input for `aria-label` and `aria-labelledby`.
Radio follows the [Radio Group WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/). It uses native `<input type="radio">` elements to ensure an accessible experience by default.

### Daffodil provides
- Native radio button semantics with proper grouping
- `aria-labelledby` on the `radiogroup` associated with the `<daff-form-label>`

### Developer responsibilities
- Always provide a visible label for the radio set using `<daff-form-label>`
- Ensure each radio option has descriptive label text

### Keyboard interactions
| Key | Action |
| --- | ------ |
| `Tab` | Move focus to the radio group |
| `Up Arrow` / `Left Arrow` | Move focus to and select the previous option |
| `Down Arrow` / `Right Arrow` | Move focus to and select the next option |
56 changes: 0 additions & 56 deletions libs/design/radio/src/cva/radio-cva.directive.spec.ts

This file was deleted.

Loading