- Add new libraries: ui-accessibility, ui-animations, ui-backgrounds, ui-code-display, ui-data-utils, ui-font-manager, hcl-studio - Add extensive layout components: gallery-grid, infinite-scroll-container, kanban-board, masonry, split-view, sticky-layout - Add comprehensive demo components for all new features - Update project configuration and dependencies - Expand component exports and routing structure - Add UI landing pages planning document 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
275 lines
9.2 KiB
HTML
275 lines
9.2 KiB
HTML
<div class="accessibility-demo">
|
||
<!-- Skip Links Demo -->
|
||
<ui-skip-links></ui-skip-links>
|
||
|
||
<header class="demo-header">
|
||
<h1 id="main">UI Accessibility Library Demo</h1>
|
||
<p>Interactive examples of accessibility features with WCAG 2.1 Level AA compliance.</p>
|
||
|
||
<ui-screen-reader-only>
|
||
This page demonstrates various accessibility features. Use keyboard shortcuts: Ctrl+Shift+A to make announcements, Ctrl+M to toggle modal.
|
||
</ui-screen-reader-only>
|
||
</header>
|
||
|
||
<!-- Current Preferences Display -->
|
||
<section class="demo-section" aria-labelledby="preferences-heading">
|
||
<h2 id="preferences-heading">Accessibility Preferences</h2>
|
||
<div class="preferences-display">
|
||
<p><strong>High Contrast:</strong> {{ currentPreferences.prefersHighContrast ? 'Enabled' : 'Disabled' }}</p>
|
||
<p><strong>Reduced Motion:</strong> {{ currentPreferences.prefersReducedMotion ? 'Enabled' : 'Disabled' }}</p>
|
||
<p><strong>Color Scheme:</strong> {{ currentPreferences.colorScheme || 'Not detected' }}</p>
|
||
<ui-button variant="tonal" size="small" (click)="refreshPreferences()">
|
||
Refresh Preferences
|
||
</ui-button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Live Announcements Demo -->
|
||
<section class="demo-section" aria-labelledby="announcements-heading">
|
||
<h2 id="announcements-heading">Live Announcements</h2>
|
||
<div class="demo-controls">
|
||
<div class="input-group">
|
||
<label for="announcement-text">Announcement Text:</label>
|
||
<input
|
||
id="announcement-text"
|
||
type="text"
|
||
[(ngModel)]="announcementText"
|
||
class="demo-input"
|
||
>
|
||
</div>
|
||
|
||
<div class="input-group">
|
||
<label for="politeness-level">Politeness Level:</label>
|
||
<select id="politeness-level" [(ngModel)]="selectedPoliteness" class="demo-select">
|
||
<option value="polite">Polite</option>
|
||
<option value="assertive">Assertive</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="button-group">
|
||
<ui-button (click)="makeAnnouncement()">Make Announcement</ui-button>
|
||
<ui-button variant="tonal" (click)="makeSequenceAnnouncement()">Sequence Announcement</ui-button>
|
||
</div>
|
||
|
||
<div class="button-group">
|
||
<ui-button variant="filled" (click)="announceSuccess()">Success Message</ui-button>
|
||
<ui-button variant="outlined" (click)="announceError()">Error Message</ui-button>
|
||
<ui-button variant="tonal" (click)="announceLoading()">Loading Message</ui-button>
|
||
<ui-button variant="outlined" (click)="simulateFormValidation()">Simulate Validation</ui-button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Focus Management Demo -->
|
||
<section class="demo-section" aria-labelledby="focus-heading">
|
||
<h2 id="focus-heading">Focus Management</h2>
|
||
|
||
<div class="focus-demo">
|
||
<div class="input-group">
|
||
<label for="monitored-input">Monitored Input (Focus Origin: {{ focusOrigin }}):</label>
|
||
<input
|
||
#monitoredInput
|
||
id="monitored-input"
|
||
type="text"
|
||
placeholder="Click, tab, or programmatically focus this input"
|
||
class="demo-input"
|
||
>
|
||
</div>
|
||
|
||
<div class="button-group">
|
||
<ui-button (click)="focusViaKeyboard()">Focus via Keyboard</ui-button>
|
||
<ui-button (click)="focusViaMouse()">Focus via Mouse</ui-button>
|
||
<ui-button (click)="focusViaProgram()">Focus via Program</ui-button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Focus Trap Demo -->
|
||
<section class="demo-section" aria-labelledby="trap-heading">
|
||
<h2 id="trap-heading">Focus Trap</h2>
|
||
|
||
<div class="trap-controls">
|
||
<ui-button (click)="toggleFocusTrap()">
|
||
{{ trapEnabled ? 'Disable' : 'Enable' }} Focus Trap
|
||
</ui-button>
|
||
</div>
|
||
|
||
<div
|
||
#trapContainer
|
||
class="focus-trap-container"
|
||
[class.trap-enabled]="trapEnabled"
|
||
[uiFocusTrap]="trapEnabled"
|
||
[autoFocus]="true"
|
||
[restoreFocus]="true"
|
||
>
|
||
<h3>Focus Trap Container {{ trapEnabled ? '(Active)' : '(Inactive)' }}</h3>
|
||
<p>When enabled, Tab navigation will be trapped within this container.</p>
|
||
|
||
<input type="text" placeholder="First input" class="demo-input">
|
||
<input type="text" placeholder="Second input" class="demo-input">
|
||
<ui-button>Trapped Button 1</ui-button>
|
||
<ui-button variant="tonal">Trapped Button 2</ui-button>
|
||
<select class="demo-select">
|
||
<option>Option 1</option>
|
||
<option>Option 2</option>
|
||
</select>
|
||
<textarea placeholder="Textarea" class="demo-textarea"></textarea>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Arrow Navigation Demo -->
|
||
<section class="demo-section" aria-labelledby="navigation-heading">
|
||
<h2 id="navigation-heading">Arrow Navigation</h2>
|
||
|
||
<div class="navigation-demo">
|
||
<h3>Vertical Navigation (Use ↑↓ arrows):</h3>
|
||
<ul
|
||
class="navigation-list vertical"
|
||
uiArrowNavigation="vertical"
|
||
[wrap]="true"
|
||
(navigationChange)="onNavigationChange($event)"
|
||
>
|
||
@for (item of navigationItems; track item.id) {
|
||
<li
|
||
[tabindex]="$first ? '0' : '-1'"
|
||
[class.disabled]="item.disabled"
|
||
[attr.aria-disabled]="item.disabled"
|
||
>
|
||
{{ item.label }}
|
||
</li>
|
||
}
|
||
</ul>
|
||
|
||
<h3>Grid Navigation (Use ↑↓←→ arrows, 3 columns):</h3>
|
||
<div
|
||
class="navigation-grid"
|
||
uiArrowNavigation="grid"
|
||
[gridColumns]="3"
|
||
[wrap]="true"
|
||
(navigationChange)="onGridNavigationChange($event)"
|
||
>
|
||
@for (item of gridItems; track item.id) {
|
||
<button
|
||
class="grid-item"
|
||
[tabindex]="$first ? '0' : '-1'"
|
||
[disabled]="item.disabled"
|
||
[attr.aria-disabled]="item.disabled"
|
||
>
|
||
{{ item.label }}
|
||
</button>
|
||
}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Modal Demo -->
|
||
<section class="demo-section" aria-labelledby="modal-heading">
|
||
<h2 id="modal-heading">Modal with Focus Trap</h2>
|
||
|
||
<ui-button (click)="toggleModal()">Open Modal</ui-button>
|
||
|
||
@if (showModal) {
|
||
<div class="modal-backdrop" (click)="toggleModal()">
|
||
<div
|
||
class="modal-content"
|
||
[uiFocusTrap]="true"
|
||
[autoFocus]="true"
|
||
[restoreFocus]="true"
|
||
role="dialog"
|
||
aria-labelledby="modal-title"
|
||
aria-modal="true"
|
||
(click)="$event.stopPropagation()"
|
||
>
|
||
<header class="modal-header">
|
||
<h3 id="modal-title">Demo Modal</h3>
|
||
<button
|
||
class="modal-close"
|
||
(click)="toggleModal()"
|
||
aria-label="Close modal"
|
||
>
|
||
×
|
||
</button>
|
||
</header>
|
||
|
||
<div class="modal-body">
|
||
<p>This modal demonstrates focus trapping. Tab navigation is contained within the modal.</p>
|
||
|
||
<input type="text" placeholder="Modal input" class="demo-input">
|
||
<ui-button variant="tonal">Modal Button</ui-button>
|
||
</div>
|
||
|
||
<footer class="modal-footer">
|
||
<ui-button (click)="toggleModal()">Close</ui-button>
|
||
<ui-button variant="filled">Save Changes</ui-button>
|
||
</footer>
|
||
</div>
|
||
</div>
|
||
}
|
||
</section>
|
||
|
||
<!-- Screen Reader Components -->
|
||
<section class="demo-section" aria-labelledby="sr-heading">
|
||
<h2 id="sr-heading">Screen Reader Components</h2>
|
||
|
||
<div class="sr-demo">
|
||
<h3>Screen Reader Only Text:</h3>
|
||
<p>
|
||
This text is visible.
|
||
<ui-screen-reader-only>This text is only for screen readers.</ui-screen-reader-only>
|
||
This text is visible again.
|
||
</p>
|
||
|
||
<h3>Focusable Screen Reader Text:</h3>
|
||
<ui-screen-reader-only type="focusable">
|
||
This text becomes visible when focused (try tabbing through the page).
|
||
</ui-screen-reader-only>
|
||
|
||
<h3>Dynamic Status Messages:</h3>
|
||
<div class="status-demo">
|
||
<ui-screen-reader-only type="status" statusType="success">
|
||
Form submitted successfully!
|
||
</ui-screen-reader-only>
|
||
|
||
<ui-screen-reader-only type="status" statusType="error">
|
||
Error: Please check your input.
|
||
</ui-screen-reader-only>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Keyboard Shortcuts Info -->
|
||
<section class="demo-section" aria-labelledby="shortcuts-heading">
|
||
<h2 id="shortcuts-heading">Keyboard Shortcuts</h2>
|
||
|
||
<div class="shortcuts-info">
|
||
<dl class="shortcuts-list">
|
||
<dt>Ctrl + Shift + A</dt>
|
||
<dd>Make announcement</dd>
|
||
|
||
<dt>Ctrl + M</dt>
|
||
<dd>Toggle modal</dd>
|
||
|
||
<dt>Tab / Shift + Tab</dt>
|
||
<dd>Navigate through interactive elements</dd>
|
||
|
||
<dt>Arrow Keys</dt>
|
||
<dd>Navigate within lists and grids (when focused)</dd>
|
||
|
||
<dt>Home / End</dt>
|
||
<dd>Jump to first/last item in navigable containers</dd>
|
||
|
||
<dt>Escape</dt>
|
||
<dd>Close modal or exit focus trap</dd>
|
||
</dl>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Footer -->
|
||
<footer class="demo-footer">
|
||
<p>
|
||
<ui-screen-reader-only>End of accessibility demo.</ui-screen-reader-only>
|
||
This demo showcases WCAG 2.1 Level AA compliant accessibility features using semantic design tokens.
|
||
</p>
|
||
</footer>
|
||
</div>
|