mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
UI Expandable Directives
A set of Angular directives for creating expandable/collapsible content sections with proper accessibility support.
Features
- Signal-based expanded/collapsed state management
- Simple template-based conditional rendering
- Supports two-way binding
- Built-in accessibility support (ARIA attributes)
- Modern Angular implementation using directives, signals, effects, and DI
Installation
This library is part of the ISA-Frontend project and is already available in the workspace.
Usage
Basic Usage
import { Component } from '@angular/core';
import {
ExpandableDirective,
ExpandedDirective,
CollapsedDirective,
ExpandableTriggerDirective
} from '@isa/ui/expandable';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [
ExpandableDirective,
ExpandedDirective,
CollapsedDirective,
ExpandableTriggerDirective
],
template: `
<div uiExpandable>
<button
uiExpandableTrigger="my-section"
#trigger="uiExpandableTrigger"
uiTextButton
type="button"
color="strong"
size="small"
>
<ng-icon [name]="trigger.expanded() ? 'isaActionMinus' : 'isaActionPlus'"></ng-icon>
{{ trigger.expanded() ? 'Less details' : 'More details' }}
</button>
<div [id]="'my-section'">
<ng-container *uiCollapsed>
<!-- Content shown when collapsed -->
<p>Summary information</p>
</ng-container>
<ng-container *uiExpanded>
<!-- Content shown when expanded -->
<p>Detailed information</p>
</ng-container>
</div>
</div>
`
})
export class MyComponent {}
With Two-Way Binding
import { Component, signal } from '@angular/core';
import { ExpandableDirectives } from '@isa/ui/expandable';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [...ExpandableDirectives],
template: `
<div uiExpandable [(uiExpandable)]="isExpanded">
<button
uiExpandableTrigger="details-section"
#trigger="uiExpandableTrigger"
uiTextButton
>
Toggle Details
</button>
<div id="details-section">
<ng-container *uiExpanded>
Expanded content
</ng-container>
<ng-container *uiCollapsed>
Collapsed content
</ng-container>
</div>
</div>
<p>The section is currently: {{ isExpanded() ? 'Expanded' : 'Collapsed' }}</p>
<button (click)="isExpanded.set(true)">Expand from outside</button>
`
})
export class MyComponent {
isExpanded = signal(false);
}
API Reference
ExpandableDirective
The main container directive that manages expanded/collapsed state.
Selector: [uiExpandable]
Inputs:
[(uiExpandable)]: Two-way binding for the expanded state.
Methods:
toggle(): Toggles between expanded and collapsed states.
ExpandedDirective
Structural directive that shows content only when expanded.
Selector: [uiExpanded]
CollapsedDirective
Structural directive that shows content only when collapsed.
Selector: [uiCollapsed]
ExpandableTriggerDirective
Adds toggle functionality and accessibility attributes to an element.
Selector: [uiExpandableTrigger]
Inputs:
uiExpandableTrigger: String ID of the element being controlled (used for aria-controls).
Methods:
toggle(): Toggles the parent expandable's state.expanded(): Returns the current expanded state (signal).
Exported as: uiExpandableTrigger
Accessibility
These directives automatically add the following accessibility features:
role="button"on the trigger elementaria-expandedwith the current state on the trigger elementaria-controlslinking the trigger to the content section (requires matching the ID)
Example: Real-world Usage in Return Details Component
<div uiExpandable>
<label class="-ml-3" uiTextButton type="button" color="strong" size="small" uiExpandableTrigger="return-details" #trigger="uiExpandableTrigger">
<ng-icon [name]="trigger.expanded() ? 'isaActionMinus' : 'isaActionPlus'"></ng-icon>
{{ trigger.expanded() ? 'Weniger anzeigen' : 'Bestelldetails anzeigen' }}
</label>
<div id="return-details">
<ng-container *uiExpanded>
<oms-feature-return-details-order-group-data [receipt]="receipt"></oms-feature-return-details-order-group-data>
</ng-container>
<ng-container *uiCollapsed>
<oms-feature-return-details-data [receipt]="receipt"></oms-feature-return-details-data>
</ng-container>
</div>
</div>
Running unit tests
Run nx test ui-expandable to execute the unit tests.