@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
745 lines (740 loc) • 59.4 kB
JavaScript
/*!
* All material copyright ESRI, All Rights Reserved, unless otherwise specified.
* See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
*/
import { r as registerInstance, f as forceUpdate, h, g as getElement, c as createEvent, H as Host } from './index-bd94948c.js';
import { g as guid } from './guid-196bd5ea.js';
import { c as createObserver } from './observers-46118290.js';
import { j as intersects } from './dom-e7fa77b9.js';
import { d as decimalPlaces, c as clamp } from './math-456207f5.js';
import { c as connectLabel, d as disconnectLabel } from './label-68f22660.js';
import { c as connectForm, d as disconnectForm, a as afterConnectDefaultValueSet, H as HiddenFormInputSlot } from './form-5e4609eb.js';
import { u as updateHostInteraction } from './interactive-48b5cc0f.js';
/**
* Calculate slope of the tangents
* uses Steffen interpolation as it's monotonic
* http://jrwalsh1.github.io/posts/interpolations/
*/
function slope(p0, p1, p2) {
const dx = p1[0] - p0[0];
const dx1 = p2[0] - p1[0];
const dy = p1[1] - p0[1];
const dy1 = p2[1] - p1[1];
const m = dy / (dx || (dx1 < 0 && 0));
const m1 = dy1 / (dx1 || (dx < 0 && 0));
const p = (m * dx1 + m1 * dx) / (dx + dx1);
return (Math.sign(m) + Math.sign(m1)) * Math.min(Math.abs(m), Math.abs(m1), 0.5 * Math.abs(p)) || 0;
}
/**
* Calculate slope for just one tangent (single-sided)
*/
function slopeSingle(p0, p1, m) {
const dx = p1[0] - p0[0];
const dy = p1[1] - p0[1];
return dx ? ((3 * dy) / dx - m) / 2 : m;
}
/**
* Given two points and their tangent slopes,
* calculate the bezier handle coordinates and return draw command.
*
* Translates Hermite Spline to Beziér curve:
* stackoverflow.com/questions/42574940/
*/
function bezier(p0, p1, m0, m1, t) {
const [x0, y0] = p0;
const [x1, y1] = p1;
const dx = (x1 - x0) / 3;
const h1 = t([x0 + dx, y0 + dx * m0]).join(",");
const h2 = t([x1 - dx, y1 - dx * m1]).join(",");
const p = t([x1, y1]).join(",");
return `C ${h1} ${h2} ${p}`;
}
/**
* Generate a function which will translate a point
* from the data coordinate space to svg viewbox oriented pixels
*/
function translate({ width, height, min, max }) {
const rangeX = max[0] - min[0];
const rangeY = max[1] - min[1];
return (point) => {
const x = ((point[0] - min[0]) / rangeX) * width;
const y = height - (point[1] / rangeY) * height;
return [x, y];
};
}
/**
* Get the min and max values from the dataset
*/
function range(data) {
const [startX, startY] = data[0];
const min = [startX, startY];
const max = [startX, startY];
return data.reduce(({ min, max }, [x, y]) => ({
min: [Math.min(min[0], x), Math.min(min[1], y)],
max: [Math.max(max[0], x), Math.max(max[1], y)]
}), { min, max });
}
/**
* Generate drawing commands for an area graph
* returns a string can can be passed directly to a path element's `d` attribute
*/
function area({ data, min, max, t }) {
if (data.length === 0) {
return "";
}
// important points for beginning and ending the path
const [startX, startY] = t(data[0]);
const [minX, minY] = t(min);
const [maxX] = t(max);
// keep track of previous slope/points
let m;
let p0;
let p1;
// iterate over data points, calculating command for each
const commands = data.reduce((acc, point, i) => {
p0 = data[i - 2];
p1 = data[i - 1];
if (i > 1) {
const m1 = slope(p0, p1, point);
const m0 = m === undefined ? slopeSingle(p0, p1, m1) : m;
const command = bezier(p0, p1, m0, m1, t);
m = m1;
return `${acc} ${command}`;
}
return acc;
}, `M ${minX},${minY} L ${minX},${startY} L ${startX},${startY}`);
// close the path
const last = data[data.length - 1];
const end = bezier(p1, last, m, slopeSingle(p1, last, m), t);
return `${commands} ${end} L ${maxX},${minY} Z`;
}
const graphCss = "@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.calcite-animate{opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:var(--calcite-animation-timing);animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{-webkit-animation-name:in;animation-name:in}.calcite-animate__in-down{-webkit-animation-name:in-down;animation-name:in-down}.calcite-animate__in-up{-webkit-animation-name:in-up;animation-name:in-up}.calcite-animate__in-scale{-webkit-animation-name:in-scale;animation-name:in-scale}:root{--calcite-popper-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}:host{display:block}.svg{fill:currentColor;stroke:transparent;margin:0px;display:block;height:100%;width:100%;padding:0px}.svg .graph-path--highlight{fill:var(--calcite-ui-brand);opacity:0.5}";
const Graph = class {
constructor(hostRef) {
registerInstance(this, hostRef);
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
/**
* Array of tuples describing a single data point ([x, y])
* These data points should be sorted by x-axis value
*/
this.data = [];
//--------------------------------------------------------------------------
//
// Private State/Props
//
//--------------------------------------------------------------------------
this.graphId = `calcite-graph-${guid()}`;
this.resizeObserver = createObserver("resize", () => forceUpdate(this));
}
//--------------------------------------------------------------------------
//
// Lifecycle
//
//--------------------------------------------------------------------------
connectedCallback() {
var _a;
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.observe(this.el);
}
disconnectedCallback() {
var _a;
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
}
render() {
const { data, colorStops, el, highlightMax, highlightMin, min, max } = this;
const id = this.graphId;
const { clientHeight: height, clientWidth: width } = el;
// if we have no data, return empty svg
if (!data || data.length === 0) {
return (h("svg", { class: "svg", height: height, preserveAspectRatio: "none", viewBox: `0 0 ${width} ${height}`, width: width }));
}
const { min: rangeMin, max: rangeMax } = range(data);
let currentMin = rangeMin;
let currentMax = rangeMax;
if (min < rangeMin[0] || min > rangeMin[0]) {
currentMin = [min, 0];
}
if (max > rangeMax[0] || max < rangeMax[0]) {
currentMax = [max, rangeMax[1]];
}
const t = translate({ min: currentMin, max: currentMax, width, height });
const [hMinX] = t([highlightMin, currentMax[1]]);
const [hMaxX] = t([highlightMax, currentMax[1]]);
const areaPath = area({ data, min: rangeMin, max: rangeMax, t });
const fill = colorStops ? `url(#linear-gradient-${id})` : undefined;
return (h("svg", { class: "svg", height: height, preserveAspectRatio: "none", viewBox: `0 0 ${width} ${height}`, width: width }, colorStops ? (h("defs", null, h("linearGradient", { id: `linear-gradient-${id}`, x1: "0", x2: "1", y1: "0", y2: "0" }, colorStops.map(({ offset, color, opacity }) => (h("stop", { offset: `${offset * 100}%`, "stop-color": color, "stop-opacity": opacity })))))) : null, highlightMin !== undefined ? ([
h("mask", { height: "100%", id: `${id}1`, width: "100%", x: "0%", y: "0%" }, h("path", { d: `
M 0,0
L ${hMinX - 1},0
L ${hMinX - 1},${height}
L 0,${height}
Z
`, fill: "white" })),
h("mask", { height: "100%", id: `${id}2`, width: "100%", x: "0%", y: "0%" }, h("path", { d: `
M ${hMinX + 1},0
L ${hMaxX - 1},0
L ${hMaxX - 1},${height}
L ${hMinX + 1}, ${height}
Z
`, fill: "white" })),
h("mask", { height: "100%", id: `${id}3`, width: "100%", x: "0%", y: "0%" }, h("path", { d: `
M ${hMaxX + 1},0
L ${width},0
L ${width},${height}
L ${hMaxX + 1}, ${height}
Z
`, fill: "white" })),
h("path", { class: "graph-path", d: areaPath, fill: fill, mask: `url(#${id}1)` }),
h("path", { class: "graph-path--highlight", d: areaPath, fill: fill, mask: `url(#${id}2)` }),
h("path", { class: "graph-path", d: areaPath, fill: fill, mask: `url(#${id}3)` })
]) : (h("path", { class: "graph-path", d: areaPath, fill: fill }))));
}
get el() { return getElement(this); }
};
Graph.style = graphCss;
const sliderCss = "@charset \"UTF-8\";@-webkit-keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-down{0%{opacity:0;-webkit-transform:translate3D(0, -5px, 0);transform:translate3D(0, -5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;-webkit-transform:translate3D(0, 5px, 0);transform:translate3D(0, 5px, 0)}100%{opacity:1;-webkit-transform:translate3D(0, 0, 0);transform:translate3D(0, 0, 0)}}@-webkit-keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}@keyframes in-scale{0%{opacity:0;-webkit-transform:scale3D(0.95, 0.95, 1);transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;-webkit-transform:scale3D(1, 1, 1);transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.calcite-animate{opacity:0;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:var(--calcite-animation-timing);animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{-webkit-animation-name:in;animation-name:in}.calcite-animate__in-down{-webkit-animation-name:in-down;animation-name:in-down}.calcite-animate__in-up{-webkit-animation-name:in-up;animation-name:in-up}.calcite-animate__in-scale{-webkit-animation-name:in-scale;animation-name:in-scale}:root{--calcite-popper-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}.scale--s{--calcite-slider-handle-size:10px;--calcite-slider-handle-extension-height:6.5px;--calcite-slider-container-font-size:var(--calcite-font-size--3)}.scale--s .handle__label,.scale--s .tick__label{line-height:.75rem}.scale--m{--calcite-slider-handle-size:14px;--calcite-slider-handle-extension-height:8px;--calcite-slider-container-font-size:var(--calcite-font-size--2)}.scale--m .handle__label,.scale--m .tick__label{line-height:1rem}.scale--l{--calcite-slider-handle-size:16px;--calcite-slider-handle-extension-height:10.5px;--calcite-slider-container-font-size:var(--calcite-font-size--1)}.scale--l .handle__label,.scale--l .tick__label{line-height:1rem}.handle__label,.tick__label{font-weight:var(--calcite-font-weight-medium);color:var(--calcite-ui-text-2);font-size:var(--calcite-slider-container-font-size)}:host{display:block}.container{position:relative;display:block;padding:calc(var(--calcite-slider-handle-size) * 0.5);margin:calc(var(--calcite-slider-handle-size) * 0.5) 0;--calcite-slider-full-handle-height:calc(\n var(--calcite-slider-handle-size) + var(--calcite-slider-handle-extension-height)\n )}:host([disabled]){pointer-events:none;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;opacity:var(--calcite-ui-opacity-disabled)}:host([disabled]) .track__range,:host([disabled]) .tick--active{background-color:var(--calcite-ui-text-3)}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.scale--s .thumb:not(.thumb--precise){--calcite-slider-thumb-y-offset:-6px}.scale--m .thumb:not(.thumb--precise){--calcite-slider-thumb-y-offset:-8px}.scale--l .thumb:not(.thumb--precise){--calcite-slider-thumb-y-offset:-9px}:host([precise]:not([has-histogram])) .container .thumb--value{--calcite-slider-thumb-y-offset:calc(var(--calcite-slider-full-handle-height) * -1)}.thumb-container{position:relative;max-width:100%}.thumb{--calcite-slider-thumb-x-offset:calc(var(--calcite-slider-handle-size) * 0.5);position:absolute;margin:0px;display:-ms-flexbox;display:flex;cursor:pointer;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;border-style:none;background-color:transparent;padding:0px;font-family:inherit;outline:2px solid transparent;outline-offset:2px;-webkit-transform:translate(var(--calcite-slider-thumb-x-offset), var(--calcite-slider-thumb-y-offset));transform:translate(var(--calcite-slider-thumb-x-offset), var(--calcite-slider-thumb-y-offset))}.thumb .handle__label.static,.thumb .handle__label.transformed{position:absolute;top:0px;bottom:0px;opacity:0}.thumb .handle__label.hyphen::after{content:\"—\";display:inline-block;width:1em}.thumb .handle__label.hyphen--wrap{display:-ms-flexbox;display:flex}.thumb .handle{-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:9999px;background-color:var(--calcite-ui-foreground-1);outline-offset:0;outline-color:transparent;-webkit-transition:outline-offset 100ms ease-in-out, outline-color 100ms ease-in-out;transition:outline-offset 100ms ease-in-out, outline-color 100ms ease-in-out;height:var(--calcite-slider-handle-size);width:var(--calcite-slider-handle-size);-webkit-box-shadow:0 0 0 2px var(--calcite-ui-text-3) inset;box-shadow:0 0 0 2px var(--calcite-ui-text-3) inset;-webkit-transition:border var(--calcite-internal-animation-timing-medium) ease, background-color var(--calcite-internal-animation-timing-medium) ease, -webkit-box-shadow var(--calcite-animation-timing) ease;transition:border var(--calcite-internal-animation-timing-medium) ease, background-color var(--calcite-internal-animation-timing-medium) ease, -webkit-box-shadow var(--calcite-animation-timing) ease;transition:border var(--calcite-internal-animation-timing-medium) ease, background-color var(--calcite-internal-animation-timing-medium) ease, box-shadow var(--calcite-animation-timing) ease;transition:border var(--calcite-internal-animation-timing-medium) ease, background-color var(--calcite-internal-animation-timing-medium) ease, box-shadow var(--calcite-animation-timing) ease, -webkit-box-shadow var(--calcite-animation-timing) ease}.thumb .handle-extension{width:0.125rem;height:var(--calcite-slider-handle-extension-height);background-color:var(--calcite-ui-text-3)}.thumb:hover .handle{-webkit-box-shadow:0 0 0 3px var(--calcite-ui-brand) inset;box-shadow:0 0 0 3px var(--calcite-ui-brand) inset}.thumb:hover .handle-extension{background-color:var(--calcite-ui-brand)}.thumb:focus .handle{outline:2px solid var(--calcite-ui-brand);outline-offset:2px}.thumb:focus .handle-extension{background-color:var(--calcite-ui-brand)}.thumb.thumb--minValue{-webkit-transform:translate(calc(var(--calcite-slider-thumb-x-offset) * -1), var(--calcite-slider-thumb-y-offset));transform:translate(calc(var(--calcite-slider-thumb-x-offset) * -1), var(--calcite-slider-thumb-y-offset))}.thumb.thumb--precise{--calcite-slider-thumb-y-offset:-2px}:host([label-handles]) .thumb{--calcite-slider-thumb-x-offset:50%}:host([label-handles]):host(:not([has-histogram])) .scale--s .thumb:not(.thumb--precise){--calcite-slider-thumb-y-offset:-23px}:host([label-handles]):host(:not([has-histogram])) .scale--m .thumb:not(.thumb--precise){--calcite-slider-thumb-y-offset:-30px}:host([label-handles]):host(:not([has-histogram])) .scale--l .thumb:not(.thumb--precise){--calcite-slider-thumb-y-offset:-32px}:host([has-histogram][label-handles]) .handle__label,:host([label-handles]:not([has-histogram])) .thumb--minValue.thumb--precise .handle__label{margin-top:0.5em}:host(:not([has-histogram]):not([precise])) .handle__label,:host([label-handles]:not([has-histogram])) .thumb--value .handle__label{margin-bottom:0.5em}:host([label-handles][precise]):host(:not([has-histogram])) .scale--s .thumb--value{--calcite-slider-thumb-y-offset:-33px}:host([label-handles][precise]):host(:not([has-histogram])) .scale--m .thumb--value{--calcite-slider-thumb-y-offset:-44px}:host([label-handles][precise]):host(:not([has-histogram])) .scale--l .thumb--value{--calcite-slider-thumb-y-offset:-49px}.thumb:focus .handle,.thumb--active .handle{background-color:var(--calcite-ui-brand);-webkit-box-shadow:0 0 8px 0 rgba(0, 0, 0, 0.16);box-shadow:0 0 8px 0 rgba(0, 0, 0, 0.16)}.thumb:hover.thumb--precise:after,.thumb:focus.thumb--precise:after,.thumb--active.thumb--precise:after{background-color:var(--calcite-ui-brand)}.track{position:relative;height:0.125rem;border-radius:0px;background-color:var(--calcite-ui-border-2);-webkit-transition:all var(--calcite-internal-animation-timing-medium) ease-in;transition:all var(--calcite-internal-animation-timing-medium) ease-in}.track__range{position:absolute;top:0px;height:0.125rem;background-color:var(--calcite-ui-brand)}.container--range .track__range:hover{cursor:ew-resize}.container--range .track__range:after{position:absolute;width:100%;content:\"\";top:calc(var(--calcite-slider-full-handle-height) * 0.5 * -1);height:calc(var(--calcite-slider-handle-size) + var(--calcite-slider-handle-extension-height))}.tick{position:absolute;height:0.25rem;width:0.125rem;border-width:1px;border-style:solid;background-color:var(--calcite-ui-border-input);border-color:var(--calcite-ui-foreground-1);top:-2px;pointer-events:none;-webkit-margin-start:calc(-1 * 0.125rem);margin-inline-start:calc(-1 * 0.125rem)}.tick--active{background-color:var(--calcite-ui-brand)}.tick__label{pointer-events:none;margin-top:0.875rem;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center}.tick__label--min{-webkit-transition:opacity var(--calcite-animation-timing);transition:opacity var(--calcite-animation-timing)}.tick__label--max{-webkit-transition:opacity var(--calcite-internal-animation-timing-fast);transition:opacity var(--calcite-internal-animation-timing-fast)}:host([has-histogram][label-handles]) .tick__label--min,:host([has-histogram][label-handles]) .tick__label--max,:host([has-histogram][precise]) .tick__label--min,:host([has-histogram][precise]) .tick__label--max{font-weight:var(--calcite-font-weight-normal);color:var(--calcite-ui-text-3)}.graph{color:var(--calcite-ui-foreground-3);height:48px}:host([label-ticks][ticks]) .container{padding-bottom:calc(0.875rem + var(--calcite-slider-container-font-size))}:host([has-histogram]):host([precise][label-handles]) .container{padding-bottom:calc(var(--calcite-slider-full-handle-height) + 1em)}:host([has-histogram]):host([label-handles]:not([precise])) .container{padding-bottom:calc(var(--calcite-slider-handle-size) * 0.5 + 1em)}:host([has-histogram]):host([precise]:not([label-handles])) .container{padding-bottom:var(--calcite-slider-full-handle-height)}:host(:not([has-histogram])):host([precise]:not([label-handles])) .container{padding-top:var(--calcite-slider-full-handle-height)}:host(:not([has-histogram])):host([precise]:not([label-handles])) .container--range{padding-bottom:var(--calcite-slider-full-handle-height)}:host(:not([has-histogram])):host([label-handles]:not([precise])) .container{padding-top:calc(var(--calcite-slider-full-handle-height) + 4px)}:host(:not([has-histogram])):host([label-handles][precise]) .container{padding-top:calc(var(--calcite-slider-full-handle-height) + var(--calcite-slider-container-font-size) + 4px)}:host(:not([has-histogram])):host([label-handles][precise]) .container--range{padding-bottom:calc(var(--calcite-slider-full-handle-height) + var(--calcite-slider-container-font-size) + 4px)}::slotted(input[slot=hidden-form-input]){bottom:0 !important;left:0 !important;margin:0 !important;opacity:0 !important;outline:none !important;padding:0 !important;position:absolute !important;right:0 !important;top:0 !important;-webkit-transform:none !important;transform:none !important;-webkit-appearance:none !important;z-index:-1 !important}";
const Slider = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.calciteSliderInput = createEvent(this, "calciteSliderInput", 7);
this.calciteSliderChange = createEvent(this, "calciteSliderChange", 7);
this.calciteSliderUpdate = createEvent(this, "calciteSliderUpdate", 7);
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
/** Disable and gray out the slider */
this.disabled = false;
/** Indicates if a histogram is present */
this.hasHistogram = false;
/** Label handles with their numeric value */
this.labelHandles = false;
/** Label tick marks with their numeric value. */
this.labelTicks = false;
/** Maximum selectable value */
this.max = 100;
/** Minimum selectable value */
this.min = 0;
/**
* When true, the slider will display values from high to low.
*
* Note that this value will be ignored if the slider has an associated histogram.
*/
this.mirrored = false;
/** Use finer point for handles */
this.precise = false;
/**
* When true, makes the component required for form-submission.
*/
this.required = false;
/** When true, enables snap selection along the step interval */
this.snap = false;
/** Interval to move on up/down keys */
this.step = 1;
/** Currently selected number (if single select) */
this.value = null;
/**
* Specify the scale of the slider, defaults to m
*/
this.scale = "m";
this.guid = `calcite-slider-${guid()}`;
this.isRange = false;
this.activeProp = "value";
this.minMaxValueRange = null;
this.minValueDragRange = null;
this.maxValueDragRange = null;
this.tickValues = [];
this.dragUpdate = (event) => {
event.preventDefault();
if (this.dragProp) {
const value = this.translate(event.clientX || event.pageX);
if (this.isRange && this.dragProp === "minMaxValue") {
if (this.minValueDragRange && this.maxValueDragRange && this.minMaxValueRange) {
const newMinValue = value - this.minValueDragRange;
const newMaxValue = value + this.maxValueDragRange;
if (newMaxValue <= this.max &&
newMinValue >= this.min &&
newMaxValue - newMinValue === this.minMaxValueRange) {
this.minValue = this.clamp(newMinValue, "minValue");
this.maxValue = this.clamp(newMaxValue, "maxValue");
}
}
else {
this.minValueDragRange = value - this.minValue;
this.maxValueDragRange = this.maxValue - value;
this.minMaxValueRange = this.maxValue - this.minValue;
}
}
else {
this.setValue(this.dragProp, this.clamp(value, this.dragProp));
}
}
};
this.dragEnd = (event) => {
this.removeDragListeners();
this.focusActiveHandle(event.clientX);
if (this.lastDragPropValue != this[this.dragProp]) {
this.emitChange();
}
this.dragProp = null;
this.lastDragPropValue = null;
this.minValueDragRange = null;
this.maxValueDragRange = null;
this.minMaxValueRange = null;
};
/**
* Set the reference of the track Element
* @internal
* @param node
*/
this.storeTrackRef = (node) => {
this.trackEl = node;
};
}
histogramWatcher(newHistogram) {
this.hasHistogram = !!newHistogram;
}
//--------------------------------------------------------------------------
//
// Lifecycle
//
//--------------------------------------------------------------------------
connectedCallback() {
connectLabel(this);
connectForm(this);
}
disconnectedCallback() {
disconnectLabel(this);
disconnectForm(this);
this.removeDragListeners();
}
componentWillLoad() {
this.isRange = !!(this.maxValue || this.maxValue === 0);
this.tickValues = this.generateTickValues();
this.value = this.clamp(this.value);
afterConnectDefaultValueSet(this, this.value);
if (this.snap) {
this.value = this.getClosestStep(this.value);
}
if (this.histogram) {
this.hasHistogram = true;
}
}
componentDidRender() {
if (this.labelHandles) {
this.adjustHostObscuredHandleLabel("value");
if (this.isRange) {
this.adjustHostObscuredHandleLabel("minValue");
if (!(this.precise && this.isRange && !this.hasHistogram)) {
this.hyphenateCollidingRangeHandleLabels();
}
}
}
this.hideObscuredBoundingTickLabels();
updateHostInteraction(this);
}
render() {
const id = this.el.id || this.guid;
const min = this.minValue || this.min;
const max = this.maxValue || this.value;
const maxProp = this.isRange ? "maxValue" : "value";
const value = this[maxProp];
const useMinValue = this.shouldUseMinValue();
const minInterval = this.getUnitInterval(useMinValue ? this.minValue : min) * 100;
const maxInterval = this.getUnitInterval(max) * 100;
const mirror = this.shouldMirror();
const leftThumbOffset = `${mirror ? 100 - minInterval : minInterval}%`;
const rightThumbOffset = `${mirror ? maxInterval : 100 - maxInterval}%`;
const handle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.isRange ? this.maxLabel : this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": value, class: {
thumb: true,
"thumb--value": true,
"thumb--active": this.lastDragProp !== "minMaxValue" && this.dragProp === maxProp
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = maxProp), onPointerDown: () => this.dragStart(maxProp), ref: (el) => (this.maxHandle = el), role: "slider", style: { right: rightThumbOffset }, tabIndex: 0 }, h("div", { class: "handle" })));
const labeledHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.isRange ? this.maxLabel : this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": value, class: {
thumb: true,
"thumb--value": true,
"thumb--active": this.lastDragProp !== "minMaxValue" && this.dragProp === maxProp
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = maxProp), onPointerDown: () => this.dragStart(maxProp), ref: (el) => (this.maxHandle = el), role: "slider", style: { right: rightThumbOffset }, tabIndex: 0 }, h("span", { "aria-hidden": "true", class: "handle__label handle__label--value" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value static" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value transformed" }, value ? value.toLocaleString() : value), h("div", { class: "handle" })));
const histogramLabeledHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.isRange ? this.maxLabel : this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": value, class: {
thumb: true,
"thumb--value": true,
"thumb--active": this.lastDragProp !== "minMaxValue" && this.dragProp === maxProp
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = maxProp), onPointerDown: () => this.dragStart(maxProp), ref: (el) => (this.maxHandle = el), role: "slider", style: { right: rightThumbOffset }, tabIndex: 0 }, h("div", { class: "handle" }), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value static" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value transformed" }, value ? value.toLocaleString() : value)));
const preciseHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.isRange ? this.maxLabel : this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": value, class: {
thumb: true,
"thumb--value": true,
"thumb--active": this.lastDragProp !== "minMaxValue" && this.dragProp === maxProp,
"thumb--precise": true
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = maxProp), onPointerDown: () => this.dragStart(maxProp), ref: (el) => (this.maxHandle = el), role: "slider", style: { right: rightThumbOffset }, tabIndex: 0 }, h("div", { class: "handle" }), h("div", { class: "handle-extension" })));
const histogramPreciseHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.isRange ? this.maxLabel : this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": value, class: {
thumb: true,
"thumb--value": true,
"thumb--active": this.lastDragProp !== "minMaxValue" && this.dragProp === maxProp,
"thumb--precise": true
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = maxProp), onPointerDown: () => this.dragStart(maxProp), ref: (el) => (this.maxHandle = el), role: "slider", style: { right: rightThumbOffset }, tabIndex: 0 }, h("div", { class: "handle-extension" }), h("div", { class: "handle" })));
const labeledPreciseHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.isRange ? this.maxLabel : this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": value, class: {
thumb: true,
"thumb--value": true,
"thumb--active": this.lastDragProp !== "minMaxValue" && this.dragProp === maxProp,
"thumb--precise": true
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = maxProp), onPointerDown: () => this.dragStart(maxProp), ref: (el) => (this.maxHandle = el), role: "slider", style: { right: rightThumbOffset }, tabIndex: 0 }, h("span", { "aria-hidden": "true", class: "handle__label handle__label--value" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value static" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value transformed" }, value ? value.toLocaleString() : value), h("div", { class: "handle" }), h("div", { class: "handle-extension" })));
const histogramLabeledPreciseHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.isRange ? this.maxLabel : this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": value, class: {
thumb: true,
"thumb--value": true,
"thumb--active": this.lastDragProp !== "minMaxValue" && this.dragProp === maxProp,
"thumb--precise": true
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = maxProp), onPointerDown: () => this.dragStart(maxProp), ref: (el) => (this.maxHandle = el), role: "slider", style: { right: rightThumbOffset }, tabIndex: 0 }, h("div", { class: "handle-extension" }), h("div", { class: "handle" }), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value static" }, value ? value.toLocaleString() : value), h("span", { "aria-hidden": "true", class: "handle__label handle__label--value transformed" }, value ? value.toLocaleString() : value)));
const minHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": this.minValue, class: {
thumb: true,
"thumb--minValue": true,
"thumb--active": this.dragProp === "minValue"
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = "minValue"), onPointerDown: () => this.dragStart("minValue"), ref: (el) => (this.minHandle = el), role: "slider", style: { left: leftThumbOffset }, tabIndex: 0 }, h("div", { class: "handle" })));
const minLabeledHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": this.minValue, class: {
thumb: true,
"thumb--minValue": true,
"thumb--active": this.dragProp === "minValue"
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = "minValue"), onPointerDown: () => this.dragStart("minValue"), ref: (el) => (this.minHandle = el), role: "slider", style: { left: leftThumbOffset }, tabIndex: 0 }, h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue" }, this.minValue && this.minValue.toLocaleString()), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue static" }, this.minValue && this.minValue.toLocaleString()), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue transformed" }, this.minValue && this.minValue.toLocaleString()), h("div", { class: "handle" })));
const minHistogramLabeledHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": this.minValue, class: {
thumb: true,
"thumb--minValue": true,
"thumb--active": this.dragProp === "minValue"
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = "minValue"), onPointerDown: () => this.dragStart("minValue"), ref: (el) => (this.minHandle = el), role: "slider", style: { left: leftThumbOffset }, tabIndex: 0 }, h("div", { class: "handle" }), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue" }, this.minValue && this.minValue.toLocaleString()), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue static" }, this.minValue && this.minValue.toLocaleString()), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue transformed" }, this.minValue && this.minValue.toLocaleString())));
const minPreciseHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": this.minValue, class: {
thumb: true,
"thumb--minValue": true,
"thumb--active": this.dragProp === "minValue",
"thumb--precise": true
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = "minValue"), onPointerDown: () => this.dragStart("minValue"), ref: (el) => (this.minHandle = el), role: "slider", style: { left: leftThumbOffset }, tabIndex: 0 }, h("div", { class: "handle-extension" }), h("div", { class: "handle" })));
const minLabeledPreciseHandle = (h("div", { "aria-disabled": this.disabled, "aria-label": this.minLabel, "aria-orientation": "horizontal", "aria-valuemax": this.max, "aria-valuemin": this.min, "aria-valuenow": this.minValue, class: {
thumb: true,
"thumb--minValue": true,
"thumb--active": this.dragProp === "minValue",
"thumb--precise": true
}, onBlur: () => (this.activeProp = null), onFocus: () => (this.activeProp = "minValue"), onPointerDown: () => this.dragStart("minValue"), ref: (el) => (this.minHandle = el), role: "slider", style: { left: leftThumbOffset }, tabIndex: 0 }, h("div", { class: "handle-extension" }), h("div", { class: "handle" }), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue" }, this.minValue && this.minValue.toLocaleString()), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue static" }, this.minValue && this.minValue.toLocaleString()), h("span", { "aria-hidden": "true", class: "handle__label handle__label--minValue transformed" }, this.minValue && this.minValue.toLocaleString())));
return (h(Host, { id: id, onTouchStart: this.handleTouchStart }, h("div", { class: {
["container"]: true,
["container--range"]: this.isRange,
[`scale--${this.scale}`]: true
} }, this.renderGraph(), h("div", { class: "track", ref: this.storeTrackRef }, h("div", { class: "track__range", onPointerDown: () => this.dragStart("minMaxValue"), style: {
left: `${mirror ? 100 - maxInterval : minInterval}%`,
right: `${mirror ? minInterval : 100 - maxInterval}%`
} }), h("div", { class: "ticks" }, this.tickValues.map((tick) => {
const tickOffset = `${this.getUnitInterval(tick) * 100}%`;
let activeTicks = tick >= min && tick <= max;
if (useMinValue) {
activeTicks = tick >= this.minValue && tick <= this.maxValue;
}
return (h("span", { class: {
tick: true,
"tick--active": activeTicks
}, style: {
left: mirror ? "" : tickOffset,
right: mirror ? tickOffset : ""
} }, this.renderTickLabel(tick)));
}))), h("div", { class: "thumb-container" }, !this.precise && !this.labelHandles && this.isRange && minHandle, !this.hasHistogram &&
!this.precise &&
this.labelHandles &&
this.isRange &&
minLabeledHandle, this.precise && !this.labelHandles && this.isRange && minPreciseHandle, this.precise && this.labelHandles && this.isRange && minLabeledPreciseHandle, this.hasHistogram &&
!this.precise &&
this.labelHandles &&
this.isRange &&
minHistogramLabeledHandle, !this.precise && !this.labelHandles && handle, !this.hasHistogram && !this.precise && this.labelHandles && labeledHandle, !this.hasHistogram && this.precise && !this.labelHandles && preciseHandle, this.hasHistogram && this.precise && !this.labelHandles && histogramPreciseHandle, !this.hasHistogram && this.precise && this.labelHandles && labeledPreciseHandle, this.hasHistogram && !this.precise && this.labelHandles && histogramLabeledHandle, this.hasHistogram &&
this.precise &&
this.labelHandles &&
histogramLabeledPreciseHandle, h(HiddenFormInputSlot, { component: this })))));
}
renderGraph() {
return this.histogram ? (h("calcite-graph", { class: "graph", colorStops: this.histogramStops, data: this.histogram, highlightMax: this.isRange ? this.maxValue : this.value, highlightMin: this.isRange ? this.minValue : this.min, max: this.max, min: this.min })) : null;
}
renderTickLabel(tick) {
const isMinTickLabel = tick === this.min;
const isMaxTickLabel = tick === this.max;
const tickLabel = (h("span", { class: {
tick__label: true,
"tick__label--min": isMinTickLabel,
"tick__label--max": isMaxTickLabel
} }, tick.toLocaleString()));
if (this.labelTicks && !this.hasHistogram && !this.isRange) {
return tickLabel;
}
if (this.labelTicks &&
!this.hasHistogram &&
this.isRange &&
!this.precise &&
!this.labelHandles) {
return tickLabel;
}
if (this.labelTicks &&
!this.hasHistogram &&
this.isRange &&
!this.precise &&
this.labelHandles) {
return tickLabel;
}
if (this.labelTicks &&
!this.hasHistogram &&
this.isRange &&
this.precise &&
(isMinTickLabel || isMaxTickLabel)) {
return tickLabel;
}
if (this.labelTicks && this.hasHistogram && !this.precise && !this.labelHandles) {
return tickLabel;
}
if (this.labelTicks &&
this.hasHistogram &&
this.precise &&
!this.labelHandles &&
(isMinTickLabel || isMaxTickLabel)) {
return tickLabel;
}
if (this.labelTicks &&
this.hasHistogram &&
!this.precise &&
this.labelHandles &&
(isMinTickLabel || isMaxTickLabel)) {
return tickLabel;
}
if (this.labelTicks &&
this.hasHistogram &&
this.precise &&
this.labelHandles &&
(isMinTickLabel || isMaxTickLabel)) {
return tickLabel;
}
return null;
}
//--------------------------------------------------------------------------
//
// Event Listeners
//
//--------------------------------------------------------------------------
keyDownHandler(event) {
const mirror = this.shouldMirror();
const { activeProp, max, min, pageStep, step } = this;
const value = this[activeProp];
const key = event.key;
if (key === "Enter" || key === " ") {
event.preventDefault();
return;
}
let adjustment;
if (key === "ArrowUp" || key === "ArrowRight") {
const directionFactor = mirror && key === "ArrowRight" ? -1 : 1;
adjustment = value + step * directionFactor;
}
else if (key === "ArrowDown" || key === "ArrowLeft") {
const directionFactor = mirror && key === "ArrowLeft" ? -1 : 1;
adjustment = value - step * directionFactor;
}
else if (key === "PageUp") {
if (pageStep) {
adjustment = value + pageStep;
}
}
else if (key === "PageDown") {
if (pageStep) {
adjustment = value - pageStep;
}
}
else if (key === "Home") {
adjustment = min;
}
else if (key === "End") {
adjustment = max;
}
if (isNaN(adjustment)) {
return;
}
event.preventDefault();
const fixedDecimalAdjustment = Number(adjustment.toFixed(decimalPlaces(step)));
this.setValue(activeProp, this.clamp(fixedDecimalAdjustment, activeProp));
}
clickHandler(event) {
this.focusActiveHandle(event.clientX);
}
pointerDownHandler(event) {
const x = event.clientX || event.pageX;
const position = this.translate(x);
let prop = "value";
if (this.isRange) {
const inRange = position >= this.minValue && position <= this.maxValue;
if (inRange && this.lastDragProp === "minMaxValue") {
prop = "minMaxValue";
}
else {
const closerToMax = Math.abs(this.maxValue - position) < Math.abs(this.minValue - position);
prop = closerToMax || position > this.maxValue ? "maxValue" : "minValue";
}
}
this.lastDragPropValue = this[prop];
this.dragStart(prop);
const isThumbActive = this.el.shadowRoot.querySelector(".thumb:active");
if (!isThumbActive) {
this.setValue(prop, this.clamp(position, prop));
}
}
handleTouchStart(event) {
// needed to prevent extra click at the end of a handle drag
event.preventDefault();
}
//--------------------------------------------------------------------------
//
// Public Methods
//
//--------------------------------------------------------------------------
/** Sets focus on the component. */
async setFocus() {
const handle = this.minHandle ? this.minHandle : this.maxHandle;
handle.focus();
}
//--------------------------------------------------------------------------
//
// Private Methods
//
//--------------------------------------------------------------------------
onLabelClick() {
this.setFocus();
}
shouldMirror() {
return this.mirrored && !this.hasHistogram;
}
shouldUseMinValue() {
if (!this.isRange) {
return false;
}
return ((this.hasHistogram && this.maxValue === 0) || (!this.hasHistogram && this.minValue === 0));
}
generateTickValues() {
const ticks = [];
let current = this.min;
while (this.ticks && current < this.max + this.ticks) {
ticks.push(Math.min(current, this.max));
current = current + this.ticks;
}
return ticks;
}
dragStart(prop) {
this.dragProp = prop;
this.lastDragProp = this.dragProp;
this.activeProp = prop;
document.addEventListener("pointermove", this.dragUpdate);
document.addEventListener("pointerup", this.dragEnd);
document.addEventListener("pointercancel", this.dragEnd);
}
focusActiveHandle(valueX) {
switch (this.dragProp) {
case "minValue":
this.minHandle.focus();
break;
case "maxValue":
this.maxHandle.focus();
break;
case "minMaxValue":
this.getClosestHandle(valueX).focus();
break;
}
}
emitInput() {
this.calciteSliderInput.emit();
this.calciteSliderUpdate.emit();
}
emitChange() {
this.calciteSliderChange.emit();
}
removeDragListeners() {
document.removeEventListener("pointermove", this.dragUpdate);
document.removeEventListener("pointerup", this.dragEnd);
document.removeEventListener("pointercancel", this.dragEnd);
}
/**
* Set the prop value if changed at the component level
* @param valueProp
* @param value
*/
setValue(valueProp, value) {
const oldValue = this[valueProp];
const valueChanged = oldValue !== value;
if (!valueChanged) {
return;
}
this[valueProp] = value;
const dragging = this.dragProp;
if (!dragging) {
this.emitChange();
}
this.emitInput();
}
/**
* If number is outside range, constrain to min or max
* @internal
*/
clamp(value, prop) {
value = clamp(value, this.min, this.max);
// ensure that maxValue and minValue don't swap positions
if (prop === "maxValue") {
value = Math.max(value, this.minValue);
}
if (prop === "minValue") {
value = Math.min(value, this.maxValue);
}
return value;
}
/**
* Translate a pixel position to value along the range
* @internal
*/
translate(x) {
const range = this.max - this.min;
const { left, width } = this.trackEl.getBoundingClientRect();
const percent = (x - left) / width;
const mirror = this.shouldMirror();
const clampedValue = this.clamp(this.min + range * (mirror ? 1 - percent : percent));
let value = Number(clampedValue.toFixed(decimalPlaces(this.step)));
if (this.snap && this.step) {
value = this.getClosestStep(value);
}
return value;
}
/**
* Get closest allowed value along stepped values
* @internal
*/
getClosestStep(num) {
num = Number(this.clamp(num).toFixed(decimalPlaces(this.step)));
if (this.step) {
const step = Math.round(num / this.step) * this.step;
num = Number(this.clamp(step).toFixed(decimalPlaces(this.step)));
}
return num;
}
getClosestHandle(valueX) {
return this.getDistanceX(this.maxHandle, valueX) > this.getDistanceX(this.minHandle, valueX)
? this.minHandle
: this.maxHandle;
}
getDistanceX(el, valueX) {
return Math.abs(el.getBoundingClientRect().left - valueX);
}
getFontSizeForElement(element) {
return Number(window.getComputedStyle(element).getPropertyValue("font-size").match(/\d+/)[0]);
}
/**
* Get position of value along range as fractional value
* @return {number} number in the unit interval [0,1]
* @internal
*/
getUnitInterval(num) {
num = this.clamp(num);
const range = this.max - this.min;
return (num - this.min) / range;
}
adjustHostObscuredHandleLabel(name) {
const label = this.el.shadowRoot.querySelector(`.handle__label--${name}`);
const labelStatic = this.el.shadowRoot.querySelector(`.handle__label--${name}.static`);
const labelTransfor