@fluentui/react
Version:
Reusable React components for building web experiences.
332 lines • 16.9 kB
JavaScript
define(["require", "exports", "tslib", "react", "@fluentui/react-hooks", "@fluentui/utilities"], function (require, exports, tslib_1, React, react_hooks_1, utilities_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSlider = exports.ONKEYDOWN_TIMEOUT_DURATION = void 0;
exports.ONKEYDOWN_TIMEOUT_DURATION = 1000;
var getClassNames = utilities_1.classNamesFunction();
var getSlotStyleFn = function (sty) {
return function (value) {
var _a;
return _a = {},
_a[sty] = value + "%",
_a;
};
};
var getPositionStyleFn = function (vertical, rtl) {
if (vertical === void 0) { vertical = false; }
if (rtl === void 0) { rtl = false; }
if (vertical) {
return getSlotStyleFn('bottom');
}
return getSlotStyleFn(rtl ? 'right' : 'left');
};
var getPercent = function (value, sliderMin, sliderMax) {
return sliderMax === sliderMin ? 0 : ((value - sliderMin) / (sliderMax - sliderMin)) * 100;
};
var getLineSectionStylesFn = function (vertical) {
if (vertical === void 0) { vertical = false; }
var lengthString = vertical ? 'height' : 'width';
return getSlotStyleFn(lengthString);
};
var useComponentRef = function (props, thumb, value, range) {
React.useImperativeHandle(props.componentRef, function () { return ({
get value() {
return value;
},
get range() {
return props.ranged ? range : undefined;
},
focus: function () {
if (thumb.current) {
thumb.current.focus();
}
},
}); }, [thumb, value, props.ranged, range]);
};
var useSlider = function (props, ref) {
var _a = props.step, step = _a === void 0 ? 1 : _a, className = props.className, _b = props.disabled, disabled = _b === void 0 ? false : _b, label = props.label, _c = props.max, max = _c === void 0 ? 10 : _c, _d = props.min, min = _d === void 0 ? 0 : _d, _e = props.showValue, showValue = _e === void 0 ? true : _e, _f = props.buttonProps, buttonProps = _f === void 0 ? {} : _f, _g = props.vertical, vertical = _g === void 0 ? false : _g, valueFormat = props.valueFormat, styles = props.styles, theme = props.theme, originFromZero = props.originFromZero, ariaLabel = props["aria-label"], ranged = props.ranged;
var disposables = React.useRef([]);
var sliderLine = React.useRef(null);
var _h = react_hooks_1.useControllableValue(props.value, props.defaultValue, function (ev, v) { var _a; return (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, v, ranged ? [lowerValue, v] : undefined); }), unclampedValue = _h[0], setValue = _h[1];
var _j = react_hooks_1.useControllableValue(props.lowerValue, props.defaultLowerValue, function (ev, lv) { var _a; return (_a = props.onChange) === null || _a === void 0 ? void 0 : _a.call(props, value, [lv, value]); }), unclampedLowerValue = _j[0], setLowerValue = _j[1];
var isAdjustingLowerValueRef = React.useRef(false);
// Ensure that value is always a number and is clamped by min/max.
var value = Math.max(min, Math.min(max, unclampedValue || 0));
var lowerValue = Math.max(min, Math.min(value, unclampedLowerValue || 0));
var id = react_hooks_1.useId('Slider');
var _k = react_hooks_1.useBoolean(true), useShowTransitions = _k[0], toggleUseShowTransitions = _k[1].toggle;
var classNames = getClassNames(styles, {
className: className,
disabled: disabled,
vertical: vertical,
showTransitions: useShowTransitions,
showValue: showValue,
ranged: ranged,
theme: theme,
});
var _l = React.useState(0), timerId = _l[0], setTimerId = _l[1];
var steps = (max - min) / step;
var clearOnKeyDownTimer = function () {
clearTimeout(timerId);
};
var setOnKeyDownTimer = function (event) {
clearOnKeyDownTimer();
setTimerId(setTimeout(function () {
if (props.onChanged) {
props.onChanged(event, value);
}
}, exports.ONKEYDOWN_TIMEOUT_DURATION));
};
var getAriaValueText = function (valueProps) {
var ariaValueText = props.ariaValueText;
if (valueProps !== undefined) {
return ariaValueText ? ariaValueText(valueProps) : valueProps.toString();
}
return undefined;
};
var updateValue = function (valueProp, renderedValueProp) {
var snapToStep = props.snapToStep;
var numDec = 0;
if (isFinite(step)) {
while (Math.round(step * Math.pow(10, numDec)) / Math.pow(10, numDec) !== step) {
numDec++;
}
}
// Make sure value has correct number of decimal places based on number of decimals in step
var roundedValue = parseFloat(valueProp.toFixed(numDec));
if (snapToStep) {
renderedValueProp = roundedValue;
}
if (ranged) {
// decided which thumb value to change
if (isAdjustingLowerValueRef.current && (originFromZero ? roundedValue <= 0 : roundedValue <= value)) {
setLowerValue(roundedValue);
}
else if (!isAdjustingLowerValueRef.current &&
(originFromZero ? roundedValue >= 0 : roundedValue >= lowerValue)) {
setValue(roundedValue);
}
}
else {
setValue(roundedValue);
}
};
var onKeyDown = function (event) {
var newCurrentValue = isAdjustingLowerValueRef.current ? lowerValue : value;
var diff = 0;
// eslint-disable-next-line deprecation/deprecation
switch (event.which) {
case utilities_1.getRTLSafeKeyCode(utilities_1.KeyCodes.left, props.theme):
case utilities_1.KeyCodes.down:
diff = -step;
clearOnKeyDownTimer();
setOnKeyDownTimer(event);
break;
case utilities_1.getRTLSafeKeyCode(utilities_1.KeyCodes.right, props.theme):
case utilities_1.KeyCodes.up:
diff = step;
clearOnKeyDownTimer();
setOnKeyDownTimer(event);
break;
case utilities_1.KeyCodes.home:
newCurrentValue = min;
clearOnKeyDownTimer();
setOnKeyDownTimer(event);
break;
case utilities_1.KeyCodes.end:
newCurrentValue = max;
clearOnKeyDownTimer();
setOnKeyDownTimer(event);
break;
default:
return;
}
var newValue = Math.min(max, Math.max(min, newCurrentValue + diff));
updateValue(newValue, newValue);
event.preventDefault();
event.stopPropagation();
};
var getPosition = function (event, verticalProp) {
var currentPosition;
switch (event.type) {
case 'mousedown':
case 'mousemove':
currentPosition = !verticalProp ? event.clientX : event.clientY;
break;
case 'touchstart':
case 'touchmove':
currentPosition = !verticalProp
? event.touches[0].clientX
: event.touches[0].clientY;
break;
}
return currentPosition;
};
var calculateCurrentSteps = function (event) {
if (!sliderLine.current) {
return;
}
var sliderPositionRect = sliderLine.current.getBoundingClientRect();
var sliderLength = !props.vertical ? sliderPositionRect.width : sliderPositionRect.height;
var stepLength = sliderLength / steps;
var currentSteps;
var distance;
if (!props.vertical) {
var left = getPosition(event, props.vertical);
distance = utilities_1.getRTL(props.theme) ? sliderPositionRect.right - left : left - sliderPositionRect.left;
currentSteps = distance / stepLength;
}
else {
var bottom = getPosition(event, props.vertical);
distance = sliderPositionRect.bottom - bottom;
currentSteps = distance / stepLength;
}
return currentSteps;
};
var onMouseMoveOrTouchMove = function (event, suppressEventCancelation) {
var currentSteps = calculateCurrentSteps(event);
var newCurrentValue;
var newRenderedValue;
// The value shouldn't be bigger than max or be smaller than min.
if (currentSteps > Math.floor(steps)) {
newRenderedValue = newCurrentValue = max;
}
else if (currentSteps < 0) {
newRenderedValue = newCurrentValue = min;
}
else {
newRenderedValue = min + step * currentSteps;
newCurrentValue = min + step * Math.round(currentSteps);
}
updateValue(newCurrentValue, newRenderedValue);
if (!suppressEventCancelation) {
event.preventDefault();
event.stopPropagation();
}
};
var onMouseDownOrTouchStart = function (event) {
if (ranged) {
var currentSteps = calculateCurrentSteps(event);
var newRenderedValue = min + step * currentSteps;
if (newRenderedValue <= lowerValue || newRenderedValue - lowerValue <= value - newRenderedValue) {
isAdjustingLowerValueRef.current = true;
}
else {
isAdjustingLowerValueRef.current = false;
}
}
if (event.type === 'mousedown') {
disposables.current.push(utilities_1.on(window, 'mousemove', onMouseMoveOrTouchMove, true), utilities_1.on(window, 'mouseup', onMouseUpOrTouchEnd, true));
}
else if (event.type === 'touchstart') {
disposables.current.push(utilities_1.on(window, 'touchmove', onMouseMoveOrTouchMove, true), utilities_1.on(window, 'touchend', onMouseUpOrTouchEnd, true));
}
toggleUseShowTransitions();
onMouseMoveOrTouchMove(event, true);
};
var onMouseUpOrTouchEnd = function (event) {
if (props.onChanged) {
props.onChanged(event, value);
}
toggleUseShowTransitions();
disposeListeners();
};
var onThumbFocus = function (event) {
isAdjustingLowerValueRef.current = event.target === lowerValueThumbRef.current;
};
var disposeListeners = function () {
disposables.current.forEach(function (dispose) { return dispose(); });
disposables.current = [];
};
var onMouseDownProp = disabled ? {} : { onMouseDown: onMouseDownOrTouchStart };
var onTouchStartProp = disabled ? {} : { onTouchStart: onMouseDownOrTouchStart };
var onKeyDownProp = disabled ? {} : { onKeyDown: onKeyDown };
var onFocusProp = disabled ? {} : { onFocus: onThumbFocus };
var lowerValueThumbRef = React.useRef(null);
var thumbRef = React.useRef(null);
useComponentRef(props, ranged && !vertical ? lowerValueThumbRef : thumbRef, value, [lowerValue, value]);
var getPositionStyles = getPositionStyleFn(vertical, utilities_1.getRTL(props.theme));
var getTrackStyles = getLineSectionStylesFn(vertical);
var originValue = originFromZero ? 0 : min;
var valuePercent = getPercent(value, min, max);
var lowerValuePercent = getPercent(lowerValue, min, max);
var originPercentOfLine = getPercent(originValue, min, max);
var activeSectionWidth = ranged ? valuePercent - lowerValuePercent : Math.abs(originPercentOfLine - valuePercent);
var topSectionWidth = Math.min(100 - valuePercent, 100 - originPercentOfLine);
var bottomSectionWidth = ranged ? lowerValuePercent : Math.min(valuePercent, originPercentOfLine);
var rootProps = {
className: classNames.root,
ref: ref,
};
var divButtonProps = buttonProps
? utilities_1.getNativeProps(buttonProps, utilities_1.divProperties)
: undefined;
var labelProps = {
className: classNames.titleLabel,
children: label,
disabled: disabled,
htmlFor: ariaLabel ? undefined : id,
};
var valueLabelProps = showValue
? {
className: classNames.valueLabel,
children: valueFormat ? valueFormat(value) : value,
disabled: disabled,
}
: undefined;
var lowerValueLabelProps = ranged && showValue
? {
className: classNames.valueLabel,
children: valueFormat ? valueFormat(lowerValue) : lowerValue,
disabled: disabled,
}
: undefined;
var zeroTickProps = originFromZero
? {
className: classNames.zeroTick,
style: getPositionStyles(originPercentOfLine),
}
: undefined;
var trackActiveProps = {
className: utilities_1.css(classNames.lineContainer, classNames.activeSection),
style: getTrackStyles(activeSectionWidth),
};
var trackTopInactiveProps = {
className: utilities_1.css(classNames.lineContainer, classNames.inactiveSection),
style: getTrackStyles(topSectionWidth),
};
var trackBottomInactiveProps = {
className: utilities_1.css(classNames.lineContainer, classNames.inactiveSection),
style: getTrackStyles(bottomSectionWidth),
};
var sliderProps = tslib_1.__assign({ 'aria-disabled': disabled, role: 'slider', tabIndex: disabled ? undefined : 0 }, { 'data-is-focusable': !disabled });
var sliderBoxProps = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ id: id, className: utilities_1.css(classNames.slideBox, buttonProps.className) }, onMouseDownProp), onTouchStartProp), onKeyDownProp), divButtonProps), (!ranged && tslib_1.__assign(tslib_1.__assign({}, sliderProps), { 'aria-valuemin': min, 'aria-valuemax': max, 'aria-valuenow': value, 'aria-valuetext': getAriaValueText(value), 'aria-label': ariaLabel || label })));
var thumbProps = tslib_1.__assign({ ref: thumbRef, className: classNames.thumb, style: getPositionStyles(valuePercent) }, (ranged && tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, sliderProps), onFocusProp), { id: "max-" + id, 'aria-valuemin': lowerValue, 'aria-valuemax': max, 'aria-valuenow': value, 'aria-valuetext': getAriaValueText(value), 'aria-label': "max " + (ariaLabel || label) })));
var lowerValueThumbProps = ranged
? tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ ref: lowerValueThumbRef, className: classNames.thumb, style: getPositionStyles(lowerValuePercent) }, sliderProps), onFocusProp), { id: "min-" + id, 'aria-valuemin': min, 'aria-valuemax': value, 'aria-valuenow': lowerValue, 'aria-valuetext': getAriaValueText(lowerValue), 'aria-label': "min " + (ariaLabel || label) }) : undefined;
var containerProps = {
className: classNames.container,
};
var sliderLineProps = {
ref: sliderLine,
className: classNames.line,
};
return {
root: rootProps,
label: labelProps,
sliderBox: sliderBoxProps,
container: containerProps,
valueLabel: valueLabelProps,
lowerValueLabel: lowerValueLabelProps,
thumb: thumbProps,
lowerValueThumb: lowerValueThumbProps,
zeroTick: zeroTickProps,
activeTrack: trackActiveProps,
topInactiveTrack: trackTopInactiveProps,
bottomInactiveTrack: trackBottomInactiveProps,
sliderLine: sliderLineProps,
};
};
exports.useSlider = useSlider;
});
//# sourceMappingURL=useSlider.js.map