UNPKG

@drivy/cobalt

Version:

Opinionated design system for Drivy's projects.

92 lines (89 loc) 4.64 kB
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