UNPKG

igniteui-webcomponents

Version:

Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.

461 lines 16.8 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { LitElement, html, nothing } from 'lit'; import { property, query, queryAssignedElements, state, } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { styleMap } from 'lit/directives/style-map.js'; import { themes } from '../../theming/theming-decorator.js'; import { addKeybindings, arrowDown, arrowLeft, arrowRight, arrowUp, endKey, homeKey, pageDownKey, pageUpKey, } from '../common/controllers/key-bindings.js'; import { blazorDeepImport } from '../common/decorators/blazorDeepImport.js'; import { blazorTypeOverride } from '../common/decorators/blazorTypeOverride.js'; import { watch } from '../common/decorators/watch.js'; import { asNumber, asPercent, clamp, formatString, isDefined, isLTR, } from '../common/util.js'; import { styles as shared } from './themes/shared/slider.common.css.js'; import { styles } from './themes/slider.base.css.js'; import { all } from './themes/themes.js'; let IgcSliderBaseComponent = class IgcSliderBaseComponent extends LitElement { get hasLabels() { return this.labels?.length > 0; } get distance() { return this.max - this.min; } set min(value) { if (!isDefined(value) || value > this.max) { return; } this._min = this.hasLabels ? 0 : value; if (isDefined(this._lowerBound) && this._lowerBound < value) { this._lowerBound = value; } } get min() { return this._min; } set max(value) { if (!isDefined(value) || value < this._min) { return; } this._max = this.hasLabels ? this.labels.length - 1 : value; if (isDefined(this._upperBound) && this._upperBound > value) { this._upperBound = value; } } get max() { return this._max; } set lowerBound(value) { if (!isDefined(value)) return; this._lowerBound = Math.min(this._upperBound ?? value, value); } get lowerBound() { const current = this._lowerBound ?? this._min; const upper = Math.min(this._upperBound ?? this._max, this._max); return clamp(current, this._min, upper); } set upperBound(value) { if (!isDefined(value)) return; this._upperBound = Math.max(this._lowerBound ?? value, value); } get upperBound() { const current = this._upperBound ?? this._max; const lower = Math.max(this._lowerBound ?? this._min, this.min); return clamp(current, lower, this._max); } set step(value) { this._step = this.hasLabels ? 1 : asNumber(value, this._step); } get step() { return this._step; } constraintsChange() { this.normalizeValue(); } constructor() { super(); this._min = 0; this._max = 100; this._step = 1; this.pointerCaptured = false; this.thumbLabelsVisible = false; this.labels = []; this.disabled = false; this.discreteTrack = false; this.hideTooltip = false; this.primaryTicks = 0; this.secondaryTicks = 0; this.tickOrientation = 'end'; this.hidePrimaryLabels = false; this.hideSecondaryLabels = false; this.locale = 'en'; this.tickLabelRotation = 0; this.addEventListener('pointerdown', this.pointerDown); this.addEventListener('pointermove', this.pointerMove); this.addEventListener('lostpointercapture', this.lostPointerCapture); this.addEventListener('keyup', this.handleKeyUp); addKeybindings(this, { skip: () => this.disabled, bindingDefaults: { preventDefault: true }, }) .set(arrowLeft, () => this.handleArrowKeys(isLTR(this) ? -1 : 1)) .set(arrowRight, () => this.handleArrowKeys(isLTR(this) ? 1 : -1)) .set(arrowUp, () => this.handleArrowKeys(1)) .set(arrowDown, () => this.handleArrowKeys(-1)) .set(homeKey, () => this.handleKeyboardIncrement(this.lowerBound - this.activeValue)) .set(endKey, () => this.handleKeyboardIncrement(this.upperBound - this.activeValue)) .set(pageUpKey, () => this.handlePageKeys(1)) .set(pageDownKey, () => this.handlePageKeys(-1)); } handleArrowKeys(delta) { const step = this.step ? this.step : 1; this.handleKeyboardIncrement(step * delta); } handlePageKeys(delta) { const step = this.step ? this.step : 1; this.handleKeyboardIncrement(delta * Math.max((this.upperBound - this.lowerBound) / 10, step)); } handleKeyboardIncrement(increment) { if (increment) { const updated = this.updateValue(increment); this.showThumbLabels(); this.hideThumbLabels(); if (updated) { this.emitChangeEvent(); } } } handleKeyUp() { this.activeThumb?.part.add('focused'); } handleSlotChange() { this.labels = this.labelElements.map((label) => label.textContent ?? ''); if (this.hasLabels) { this.min = 0; this.max = this.labels.length - 1; this.step = 1; } } get activeValue() { return 0; } normalizeValue() { } getTrackStyle() { return {}; } updateValue(_increment) { return false; } renderThumbs() { return html ``; } emitInputEvent() { } emitChangeEvent() { } validateValue(value) { return this.normalizeByStep(clamp(value, this.lowerBound, this.upperBound)); } formatValue(value) { const strValue = value.toLocaleString(this.locale, this.valueFormatOptions); return this.valueFormat ? formatString(this.valueFormat, strValue) : strValue; } normalizeByStep(value) { return this.step ? value - ((value - this.lowerBound) % this.step) : value; } closestHandle(_event) { return this.thumb; } totalTickCount() { const primaryTicks = this.hasLabels ? this.primaryTicks > 0 ? this.labels.length : 0 : this.primaryTicks === 1 ? 2 : this.primaryTicks; return primaryTicks > 0 ? (primaryTicks - 1) * this.secondaryTicks + primaryTicks : this.secondaryTicks > 0 ? this.secondaryTicks : 0; } tickValue(idx) { const tickCount = this.totalTickCount(); const distance = this.distance; const labelStep = tickCount > 1 ? distance / (tickCount - 1) : distance; const labelVal = labelStep * idx; return this.min + labelVal; } isPrimary(idx) { return this.primaryTicks <= 0 ? false : idx % (this.secondaryTicks + 1) === 0; } showThumbLabels() { if (this.disabled || this.hideTooltip) { return; } if (this.thumbHoverTimer) { clearTimeout(this.thumbHoverTimer); this.thumbHoverTimer = null; } this.thumbLabelsVisible = true; } hideThumbLabels() { if (this.pointerCaptured || !this.thumbLabelsVisible) { return; } this.thumbHoverTimer = setTimeout(() => { this.thumbLabelsVisible = false; }, 750); } calculateTrackUpdate(mouseX) { const { width, left } = this.activeThumb.getBoundingClientRect(); const { width: trackWidth } = this.base.getBoundingClientRect(); const thumbX = left + width / 2; const scale = trackWidth / this.distance; const change = isLTR(this) ? mouseX - thumbX : thumbX - mouseX; if (this.step) { const stepDistance = scale * this.step; if (Math.abs(change) < stepDistance / 2) { return 0; } return Math.round(change / stepDistance) * this.step; } return change / scale; } updateSlider(mouseX) { if (this.disabled || !this.activeThumb) { return; } const increment = this.calculateTrackUpdate(mouseX); if (increment !== 0) { this.updateValue(increment); } } pointerDown(event) { const thumb = this.closestHandle(event); thumb.focus(); this.startValue = this.activeValue; this.updateSlider(event.clientX); this.setPointerCapture(event.pointerId); this.pointerCaptured = true; this.showThumbLabels(); event.preventDefault(); this.activeThumb?.part.remove('focused'); } pointerMove(event) { if (this.pointerCaptured) { this.updateSlider(event.clientX); } } lostPointerCapture() { this.pointerCaptured = false; this.hideThumbLabels(); if (this.startValue !== this.activeValue) { this.emitChangeEvent(); } this.startValue = undefined; } handleThumbFocus(event) { this.activeThumb = event.target; } handleThumbBlur() { this.activeThumb?.part.remove('focused'); this.activeThumb = undefined; } *_renderTicks() { const total = this.totalTickCount(); const secondaryTicks = this.secondaryTicks + 1; for (let i = 0; i < total; i++) { const primary = this.isPrimary(i); const shown = primary ? this.hidePrimaryLabels : this.hideSecondaryLabels; const labelInner = this.hasLabels ? primary ? this.labels[Math.round(i / secondaryTicks)] : nothing : this.formatValue(this.tickValue(i)); yield html `<div part="tick-group"> <div part="tick" data-primary=${primary}> ${shown ? nothing : html ` <div part="tick-label"> <span part="tick-label-inner">${labelInner}</span> </div> `} </div> </div>`; } } renderTicks() { return html `<div part="ticks">${this._renderTicks()}</div>`; } renderThumb(value, ariaLabel, thumbId) { const percent = `${asPercent(value - this.min, this.distance)}%`; const thumbStyles = { insetInlineStart: percent }; const tooltipStyles = { insetInlineStart: percent, opacity: this.thumbLabelsVisible ? 1 : 0, }; const textValue = this.hasLabels ? this.labels[value] : this.valueFormat || this.valueFormatOptions ? this.formatValue(value) : undefined; return html ` <div part="thumb" id=${ifDefined(thumbId)} tabindex=${this.disabled ? -1 : 0} style=${styleMap(thumbStyles)} role="slider" aria-valuemin=${this.lowerBound} aria-valuemax=${this.upperBound} aria-valuenow=${value} aria-valuetext=${ifDefined(textValue)} aria-label=${ifDefined(ariaLabel)} aria-disabled=${this.disabled ? 'true' : 'false'} @pointerenter=${this.showThumbLabels} @pointerleave=${this.hideThumbLabels} @focus=${this.handleThumbFocus} @blur=${this.handleThumbBlur} ></div> ${this.hideTooltip ? nothing : html ` <div part="thumb-label" style=${styleMap(tooltipStyles)}> <div part="thumb-label-inner"> ${this.hasLabels ? this.labels[value] : this.formatValue(value)} </div> </div> `} `; } renderSteps() { if (!this.discreteTrack || !this.step) { return nothing; } const interval = (100 * Math.SQRT2 * this.step) / this.distance; return html ` <div part="steps"> <svg width="100%" height="100%" style="display: flex"> <line x1="0" y1="1" x2="100%" y2="1" stroke="currentColor" stroke-dasharray="0, calc(${interval}%)" stroke-linecap="round" stroke-width="2px" ></line> </svg> </div> `; } render() { const isStart = this.tickOrientation === 'start'; const isMirrored = this.tickOrientation === 'mirror'; return html ` <div part="base"> ${isStart || isMirrored ? html `${this.renderTicks()}` : nothing} <div part="track"> <div part="inactive"></div> <div part="fill" style=${styleMap(this.getTrackStyle())}></div> ${this.renderSteps()} </div> ${!isStart ? html `${this.renderTicks()}` : nothing} <div part="thumbs">${this.renderThumbs()}</div> <slot @slotchange=${this.handleSlotChange}></slot> </div> `; } }; IgcSliderBaseComponent.styles = [styles, shared]; __decorate([ query(`[part~='thumb']`) ], IgcSliderBaseComponent.prototype, "thumb", void 0); __decorate([ query(`[part='base']`, true) ], IgcSliderBaseComponent.prototype, "base", void 0); __decorate([ queryAssignedElements({ selector: 'igc-slider-label' }) ], IgcSliderBaseComponent.prototype, "labelElements", void 0); __decorate([ state() ], IgcSliderBaseComponent.prototype, "thumbLabelsVisible", void 0); __decorate([ state() ], IgcSliderBaseComponent.prototype, "labels", void 0); __decorate([ property({ type: Number }) ], IgcSliderBaseComponent.prototype, "min", null); __decorate([ property({ type: Number }) ], IgcSliderBaseComponent.prototype, "max", null); __decorate([ property({ type: Number, attribute: 'lower-bound' }) ], IgcSliderBaseComponent.prototype, "lowerBound", null); __decorate([ property({ type: Number, attribute: 'upper-bound' }) ], IgcSliderBaseComponent.prototype, "upperBound", null); __decorate([ property({ type: Boolean, reflect: true }) ], IgcSliderBaseComponent.prototype, "disabled", void 0); __decorate([ property({ type: Boolean, attribute: 'discrete-track' }) ], IgcSliderBaseComponent.prototype, "discreteTrack", void 0); __decorate([ property({ type: Boolean, attribute: 'hide-tooltip' }) ], IgcSliderBaseComponent.prototype, "hideTooltip", void 0); __decorate([ property({ type: Number }) ], IgcSliderBaseComponent.prototype, "step", null); __decorate([ property({ type: Number, attribute: 'primary-ticks' }) ], IgcSliderBaseComponent.prototype, "primaryTicks", void 0); __decorate([ property({ type: Number, attribute: 'secondary-ticks' }) ], IgcSliderBaseComponent.prototype, "secondaryTicks", void 0); __decorate([ property({ attribute: 'tick-orientation' }) ], IgcSliderBaseComponent.prototype, "tickOrientation", void 0); __decorate([ property({ type: Boolean, attribute: 'hide-primary-labels' }) ], IgcSliderBaseComponent.prototype, "hidePrimaryLabels", void 0); __decorate([ property({ type: Boolean, attribute: 'hide-secondary-labels' }) ], IgcSliderBaseComponent.prototype, "hideSecondaryLabels", void 0); __decorate([ property() ], IgcSliderBaseComponent.prototype, "locale", void 0); __decorate([ property({ attribute: 'value-format' }) ], IgcSliderBaseComponent.prototype, "valueFormat", void 0); __decorate([ property({ attribute: false }) ], IgcSliderBaseComponent.prototype, "valueFormatOptions", void 0); __decorate([ property({ type: Number, reflect: true, attribute: 'tick-label-rotation' }), blazorTypeOverride('TickLabelRotation', true) ], IgcSliderBaseComponent.prototype, "tickLabelRotation", void 0); __decorate([ watch('min', { waitUntilFirstUpdate: true }), watch('max', { waitUntilFirstUpdate: true }), watch('lowerBound', { waitUntilFirstUpdate: true }), watch('upperBound', { waitUntilFirstUpdate: true }), watch('step', { waitUntilFirstUpdate: true }) ], IgcSliderBaseComponent.prototype, "constraintsChange", null); IgcSliderBaseComponent = __decorate([ themes(all), blazorDeepImport ], IgcSliderBaseComponent); export { IgcSliderBaseComponent }; //# sourceMappingURL=slider-base.js.map