mirror of https://github.com/Squidex/squidex.git
16 changed files with 144 additions and 450 deletions
@ -1,9 +1,9 @@ |
|||
<span class="form-check" *ngFor="let value of values"> |
|||
<input type="checkbox" class="form-check-input" id="{{snapshot.controlId}}{{value}}" |
|||
(blur)="blur()" |
|||
<input type="checkbox" class="form-check-input" id="{{controlId}}{{value}}" |
|||
(blur)="callTouched()" |
|||
(change)="check($event.target.checked, value)" |
|||
[checked]="isChecked(value)" |
|||
[disabled]="snapshot.isDisabled"> |
|||
|
|||
<label class="form-check-label" for="{{snapshot.controlId}}{{value}}">{{value}}</label> |
|||
<label class="form-check-label" for="{{controlId}}{{value}}">{{value}}</label> |
|||
</span> |
|||
@ -1,19 +1,19 @@ |
|||
<div> |
|||
<div class="form-inline"> |
|||
<div class="form-group date-group"> |
|||
<input type="text" class="form-control" [formControl]="dateControl" (blur)="touched()" #dateInput /> |
|||
<input type="text" class="form-control" [formControl]="dateControl" (blur)="callTouched()" #dateInput /> |
|||
</div> |
|||
<div class="form-group time-group" *ngIf="showTime"> |
|||
<input type="text" class="form-control" [formControl]="timeControl" (blur)="touched()" /> |
|||
<input type="text" class="form-control" [formControl]="timeControl" (blur)="callTouched()" /> |
|||
</div> |
|||
<div class="form-group" *ngIf="showTime"> |
|||
<button class="btn btn-secondary" [disabled]="isDisabled" (click)="writeNow()">Now</button> |
|||
<button class="btn btn-secondary" [disabled]="snapshot.isDisabled" (click)="writeNow()">Now</button> |
|||
</div> |
|||
<div class="form-group" *ngIf="!showTime"> |
|||
<button class="btn btn-secondary" [disabled]="isDisabled" (click)="writeNow()">Today</button> |
|||
<button class="btn btn-secondary" [disabled]="snapshot.isDisabled" (click)="writeNow()">Today</button> |
|||
</div> |
|||
<div class="form-group" [class.hidden]="!hasValue" *ngIf="!hideClear"> |
|||
<button class="btn btn-text clear" [disabled]="isDisabled" (click)="reset()">Clear</button> |
|||
<button class="btn btn-text clear" [disabled]="snapshot.isDisabled" (click)="reset()">Clear</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
@ -1,3 +0,0 @@ |
|||
<div class="slider-bar" #bar (click)="onBarMouseClick($event)" [class.disabled]="isDisabled"> |
|||
<div class="slider-thumb" #thumb (mousedown)="onThumbMouseDown($event)" [class.disabled]="isDisabled"></div> |
|||
</div> |
|||
@ -1,51 +0,0 @@ |
|||
@import '_mixins'; |
|||
@import '_vars'; |
|||
|
|||
$bar-height: .8rem; |
|||
|
|||
$thumb-size: 1.25rem; |
|||
$thumb-margin: ($thumb-size - $bar-height) * .5; |
|||
|
|||
.slider { |
|||
&-bar { |
|||
& { |
|||
@include border-radius($bar-height * .5); |
|||
position: relative; |
|||
border: 1px solid $color-input-border; |
|||
margin-bottom: 1.25rem; |
|||
margin-top: .25rem; |
|||
margin-right: $thumb-size * .5; |
|||
background: $color-dark-foreground; |
|||
height: $bar-height; |
|||
} |
|||
|
|||
&.disabled { |
|||
background: lighten($color-border, 5%); |
|||
} |
|||
} |
|||
|
|||
&-thumb { |
|||
& { |
|||
@include border-radius($thumb-size * .5); |
|||
position: absolute; |
|||
width: $thumb-size; |
|||
height: $thumb-size; |
|||
border: 1px solid $color-input-border; |
|||
background: $color-dark-foreground; |
|||
margin-top: -$thumb-margin; |
|||
margin-left: -$thumb-size * .5; |
|||
} |
|||
|
|||
&.disabled { |
|||
background: lighten($color-border, 5%); |
|||
} |
|||
|
|||
&.focused { |
|||
border-color: $color-theme-blue; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.disabled { |
|||
pointer-events: none; |
|||
} |
|||
@ -1,196 +0,0 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
|||
*/ |
|||
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, Renderer2, ViewChild } from '@angular/core'; |
|||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; |
|||
|
|||
import { Types } from '@app/framework/internal'; |
|||
|
|||
export const SQX_SLIDER_CONTROL_VALUE_ACCESSOR: any = { |
|||
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SliderComponent), multi: true |
|||
}; |
|||
|
|||
@Component({ |
|||
selector: 'sqx-slider', |
|||
styleUrls: ['./slider.component.scss'], |
|||
templateUrl: './slider.component.html', |
|||
providers: [SQX_SLIDER_CONTROL_VALUE_ACCESSOR], |
|||
changeDetection: ChangeDetectionStrategy.OnPush |
|||
}) |
|||
export class SliderComponent implements ControlValueAccessor { |
|||
private callChange = (v: any) => { /* NOOP */ }; |
|||
private callTouched = () => { /* NOOP */ }; |
|||
private windowMouseMoveListener: Function | null = null; |
|||
private windowMouseUpListener: Function | null = null; |
|||
private centerStartOffset = 0; |
|||
private lastValue: number; |
|||
private value: number; |
|||
private isDragging = false; |
|||
|
|||
@ViewChild('bar') |
|||
public bar: ElementRef<Element>; |
|||
|
|||
@ViewChild('thumb') |
|||
public thumb: ElementRef<Element>; |
|||
|
|||
@Input() |
|||
public min = 0; |
|||
|
|||
@Input() |
|||
public max = 100; |
|||
|
|||
@Input() |
|||
public step = 1; |
|||
|
|||
public isDisabled = false; |
|||
|
|||
constructor( |
|||
private readonly changeDetector: ChangeDetectorRef, |
|||
private readonly renderer: Renderer2 |
|||
) { |
|||
} |
|||
|
|||
public writeValue(obj: any) { |
|||
this.lastValue = this.value = Types.isNumber(obj) ? obj : 0; |
|||
|
|||
this.updateThumbPosition(); |
|||
|
|||
this.changeDetector.markForCheck(); |
|||
} |
|||
|
|||
public setDisabledState(isDisabled: boolean): void { |
|||
this.isDisabled = isDisabled; |
|||
|
|||
this.changeDetector.markForCheck(); |
|||
} |
|||
|
|||
public registerOnChange(fn: any) { |
|||
this.callChange = fn; |
|||
} |
|||
|
|||
public registerOnTouched(fn: any) { |
|||
this.callTouched = fn; |
|||
} |
|||
|
|||
public onBarMouseClick(event: MouseEvent): boolean { |
|||
if (this.windowMouseMoveListener) { |
|||
return true; |
|||
} |
|||
|
|||
const relativeValue = this.getRelativeX(event); |
|||
|
|||
this.value = Math.round((relativeValue * (this.max - this.min) + this.min) / this.step) * this.step; |
|||
|
|||
this.updateThumbPosition(); |
|||
this.updateTouched(); |
|||
this.updateValue(); |
|||
|
|||
return false; |
|||
} |
|||
|
|||
public onThumbMouseDown(event: MouseEvent): boolean { |
|||
this.centerStartOffset = event.offsetX - this.thumb.nativeElement.clientWidth * 0.5; |
|||
|
|||
this.windowMouseMoveListener = |
|||
this.renderer.listen('window', 'mousemove', (e: MouseEvent) => { |
|||
this.onMouseMove(e); |
|||
}); |
|||
|
|||
this.windowMouseUpListener = |
|||
this.renderer.listen('window', 'mouseup', () => { |
|||
this.onMouseUp(); |
|||
}); |
|||
|
|||
this.renderer.addClass(this.thumb.nativeElement, 'focused'); |
|||
|
|||
this.isDragging = true; |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private onMouseMove(event: MouseEvent): boolean { |
|||
if (!this.isDragging) { |
|||
return true; |
|||
} |
|||
|
|||
const relativeValue = this.getRelativeX(event); |
|||
|
|||
this.value = Math.round((relativeValue * (this.max - this.min) + this.min) / this.step) * this.step; |
|||
|
|||
this.updateThumbPosition(); |
|||
this.updateTouched(); |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private onMouseUp(): boolean { |
|||
this.updateValue(); |
|||
|
|||
setTimeout(() => { |
|||
this.releaseMouseHandlers(); |
|||
this.renderer.removeClass(this.thumb.nativeElement, 'focused'); |
|||
}, 10); |
|||
|
|||
this.centerStartOffset = 0; |
|||
|
|||
this.isDragging = false; |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private getRelativeX(event: MouseEvent): number { |
|||
const parentOffsetX = this.getParentX(event, this.bar.nativeElement) - this.centerStartOffset; |
|||
const parentWidth = this.bar.nativeElement.clientWidth; |
|||
|
|||
const relativeValue = Math.min(1, Math.max(0, (parentOffsetX - this.centerStartOffset) / parentWidth)); |
|||
|
|||
return relativeValue; |
|||
} |
|||
|
|||
private getParentX(e: any, container: any): number { |
|||
const rect = container.getBoundingClientRect(); |
|||
|
|||
const x = |
|||
!!e.touches ? |
|||
e.touches[0].pageX : |
|||
e.pageX; |
|||
|
|||
return x - rect.left; |
|||
} |
|||
|
|||
private updateTouched() { |
|||
this.callTouched(); |
|||
} |
|||
|
|||
private updateValue() { |
|||
if (this.lastValue !== this.value) { |
|||
this.lastValue = this.value; |
|||
|
|||
this.callChange(this.value); |
|||
} |
|||
} |
|||
|
|||
private updateThumbPosition() { |
|||
const relativeValue = Math.min(1, Math.max(0, (this.value - this.min) / (this.max - this.min))); |
|||
|
|||
this.renderer.setStyle(this.thumb.nativeElement, 'left', relativeValue * 100 + '%'); |
|||
} |
|||
|
|||
private releaseMouseHandlers() { |
|||
if (this.windowMouseMoveListener) { |
|||
this.windowMouseMoveListener(); |
|||
this.windowMouseMoveListener = null; |
|||
} |
|||
|
|||
if (this.windowMouseUpListener) { |
|||
this.windowMouseUpListener(); |
|||
this.windowMouseUpListener = null; |
|||
} |
|||
|
|||
this.isDragging = false; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue