INIT
This commit is contained in:
+219
@@ -0,0 +1,219 @@
|
||||
export function getRangeStyles(direction, min, max) {
|
||||
const styles = {
|
||||
position: "absolute",
|
||||
};
|
||||
if (direction === "lr") {
|
||||
styles.left = `${min}%`;
|
||||
styles.right = `${max}%`;
|
||||
}
|
||||
else if (direction === "rl") {
|
||||
styles.right = `${min}%`;
|
||||
styles.left = `${max}%`;
|
||||
}
|
||||
else if (direction === "bt") {
|
||||
styles.bottom = `${min}%`;
|
||||
styles.top = `${max}%`;
|
||||
}
|
||||
else {
|
||||
styles.top = `${min}%`;
|
||||
styles.bottom = `${max}%`;
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
export function getThumbStyles(direction, thumbPos) {
|
||||
const styles = {
|
||||
position: "absolute",
|
||||
};
|
||||
if (direction === "lr") {
|
||||
styles.left = `${thumbPos}%`;
|
||||
styles.translate = "-50% 0";
|
||||
}
|
||||
else if (direction === "rl") {
|
||||
styles.right = `${thumbPos}%`;
|
||||
styles.translate = "50% 0";
|
||||
}
|
||||
else if (direction === "bt") {
|
||||
styles.bottom = `${thumbPos}%`;
|
||||
styles.translate = "0 50%";
|
||||
}
|
||||
else {
|
||||
styles.top = `${thumbPos}%`;
|
||||
styles.translate = "0 -50%";
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
export function getTickStyles(direction, tickPosition, offsetPercentage) {
|
||||
const style = {
|
||||
position: "absolute",
|
||||
};
|
||||
if (direction === "lr") {
|
||||
style.left = `${tickPosition}%`;
|
||||
style.translate = `${offsetPercentage}% 0`;
|
||||
}
|
||||
else if (direction === "rl") {
|
||||
style.right = `${tickPosition}%`;
|
||||
style.translate = `${-offsetPercentage}% 0`;
|
||||
}
|
||||
else if (direction === "bt") {
|
||||
style.bottom = `${tickPosition}%`;
|
||||
style.translate = `0 ${-offsetPercentage}%`;
|
||||
}
|
||||
else {
|
||||
style.top = `${tickPosition}%`;
|
||||
style.translate = `0 ${offsetPercentage}%`;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
export function getTickLabelStyles(direction, tickPosition, labelPosition = "top") {
|
||||
const style = {
|
||||
position: "absolute",
|
||||
};
|
||||
if (direction === "lr" || direction === "rl") {
|
||||
// Horizontal slider
|
||||
style.left = direction === "lr" ? `${tickPosition}%` : undefined;
|
||||
style.right = direction === "rl" ? `${tickPosition}%` : undefined;
|
||||
style.translate = "-50% 0";
|
||||
if (labelPosition === "top") {
|
||||
style.bottom = "100%";
|
||||
}
|
||||
else if (labelPosition === "bottom") {
|
||||
style.top = "100%";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Vertical slider - use same positioning as ticks
|
||||
if (direction === "tb") {
|
||||
style.top = `${tickPosition}%`;
|
||||
}
|
||||
else {
|
||||
style.bottom = `${tickPosition}%`;
|
||||
}
|
||||
style.translate = "0 50%";
|
||||
if (labelPosition === "left") {
|
||||
style.right = "100%";
|
||||
}
|
||||
else if (labelPosition === "right") {
|
||||
style.left = "100%";
|
||||
}
|
||||
}
|
||||
return style;
|
||||
}
|
||||
export function getThumbLabelStyles(direction, thumbPosition, labelPosition = "top") {
|
||||
const style = {
|
||||
position: "absolute",
|
||||
};
|
||||
if (direction === "lr" || direction === "rl") {
|
||||
// Horizontal slider
|
||||
style.left = direction === "lr" ? `${thumbPosition}%` : undefined;
|
||||
style.right = direction === "rl" ? `${thumbPosition}%` : undefined;
|
||||
style.translate = "-50% 0";
|
||||
if (labelPosition === "top") {
|
||||
style.bottom = "100%";
|
||||
}
|
||||
else if (labelPosition === "bottom") {
|
||||
style.top = "100%";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Vertical slider
|
||||
if (direction === "tb") {
|
||||
style.top = `${thumbPosition}%`;
|
||||
}
|
||||
else {
|
||||
style.bottom = `${thumbPosition}%`;
|
||||
}
|
||||
style.translate = "0 -50%";
|
||||
if (labelPosition === "left") {
|
||||
style.right = "100%";
|
||||
}
|
||||
else if (labelPosition === "right") {
|
||||
style.left = "100%";
|
||||
}
|
||||
}
|
||||
return style;
|
||||
}
|
||||
/**
|
||||
* Gets the number of decimal places in a number
|
||||
*/
|
||||
function getDecimalPlaces(num) {
|
||||
if (Math.floor(num) === num)
|
||||
return 0;
|
||||
const str = num.toString();
|
||||
if (str.indexOf(".") !== -1 && str.indexOf("e-") === -1) {
|
||||
return str.split(".")[1].length;
|
||||
}
|
||||
else if (str.indexOf("e-") !== -1) {
|
||||
const parts = str.split("e-");
|
||||
return parseInt(parts[1], 10);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Rounds a number to the specified number of decimal places
|
||||
*/
|
||||
function roundToPrecision(num, precision) {
|
||||
const factor = Math.pow(10, precision);
|
||||
return Math.round(num * factor) / factor;
|
||||
}
|
||||
/**
|
||||
* Normalizes step to always be a sorted array of valid values within min/max range
|
||||
*/
|
||||
export function normalizeSteps(step, min, max) {
|
||||
if (typeof step === "number") {
|
||||
// generate regular steps - match original behavior exactly
|
||||
const difference = max - min;
|
||||
let count = Math.ceil(difference / step);
|
||||
// Get precision from step to avoid floating point errors
|
||||
const precision = getDecimalPlaces(step);
|
||||
// Check if difference is divisible by step using integer arithmetic to avoid floating point errors
|
||||
const factor = Math.pow(10, precision);
|
||||
const intDifference = Math.round(difference * factor);
|
||||
const intStep = Math.round(step * factor);
|
||||
if (intDifference % intStep === 0) {
|
||||
count++;
|
||||
}
|
||||
const steps = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const value = min + i * step;
|
||||
// Round to the precision of the step to avoid floating point errors
|
||||
const roundedValue = roundToPrecision(value, precision);
|
||||
steps.push(roundedValue);
|
||||
}
|
||||
return steps;
|
||||
}
|
||||
return [...new Set(step)].filter((value) => value >= min && value <= max).sort((a, b) => a - b);
|
||||
}
|
||||
/**
|
||||
* Snaps a value to the nearest step in a custom steps array
|
||||
*/
|
||||
export function snapValueToCustomSteps(value, steps) {
|
||||
if (steps.length === 0)
|
||||
return value;
|
||||
// Find the closest step
|
||||
let closest = steps[0];
|
||||
let minDistance = Math.abs(value - closest);
|
||||
for (const step of steps) {
|
||||
const distance = Math.abs(value - step);
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
closest = step;
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
/**
|
||||
* Gets the next/previous step value for keyboard navigation
|
||||
*/
|
||||
export function getAdjacentStepValue(currentValue, steps, direction) {
|
||||
const currentIndex = steps.indexOf(currentValue);
|
||||
if (currentIndex === -1) {
|
||||
// current value is not in steps, snap to nearest
|
||||
return snapValueToCustomSteps(currentValue, steps);
|
||||
}
|
||||
if (direction === "next") {
|
||||
return currentIndex < steps.length - 1 ? steps[currentIndex + 1] : currentValue;
|
||||
}
|
||||
else {
|
||||
return currentIndex > 0 ? steps[currentIndex - 1] : currentValue;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user