Skip to content

Commit

Permalink
Theming | Add rating
Browse files Browse the repository at this point in the history
  • Loading branch information
cetincakiroglu committed Jul 17, 2024
1 parent 2c724f4 commit fbd08b2
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 29 deletions.
15 changes: 0 additions & 15 deletions src/app/components/rating/rating.css

This file was deleted.

45 changes: 31 additions & 14 deletions src/app/components/rating/rating.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
import { CommonModule } from '@angular/common';
import { booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, EventEmitter, forwardRef, Input, NgModule, numberAttribute, OnInit, Output, QueryList, signal, TemplateRef, ViewEncapsulation } from '@angular/core';
import {
booleanAttribute,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ContentChildren,
EventEmitter,
forwardRef,
inject,
Input,
NgModule,
numberAttribute,
OnInit,
Output,
QueryList,
signal,
TemplateRef,
ViewEncapsulation
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { PrimeNGConfig, PrimeTemplate, SharedModule } from 'primeng/api';
import { BanIcon } from 'primeng/icons/ban';
Expand All @@ -10,6 +28,8 @@ import { RatingRateEvent } from './rating.interface';
import { DomHandler } from 'primeng/dom';
import { UniqueComponentId } from 'primeng/utils';
import { AutoFocusModule } from 'primeng/autofocus';
import { RatingStyle } from './style/ratingstyle';
import { BaseComponent } from 'primeng/basecomponent';

export const RATING_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
Expand All @@ -25,12 +45,12 @@ export const RATING_VALUE_ACCESSOR: any = {
template: `
<div class="p-rating" [ngClass]="{ 'p-readonly': readonly, 'p-disabled': disabled }" [attr.data-pc-name]="'rating'" [attr.data-pc-section]="'root'">
<ng-container *ngIf="!isCustomIcon; else customTemplate">
<div *ngIf="cancel" [attr.data-pc-section]="'cancelItem'" (click)="onOptionClick($event, 0)" [ngClass]="{ 'p-focus': focusedOptionIndex() === 0 && isFocusVisibleItem }" class="p-rating-item p-rating-cancel-item">
<div *ngIf="cancel" [attr.data-pc-section]="'cancelItem'" (click)="onOptionClick($event, 0)" [ngClass]="{ 'p-focus': focusedOptionIndex() === 0 && isFocusVisibleItem }" class="p-rating-option p-rating-cancel">
<span class="p-hidden-accessible" [attr.data-p-hidden-accessible]="true">
<input
type="radio"
value="0"
[name]="name"
[name]="nameattr"
[checked]="value === 0"
[disabled]="disabled"
[readonly]="readonly"
Expand All @@ -46,12 +66,12 @@ export const RATING_VALUE_ACCESSOR: any = {
<BanIcon *ngIf="!iconCancelClass" [styleClass]="'p-rating-icon p-rating-cancel'" [ngStyle]="iconCancelStyle" [attr.data-pc-section]="'cancelIcon'" />
</div>
<ng-template ngFor [ngForOf]="starsArray" let-star let-i="index">
<div class="p-rating-item" [ngClass]="{ 'p-rating-item-active': star + 1 <= value, 'p-focus': star + 1 === focusedOptionIndex() && isFocusVisibleItem }" (click)="onOptionClick($event, star + 1)">
<div class="p-rating-option" [ngClass]="{ 'p-rating-option-active': star + 1 <= value, 'p-focus-visible': star + 1 === focusedOptionIndex() && isFocusVisibleItem }" (click)="onOptionClick($event, star + 1)">
<span class="p-hidden-accessible" [attr.data-p-hidden-accessible]="true">
<input
type="radio"
value="0"
[name]="name"
[name]="nameattr"
[checked]="value === 0"
[disabled]="disabled"
[readonly]="readonly"
Expand Down Expand Up @@ -84,15 +104,14 @@ export const RATING_VALUE_ACCESSOR: any = {
</ng-template>
</div>
`,
providers: [RATING_VALUE_ACCESSOR],
providers: [RATING_VALUE_ACCESSOR, RatingStyle],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
styleUrls: ['./rating.css'],
host: {
class: 'p-element'
}
})
export class Rating implements OnInit, ControlValueAccessor {
export class Rating extends BaseComponent implements OnInit, ControlValueAccessor {
/**
* When present, it specifies that the element should be disabled.
* @group Props
Expand Down Expand Up @@ -193,15 +212,13 @@ export class Rating implements OnInit, ControlValueAccessor {

focusedOptionIndex = signal<number>(-1);

name: string | undefined;
nameattr: string | undefined;

constructor(
private cd: ChangeDetectorRef,
private config: PrimeNGConfig
) {}
_componentStyle = inject(RatingStyle);

ngOnInit() {
this.name = this.name || UniqueComponentId();
super.ngOnInit();
this.nameattr = this.nameattr || UniqueComponentId();
this.starsArray = [];
for (let i = 0; i < this.stars; i++) {
this.starsArray[i] = i;
Expand Down
75 changes: 75 additions & 0 deletions src/app/components/rating/style/ratingstyle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Injectable } from '@angular/core';
import { BaseStyle } from 'primeng/base';

const theme = ({ dt }) => `
.p-rating {
position: relative;
display: flex;
align-items: center;
gap: ${dt('rating.gap')};
}
.p-rating-option {
display: inline-flex;
align-items: center;
cursor: pointer;
outline-color: transparent;
border-radius: 50%;
cursor: pointer;
transition: background ${dt('rating.transition.duration')}, color ${dt('rating.transition.duration')}, border-color ${dt('rating.transition.duration')}, outline-color ${dt('rating.transition.duration')}, box-shadow ${dt(
'rating.transition.duration'
)};
}
.p-rating-option.p-focus-visible {
box-shadow: ${dt('focus.ring.shadow')};
outline: ${dt('focus.ring.width')} ${dt('focus.ring.style')} ${dt('focus.ring.color')};
outline-offset: ${dt('focus.ring.offset')};
}
.p-rating-icon {
color: ${dt('rating.icon.color')};
transition: background ${dt('rating.transition.duration')}, color ${dt('rating.transition.duration')}, border-color ${dt('rating.transition.duration')}, outline-color ${dt('rating.transition.duration')}, box-shadow ${dt(
'rating.transition.duration'
)};
font-size: ${dt('rating.icon.size')};
width: ${dt('rating.icon.size')};
height: ${dt('rating.icon.size')};
}
.p-rating:not(.p-disabled):not(.p-readonly) .p-rating-option:hover .p-rating-icon {
color: ${dt('rating.icon.hover.color')};
}
.p-rating-option-active .p-rating-icon {
color: ${dt('rating.icon.active.color')};
}
`;

const classes = {
root: ({ props }) => [
'p-rating',
{
'p-readonly': props.readonly,
'p-disabled': props.disabled
}
],
option: ({ instance, props, value }) => [
'p-rating-option',
{
'p-rating-option-active': value <= props.modelValue,
'p-focus-visible': value === instance.focusedOptionIndex && instance.isFocusVisibleItem
}
],
onIcon: 'p-rating-icon p-rating-on-icon',
offIcon: 'p-rating-icon p-rating-off-icon'
};

@Injectable()
export class RatingStyle extends BaseStyle {
name = 'rating';

theme = theme;

classes = classes;
}

0 comments on commit fbd08b2

Please sign in to comment.