Files
ui-essentials/projects/demo-ui-essentials/src/app/demos/range-slider-demo/range-slider-demo.component.ts
skyai_dev 6f0ab0cf5f Fix SCSS semantic token variable errors across components
- Replace incorrect semantic token names with correct ones:
  • $semantic-border-width-thin → $semantic-border-width-1
  • $semantic-color-border-default → $semantic-color-border-primary
  • $semantic-spacing-content-* → $semantic-spacing-component-*
  • $semantic-typography-body-* → $semantic-typography-font-size-*
  • $semantic-typography-caption-* → $semantic-typography-font-size-*
  • $semantic-motion-easing-standard → $semantic-easing-standard
  • $semantic-color-surface-tertiary → $semantic-color-surface-secondary
  • Various hover color tokens → base color tokens

- Fix typography map usage errors:
  • Replace heading map tokens with individual size tokens
  • $semantic-typography-heading-h* → $semantic-typography-heading-h*-size

- Update affected components:
  • tooltip, divider, progress-circle, range-slider components
  • Related demo components and SCSS files

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-03 07:50:34 +10:00

513 lines
15 KiB
TypeScript

import { Component, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup } from '@angular/forms';
import { RangeSliderComponent, RangeSliderTickMark } from '../../../../../ui-essentials/src/public-api';
@Component({
selector: 'ui-range-slider-demo',
standalone: true,
imports: [CommonModule, FormsModule, ReactiveFormsModule, RangeSliderComponent],
template: `
<div class="demo-container">
<h2>Range Slider Demo</h2>
<!-- Size Variants -->
<section class="demo-section">
<h3>Sizes</h3>
<div class="demo-column">
@for (size of sizes; track size) {
<div class="demo-item">
<ui-range-slider
[size]="size"
[value]="75"
[label]="size.toUpperCase() + ' Size'"
[showValue]="true">
</ui-range-slider>
</div>
}
</div>
</section>
<!-- Color Variants -->
<section class="demo-section">
<h3>Variants</h3>
<div class="demo-column">
@for (variant of variants; track variant) {
<div class="demo-item">
<ui-range-slider
[variant]="variant"
[value]="65"
[label]="variant + ' variant'"
[showValue]="true">
</ui-range-slider>
</div>
}
</div>
</section>
<!-- States -->
<section class="demo-section">
<h3>States</h3>
<div class="demo-column">
<div class="demo-item">
<ui-range-slider
[value]="45"
label="Default State"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[disabled]="true"
[value]="45"
label="Disabled State"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[readonly]="true"
[value]="75"
label="Readonly State"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[value]="30"
[hasError]="true"
label="Error State"
helperText="This field has an error"
[showValue]="true">
</ui-range-slider>
</div>
</div>
</section>
<!-- Range Configurations -->
<section class="demo-section">
<h3>Range Configurations</h3>
<div class="demo-column">
<div class="demo-item">
<ui-range-slider
[min]="0"
[max]="100"
[step]="1"
[value]="50"
label="Standard (0-100, step 1)"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[min]="0"
[max]="10"
[step]="0.5"
[value]="7.5"
label="Decimal Steps (0-10, step 0.5)"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[min]="-50"
[max]="50"
[step]="5"
[value]="-10"
label="Negative Range (-50 to 50, step 5)"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[min]="1000"
[max]="10000"
[step]="100"
[value]="5500"
label="Large Numbers (1K-10K)"
[showValue]="true"
valueUnit=" units">
</ui-range-slider>
</div>
</div>
</section>
<!-- With Tick Marks -->
<section class="demo-section">
<h3>Tick Marks</h3>
<div class="demo-column">
<div class="demo-item">
<ui-range-slider
[min]="0"
[max]="100"
[step]="10"
[value]="60"
[ticks]="basicTicks"
label="Basic Tick Marks"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[min]="0"
[max]="5"
[step]="1"
[value]="3"
[ticks]="labeledTicks"
[showTickLabels]="true"
label="Labeled Tick Marks"
[showValue]="true">
</ui-range-slider>
</div>
<div class="demo-item">
<ui-range-slider
[min]="0"
[max]="100"
[step]="5"
[value]="75"
[ticks]="majorMinorTicks"
[showTickLabels]="true"
label="Major & Minor Ticks"
[showValue]="true">
</ui-range-slider>
</div>
</div>
</section>
<!-- Interactive Example -->
<section class="demo-section">
<h3>Interactive Configuration</h3>
<div class="demo-controls">
<div class="control-row">
<div class="control-group">
<label>Min Value: {{ interactiveMin() }}</label>
<input
type="range"
min="-100"
max="100"
[value]="interactiveMin()"
(input)="updateMin($event)" />
</div>
<div class="control-group">
<label>Max Value: {{ interactiveMax() }}</label>
<input
type="range"
min="0"
max="200"
[value]="interactiveMax()"
(input)="updateMax($event)" />
</div>
<div class="control-group">
<label>Step: {{ interactiveStep() }}</label>
<select [value]="interactiveStep()" (change)="updateStep($event)">
<option value="1">1</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="0.1">0.1</option>
<option value="0.5">0.5</option>
</select>
</div>
</div>
<div class="control-row">
<div class="control-group">
<label>Size:</label>
<select [value]="interactiveSize()" (change)="updateSize($event)">
@for (size of sizes; track size) {
<option [value]="size">{{ size }}</option>
}
</select>
</div>
<div class="control-group">
<label>Variant:</label>
<select [value]="interactiveVariant()" (change)="updateVariant($event)">
@for (variant of variants; track variant) {
<option [value]="variant">{{ variant }}</option>
}
</select>
</div>
<div class="control-group">
<label>
<input
type="checkbox"
[checked]="interactiveShowValue()"
(change)="toggleShowValue($event)" />
Show Value
</label>
</div>
<div class="control-group">
<label>
<input
type="checkbox"
[checked]="interactiveDisabled()"
(change)="toggleDisabled($event)" />
Disabled
</label>
</div>
</div>
</div>
<div class="demo-interactive-result">
<ui-range-slider
[min]="interactiveMin()"
[max]="interactiveMax()"
[step]="interactiveStep()"
[value]="interactiveValue()"
[size]="interactiveSize()"
[variant]="interactiveVariant()"
[showValue]="interactiveShowValue()"
[disabled]="interactiveDisabled()"
label="Interactive Slider"
helperText="Customize using controls above"
(valueChange)="onInteractiveValueChange($event)">
</ui-range-slider>
</div>
</section>
<!-- Form Integration -->
<section class="demo-section">
<h3>Form Integration</h3>
<form [formGroup]="demoForm" class="demo-form">
<div class="form-row">
<ui-range-slider
formControlName="volume"
[min]="0"
[max]="100"
[step]="1"
label="Volume"
[showValue]="true"
valueUnit="%"
helperText="Adjust the volume level">
</ui-range-slider>
</div>
<div class="form-row">
<ui-range-slider
formControlName="brightness"
[min]="0"
[max]="255"
[step]="5"
label="Brightness"
[showValue]="true"
variant="secondary"
helperText="Screen brightness setting">
</ui-range-slider>
</div>
<div class="form-row">
<ui-range-slider
formControlName="temperature"
[min]="16"
[max]="30"
[step]="0.5"
[ticks]="temperatureTicks"
[showTickLabels]="true"
label="Temperature"
[showValue]="true"
valueUnit="°C"
variant="warning">
</ui-range-slider>
</div>
<div class="form-output">
<h4>Form Values:</h4>
<pre>{{ getFormValues() | json }}</pre>
</div>
</form>
</section>
<!-- Event Demonstration -->
<section class="demo-section">
<h3>Event Handling</h3>
<div class="demo-column">
<div class="demo-item">
<ui-range-slider
[value]="eventSliderValue()"
label="Event Slider"
[showValue]="true"
(valueChange)="onValueChange($event)"
(slideStart)="onSlideStart($event)"
(slideEnd)="onSlideEnd($event)"
(sliderFocus)="onSliderFocus()"
(sliderBlur)="onSliderBlur()">
</ui-range-slider>
</div>
<div class="event-log">
<h4>Event Log:</h4>
<div class="event-list">
@for (event of eventLog(); track $index) {
<div class="event-item">{{ event }}</div>
}
</div>
<button (click)="clearEventLog()">Clear Log</button>
</div>
</div>
</section>
</div>
`,
styleUrl: './range-slider-demo.component.scss'
})
export class RangeSliderDemoComponent {
private fb = new FormBuilder();
sizes = ['sm', 'md', 'lg'] as const;
variants = ['primary', 'secondary', 'success', 'warning', 'danger'] as const;
// Interactive demo state
interactiveValue = signal(50);
interactiveMin = signal(0);
interactiveMax = signal(100);
interactiveStep = signal(1);
interactiveSize = signal<'sm' | 'md' | 'lg'>('md');
interactiveVariant = signal<'primary' | 'secondary' | 'success' | 'warning' | 'danger'>('primary');
interactiveShowValue = signal(true);
interactiveDisabled = signal(false);
// Event demo state
eventSliderValue = signal(25);
eventLog = signal<string[]>([]);
// Tick mark configurations
basicTicks: RangeSliderTickMark[] = [
{ value: 0 },
{ value: 25 },
{ value: 50 },
{ value: 75 },
{ value: 100 }
];
labeledTicks: RangeSliderTickMark[] = [
{ value: 0, label: 'Min' },
{ value: 1, label: 'Low' },
{ value: 2, label: 'Med' },
{ value: 3, label: 'High' },
{ value: 4, label: 'Very High' },
{ value: 5, label: 'Max' }
];
majorMinorTicks: RangeSliderTickMark[] = [
{ value: 0, label: '0%', major: true },
{ value: 25, major: false },
{ value: 50, label: '50%', major: true },
{ value: 75, major: false },
{ value: 100, label: '100%', major: true }
];
temperatureTicks: RangeSliderTickMark[] = [
{ value: 16, label: '16°' },
{ value: 18, label: '18°' },
{ value: 20, label: '20°' },
{ value: 22, label: '22°' },
{ value: 24, label: '24°' },
{ value: 26, label: '26°' },
{ value: 28, label: '28°' },
{ value: 30, label: '30°' }
];
// Form setup
demoForm: FormGroup = this.fb.group({
volume: [75],
brightness: [128],
temperature: [22]
});
// Interactive controls
updateMin(event: Event): void {
const target = event.target as HTMLInputElement;
const newMin = parseInt(target.value, 10);
this.interactiveMin.set(newMin);
// Adjust value if it's now below min
if (this.interactiveValue() < newMin) {
this.interactiveValue.set(newMin);
}
}
updateMax(event: Event): void {
const target = event.target as HTMLInputElement;
const newMax = parseInt(target.value, 10);
this.interactiveMax.set(newMax);
// Adjust value if it's now above max
if (this.interactiveValue() > newMax) {
this.interactiveValue.set(newMax);
}
}
updateStep(event: Event): void {
const target = event.target as HTMLSelectElement;
this.interactiveStep.set(parseFloat(target.value));
}
updateSize(event: Event): void {
const target = event.target as HTMLSelectElement;
this.interactiveSize.set(target.value as any);
}
updateVariant(event: Event): void {
const target = event.target as HTMLSelectElement;
this.interactiveVariant.set(target.value as any);
}
toggleShowValue(event: Event): void {
const target = event.target as HTMLInputElement;
this.interactiveShowValue.set(target.checked);
}
toggleDisabled(event: Event): void {
const target = event.target as HTMLInputElement;
this.interactiveDisabled.set(target.checked);
}
onInteractiveValueChange(value: number): void {
this.interactiveValue.set(value);
}
// Event handlers
onValueChange(value: number): void {
this.eventSliderValue.set(value);
this.addEventLog(`Value changed: ${value}`);
}
onSlideStart(value: number): void {
this.addEventLog(`Slide started at: ${value}`);
}
onSlideEnd(value: number): void {
this.addEventLog(`Slide ended at: ${value}`);
}
onSliderFocus(): void {
this.addEventLog('Slider focused');
}
onSliderBlur(): void {
this.addEventLog('Slider blurred');
}
private addEventLog(message: string): void {
const timestamp = new Date().toLocaleTimeString();
const newLog = `[${timestamp}] ${message}`;
this.eventLog.update(log => [newLog, ...log.slice(0, 9)]); // Keep last 10 events
}
clearEventLog(): void {
this.eventLog.set([]);
}
getFormValues(): any {
return this.demoForm.value;
}
}