@drivy/cobalt
Version:
Opinionated design system for Drivy's projects.
92 lines (89 loc) • 4.64 kB
JavaScript
import React, { useState, useMemo } from 'react';
import { Slider as Slider$1 } from '@ark-ui/react';
import cx from 'classnames';
import { FieldWrapper } from './field.js';
const MIN_BAR_HEIGHT_PERCENT = 3;
const Slider = ({ defaultValue: _defaultValue, value: _value, min, max, disabled, onValueChange, renderValue, ariaLabel, hint, label, status, className, step, bars, ...restProps }) => {
const sliderMinValue = min || 0;
const sliderMaxValue = max || 100;
const value = Array.isArray(_value)
? _value
: _value !== undefined && !isNaN(_value)
? [_value]
: undefined;
const defaultValue = Array.isArray(_defaultValue)
? _defaultValue
: _defaultValue !== undefined && !isNaN(_defaultValue)
? [_defaultValue]
: undefined;
function initValue() {
if (value !== undefined)
return value;
if (defaultValue !== undefined)
return defaultValue;
if (min !== undefined)
return [min];
return [0];
}
const [sliderValue, setSliderValue] = useState(() => initValue());
const barsData = useMemo(() => {
if (!bars || bars.step <= 0 || sliderMinValue >= sliderMaxValue)
return null;
const barsCount = (sliderMaxValue - sliderMinValue) / bars.step;
let maxBars = 0;
const rawValues = [];
for (let i = 0; i < barsCount; i++) {
const binValue = bars.bins[i * bars.step + sliderMinValue];
if (binValue) {
maxBars = Math.max(maxBars, binValue);
rawValues.push(binValue);
}
else {
rawValues.push(0);
}
}
if (maxBars === 0) {
return rawValues.map(() => 0); // all values are zero, so all bars are 0%
}
const scaleFactor = 100 - MIN_BAR_HEIGHT_PERCENT;
return rawValues.map((v) => v > 0 ? (v / maxBars) * scaleFactor + MIN_BAR_HEIGHT_PERCENT : 0);
}, [bars, sliderMinValue, sliderMaxValue]);
return (React.createElement(FieldWrapper, { ...restProps, status: status, label: label, hint: hint },
React.createElement(Slider$1.Root, { ...restProps, className: cx("cobalt-slider", className, {
"cobalt-slider--disabled": disabled,
"cobalt-slider--withHint": hint,
"cobalt-slider--withBars": !!bars,
}), thumbAlignment: "contain", disabled: disabled, "aria-label": [ariaLabel], value: sliderValue, min: min, max: max, step: step,
// Need to force disbplaying in smaller spaces like popovers
thumbSize: {
width: 24,
height: 24,
}, onValueChange: ({ value: newValueArr }) => {
setSliderValue(newValueArr);
const newValue = newValueArr.length === 1 ? newValueArr[0] : newValueArr;
onValueChange && onValueChange(newValue);
} },
React.createElement(Slider$1.Label, { className: FieldWrapper.labelClassName }, label),
renderValue && (React.createElement("div", { className: "cobalt-slider__value-container" }, renderValue((sliderValue.length === 1 ? sliderValue[0] : sliderValue), status))),
React.createElement(Slider$1.Control, null,
React.createElement("div", { className: "cobalt-slider__bars" }, barsData &&
barsData.map((val, i) => {
const barsStep = (bars === null || bars === void 0 ? void 0 : bars.step) || 1;
return (React.createElement("div", { key: i, className: cx("cobalt-slider__bar", {
"cobalt-slider__bar--active": i * barsStep + sliderMinValue >= sliderValue[0] &&
(i + 1) * barsStep + sliderMinValue <= sliderValue[1],
}), style: {
width: `calc(${100 / barsData.length}%)`,
height: `${val}%`,
} }));
})),
React.createElement(Slider$1.Track, null,
React.createElement(Slider$1.Range, null)),
sliderValue.map((_v, i) => (React.createElement(Slider$1.Thumb, { key: i, index: i },
React.createElement(Slider$1.HiddenInput, null))))))));
};
const SliderValueMeta = ({ children }) => {
return React.createElement("span", { className: "cobalt-slider__value-meta" }, children);
};
export { SliderValueMeta, Slider as default };
//# sourceMappingURL=Slider.js.map