npm package: @ng-shangjc/switch
Description: Switch component source package for ng-shangjc angular components
Author: jc-develop
Latest version: 1.0.2-beta

<p align="center">
<a href="https://juliancallejas.github.io/ng-shangjc-docs">
  <img src="https://res.cloudinary.com/dphleqb5t/image/upload/v1772819746/shangjc/shangjc-64-bg-dark_kwzs81.svg" width="307" alt="Shangjc"  /> 
</a>
</p>

# Switch Component

A versatile toggle switch component for binary choices with full form integration, accessibility support, and extensive customization options. Built with modern Angular signals and optimized for performance.

## Official Documentation

<a href="https://juliancallejas.github.io/ng-shangjc-docs/?path=/docs/components-switch">
    ng-Shangjc docs
</a>

## Features

- 🚀 **Two-way Data Binding**: Built-in support for both signal and traditional property binding
- 🎨 **Customizable Styling**: Separate class inputs for switch container and thumb styling
- ♿ **Full Accessibility**: Complete ARIA compliance with proper roles and states
- ⌨️ **Keyboard Navigation**: Full support for Space and Enter keys
- 🎯 **Type-Safe**: Fully typed API with strict TypeScript support
- 📝 **Form Integration**: Seamless integration with both template-driven and reactive forms
- ⚡ **Performance Optimized**: Built with Angular signals and OnPush change detection
- 🔧 **Control Value Accessor**: Implements ControlValueAccessor for form integration
- 🎭 **Multiple States**: Supports checked, unchecked, and disabled states
- 🌐 **SSR Compatible**: Compatible with Angular Universal
- 📱 **Responsive Design**: Mobile-friendly touch interactions
- 🎪 **Rich Content Support**: Supports icons and custom content in thumb area

## Installation

### Step 1: Install the CLI

First, install the ng-shangjc CLI globally or use npx:

```bash
# Install globally
npm install -g @ng-shangjc/cli

# or with yarn
yarn global add @ng-shangjc/cli

# or with pnpm
pnpm install -g @ng-shangjc/cli

# Or use npx without installation
npx @ng-shangjc/cli <command>
```

### Step 2: Initialize your project

If you haven't already, initialize your Angular project for ng-shangjc components:

```bash
ng-shangjc init
```

This will create a `shangjc.config.json` file and set up your project for component installations.

### Step 3: Install the component

Install the switch component into your project:

```bash
ng-shangjc install switch
```

The component will be installed in the configured path (default: `src/ui/shangjc`). Adjust the import path in your components based on your project structure and the configured installation path.

## Import

After installation, import the components from your configured installation path. The examples below use the default path `src/ui/shangjc` - adjust the path according to your project structure and configuration.

### Standalone Components (Recommended)

Import and use the individual components directly in your standalone components:

```typescript
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SwitchComponent } from './ui/shangjc/switch';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [
    CommonModule,
    SwitchComponent,
  ],
  template: `
    <ng-shangjc-switch>
      <!-- Component content -->
    </ng-shangjc-switch>
  `
})
export class ExampleComponent { }
```

### Using NgModule (Legacy)

If you're using NgModules, import the `SwitchModule`:

```typescript
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SwitchModule } from './ui/shangjc/switch';

@NgModule({
  declarations: [YourComponent],
  imports: [
    CommonModule,
    SwitchModule
  ]
})
export class YourModule { }
```

Then use the components in your templates:

```html
<ng-shangjc-switch>
  <!-- Component content -->
</ng-shangjc-switch>
```

## Basic Usage

### Default Example

```typescript
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SwitchComponent } from './ui/shangjc/switch';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [
    CommonModule,
    SwitchComponent
  ],
  template: `
    <div class="flex items-center space-x-2">
      <ng-shangjc-switch 
        [(checked)]="notificationsEnabled"
        id="notifications">
      </ng-shangjc-switch>
      <label for="notifications" class="text-sm font-medium">
        Enable notifications
      </label>
    </div>
  `,
})
export class ExampleComponent {
  notificationsEnabled = false;
}
```

### With Initial Value

```html
<ng-shangjc-switch [checked]="true"></ng-shangjc-switch>
```

### Disabled State

```html
<ng-shangjc-switch [disabled]="true"></ng-shangjc-switch>
```

## Advanced Usage

### Controlled Component

