'use client'; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { useSpinButtonBase_unstable: function() { return useSpinButtonBase_unstable; }, useSpinButton_unstable: function() { return useSpinButton_unstable; } }); const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); const _reactfield = require("@fluentui/react-field"); const _reactutilities = require("@fluentui/react-utilities"); const _keyboardkeys = require("@fluentui/keyboard-keys"); const _index = require("../../utils/index"); const _reacticons = require("@fluentui/react-icons"); const _reactsharedcontexts = require("@fluentui/react-shared-contexts"); const DEFAULT_SPIN_DELAY_MS = 150; const MIN_SPIN_DELAY_MS = 80; const MAX_SPIN_TIME_MS = 1000; // This is here to give an ease for the mouse held down case. // Exact easing it to be defined. Once it is we'll likely // pull this out into a util function in the SpinButton package. const lerp = (start, end, percent)=>start + (end - start) * percent; const useSpinButtonBase_unstable = (props, ref)=>{ const nativeProps = (0, _reactutilities.getPartitionedNativeProps)({ props, primarySlotTagName: 'input', excludedPropNames: [ 'defaultValue', 'max', 'min', 'onChange', 'value' ] }); const { value, displayValue, defaultValue, min, max, step = 1, stepPage = 1, precision: precisionFromProps, onChange, root, input, incrementButton, decrementButton } = props; const precision = _react.useMemo(()=>{ return precisionFromProps !== null && precisionFromProps !== void 0 ? precisionFromProps : Math.max((0, _index.calculatePrecision)(step), 0); }, [ precisionFromProps, step ]); const [currentValue, setCurrentValue] = (0, _reactutilities.useControllableState)({ state: value, defaultState: defaultValue, initialState: 0 }); const inputRef = _react.useRef(null); const isControlled = value !== undefined; const [textValue, setTextValue] = _react.useState(undefined); const [keyboardSpinState, setKeyboardSpinState] = _react.useState('rest'); const internalState = _react.useRef({ value: currentValue, spinState: 'rest', spinTime: 0, spinDelay: DEFAULT_SPIN_DELAY_MS, atBound: currentValue !== null ? (0, _index.getBound)((0, _index.precisionRound)(currentValue, precision), min, max) : 'none' }); const [setStepTimeout, clearStepTimeout] = (0, _reactutilities.useTimeout)(); const stepValue = (e, direction, startFrom)=>{ let startValue = internalState.current.value; if (startFrom) { const num = parseFloat(startFrom); if (!isNaN(num)) { startValue = num; } } const val = startValue; const dir = direction === 'up' || direction === 'upPage' ? 1 : -1; const stepSize = direction === 'upPage' || direction === 'downPage' ? stepPage : step; if (val === null) { const stepStart = min === undefined ? 0 : min; const nullStep = (0, _index.clamp)(stepStart + stepSize * dir, min, max); commit(e, nullStep); return; } let newValue = val + stepSize * dir; if (!Number.isNaN(newValue)) { newValue = (0, _index.clamp)(newValue, min, max); } commit(e, newValue); if (internalState.current.spinState !== 'rest') { setStepTimeout(()=>{ // Ease the step speed a bit internalState.current.spinTime += internalState.current.spinDelay; internalState.current.spinDelay = lerp(DEFAULT_SPIN_DELAY_MS, MIN_SPIN_DELAY_MS, internalState.current.spinTime / MAX_SPIN_TIME_MS); stepValue(e, direction); }, internalState.current.spinDelay); } }; const handleInputChange = (e)=>{ if (!internalState.current.previousTextValue) { internalState.current.previousTextValue = textValue !== null && textValue !== void 0 ? textValue : String(currentValue); } const newValue = e.target.value; setTextValue(newValue); if (inputRef.current) { // we need to set this here using the IDL attribute directly, because otherwise the timing of the ARIA value update // is not in sync with the user-entered native input value, and some screen readers end up reading the wrong value. // eslint-disable-next-line react-compiler/react-compiler inputRef.current.ariaValueNow = newValue; } }; const handleIncrementMouseDown = (e)=>{ commit(e, currentValue, textValue); internalState.current.spinState = 'up'; stepValue(e, 'up'); }; const handleDecrementMouseDown = (e)=>{ commit(e, currentValue, textValue); internalState.current.spinState = 'down'; stepValue(e, 'down'); }; const handleStepMouseUpOrLeave = (e)=>{ clearStepTimeout(); internalState.current.spinState = 'rest'; internalState.current.spinDelay = DEFAULT_SPIN_DELAY_MS; internalState.current.spinTime = 0; }; const handleBlur = (e)=>{ commit(e, currentValue, textValue); internalState.current.previousTextValue = undefined; }; const handleKeyDown = (e)=>{ let nextKeyboardSpinState = 'rest'; if (e.currentTarget.readOnly) { return; } if (e.key === _keyboardkeys.ArrowUp) { stepValue(e, 'up', textValue); nextKeyboardSpinState = 'up'; } else if (e.key === _keyboardkeys.ArrowDown) { stepValue(e, 'down', textValue); nextKeyboardSpinState = 'down'; } else if (e.key === _keyboardkeys.PageUp) { e.preventDefault(); stepValue(e, 'upPage', textValue); nextKeyboardSpinState = 'up'; } else if (e.key === _keyboardkeys.PageDown) { e.preventDefault(); stepValue(e, 'downPage', textValue); nextKeyboardSpinState = 'down'; } else if (!e.shiftKey && e.key === _keyboardkeys.Home && min !== undefined) { commit(e, min); nextKeyboardSpinState = 'down'; } else if (!e.shiftKey && e.key === _keyboardkeys.End && max !== undefined) { commit(e, max); nextKeyboardSpinState = 'up'; } else if (e.key === _keyboardkeys.Enter) { commit(e, currentValue, textValue); internalState.current.previousTextValue = undefined; } else if (e.key === _keyboardkeys.Escape) { if (internalState.current.previousTextValue) { setTextValue(undefined); internalState.current.previousTextValue = undefined; } } if (keyboardSpinState !== nextKeyboardSpinState) { setKeyboardSpinState(nextKeyboardSpinState); } }; const handleKeyUp = (e)=>{ if (keyboardSpinState !== 'rest') { setKeyboardSpinState('rest'); internalState.current.spinState = 'rest'; } }; const commit = (e, newValue, newDisplayValue)=>{ const valueChanged = newValue !== undefined && currentValue !== newValue; const displayValueChanged = newDisplayValue !== undefined && internalState.current.previousTextValue !== undefined && internalState.current.previousTextValue !== newDisplayValue; let roundedValue; if (valueChanged) { roundedValue = (0, _index.precisionRound)(newValue, precision); setCurrentValue(roundedValue); internalState.current.value = roundedValue; } else if (displayValueChanged && !isControlled) { const nextValue = parseFloat(newDisplayValue); if (!isNaN(nextValue)) { setCurrentValue((0, _index.precisionRound)(nextValue, precision)); internalState.current.value = (0, _index.precisionRound)(nextValue, precision); } } if (valueChanged || displayValueChanged) { onChange === null || onChange === void 0 ? void 0 : onChange(e, { value: roundedValue, displayValue: newDisplayValue }); } setTextValue(undefined); }; let valueToDisplay; if (textValue !== undefined) { valueToDisplay = textValue; } else if (value === null || currentValue === null) { valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : ''; internalState.current.value = null; internalState.current.atBound = 'none'; } else { const roundedValue = (0, _index.precisionRound)(currentValue, precision); internalState.current.value = roundedValue; internalState.current.atBound = (0, _index.getBound)(roundedValue, min, max); if (isControlled) { valueToDisplay = displayValue !== null && displayValue !== void 0 ? displayValue : String(roundedValue); } else { valueToDisplay = String(roundedValue); } } const state = { spinState: keyboardSpinState, atBound: internalState.current.atBound, components: { root: 'span', input: 'input', incrementButton: 'button', decrementButton: 'button' }, root: _reactutilities.slot.always(root, { defaultProps: nativeProps.root, elementType: 'span' }), input: _reactutilities.slot.always(input, { defaultProps: { autoComplete: 'off', role: 'spinbutton', type: 'text', ...nativeProps.primary }, elementType: 'input' }), incrementButton: _reactutilities.slot.always(incrementButton, { defaultProps: { tabIndex: -1, disabled: nativeProps.primary.readOnly || nativeProps.primary.disabled || internalState.current.atBound === 'max' || internalState.current.atBound === 'both', 'aria-label': 'Increment value', type: 'button' }, elementType: 'button' }), decrementButton: _reactutilities.slot.always(decrementButton, { defaultProps: { tabIndex: -1, disabled: nativeProps.primary.readOnly || nativeProps.primary.disabled || internalState.current.atBound === 'min' || internalState.current.atBound === 'both', 'aria-label': 'Decrement value', type: 'button' }, elementType: 'button' }) }; state.input.value = valueToDisplay; state.input.ref = (0, _reactutilities.useMergedRefs)(inputRef, ref); state.input['aria-valuemin'] = min; state.input['aria-valuemax'] = max; var _internalState_current_value; state.input['aria-valuenow'] = (_internalState_current_value = internalState.current.value) !== null && _internalState_current_value !== void 0 ? _internalState_current_value : undefined; var _state_input_ariavaluetext; state.input['aria-valuetext'] = (_state_input_ariavaluetext = state.input['aria-valuetext']) !== null && _state_input_ariavaluetext !== void 0 ? _state_input_ariavaluetext : value !== undefined && displayValue || undefined; state.input.onChange = (0, _reactutilities.mergeCallbacks)(state.input.onChange, handleInputChange); state.input.onInput = (0, _reactutilities.mergeCallbacks)(state.input.onInput, handleInputChange); state.input.onBlur = (0, _reactutilities.mergeCallbacks)(state.input.onBlur, handleBlur); state.input.onKeyDown = (0, _reactutilities.mergeCallbacks)(state.input.onKeyDown, handleKeyDown); state.input.onKeyUp = (0, _reactutilities.mergeCallbacks)(state.input.onKeyUp, handleKeyUp); state.incrementButton.onMouseDown = (0, _reactutilities.mergeCallbacks)(handleIncrementMouseDown, state.incrementButton.onMouseDown); state.incrementButton.onMouseUp = (0, _reactutilities.mergeCallbacks)(state.incrementButton.onMouseUp, handleStepMouseUpOrLeave); state.incrementButton.onMouseLeave = (0, _reactutilities.mergeCallbacks)(state.incrementButton.onMouseLeave, handleStepMouseUpOrLeave); state.decrementButton.onMouseDown = (0, _reactutilities.mergeCallbacks)(handleDecrementMouseDown, state.decrementButton.onMouseDown); state.decrementButton.onMouseUp = (0, _reactutilities.mergeCallbacks)(state.decrementButton.onMouseUp, handleStepMouseUpOrLeave); state.decrementButton.onMouseLeave = (0, _reactutilities.mergeCallbacks)(state.decrementButton.onMouseLeave, handleStepMouseUpOrLeave); return state; }; const useSpinButton_unstable = (props, ref)=>{ var _state_incrementButton, _state_decrementButton; // Merge props from surrounding , if any props = (0, _reactfield.useFieldControlProps_unstable)(props, { supportsLabelFor: true, supportsRequired: true }); const overrides = (0, _reactsharedcontexts.useOverrides_unstable)(); var _overrides_inputDefaultAppearance; const { appearance = (_overrides_inputDefaultAppearance = overrides.inputDefaultAppearance) !== null && _overrides_inputDefaultAppearance !== void 0 ? _overrides_inputDefaultAppearance : 'outline', size = 'medium', ...baseProps } = props; const state = useSpinButtonBase_unstable(baseProps, ref); var _children; (_children = (_state_incrementButton = state.incrementButton).children) !== null && _children !== void 0 ? _children : _state_incrementButton.children = /*#__PURE__*/ _react.createElement(_reacticons.ChevronUp16Regular, null); var _children1; (_children1 = (_state_decrementButton = state.decrementButton).children) !== null && _children1 !== void 0 ? _children1 : _state_decrementButton.children = /*#__PURE__*/ _react.createElement(_reacticons.ChevronDown16Regular, null); return { ...state, appearance, size }; };