{"mappings":"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","sources":["packages/react-aria/src/slider/useSlider.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaLabelingProps, DOMAttributes, DOMProps, RefObject} from '@react-types/shared';\nimport {clamp} from 'react-stately/private/utils/number';\nimport {getSliderThumbId, sliderData} from './utils';\nimport {mergeProps} from '../utils/mergeProps';\nimport React, {LabelHTMLAttributes, OutputHTMLAttributes, useRef} from 'react';\nimport {setInteractionModality} from '../interactions/useFocusVisible';\nimport {SliderProps, SliderState} from 'react-stately/useSliderState';\nimport {useGlobalListeners} from '../utils/useGlobalListeners';\nimport {useLabel} from '../label/useLabel';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useMove} from '../interactions/useMove';\n\nexport interface AriaSliderProps<T = number | number[]> extends SliderProps<T>, DOMProps, AriaLabelingProps {}\n\nexport interface SliderAria {\n  /** Props for the label element. */\n  labelProps: LabelHTMLAttributes<HTMLLabelElement>,\n\n  /** Props for the root element of the slider component; groups slider inputs. */\n  groupProps: DOMAttributes,\n\n  /** Props for the track element. */\n  trackProps: DOMAttributes,\n\n  /** Props for the output element, displaying the value of the slider thumbs. */\n  outputProps: OutputHTMLAttributes<HTMLOutputElement>\n}\n\n/**\n * Provides the behavior and accessibility implementation for a slider component representing one or more values.\n *\n * @param props Props for the slider.\n * @param state State for the slider, as returned by `useSliderState`.\n * @param trackRef Ref for the \"track\" element.  The width of this element provides the \"length\"\n * of the track -- the span of one dimensional space that the slider thumb can be.  It also\n * accepts click and drag motions, so that the closest thumb will follow clicks and drags on\n * the track.\n */\nexport function useSlider<T extends number | number[]>(\n  props: AriaSliderProps<T>,\n  state: SliderState,\n  trackRef: RefObject<Element | null>\n): SliderAria {\n  let {labelProps, fieldProps} = useLabel(props);\n\n  let isVertical = props.orientation === 'vertical';\n\n  // Attach id of the label to the state so it can be accessed by useSliderThumb.\n  sliderData.set(state, {\n    id: (labelProps.id ?? fieldProps.id)!,\n    'aria-describedby': props['aria-describedby'],\n    'aria-details': props['aria-details']\n  });\n\n  let {direction} = useLocale();\n\n  let {addGlobalListener, removeGlobalListener} = useGlobalListeners();\n\n  // When the user clicks or drags the track, we want the motion to set and drag the\n  // closest thumb.  Hence we also need to install useMove() on the track element.\n  // Here, we keep track of which index is the \"closest\" to the drag start point.\n  // It is set onMouseDown/onTouchDown; see trackProps below.\n  const realTimeTrackDraggingIndex = useRef<number | null>(null);\n\n  const reverseX = direction === 'rtl';\n  const currentPosition = useRef<number | null>(null);\n  const {moveProps} = useMove({\n    onMoveStart() {\n      currentPosition.current = null;\n    },\n    onMove({deltaX, deltaY}) {\n      if (!trackRef.current) {\n        return;\n      }\n      let {height, width} = trackRef.current.getBoundingClientRect();\n      let size = isVertical ? height : width;\n\n      if (currentPosition.current == null && realTimeTrackDraggingIndex.current != null) {\n        currentPosition.current = state.getThumbPercent(realTimeTrackDraggingIndex.current) * size;\n      }\n\n      let delta = isVertical ? deltaY : deltaX;\n      if (isVertical || reverseX) {\n        delta = -delta;\n      }\n\n      currentPosition.current! += delta;\n\n      if (realTimeTrackDraggingIndex.current != null && trackRef.current) {\n        const percent = clamp(currentPosition.current! / size, 0, 1);\n        state.setThumbPercent(realTimeTrackDraggingIndex.current, percent);\n      }\n    },\n    onMoveEnd() {\n      if (realTimeTrackDraggingIndex.current != null) {\n        state.setThumbDragging(realTimeTrackDraggingIndex.current, false);\n        realTimeTrackDraggingIndex.current = null;\n      }\n    }\n  });\n\n  let currentPointer = useRef<number | null | undefined>(undefined);\n  let onDownTrack = (e: React.UIEvent, id: number | undefined, clientX: number, clientY: number) => {\n    // We only trigger track-dragging if the user clicks on the track itself and nothing is currently being dragged.\n    if (trackRef.current && !props.isDisabled && state.values.every((_, i) => !state.isThumbDragging(i))) {\n      let {height, width, top, left} = trackRef.current.getBoundingClientRect();\n      let size = isVertical ? height : width;\n      // Find the closest thumb\n      const trackPosition = isVertical ? top : left;\n      const clickPosition = isVertical ? clientY : clientX;\n      const offset = clickPosition - trackPosition;\n      let percent = offset / size;\n      if (direction === 'rtl' || isVertical) {\n        percent = 1 - percent;\n      }\n      let value = state.getPercentValue(percent);\n\n      // to find the closet thumb we split the array based on the first thumb position to the \"right/end\" of the click.\n      let closestThumb;\n      let split = state.values.findIndex(v => value - v < 0);\n      if (split === 0) { // If the index is zero then the closetThumb is the first one\n        closestThumb = split;\n      } else if (split === -1) { // If no index is found they've clicked past all the thumbs\n        closestThumb = state.values.length - 1;\n      } else {\n        let lastLeft = state.values[split - 1];\n        let firstRight = state.values[split];\n        // Pick the last left/start thumb, unless they are stacked on top of each other, then pick the right/end one\n        if (Math.abs(lastLeft - value) < Math.abs(firstRight - value)) {\n          closestThumb = split - 1;\n        } else {\n          closestThumb = split;\n        }\n      }\n\n      // Confirm that the found closest thumb is editable, not disabled, and move it\n      if (closestThumb >= 0 && state.isThumbEditable(closestThumb)) {\n        // Don't unfocus anything\n        e.preventDefault();\n\n        realTimeTrackDraggingIndex.current = closestThumb;\n        state.setFocusedThumb(closestThumb);\n        currentPointer.current = id;\n\n        state.setThumbDragging(realTimeTrackDraggingIndex.current!, true);\n        state.setThumbValue(closestThumb, value);\n\n        addGlobalListener(window, 'mouseup', onUpTrack, false);\n        addGlobalListener(window, 'touchend', onUpTrack, false);\n        addGlobalListener(window, 'pointerup', onUpTrack, false);\n      } else {\n        realTimeTrackDraggingIndex.current = null;\n      }\n    }\n  };\n\n  let onUpTrack = (e) => {\n    let id = e.pointerId ?? e.changedTouches?.[0].identifier;\n    if (id === currentPointer.current) {\n      if (realTimeTrackDraggingIndex.current != null) {\n        state.setThumbDragging(realTimeTrackDraggingIndex.current, false);\n        realTimeTrackDraggingIndex.current = null;\n      }\n\n      removeGlobalListener(window, 'mouseup', onUpTrack, false);\n      removeGlobalListener(window, 'touchend', onUpTrack, false);\n      removeGlobalListener(window, 'pointerup', onUpTrack, false);\n    }\n  };\n\n  if ('htmlFor' in labelProps && labelProps.htmlFor) {\n    // Ideally the `for` attribute should point to the first thumb, but VoiceOver on iOS\n    // causes this to override the `aria-labelledby` on the thumb. This causes the first\n    // thumb to only be announced as the slider label rather than its individual name as well.\n    // See https://bugs.webkit.org/show_bug.cgi?id=172464.\n    delete labelProps.htmlFor;\n    labelProps.onClick = () => {\n      // Safari does not focus <input type=\"range\"> elements when clicking on an associated <label>,\n      // so do it manually. In addition, make sure we show the focus ring.\n      document.getElementById(getSliderThumbId(state, 0))?.focus();\n      setInteractionModality('keyboard');\n    };\n  }\n\n  return {\n    labelProps,\n    // The root element of the Slider will have role=\"group\" to group together\n    // all the thumb inputs in the Slider.  The label of the Slider will\n    // be used to label the group.\n    groupProps: {\n      role: 'group',\n      ...fieldProps\n    },\n    trackProps: mergeProps({\n      onMouseDown(e: React.MouseEvent) {\n        if (e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey) {\n          return;\n        }\n        onDownTrack(e, undefined, e.clientX, e.clientY);\n      },\n      onPointerDown(e: React.PointerEvent) {\n        if (e.pointerType === 'mouse' && (e.button !== 0 || e.altKey || e.ctrlKey || e.metaKey)) {\n          return;\n        }\n        onDownTrack(e, e.pointerId, e.clientX, e.clientY);\n      },\n      onTouchStart(e: React.TouchEvent) { onDownTrack(e, e.changedTouches[0].identifier, e.changedTouches[0].clientX, e.changedTouches[0].clientY); },\n      style: {\n        position: 'relative',\n        touchAction: 'none'\n      }\n    }, moveProps),\n    outputProps: {\n      htmlFor: state.values.map((_, index) => getSliderThumbId(state, index)).join(' '),\n      'aria-live': 'off'\n    }\n  };\n}\n"],"names":[],"version":3,"file":"useSlider.cjs.map"}