```typescript
import { Component, signal } from '@angular/core';
import { SwitchComponent } from './ui/shangjc/switch';

@Component({
  selector: 'app-controlled-example',
  standalone: true,
  imports: [SwitchComponent],
  template: `
    <div class="space-y-4">
      <div class="flex items-center space-x-2">
        <ng-shangjc-switch 
          [(checked)]="isControlled"
          id="controlled-switch">
        </ng-shangjc-switch>
        <label for="controlled-switch" class="text-sm font-medium">
          Controlled Switch ({{ isControlled() ? 'ON' : 'OFF' }})
        </label>
      </div>
      
      <div class="flex gap-2">
        <button 
          class="px-3 py-1.5 text-sm font-medium bg-blue-100 text-blue-700 rounded"
          (click)="setControlled(true)">
          Turn ON
        </button>
        <button 
          class="px-3 py-1.5 text-sm font-medium bg-gray-100 text-gray-700 rounded"
          (click)="setControlled(false)">
          Turn OFF
        </button>
      </div>
    </div>
  `
})
export class ControlledExampleComponent {
  isControlled = signal(false);
  
  setControlled(value: boolean) {
    this.isControlled.set(value);
  }
}
```

### Reactive Forms Integration

```typescript
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { SwitchComponent } from './ui/shangjc/switch';

@Component({
  selector: 'app-settings',
  standalone: true,
  imports: [ReactiveFormsModule, SwitchComponent],
  template: `
    <form [formGroup]="settingsForm" class="space-y-4">
      <div class="flex items-center space-x-2">
        <ng-shangjc-switch
          formControlName="notifications"
          id="notifications">
        </ng-shangjc-switch>
        <label for="notifications" class="text-sm font-medium">
          Email Notifications
        </label>
      </div>
      
      <div class="flex items-center space-x-2">
        <ng-shangjc-switch
          formControlName="darkMode"
          id="darkMode">
        </ng-shangjc-switch>
        <label for="darkMode" class="text-sm font-medium">
          Dark Mode
        </label>
      </div>
    </form>
  `
})
export class SettingsComponent {
  settingsForm: FormGroup;
  
  constructor(private fb: FormBuilder) {
    this.settingsForm = this.fb.group({
      notifications: [true],
      darkMode: [false]
    });
  }
}
```

### Custom Styling

```html
<!-- Custom colors -->
<ng-shangjc-switch 
  [class]="'data-[state=checked]:bg-green-500 border-green-500'"
  [thumbClass]="'bg-white'">
</ng-shangjc-switch>

<!-- Larger switch -->
<ng-shangjc-switch 
  [class]="'h-8 w-14 data-[state=checked]:bg-purple-500'"
  [thumbClass]="'h-7 w-7 data-[state=checked]:translate-x-7'">
</ng-shangjc-switch>

<!-- Square switch -->
<ng-shangjc-switch 
  [class]="'rounded-md data-[state=checked]:bg-orange-500'"
  [thumbClass]="'rounded-md'">
</ng-shangjc-switch>
```

## API Reference

### SwitchComponent

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `checked` | `model<boolean>` | `false` | Whether the switch is checked (supports two-way binding) |
| `disabled` | `model<boolean>` | `false` | Whether the switch is disabled |
| `id` | `input<string>` | `''` | ID for the switch. Auto-generated if not provided |
| `class` | `input<string>` | `''` | Classes to apply to the switch container |
| `thumbClass` | `input<string>` | `''` | Classes to apply to the switch thumb |
| `checkedChange` | `EventEmitter<boolean>` | - | Event emitted when the checked state changes |

## Accessibility

- **Keyboard Navigation**: Full support for Tab, Shift+Tab, Enter, and Space keys
- **ARIA Attributes**: Proper `role="switch"`, `aria-checked`, and `aria-disabled` attributes
- **Focus Management**: Visible focus indicators and proper focus handling
- **Screen Reader**: Compatible with screen readers and assistive technologies
- **Semantic Structure**: Uses proper HTML semantic elements and button element for switch

### ARIA Features

- `role="switch"` on the button element
- `aria-checked` indicates current checked state (true/false)
- `aria-disabled` indicates disabled state when applicable
- `data-state` attribute provides additional state information for styling
- Proper focus management with visible focus rings

## Browser Support

- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+

## Contributing

See the main project [CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines.

---

**Part of ng-shangjc component library** • [Documentation](https://juliancallejas.github.io/ng-shangjc-docs/)

<p align="center">
<a href="https://github.com/JulianCallejas">
  <img src="https://res.cloudinary.com/dphleqb5t/image/upload/v1740784502/github-jc-develop/JC-LOGO-Horizontal-170-50-thin-github_uu3b5n.svg" width="170" alt="{ jc - develop }"  /> 
</a>
</p>