mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
feat(shared-filter, ui-switch): add switch filter menu button for inline toggle filters
Add a new SwitchMenuButtonComponent that renders filter inputs as compact toggle switches
without an overlay menu. This provides a more streamlined UX for simple boolean/single-option
filters directly in the controls panel.
Key changes:
- Create new switch-menu module with button component and tests
- Extend FilterControlsPanelComponent to accept switchFilters input array
- Rename IconSwitchComponent to SwitchComponent for consistency
- Update filter actions to use 'target' property instead of 'group' for filtering
- Add isEmptyFilterInput support for NumberRange inputs
- Export switch-menu module from shared/filter public API
The switch button auto-commits on toggle and uses the checkbox filter model internally,
allowing simple configuration like:
switchFilters = [{ filter: stockFilter, icon: 'isaFiliale' }]
This implementation follows the existing filter architecture patterns and maintains
full accessibility support through ARIA attributes and keyboard navigation.
Ref: #5427
186 lines
5.1 KiB
Markdown
186 lines
5.1 KiB
Markdown
# UI Switch Library
|
|
|
|
This library provides a toggle switch component with an icon for Angular applications.
|
|
|
|
## Components
|
|
|
|
### IconSwitchComponent
|
|
|
|
A toggle switch component that displays an icon and supports two states (on/off).
|
|
|
|
**Important**: Use only when the icon meaning is universally clear, otherwise prefer a labeled switch.
|
|
|
|
#### Features
|
|
|
|
- ✅ Customizable icon via `ng-icons`
|
|
- ✅ Two-way binding with model signal
|
|
- ✅ Hover state styling
|
|
- ✅ Disabled state handling
|
|
- ✅ Keyboard navigation support (Enter, Space)
|
|
- ✅ Fully accessible with ARIA attributes
|
|
- ✅ Smooth animations
|
|
|
|
#### Usage
|
|
|
|
```typescript
|
|
import { Component } from '@angular/core';
|
|
import { IconSwitchComponent } from '@isa/ui/switch';
|
|
import { provideIcons } from '@ng-icons/core';
|
|
import { isaNavigationDashboard } from '@isa/icons';
|
|
|
|
@Component({
|
|
selector: 'app-example',
|
|
standalone: true,
|
|
imports: [IconSwitchComponent],
|
|
providers: [provideIcons({ isaNavigationDashboard })],
|
|
template: `
|
|
<ui-icon-switch
|
|
icon="isaNavigationDashboard"
|
|
[(checked)]="isEnabled"
|
|
[disabled]="false">
|
|
</ui-icon-switch>
|
|
`,
|
|
})
|
|
export class ExampleComponent {
|
|
isEnabled = false;
|
|
}
|
|
```
|
|
|
|
#### Inputs
|
|
|
|
| Property | Type | Default | Description |
|
|
| ---------- | ---------------- | ----------- | ---------------------------------------------------- |
|
|
| `icon` | `string` | (required) | The name of the icon to display |
|
|
| `checked` | `boolean` | `false` | Two-way bindable signal for the checked state |
|
|
| `color` | `IconSwitchColor`| `'primary'` | The color theme of the switch |
|
|
| `disabled` | `boolean` | `false` | Whether the switch is disabled |
|
|
| `tabIndex` | `number` | `0` | The tab index for keyboard navigation |
|
|
|
|
#### Two-Way Binding
|
|
|
|
The `checked` property uses Angular's new model signal syntax for two-way binding:
|
|
|
|
```html
|
|
<!-- Two-way binding -->
|
|
<ui-icon-switch icon="isaNavigationDashboard" [(checked)]="isEnabled"></ui-icon-switch>
|
|
|
|
<!-- One-way binding -->
|
|
<ui-icon-switch icon="isaNavigationDashboard" [checked]="isEnabled"></ui-icon-switch>
|
|
|
|
<!-- Event handling -->
|
|
<ui-icon-switch
|
|
icon="isaNavigationDashboard"
|
|
[checked]="isEnabled"
|
|
(checkedChange)="onToggle($event)">
|
|
</ui-icon-switch>
|
|
```
|
|
|
|
#### Accessibility
|
|
|
|
The component follows WAI-ARIA best practices:
|
|
|
|
- `role="switch"` - Identifies the element as a switch
|
|
- `aria-checked` - Indicates the current state
|
|
- `aria-disabled` - Indicates when the switch is disabled
|
|
- `tabindex` - Allows keyboard focus and navigation
|
|
- Keyboard support:
|
|
- `Enter` - Toggles the switch
|
|
- `Space` - Toggles the switch
|
|
|
|
#### Styling
|
|
|
|
The component uses the following CSS classes:
|
|
|
|
- `.ui-icon-switch` - Main component class
|
|
- `.ui-icon-switch__primary` - Primary color theme (currently the only supported theme)
|
|
- `.ui-icon-switch__track` - The pill-shaped background track
|
|
- `.ui-icon-switch__track--checked` - Applied when checked
|
|
- `.ui-icon-switch__thumb` - The circular toggle indicator with icon
|
|
- `.ui-icon-switch__thumb--checked` - Applied when checked
|
|
- `.disabled` - Applied when disabled
|
|
|
|
#### Color Themes
|
|
|
|
Currently, only the `primary` theme is supported, which uses:
|
|
|
|
- **Unchecked**: Neutral gray background (`isa-neutral-300`)
|
|
- **Checked**: Secondary blue background (`isa-secondary-600`)
|
|
- **Hover (unchecked)**: Darker neutral gray (`isa-neutral-400`)
|
|
- **Hover (checked)**: Darker secondary blue (`isa-secondary-700`)
|
|
- **Thumb**: White background with icon color matching the state
|
|
|
|
#### Examples
|
|
|
|
**Basic usage:**
|
|
|
|
```html
|
|
<ui-icon-switch
|
|
icon="isaNavigationDashboard"
|
|
[(checked)]="dashboardEnabled">
|
|
</ui-icon-switch>
|
|
```
|
|
|
|
**Disabled switch:**
|
|
|
|
```html
|
|
<ui-icon-switch
|
|
icon="isaNavigationDashboard"
|
|
[(checked)]="isEnabled"
|
|
[disabled]="true">
|
|
</ui-icon-switch>
|
|
```
|
|
|
|
**With event handling:**
|
|
|
|
```typescript
|
|
@Component({
|
|
template: `
|
|
<ui-icon-switch
|
|
icon="isaNavigationDashboard"
|
|
[(checked)]="isEnabled"
|
|
(checkedChange)="handleToggle($event)">
|
|
</ui-icon-switch>
|
|
`,
|
|
})
|
|
export class ExampleComponent {
|
|
isEnabled = false;
|
|
|
|
handleToggle(checked: boolean): void {
|
|
console.log('Switch toggled:', checked);
|
|
// Perform action based on state
|
|
}
|
|
}
|
|
```
|
|
|
|
## Design Guidelines
|
|
|
|
**When to use Icon Switch:**
|
|
|
|
- ✅ The icon meaning is universally clear (e.g., home, dashboard, notification)
|
|
- ✅ Space is limited
|
|
- ✅ The action is binary (on/off, enabled/disabled)
|
|
|
|
**When NOT to use Icon Switch:**
|
|
|
|
- ❌ The icon meaning is ambiguous or context-specific
|
|
- ❌ Multiple related switches need differentiation
|
|
- ❌ Users need explicit labels for clarity
|
|
|
|
For cases where labels are needed, consider using a standard labeled switch component instead.
|
|
|
|
## Development
|
|
|
|
### Running unit tests
|
|
|
|
Run `nx test ui-switch` to execute the unit tests with Vitest.
|
|
|
|
### Running Storybook
|
|
|
|
The component has a Storybook story at `apps/isa-app/stories/ui/switch/ui-icon-switch.stories.ts`.
|
|
|
|
Run Storybook to see the component in action:
|
|
|
|
```bash
|
|
npm run storybook
|
|
```
|