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"> |
<span class="form-check" *ngFor="let value of values"> |
||||
<input type="checkbox" class="form-check-input" id="{{snapshot.controlId}}{{value}}" |
<input type="checkbox" class="form-check-input" id="{{controlId}}{{value}}" |
||||
(blur)="blur()" |
(blur)="callTouched()" |
||||
(change)="check($event.target.checked, value)" |
(change)="check($event.target.checked, value)" |
||||
[checked]="isChecked(value)" |
[checked]="isChecked(value)" |
||||
[disabled]="snapshot.isDisabled"> |
[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> |
</span> |
||||
@ -1,19 +1,19 @@ |
|||||
<div> |
<div> |
||||
<div class="form-inline"> |
<div class="form-inline"> |
||||
<div class="form-group date-group"> |
<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> |
||||
<div class="form-group time-group" *ngIf="showTime"> |
<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> |
||||
<div class="form-group" *ngIf="showTime"> |
<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> |
||||
<div class="form-group" *ngIf="!showTime"> |
<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> |
||||
<div class="form-group" [class.hidden]="!hasValue" *ngIf="!hideClear"> |
<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> |
</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