@hitachivantara/uikit-react-core
Version:
UI Kit Core React components.
438 lines (437 loc) • 14.6 kB
JavaScript
"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;