UNPKG

@hitachivantara/uikit-react-core

Version:
438 lines (437 loc) 14.6 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const jsxRuntime = require("react/jsx-runtime"); const React = require("react"); const Slider = require("rc-slider"); const Tooltip = require("rc-tooltip"); const uikitReactUtils = require("@hitachivantara/uikit-react-utils"); const LabelContainer = require("../FormElement/LabelContainer.cjs"); const useControlled = require("../hooks/useControlled.cjs"); const useUniqueId = require("../hooks/useUniqueId.cjs"); const document = require("../utils/document.cjs"); const setId = require("../utils/setId.cjs"); const Slider_styles = require("./Slider.styles.cjs"); const SliderInput = require("./SliderInput/SliderInput.cjs"); const utils = require("./utils.cjs"); const FormElement = require("../FormElement/FormElement.cjs"); const WarningText = require("../FormElement/WarningText/WarningText.cjs"); const _interopDefault = (e) => e && e.__esModule ? e : { default: e }; const Slider__default = /* @__PURE__ */ _interopDefault(Slider); const Tooltip__default = /* @__PURE__ */ _interopDefault(Tooltip); const HvSlider = React.forwardRef(function HvSlider2(props, ref) { const { id, className, name, label, status, statusMessage, disabled, classes: classesProp, sliderProps, knobProps, inputProps, requiredMessage = "The value is required", outOfRangeMessage = "The value is out of range", noOverlap = true, hideInput, required, readOnly, markProperties = [], defaultValues = [void 0], values: valuesProp = [], knobProperties: knobPropertiesProp, "aria-errormessage": ariaErrorMessage, maxPointValue = 100, minPointValue = 0, divisionQuantity = 100, markStep = 20, markDigits = 0, formatMark, onChange, onBlur, onBeforeChange, onAfterChange, formatTooltip, ...others } = uikitReactUtils.useDefaultProps("HvSlider", props); const { classes, cx } = Slider_styles.useClasses(classesProp); const hasLabel = label != null; const isDirty = React.useRef(false); const elementId = useUniqueId.useUniqueId(id); const sliderInputId = setId.setId(elementId, "input"); const stepValue = React.useMemo( () => utils.calculateStepValue(maxPointValue, minPointValue, divisionQuantity), [divisionQuantity, maxPointValue, minPointValue] ); const inverseStepValue = 1 / stepValue; const marks = React.useMemo( () => utils.createMark( markProperties, markStep, divisionQuantity, minPointValue, maxPointValue, stepValue, markDigits, !!disabled, formatMark ), [ disabled, divisionQuantity, formatMark, markDigits, markProperties, markStep, minPointValue, maxPointValue, stepValue ] ); const canShowError = ariaErrorMessage == null && (status !== void 0 && statusMessage !== void 0 || // We always show an error when the value(s) are not between maxPointValue and minPointValue; and when required is true (set by user). status === void 0); const isSingle = React.useMemo( () => utils.isSingleSlider(valuesProp, defaultValues), [defaultValues, valuesProp] ); const value = React.useMemo(() => { return valuesProp?.length > 0 ? utils.knobsValuesToKnobsPositions(valuesProp, inverseStepValue, minPointValue) : void 0; }, [inverseStepValue, minPointValue, valuesProp]); const defaultKnobsPositions = React.useMemo( () => utils.knobsValuesToKnobsPositions( defaultValues, inverseStepValue, minPointValue ), [defaultValues, inverseStepValue, minPointValue] ); const [knobsPositions, setKnobsPositions] = useControlled.useControlled( value, defaultKnobsPositions ); const { arrayStatus, arrayDefaultStatus } = React.useMemo( () => utils.convertStatusToArray(knobsPositions.length, status), [knobsPositions.length, status] ); const [validationStatus, setValidationState] = useControlled.useControlled( arrayStatus, arrayDefaultStatus ); const [validationMessage, setValidationMessage] = useControlled.useControlled( statusMessage, "" ); const [isDraggingTrack, setIsDraggingTrack] = React.useState(false); const knobProperties = utils.generateDefaultKnobProperties( knobsPositions.length, disabled, knobPropertiesProp ); const rangesCount = knobProperties.length - 1; const trackStyles = utils.createTrackStyles(knobProperties); const knobStyles = utils.createKnobStyles(knobProperties); const generateKnobsPositionAndValues = React.useCallback( (knobsCurrentPosition) => { const newKnobsPosition = knobsCurrentPosition.slice(); const knobsValues2 = []; let duplicatedValue = null; const findDuplicated = newKnobsPosition.filter( (item, index) => newKnobsPosition.indexOf(item) !== index ); if (noOverlap && findDuplicated.length > 0) { [duplicatedValue] = findDuplicated; } newKnobsPosition.forEach((position, index, array) => { const newArray = array; let newPosition = position; if (noOverlap && newPosition === duplicatedValue) { const previousValue = knobsPositions[index]; if (previousValue !== newPosition) { newPosition += newPosition > previousValue ? -1 : 1; newArray[index] = newPosition; } } knobsValues2[index] = utils.knobsPositionToScaledValue( newPosition, minPointValue, stepValue ); }); return { knobsPosition: newKnobsPosition, knobsValues: knobsValues2 }; }, [knobsPositions, minPointValue, noOverlap, stepValue] ); const performValidation = React.useCallback(() => { let invalid = false; let requiredMsg = false; const mappedValues = generateKnobsPositionAndValues(knobsPositions).knobsValues; const newValidationState = mappedValues.map((knobValue) => { if (required && (knobValue == null || Number.isNaN(knobValue))) { invalid = true; requiredMsg = true; return "invalid"; } if (knobValue < minPointValue || knobValue > maxPointValue) { invalid = true; return "invalid"; } return "valid"; }); setValidationState([...newValidationState]); if (invalid) { setValidationMessage(requiredMsg ? requiredMessage : outOfRangeMessage); return; } setValidationMessage(""); }, [ generateKnobsPositionAndValues, knobsPositions, maxPointValue, minPointValue, outOfRangeMessage, required, requiredMessage, setValidationMessage, setValidationState ]); React.useEffect(() => { const stepVl = utils.calculateStepValue( maxPointValue, minPointValue, divisionQuantity ); const inverseStepVl = 1 / stepVl; if (valuesProp?.length > 0) { setKnobsPositions( utils.knobsValuesToKnobsPositions( valuesProp.length > 0 ? valuesProp : defaultValues, inverseStepVl, minPointValue ) ); } }, [ defaultValues, divisionQuantity, maxPointValue, minPointValue, setKnobsPositions, valuesProp ]); React.useEffect(() => { if (!isDirty.current) { return; } performValidation(); }, [knobsPositions, requiredMessage, performValidation]); const onMouseDownHandler = (event) => { if (event.target.className.includes("track")) { setIsDraggingTrack(true); } }; const onMouseUpHandler = () => { setIsDraggingTrack(false); }; const onBlurHandler = (event) => { const knobs = generateKnobsPositionAndValues(knobsPositions); performValidation(); onBlur?.(event, knobs.knobsValues, status); }; const onChangeHandler = (knobsPosition) => { isDirty.current = true; const knobs = generateKnobsPositionAndValues(knobsPosition); knobProperties.forEach((knobProperty, index) => { if (knobProperty.fixed) { knobs.knobsPosition[index] = utils.scaledValueToKnobsPositionValue( defaultValues[index], minPointValue, inverseStepValue ); } }); if (disabled || readOnly) return; onChange?.(knobs.knobsValues); setKnobsPositions(knobs.knobsPosition); }; const onInputChangeHandler = (inputValues, index) => { let newKnobPositions = utils.knobsValuesToKnobsPositions( inputValues, inverseStepValue, minPointValue ); newKnobPositions = utils.ensureValuesConsistency(newKnobPositions, index); onChangeHandler(newKnobPositions); }; const onBeforeChangeHandler = (knobsPosition) => { const knobs = generateKnobsPositionAndValues(knobsPosition); onBeforeChange?.(knobs.knobsValues); }; const onAfterChangeHandler = (knobsPosition) => { const knobs = generateKnobsPositionAndValues(knobsPosition); onAfterChange?.(knobs.knobsValues); }; const createKnob = (knobNode, params) => { const { value: knobValue, dragging, index } = params; const { style = {}, ...restProps } = knobNode.props; const scaledKnobValue = utils.knobsPositionToScaledValue( knobValue, minPointValue, stepValue ).toFixed(markDigits); if (dragging) { style.backgroundColor = knobProperties[index]?.dragColor; } else { style.backgroundColor = knobProperties[index]?.color; } const isEmpty = Number.isNaN(knobsPositions[index]) || knobsPositions[index] == null; const handleId = setId.setId(elementId, "knob"); const indexedHandleId = setId.setId(handleId, index); return /* @__PURE__ */ jsxRuntime.jsx( "div", { className: cx({ [classes.handleContainer]: !!(!disabled && !isEmpty), [classes.handleContainerDisabled]: !!(disabled && !isEmpty), [classes.handleHiddenContainer]: isEmpty || readOnly }), children: /* @__PURE__ */ jsxRuntime.jsx( Tooltip__default.default, { prefixCls: "rc-slider-tooltip", overlay: formatTooltip?.(scaledKnobValue) || scaledKnobValue, visible: dragging, placement: "top", overlayClassName: classes.sliderTooltip, getTooltipContainer: () => document.getElementById(indexedHandleId), children: /* @__PURE__ */ jsxRuntime.jsx( "div", { id: indexedHandleId, style, className: classes.handle, ...restProps, "aria-label": `${label}-knob-${index}`, "aria-valuenow": utils.knobsPositionToScaledValue( knobValue, minPointValue, stepValue ), "aria-valuemin": minPointValue, "aria-valuemax": maxPointValue, ...knobProps?.[index] } ) } ) }, index ); }; const knobsValuesArray = utils.knobsPositionsToKnobsValues( knobsPositions, stepValue, minPointValue ); const knobsValues = knobsValuesArray.map( (v) => Number(v.toFixed(markDigits)) ); return /* @__PURE__ */ jsxRuntime.jsxs( FormElement.HvFormElement, { className: cx( classes.root, { [classes.trackStandBy]: !readOnly && !disabled && !isSingle && !isDraggingTrack, [classes.trackDragging]: !readOnly && !disabled && !isSingle && isDraggingTrack, [classes.rootDisabled]: !!disabled }, className ), id, name, status: utils.statusArrayToFormStatus(validationStatus), disabled, required, readOnly, onMouseDown: onMouseDownHandler, onMouseUp: onMouseUpHandler, onBlur: onBlurHandler, ...others, children: [ /* @__PURE__ */ jsxRuntime.jsx( LabelContainer.HvLabelContainer, { label, inputId: sliderInputId, labelId: setId.setId(elementId, "label"), descriptionId: setId.setId(elementId, "description"), classes: { root: cx(classes.labelContainer, { [classes.labelIncluded]: hasLabel, [classes.onlyInput]: !hasLabel }), label: classes.label }, children: !hideInput && /* @__PURE__ */ jsxRuntime.jsx( SliderInput.HvSliderInput, { id: sliderInputId, label, values: knobsValues, onChange: onInputChangeHandler, status: validationStatus, disabled, readOnly, markDigits, inputProps } ) } ), /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx(classes.sliderBase, classes.sliderContainer), children: /* @__PURE__ */ jsxRuntime.jsx( Slider__default.default, { ref, range: !isSingle, handleRender: createKnob, className: cx(classes.sliderRoot, { [classes.rootRange]: !isSingle }), min: 0, max: divisionQuantity, step: 1, marks, dotStyle: disabled ? Slider_styles.sliderStyles.dotDisabled : Slider_styles.sliderStyles.dot, onChange: (singleValue) => onChangeHandler(Array().concat(singleValue)), onBeforeChange: (singleValue) => onBeforeChangeHandler(Array().concat(singleValue)), onAfterChange: (singleValue) => onAfterChangeHandler(Array().concat(singleValue)), value: knobsPositions.length === 0 ? void 0 : isSingle ? knobsPositions[0] : [...knobsPositions], allowCross: false, disabled, count: rangesCount, railStyle: Slider_styles.sliderStyles.rail, handleStyle: knobStyles.knobInner, trackStyle: trackStyles, draggableTrack: !readOnly && !isSingle, ...sliderProps } ) }), canShowError && /* @__PURE__ */ jsxRuntime.jsx( WarningText.HvWarningText, { id: setId.setId(elementId, "error"), className: classes.error, disableBorder: true, children: validationMessage } ) ] } ); }); exports.sliderClasses = Slider_styles.staticClasses; exports.HvSlider = HvSlider;