UNPKG

@grafana/ui

Version:
154 lines (151 loc) 4.8 kB
import { jsxs, jsx } from 'react/jsx-runtime'; import { cx } from '@emotion/css'; import { Global } from '@emotion/react'; import SliderComponent from '@rc-component/slider'; import { useState, useEffect, useCallback } from 'react'; import { usePrevious } from 'react-use'; import { t } from '@grafana/i18n'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { Input } from '../Input/Input.mjs'; import { getStyles } from './styles.mjs'; "use strict"; function stripAndParseNumber(raw) { const str = raw.replace(/^0+/, ""); let decimal = false; let numericBody = ""; for (let i = 0; i < str.length; i += 1) { const char = str.charAt(i); if (/\d/.test(char)) { numericBody += char; } if (char === "." && !decimal) { decimal = true; numericBody += "."; } if (char === "-" && numericBody.length === 0) { numericBody = "-"; } } const value = Number(numericBody); return value; } function roundFloatingPointError(n) { return parseFloat(n.toPrecision(12)); } function clampToAllowedValue(min, max, step, n) { if (Number.isNaN(n)) { return min; } if (n > max) { return max; } if (n < min) { return min; } const closestStep = roundFloatingPointError(Math.round((n - min) / step) * step + min); return Math.min(max, Math.max(min, closestStep)); } const Slider = ({ min, max, onChange, onAfterChange, orientation = "horizontal", reverse, step = 1, value, ariaLabelForHandle, marks, included, inputId, showInput = true }) => { const isHorizontal = orientation === "horizontal"; const styles = useStyles2(getStyles, isHorizontal, Boolean(marks)); const SliderWithTooltip = SliderComponent; const [inputValue, setInputValue] = useState((value != null ? value : min).toString()); const numericValue = clampToAllowedValue(min, max, step, stripAndParseNumber(inputValue)); const previousValue = usePrevious(value); const externalValueChanged = value !== previousValue && value !== numericValue; useEffect(() => { if (externalValueChanged && value !== void 0) { setInputValue(String(value)); } }, [externalValueChanged, value]); const dragHandleAriaLabel = ariaLabelForHandle != null ? ariaLabelForHandle : t("grafana-ui.slider.drag-handle-aria-label", "Use arrow keys to change the value"); const onSliderChange = useCallback( (v) => { const num = typeof v === "number" ? v : v[0]; setInputValue(num.toString()); onChange == null ? void 0 : onChange(num); }, [onChange] ); const handleChangeComplete = useCallback( (v) => { const num = typeof v === "number" ? v : v[0]; onAfterChange == null ? void 0 : onAfterChange(num); }, [onAfterChange] ); const onTextInputChange = useCallback( (e) => { const raw = e.target.value; setInputValue(raw === "0-" ? "-" : raw); const parsed = stripAndParseNumber(raw); if (onChange && !Number.isNaN(parsed)) { onChange(clampToAllowedValue(min, max, step, parsed)); } }, [onChange, min, max, step] ); const onTextInputBlur = useCallback( (e) => { const parsed = clampToAllowedValue(min, max, step, stripAndParseNumber(e.target.value)); setInputValue(parsed.toString()); onChange == null ? void 0 : onChange(parsed); onAfterChange == null ? void 0 : onAfterChange(parsed); }, [min, max, step, onChange, onAfterChange] ); const sliderInputClassNames = !isHorizontal ? [styles.sliderInputVertical] : []; const sliderInputFieldClassNames = !isHorizontal ? [styles.sliderInputFieldVertical] : []; return /* @__PURE__ */ jsxs("div", { className: cx(styles.container, styles.slider), children: [ /* @__PURE__ */ jsx(Global, { styles: styles.tooltip }), /* @__PURE__ */ jsxs("div", { className: cx(styles.sliderInput, ...sliderInputClassNames), children: [ /* @__PURE__ */ jsx( SliderWithTooltip, { min, max, step: step != null ? step : 0.1, value: numericValue, onChange: onSliderChange, onChangeComplete: handleChangeComplete, vertical: !isHorizontal, reverse, ariaLabelForHandle: dragHandleAriaLabel, marks, included } ), showInput && /* @__PURE__ */ jsx( Input, { type: "text", width: 7.5, className: cx(styles.sliderInputField, ...sliderInputFieldClassNames), value: inputValue, onChange: onTextInputChange, onBlur: onTextInputBlur, min, max, id: inputId } ) ] }) ] }); }; Slider.displayName = "Slider"; export { Slider }; //# sourceMappingURL=Slider.mjs.map