UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

195 lines (194 loc) 5.86 kB
"use client"; import React from 'react'; import { pickFormElementProps } from "../../shared/helpers/filterValidProps.js"; import { makeUniqueId, dispatchCustomElementEvent, getStatusState, extendPropsWithContext } from "../../shared/component-helper.js"; import Context from "../../shared/Context.js"; import { closestIndex, getFormattedNumber, getUpdatedValues, roundValue } from "./SliderHelpers.js"; import { jsx as _jsx } from "react/jsx-runtime"; const defaultProps = { statusState: 'error', min: 0, max: 100, value: -1, multiThumbBehavior: 'swap', labelDirection: 'vertical' }; export const SliderContext = React.createContext(null); export function SliderProvider(localProps) { const context = React.useContext(Context); const allProps = extendPropsWithContext(localProps, defaultProps, { skeleton: context === null || context === void 0 ? void 0 : context.skeleton }, pickFormElementProps(context === null || context === void 0 ? void 0 : context.formElement), context === null || context === void 0 ? void 0 : context.getTranslation(localProps).Slider, context === null || context === void 0 ? void 0 : context.Slider); const [_id] = React.useState(makeUniqueId); if (!allProps.id) { allProps.id = _id; } const { step, label, labelDirection, labelSrOnly, status, statusState, statusProps, statusNoAnimation, globalStatus, stretch, suffix, thumbTitle: title, subtractTitle, addTitle, hideButtons, multiThumbBehavior, numberFormat, tooltip, alwaysShowTooltip, skeleton, max, min, extensions, disabled, className, id, onChange, onDragStart, onDragEnd, vertical: _vertical, reverse: _reverse, value: _value, children: _children, ...attributes } = allProps; const [value, setValue] = React.useState(_value); const [externValue, updateExternValue] = React.useState(_value); const realtimeValue = React.useRef(_value); const [thumbState, setThumbState] = React.useState('initial'); const thumbIndex = React.useRef(-1); const [shouldAnimate, updateAnimateState] = React.useState(false); const [isVertical] = React.useState(_vertical); const [isReverse] = React.useState(isVertical ? !_reverse : _reverse); const isMulti = Array.isArray(value); const setThumbIndex = index => { if (!isNaN(index)) { thumbIndex.current = index; } }; const getAndUpdateCurrentIndex = currentValue => { let currentIndex = null; if (thumbIndex.current > -1) { currentIndex = thumbIndex.current; } else { currentIndex = closestIndex(currentValue, value); setThumbIndex(currentIndex); } return currentIndex; }; const updateValue = value => { setValue(value); realtimeValue.current = value; }; const emitChange = (event, rawValue) => { if (disabled || skeleton) { return; } let numberValue = roundValue(rawValue, { step, min, max }); let multiValues = numberValue; if (numberValue >= min) { if (isMulti) { const currentIndex = getAndUpdateCurrentIndex(numberValue); const lower = realtimeValue.current[currentIndex - 1]; const upper = realtimeValue.current[currentIndex + 1]; if (multiThumbBehavior === 'omit') { if (numberValue < lower) { numberValue = lower; } if (numberValue > upper) { numberValue = upper; } } multiValues = getUpdatedValues(multiThumbBehavior === 'push' ? realtimeValue.current : value, currentIndex, numberValue); if (multiThumbBehavior === 'push') { if (typeof lower !== 'undefined' && numberValue < lower) { multiValues[currentIndex - 1] = numberValue; } if (typeof upper !== 'undefined' && numberValue >= upper) { multiValues[currentIndex + 1] = numberValue; } } if (numberValue === realtimeValue.current[currentIndex]) { return; } } else if (numberValue === realtimeValue.current) { return; } if (typeof onChange === 'function') { const obj = { value: multiValues, rawValue, event, number: null }; if (numberFormat) { obj.number = getFormattedNumber(numberValue, numberFormat).number; } dispatchCustomElementEvent(allProps, 'onChange', obj); } updateValue(multiValues); } }; React.useEffect(() => { if (isMulti) { const hasChanged = _value.some((val, i) => { return val !== externValue[i]; }); if (hasChanged) { updateValue(_value); updateExternValue(_value); } } else if (_value !== externValue) { updateValue(_value); updateExternValue(_value); } }, [_value, isMulti]); const trackRef = React.useRef(undefined); const animationTimeout = React.useRef(undefined); const setShouldAnimate = state => { updateAnimateState(state); clearTimeout(animationTimeout.current); if (state) { animationTimeout.current = setTimeout(() => updateAnimateState(false), 250); } }; const showStatus = getStatusState(status); const showButtons = !isMulti && !hideButtons; const values = isMulti ? value : [value]; return _jsx(SliderContext, { value: { isMulti, isReverse, isVertical, shouldAnimate, value, values, setValue, attributes, showStatus, showButtons, thumbState, setThumbState, thumbIndex, setThumbIndex, emitChange, allProps, trackRef, setShouldAnimate, animationTimeout }, children: localProps.children }); } //# sourceMappingURL=SliderProvider.js.map