# @reliability-design/angular

Angular wrappers for Reliability Design web components.

## Installation

```bash
npm install @reliability-design/angular
```

## Usage

### Import the Module

```typescript
import { NgModule } from '@angular/core';
import { ReliabilityDesignModule } from '@reliability-design/angular';

@NgModule({
  imports: [ReliabilityDesignModule],
})
export class AppModule {}
```

For standalone components:

```typescript
import { Component } from '@angular/core';
import { RelButtonDirective, RelTextfieldDirective } from '@reliability-design/angular';

@Component({
  standalone: true,
  imports: [RelButtonDirective, RelTextfieldDirective],
  template: `
    <rel-textfield label="Username"></rel-textfield>
    <rel-button variant="primary">Submit</rel-button>
  `,
})
export class MyComponent {}
```

### Form Controls with Reactive Forms

All form control directives implement `ControlValueAccessor` for seamless integration with Angular forms:

```typescript
import { Component } from '@angular/core';
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { RelTextfieldDirective, RelCheckboxDirective } from '@reliability-design/angular';

@Component({
  standalone: true,
  imports: [ReactiveFormsModule, RelTextfieldDirective, RelCheckboxDirective],
  template: `
    <form [formGroup]="form">
      <rel-textfield formControlName="username" label="Username"></rel-textfield>
      <rel-checkbox formControlName="terms" label="Accept Terms"></rel-checkbox>
    </form>
  `,
})
export class FormComponent {
  form = new FormGroup({
    username: new FormControl(''),
    terms: new FormControl(false),
  });
}
```

### Form Controls with ngModel

```typescript
<rel-textfield [(ngModel)]="username" label="Username"></rel-textfield>
<rel-select [(ngModel)]="country" label="Country"></rel-select>
<rel-checkbox [(ngModel)]="accepted"></rel-checkbox>
<rel-radio [(ngModel)]="choice"></rel-radio>
<rel-switch [(ngModel)]="enabled"></rel-switch>
<rel-slider [(ngModel)]="volume" min="0" max="100"></rel-slider>
```

### Event-Driven Components

Components with custom events provide `@Output()` EventEmitters:

```typescript
import { Component } from '@angular/core';
import { RelTabDirective } from '@reliability-design/angular';

@Component({
  standalone: true,
  imports: [RelTabDirective],
  template: `
    <rel-tab (tabChange)="onTabChange($event)">
      <div slot="tab">Tab 1</div>
      <div slot="panel">Panel 1</div>
    </rel-tab>
  `,
})
export class TabsComponent {
  onTabChange(event: { index: number }) {
    console.log('Tab changed to:', event.index);
  }
}
```

## Component Categories

### Form Controls (6)
- `rel-textfield` - Text input with ControlValueAccessor
- `rel-select` - Select dropdown with ControlValueAccessor
- `rel-checkbox` - Checkbox with ControlValueAccessor
- `rel-radio` - Radio button with ControlValueAccessor
- `rel-switch` - Toggle switch with ControlValueAccessor
- `rel-slider` - Range slider with ControlValueAccessor

### Event-Driven Components (7)
- `rel-tab` - Tab navigation (@Output: tabChange)
- `rel-menu` - Menu with items (@Output: menuItemClick)
- `rel-accordion` - Expandable sections (@Output: toggle)
- `rel-chip` - Removable chips (@Output: removed, chipMove)
- `rel-toast` - Toast notifications (@Output: dismissed, action)
- `rel-snackbar` - Snackbar messages (@Output: dismissed, action)
- `rel-stepper` - Step-by-step wizard (@Output: stepChange)

### Passive Components (13)
- `rel-button` - Button
- `rel-avatar` - User avatar
- `rel-badge` - Notification badge
- `rel-card` - Card container
- `rel-cardmedia` - Card media
- `rel-container` - Layout container
- `rel-divider` - Visual divider
- `rel-layout` - Flexbox layout
- `rel-progress` - Progress indicator
- `rel-breadcrumb` - Breadcrumb navigation
- `rel-alert` - Alert messages
- `rel-segmented-button` - Segmented button group
- `rel-tooltip` - Tooltip overlay

## Typed Inputs and Deprecations (1.4.7)

Most component props pass straight through to the web component (the module uses `CUSTOM_ELEMENTS_SCHEMA`), so any attribute or `[property]` binding works without a directive input. The inputs below are declared explicitly so template type-checking sees them. Nothing was removed: every deprecated input still works and is mapped by the component itself.

| Directive | New input | Values | Deprecated input (still works) |
| --- | --- | --- | --- |
| `rel-alert` | `tone` | `neutral` \| `info` \| `success` \| `warning` \| `destructive` (aliases `error` \| `danger` \| `critical`) | `type` → use `tone` |
| `rel-toast` | `tone` | `default` \| `destructive` (aliases `error` \| `danger` \| `critical`) | `type` → use `tone` |
| `rel-container` | `surface` | `default` \| `elevated` \| `transparent` | `background` (`white`→default, `light`→elevated, `none`→transparent) |
| `rel-range-picker` | `fullWidth` | boolean (attribute `fullwidth`) | — |
| `rel-otp` | `inputMode` | `numeric` \| `alphanumeric` (attribute `input-mode`; accepted characters) | `type` → use `inputMode` |
| `rel-otp` | `inputmode` | `numeric` \| `text` (native keyboard hint, unchanged) | — |
| `rel-otp` | `size` | `small` \| `medium` \| `large` (aliases `sm` \| `md` \| `lg`) | — |
| `rel-checkbox` | `size` | `small` \| `medium` \| `large` (`large` new) | — |
| `rel-button` | `tone` | `neutral` \| `brand` \| `destructive` (`destructive` new; `critical` \| `danger` deprecated aliases) | — |
| `rel-popover` | `arrow` | boolean (opt-in chevron, default off) | — |
| `rel-tab` | `size` | `sm` \| `md` \| `lg` (aliases `small` \| `medium` \| `large`) | — |
| `rel-kbd` | `size` | `sm` \| `md` \| `lg` (aliases `small` \| `medium` \| `large`) | `pill` (radius is always 4px now) |
| `rel-snackbar` | `tone` | `neutral` \| `success` \| `warning` \| `destructive` (aliases `default`→neutral; `error` \| `danger` \| `critical`→destructive) | `type` → use `tone` |
| `rel-accordion` | `size` | `md` \| `sm` \| `small` (`small` new, 44px; aliases `large`→md, `medium`→sm) | — |
| `rel-modal` | `variant` | `default` \| `text` (`text` = opt-in message-only body) | — |
| `rel-menu` | `size` | `large` \| `medium` \| `small` (48 / 40 / 32px rows; default `large`) | — |

When both the new and the deprecated input are set, the new one wins. The value unions are exported as types (`RelAlertToneInput`, `RelToastToneInput`, `RelContainerSurface`, `RelOtpInputMode`, `RelOtpSize`, `RelCheckboxSize`, `RelButtonTone`, `RelTabSize`, `RelKbdSize`, `RelSnackbarToneInput`, `RelAccordionSize`, `RelModalVariant`, `RelMenuSize`).

## Architecture

This package uses Angular **directives** (not components) that attach to the existing web component tags. This approach:

- Preserves web component behavior and styling
- Enables Angular forms integration via ControlValueAccessor
- Maps CustomEvents to Angular EventEmitters
- Works with both NgModule and standalone components
- Maintains Light DOM (no Shadow DOM conflicts)

## License

MIT
