src/components/am-rating/am-rating.tsx
A simple rating component using StencilJS
tag | am-rating |
styleUrl | am-rating.css |
shadow | true |
Properties |
Methods |
componentWillLoad |
componentWillLoad()
|
Defined in src/components/am-rating/am-rating.tsx:98
|
Once the component is loaded do the setup
Returns :
void
|
createRatingItems |
createRatingItems()
|
Defined in src/components/am-rating/am-rating.tsx:106
|
Create rating items
Returns :
void
|
handleMouseDown | ||||
handleMouseDown(event)
|
||||
Defined in src/components/am-rating/am-rating.tsx:127
|
||||
Handle the mouse being pressed and update the internal rating
Parameters :
Returns :
void
|
render |
render()
|
Defined in src/components/am-rating/am-rating.tsx:160
|
When the state changes, render the view
Returns :
any
|
updateRating | ||||
updateRating(newRating)
|
||||
Defined in src/components/am-rating/am-rating.tsx:146
|
||||
Parameters :
Returns :
void
|
allowHalfRatings |
allowHalfRatings:
|
Type : boolean
|
Default value : false
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:39
|
Determines if half ratings are allowed |
colorOff |
colorOff:
|
Type : string
|
Default value : "#ffffff"
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:59
|
The color to fill the rating with when it's outwith the max |
colorOn |
colorOn:
|
Type : string
|
Default value : "#000000"
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:54
|
The color to fill the rating with when it's within the max |
colorOutline |
colorOutline:
|
Type : string
|
Default value : "#666666"
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:64
|
The color to fill the rating with when it's outwith the max |
direction |
direction:
|
Type : string
|
Default value : "ltr"
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:70
|
The direction of the shading. Valid settings are 'ltr' (left to right) and 'ttb' (top to bottom) |
Private directionSettings |
directionSettings:
|
Type : object
|
Default value : {
'ltr' : { "x1" : "0", "x2" : "1","y1" : "0","y2" : "0" },
'ttb' : { "x1" : "0", "x2" : "0","y1" : "0","y2" : "1" }
}
|
Defined in src/components/am-rating/am-rating.tsx:90
|
Specifies the available gradient directions |
interactive |
interactive:
|
Type : boolean
|
Default value : false
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:19
|
Determines if the user can set a rating |
Private internalRating |
internalRating:
|
Type : number
|
Default value : 0
|
Defined in src/components/am-rating/am-rating.tsx:85
|
Keeps the internal rating (prop rating cannot be reassigned) |
maxRating |
maxRating:
|
Type : number
|
Default value : 5
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:34
|
The maximum rating possible |
minRating |
minRating:
|
Type : number
|
Default value : 0
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:29
|
The minimum rating possible |
rating |
rating:
|
Type : number
|
Default value : 0
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:24
|
The rating |
ratingItems |
ratingItems:
|
Type : Array<object>
|
Default value : []
|
Decorators :
@State()
|
Defined in src/components/am-rating/am-rating.tsx:49
|
The rating items, set once the component is loaded |
ratingUpdated |
ratingUpdated:
|
Type : EventEmitter
|
Decorators :
@Event()
|
Defined in src/components/am-rating/am-rating.tsx:80
|
Event fired when the rating is updated by user input |
reference |
reference:
|
Type : string
|
Default value : "rating-component"
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:14
|
The rating identifier |
svgPoints |
svgPoints:
|
Type : string
|
Default value : "48 75 18.6107374 90.4508497 24.2235871 57.7254249 0.447174185 34.5491503 33.3053687 29.7745751 48 0 62.6946313 29.7745751 95.5528258 34.5491503 71.7764129 57.7254249 77.3892626 90.4508497"
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:44
|
This is a star! |
svgViewBox |
svgViewBox:
|
Type : string
|
Default value : "0 0 100 100"
|
Decorators :
@Prop()
|
Defined in src/components/am-rating/am-rating.tsx:75
|
The view box for the SVG |
import { Component, Prop, State, Event, EventEmitter } from '@stencil/core';
/**
* A simple rating component using StencilJS
*/
@Component({
tag: 'am-rating',
styleUrl: 'am-rating.css',
shadow: true
})
export class AMRating {
/**
* The rating identifier
*/
@Prop() reference: string = "rating-component";
/**
* Determines if the user can set a rating
*/
@Prop() interactive: boolean = false;
/**
* The rating
*/
@Prop() rating: number = 0;
/**
* The minimum rating possible
*/
@Prop() minRating: number = 0;
/**
* The maximum rating possible
*/
@Prop() maxRating: number = 5;
/**
* Determines if half ratings are allowed
*/
@Prop() allowHalfRatings: boolean = false;
/**
* This is a star!
*/
@Prop() svgPoints: string = "48 75 18.6107374 90.4508497 24.2235871 57.7254249 0.447174185 34.5491503 33.3053687 29.7745751 48 0 62.6946313 29.7745751 95.5528258 34.5491503 71.7764129 57.7254249 77.3892626 90.4508497";
/**
* The rating items, set once the component is loaded
*/
@State() ratingItems: Array<object> = [];
/**
* The color to fill the rating with when it's within the max
*/
@Prop() colorOn: string = "#000000";
/**
* The color to fill the rating with when it's outwith the max
*/
@Prop() colorOff: string = "#ffffff";
/**
* The color to fill the rating with when it's outwith the max
*/
@Prop() colorOutline: string = "#666666";
/**
* The direction of the shading.
* Valid settings are 'ltr' (left to right) and 'ttb' (top to bottom)
*/
@Prop() direction: string = "ltr";
/**
* The view box for the SVG
*/
@Prop() svgViewBox: string = "0 0 100 100";
/**
* Event fired when the rating is updated by user input
*/
@Event() ratingUpdated: EventEmitter;
/**
* Keeps the internal rating (prop rating cannot be reassigned)
*/
private internalRating: number = 0;
/**
* Specifies the available gradient directions
*/
private directionSettings = {
'ltr' : { "x1" : "0", "x2" : "1","y1" : "0","y2" : "0" },
'ttb' : { "x1" : "0", "x2" : "0","y1" : "0","y2" : "1" }
};
/**
* Once the component is loaded do the setup
*/
componentWillLoad() {
this.internalRating = this.rating;
this.createRatingItems();
}
/**
* Create rating items
*/
createRatingItems(){
let items = [];
const ratingFloor = Math.floor(this.internalRating);
const ratingRemainder = this.internalRating % 1 * 100;
for(var i = 0; i < this.maxRating; i++){
const itemPercent = i < ratingFloor ? 100 : ( ratingFloor === i ? ratingRemainder : 0 );
items.push({
svgPoints : this.svgPoints,
percent : itemPercent + "%"
});
}
this.ratingItems = items;
}
/**
* Handle the mouse being pressed and update the internal rating
*/
handleMouseDown(event) {
let svgElement = event.path[2];
if(!svgElement.getBBox || !this.interactive){
return;
}
const clickPos = event.offsetX;
const svgWidth = svgElement.getBBox().width ;
const clickPercentage = svgWidth/100*clickPos;
let newRating = 0;
while((svgElement=svgElement.previousSibling)!=null) ++newRating;
newRating = this.allowHalfRatings ? ( newRating + (clickPercentage < 50 ? + 0.5 : 1) ) : ++newRating;
this.updateRating( newRating );
}
updateRating(newRating){
this.internalRating = newRating;
this.createRatingItems();
this.ratingUpdated.emit( {
'reference' : this.reference,
'rating' : this.internalRating
});
}
/**
* When the state changes,
* render the view
*/
render() {
return (
<div>
{this.ratingItems.map( (ratingItem) =>
<svg
viewBox={this.svgViewBox}
version="1.1"
width='12px'
height = '12px'
xmlns="http://www.w3.org/2000/svg"
class="rating-item"
onMouseDown={ () => this.handleMouseDown(event) }
>
<defs>
<linearGradient
id={"fill-" + ratingItem['percent']}
x1={this.directionSettings[this.direction]['x1']}
x2={this.directionSettings[this.direction]['x2']}
y1={this.directionSettings[this.direction]['y1']}
y2={this.directionSettings[this.direction]['y2']}
>
<stop offset={ratingItem['percent']} stop-color={this.colorOn} stop-opacity="1"/>
<stop offset={ratingItem['percent']} stop-color={this.colorOff} stop-opacity="1"/>
</linearGradient>
</defs>
<g
stroke="none"
stroke-width="1">
<polygon
id="star"
stroke={this.colorOutline}
stroke-width="1"
class={"rating-item-shape rating-item-shape-fill-percent-" + ratingItem['percent']}
fill={"url(#fill-" + ratingItem['percent'] + ")"}
points={ ratingItem['svgPoints'] }>
</polygon>
</g>
</svg>
)}
</div>
);
}
}