mirror of https://github.com/Squidex/squidex.git
16 changed files with 363 additions and 134 deletions
@ -0,0 +1,10 @@ |
|||
<div class="stars-container"> |
|||
<div *ngIf="maximumStars === 0 || maximumStars > 15" class="many-stars"> |
|||
Must not have more more than 15 stars |
|||
</div> |
|||
<div *ngIf="maximumStars > 0 && maximumStars <= 15"> |
|||
<span class="stars" (mouseleave)="stopPreview()" [class.disabled]="isDisabled"> |
|||
<span class="star" *ngFor="let star of starsArray" (mouseenter)="setPreview(star)" (click)="setValue(star)" [class.selected]="star <= stars"></span> |
|||
</span> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,44 @@ |
|||
@import '_mixins'; |
|||
@import '_vars'; |
|||
|
|||
$color-gold: #ffd700; |
|||
|
|||
.many-stars { |
|||
color: $color-empty; |
|||
} |
|||
|
|||
.stars-container { |
|||
height: 1.8rem; |
|||
} |
|||
|
|||
.stars { |
|||
& { |
|||
display: inline-block; |
|||
border: 0; |
|||
} |
|||
|
|||
&.disabled { |
|||
cursor: not-allowed; |
|||
} |
|||
} |
|||
|
|||
.star { |
|||
& { |
|||
background: transparent; |
|||
border: 0; |
|||
} |
|||
|
|||
&::before { |
|||
display: inline-block; |
|||
color: $color-gold; |
|||
content: '☆'; |
|||
font-size: 1.8rem; |
|||
line-height: 2rem; |
|||
} |
|||
|
|||
&.selected { |
|||
&::before { |
|||
content: '★'; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,91 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Sebastian Stehle. All rights reserved |
|||
*/ |
|||
|
|||
import { Component, forwardRef, Input } from '@angular/core'; |
|||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; |
|||
|
|||
const NOOP = () => { /* NOOP */ }; |
|||
|
|||
export const SQX_STARS_CONTROL_VALUE_ACCESSOR: any = { |
|||
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StarsComponent), multi: true |
|||
}; |
|||
|
|||
@Component({ |
|||
selector: 'sqx-stars', |
|||
styleUrls: ['./stars.component.scss'], |
|||
templateUrl: './stars.component.html', |
|||
providers: [SQX_STARS_CONTROL_VALUE_ACCESSOR] |
|||
}) |
|||
export class StarsComponent implements ControlValueAccessor { |
|||
private changeCallback: (value: any) => void = NOOP; |
|||
private touchedCallback: () => void = NOOP; |
|||
private value = 1; |
|||
private maximumStarsValue = 5; |
|||
|
|||
public isDisabled = false; |
|||
|
|||
public stars: number; |
|||
public starsArray: number[] = [1, 2, 3, 4, 5]; |
|||
|
|||
public get maximumStars() { |
|||
return this.maximumStarsValue; |
|||
} |
|||
|
|||
@Input() |
|||
public set maximumStars(value: any) { |
|||
value = value || 5; |
|||
|
|||
if (!(typeof value === 'number')) { |
|||
value = 5; |
|||
} |
|||
|
|||
if (this.maximumStarsValue !== value) { |
|||
this.maximumStarsValue = value; |
|||
|
|||
this.starsArray = []; |
|||
|
|||
for (let i = 1; i <= value; i++) { |
|||
this.starsArray.push(i); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public writeValue(value: any) { |
|||
this.value = this.stars = value; |
|||
} |
|||
|
|||
public setDisabledState(isDisabled: boolean): void { |
|||
this.isDisabled = isDisabled; |
|||
} |
|||
|
|||
public registerOnChange(fn: any) { |
|||
this.changeCallback = fn; |
|||
} |
|||
|
|||
public registerOnTouched(fn: any) { |
|||
this.touchedCallback = fn; |
|||
} |
|||
|
|||
public setPreview(value: number) { |
|||
this.stars = value; |
|||
} |
|||
|
|||
public stopPreview() { |
|||
this.stars = this.value; |
|||
} |
|||
|
|||
public setValue(value: number) { |
|||
if (this.isDisabled) { |
|||
return; |
|||
} |
|||
|
|||
this.value = this.stars = value; |
|||
|
|||
this.changeCallback(this.value); |
|||
this.touchedCallback(); |
|||
} |
|||
} |
|||
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 51 KiB |
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue