{"version":3,"file":"AngleSlider.cjs","names":["createVarsResolver","rem","factory","useProps","findClosestNumber","useStyles","Box","classes"],"sources":["../../../src/components/AngleSlider/AngleSlider.tsx"],"sourcesContent":["import { useRef } from 'react';\nimport { normalizeRadialValue, useMergedRef, useRadialMove, useUncontrolled } from '@mantine/hooks';\nimport {\n  Box,\n  BoxProps,\n  createVarsResolver,\n  ElementProps,\n  factory,\n  Factory,\n  findClosestNumber,\n  rem,\n  StylesApiProps,\n  useProps,\n  useStyles,\n} from '../../core';\nimport classes from './AngleSlider.module.css';\n\nexport type AngleSliderStylesNames = 'root' | 'thumb' | 'label' | 'marks' | 'mark';\nexport type AngleSliderCssVariables = {\n  root: '--slider-size' | '--thumb-size';\n};\n\nexport interface AngleSliderProps\n  extends BoxProps, StylesApiProps<AngleSliderFactory>, ElementProps<'div', 'onChange'> {\n  /** Step between values @default 1 */\n  step?: number;\n\n  /** Controlled component value */\n  value?: number;\n\n  /** Uncontrolled component default value */\n  defaultValue?: number;\n\n  /** Called on value change */\n  onChange?: (value: number) => void;\n\n  /** Called after the selection is finished */\n  onChangeEnd?: (value: number) => void;\n\n  /** Called in `onMouseDown` and `onTouchStart` */\n  onScrubStart?: () => void;\n\n  /** Called in `onMouseUp` and `onTouchEnd` */\n  onScrubEnd?: () => void;\n\n  /** If set, the label is displayed inside the slider @default true */\n  withLabel?: boolean;\n\n  /** Array of marks displayed on the slider */\n  marks?: { value: number; label?: string }[];\n\n  /** Slider size in px @default 60 */\n  size?: number;\n\n  /** Size of the thumb in px. Calculated based on the `size` value by default. */\n  thumbSize?: number;\n\n  /** A function to format label based on the current value */\n  formatLabel?: (value: number) => React.ReactNode;\n\n  /** Sets `data-disabled` attribute, disables interactions */\n  disabled?: boolean;\n\n  /** If set, the selection is allowed only from the given marks array @default false */\n  restrictToMarks?: boolean;\n\n  /** Props passed down to the hidden input */\n  hiddenInputProps?: React.ComponentProps<'input'>;\n\n  /** Hidden input name, use with uncontrolled component */\n  name?: string;\n}\n\nexport type AngleSliderFactory = Factory<{\n  props: AngleSliderProps;\n  ref: HTMLDivElement;\n  stylesNames: AngleSliderStylesNames;\n  vars: AngleSliderCssVariables;\n}>;\n\nconst defaultProps = {\n  step: 1,\n  withLabel: true,\n} satisfies Partial<AngleSliderProps>;\n\nconst varsResolver = createVarsResolver<AngleSliderFactory>((_, { size, thumbSize }) => ({\n  root: {\n    '--slider-size': rem(size),\n    '--thumb-size': rem(thumbSize),\n  },\n}));\n\nexport const AngleSlider = factory<AngleSliderFactory>((_props) => {\n  const props = useProps('AngleSlider', defaultProps, _props);\n  const {\n    classNames,\n    className,\n    style,\n    styles,\n    unstyled,\n    vars,\n    step,\n    value,\n    defaultValue,\n    onChange,\n    onMouseDown,\n    withLabel,\n    marks,\n    thumbSize,\n    restrictToMarks,\n    formatLabel,\n    onChangeEnd,\n    disabled,\n    onTouchStart,\n    name,\n    hiddenInputProps,\n    'aria-label': ariaLabel,\n    tabIndex,\n    onScrubStart,\n    onScrubEnd,\n    mod,\n    attributes,\n    ref,\n    ...others\n  } = props;\n\n  const rootRef = useRef<HTMLDivElement | null>(null);\n\n  const [_value, setValue] = useUncontrolled({\n    value,\n    defaultValue,\n    finalValue: 0,\n    onChange,\n  });\n\n  const update = (val: number) => {\n    if (rootRef.current && !disabled) {\n      const newValue =\n        restrictToMarks && Array.isArray(marks)\n          ? findClosestNumber(\n              val,\n              marks.map((mark) => mark.value)\n            )\n          : val;\n\n      setValue(newValue);\n    }\n  };\n\n  const { ref: radialMoveRef } = useRadialMove(update, {\n    step,\n    onChangeEnd,\n    onScrubStart,\n    onScrubEnd,\n  });\n\n  const getStyles = useStyles<AngleSliderFactory>({\n    name: 'AngleSlider',\n    classes,\n    props,\n    className,\n    style,\n    classNames,\n    styles,\n    unstyled,\n    attributes,\n    vars,\n    varsResolver,\n  });\n\n  const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n    if (disabled) {\n      return;\n    }\n\n    let newValue = _value;\n\n    if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {\n      event.preventDefault();\n      if (_value === 0) {\n        newValue = 359;\n      } else {\n        newValue = normalizeRadialValue(_value - step, step);\n      }\n    }\n\n    if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {\n      event.preventDefault();\n      if (_value === 359) {\n        newValue = 0;\n      } else {\n        newValue = normalizeRadialValue(_value + step, step);\n      }\n    }\n\n    if (event.key === 'Home') {\n      newValue = 0;\n    }\n\n    if (event.key === 'End') {\n      newValue = 359;\n    }\n\n    if (restrictToMarks && Array.isArray(marks)) {\n      const markValues = marks.map((mark) => mark.value);\n      const currentIndex = markValues.indexOf(_value);\n\n      if (currentIndex !== -1) {\n        if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {\n          newValue = markValues[currentIndex === 0 ? markValues.length - 1 : currentIndex - 1];\n        } else if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {\n          newValue = markValues[currentIndex === markValues.length - 1 ? 0 : currentIndex + 1];\n        } else {\n          newValue = findClosestNumber(newValue, markValues);\n        }\n      } else {\n        newValue = findClosestNumber(newValue, markValues);\n      }\n    }\n\n    setValue(newValue);\n    onChangeEnd?.(newValue);\n  };\n\n  const marksItems = marks?.map((mark, index) => (\n    <div\n      {...getStyles('mark', { style: { '--angle': `${mark.value}deg` } })}\n      data-label={mark.label || undefined}\n      key={index}\n    />\n  ));\n\n  return (\n    <Box\n      ref={useMergedRef(ref, rootRef, radialMoveRef)}\n      {...getStyles('root', { focusable: true })}\n      mod={[{ disabled }, mod]}\n      {...others}\n    >\n      {marksItems && marksItems.length > 0 && <div {...getStyles('marks')}>{marksItems}</div>}\n\n      {withLabel && (\n        <div {...getStyles('label')}>\n          {typeof formatLabel === 'function' ? formatLabel(_value) : _value}\n        </div>\n      )}\n      <div\n        tabIndex={tabIndex ?? (disabled ? -1 : 0)}\n        role=\"slider\"\n        aria-valuemax={360}\n        aria-valuemin={0}\n        aria-valuenow={_value}\n        onKeyDown={handleKeyDown}\n        aria-label={ariaLabel}\n        {...getStyles('thumb', { style: { transform: `rotate(${_value}deg)` } })}\n      />\n      <input type=\"hidden\" name={name} value={_value} {...hiddenInputProps} />\n    </Box>\n  );\n});\n\nAngleSlider.displayName = '@mantine/core/AngleSlider';\nAngleSlider.classes = classes;\nAngleSlider.varsResolver = varsResolver;\n"],"mappings":"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"}