@suyouwanggang/p-ui
Version:
`p-ui`是一套使用原生`Web Components`规范开发的跨框架UI组件库,基于`lit-elment`库开发。 [github项目地址](https://github.com/suyouwanggang/p-ui)
133 lines (127 loc) • 4.92 kB
text/typescript
import { css, customElement, html, LitElement, property } from 'lit-element';
import './p-tips';
import './p-icon';
import PTips from './p-tips';
/**
* @event change
*/
('p-rate')
export default class PRate extends LitElement {
({ type: Boolean, reflect: true }) disabled: boolean = false;
({ type: String, reflect: true }) icon: string = 'star-fill';
({ type: String, reflect: true }) onColor: string = undefined;
({ type: String, reflect: true }) offColor: string = undefined;
({ type: Boolean, reflect: true }) hoverable: boolean = false;
({ type: Number, reflect: true }) size: number = undefined;
({ type: Number, reflect: true }) number: number = 5;
({ type: String, reflect: true }) name: string = undefined;
({ type: Number, reflect: true }) value: number = 0;
({ type: Array, reflect: true }) tipStrings: string[] = undefined;// ['terrible','bad','normal','good','wonderful'];
static get styles() {
return css`
:host {
display:contents;
}
:host div{
display:inline-flex;
}
p-tips{
margin:auto 4px;
}
p-tips.mouseSelect p-icon {
color: var(--rate-on-color,var(--themeColor,#42b983));
transform:scale(1.2);
transition:transform 0.3 ease;
}
p-tips p-icon{
font-size:1.5em;
cursor:pointer;
color:var(--rate-off-color,#eee);
}
:host([disabled]) div p-icon{
opacity:0.6;
}
:host([disabled]) p-tips,
:host([disabled]) p-icon{
cursor:default;
}`;
}
_hoverRate(ev: MouseEvent) {
if (!this.hoverable || this.disabled) {
return;
}
// tslint:disable-next-line: no-any
let el: any = ev.target as any;
const div = this.renderRoot.querySelector('#rate');
// tslint:disable-next-line: no-any
const array: PTips[] = [...div.querySelectorAll('p-tips') as any];
const index = array.indexOf(el);
for (let i = 0, j = array.length; i < j; i++) {
if (i <= index) {
array[i].classList.add('mouseSelect');
} else {
array[i].classList.remove('mouseSelect');
}
}
}
_leaveRate(ev: MouseEvent) {
if (!this.hoverable || this.disabled) {
return;
}
const div = this.renderRoot.querySelector('#rate');
// tslint:disable-next-line: no-any
const array: PTips[] = [...div.querySelectorAll('p-tips') as any];
// tslint:disable-next-line: no-any
for (let i = 0, j = array.length; i < j; i++) {
const el = array[i];
// tslint:disable-next-line: no-any
if (this.value > (el as any).value) {
el.classList.add('mouseSelect');
} else {
el.classList.remove('mouseSelect');
}
}
}
_click(ev: Event) {
// tslint:disable-next-line: no-any
let el: any = ev.target as any;
if (!(el instanceof PTips)) {
el = el.closest('p-tips');
}
const old = el.value;
this.value = el.value + 1;
this.dispatchEvent(new CustomEvent('change', {
bubbles: true,
detail: {
old: old,
value: this.value
}
}));
}
render() {
return html`<div id='rate' @mouseleave=${this._leaveRate}>
${Array.from({ length: this.number }).map((item, index) => {
return html`<p-tips @click='${this._click}' dir='bottom' @mouseenter=${this._hoverRate} .value=${index} class=${this.value > index ? 'mouseSelect' : ''} .tips=${this.tipStrings && this.tipStrings.length > index ? this.tipStrings[index] : ''}>
<p-icon .name=${this.icon} .size=${this.size} ></p-icon>
</p-tips>`
})}<slot></slot></div>
`;
}
update(changedProperties: Map<string | number | symbol, unknown>) {
super.update(changedProperties);
if (changedProperties.has('offColor')) {
if (this.offColor) {
this.style.setProperty('--rate-off-color', this.offColor);
} else {
this.style.removeProperty('--rate-off-color');
}
}
if (changedProperties.has('onColor')) {
if (this.onColor) {
this.style.setProperty('--rate-on-color', this.onColor);
} else {
this.style.removeProperty('--rate-on-color');
}
}
}
}