mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-24 21:55:52 +02:00
Archive commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
.slider-bar(#bar [class.disabled]="disabled" (agDrag)="drag($event)" agDragRelative="self")
|
||||
.slider-bar-fill([style.width.%]="width")
|
||||
.slider-bar-line
|
||||
.slider-bar-base([style.left.%]="width")
|
||||
.slider-bar-control
|
||||
@@ -0,0 +1,80 @@
|
||||
@import '../../../../styles/partials/variables';
|
||||
|
||||
$slider-bg: #aaa;
|
||||
$slider-fill: #eaeaea;
|
||||
|
||||
$bar-height: 8px;
|
||||
$bar-control-size: 20px;
|
||||
$bar-border-radius: $bar-height / 2;
|
||||
|
||||
:host {
|
||||
display: inline-block;
|
||||
padding: 2px ($bar-control-size - $bar-height + 10px) / 2;
|
||||
width: 100%;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.slider-bar {
|
||||
background: $slider-bg;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: $bar-height;
|
||||
width: 100%;
|
||||
border-radius: $bar-border-radius;
|
||||
|
||||
&.disabled {
|
||||
background: darken($slider-bg, 20%);
|
||||
|
||||
.slider-bar-fill {
|
||||
background: darken($progress-bg, 20%);
|
||||
}
|
||||
|
||||
.slider-bar-control {
|
||||
background: darken(theme-color('default'), 20%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slider-bar-fill {
|
||||
background: $slider-fill;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-radius: $bar-border-radius;
|
||||
}
|
||||
|
||||
.slider-bar-line {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.slider-bar-base {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.slider-bar-control {
|
||||
position: absolute;
|
||||
left: -$bar-control-size / 2;
|
||||
top: -($bar-control-size - $bar-height) / 2;
|
||||
width: $bar-control-size;
|
||||
height: $bar-control-size;
|
||||
border-radius: 50%;
|
||||
background: theme-color('default');
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
|
||||
|
||||
:host:focus & {
|
||||
box-shadow: 0 0 0 $btn-focus-width rgba($focus-color, 0.7);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
:host:focus:not(.focus-visible) & {
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import {
|
||||
Component, Input, Output, EventEmitter, ElementRef, ChangeDetectionStrategy, HostListener, ViewChild
|
||||
} from '@angular/core';
|
||||
import { clamp } from 'lodash';
|
||||
import { AgDragEvent } from '../directives/agDrag';
|
||||
import { Key } from '../../../client/input/input';
|
||||
|
||||
@Component({
|
||||
selector: 'slider-bar',
|
||||
templateUrl: 'slider-bar.pug',
|
||||
styleUrls: ['slider-bar.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
host: {
|
||||
'role': 'slider',
|
||||
'[tabindex]': 'disabled ? -1 : 0',
|
||||
'[attr.aria-valuemin]': 'min',
|
||||
'[attr.aria-valuemax]': 'max',
|
||||
'[attr.aria-valuenow]': 'value',
|
||||
'[attr.aria-disabled]': 'disabled',
|
||||
},
|
||||
})
|
||||
export class SliderBar {
|
||||
@Input() min = 0;
|
||||
@Input() max = 100;
|
||||
@Input() step = 0;
|
||||
@Input() largeStep = 10;
|
||||
@Input() disabled = false;
|
||||
@Input() value = 0;
|
||||
@Output() valueChange = new EventEmitter<number>();
|
||||
@Output() changed = new EventEmitter<number>();
|
||||
@ViewChild('bar', { static: true }) bar!: ElementRef;
|
||||
private currentWidth = 0;
|
||||
get width() {
|
||||
return clamp(((this.value - this.min) / (this.max - this.min)) * 100, 0, 100);
|
||||
}
|
||||
drag({ type, x, event }: AgDragEvent) {
|
||||
if (this.disabled)
|
||||
return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (type === 'start') {
|
||||
this.currentWidth = this.bar.nativeElement.getBoundingClientRect().width;
|
||||
}
|
||||
|
||||
let val = this.min + clamp(x / this.currentWidth, 0, 1) * (this.max - this.min);
|
||||
|
||||
if (this.step) {
|
||||
val = Math.round(val / this.step) * this.step;
|
||||
}
|
||||
|
||||
this.setValue(val, false);
|
||||
|
||||
if (type === 'end') {
|
||||
this.changed.emit(val);
|
||||
}
|
||||
}
|
||||
@HostListener('keydown', ['$event'])
|
||||
keydown(e: KeyboardEvent) {
|
||||
if (this.disabled)
|
||||
return;
|
||||
|
||||
const step = this.step || 1;
|
||||
|
||||
if (e.keyCode === Key.LEFT || e.keyCode === Key.DOWN || e.keyCode === Key.PAGE_DOWN) {
|
||||
e.preventDefault();
|
||||
this.setValue(this.value - step * (e.keyCode === Key.PAGE_DOWN ? this.largeStep : 1), true);
|
||||
} else if (e.keyCode === Key.RIGHT || e.keyCode === Key.UP || e.keyCode === Key.PAGE_UP) {
|
||||
e.preventDefault();
|
||||
this.setValue(this.value + step * (e.keyCode === Key.PAGE_UP ? this.largeStep : 1), true);
|
||||
} else if (e.keyCode === Key.HOME) {
|
||||
e.preventDefault();
|
||||
this.setValue(this.min, true);
|
||||
} else if (e.keyCode === Key.END) {
|
||||
e.preventDefault();
|
||||
this.setValue(this.max, true);
|
||||
}
|
||||
}
|
||||
private setValue(value: number, emit: boolean) {
|
||||
if (this.value !== value) {
|
||||
this.value = clamp(value, this.min, this.max);
|
||||
this.valueChange.emit(this.value);
|
||||
|
||||
if (emit) {
|
||||
this.changed.emit(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user