{"version":3,"file":"AngleSlider.cjs","sources":["../../../src/components/AngleSlider/AngleSlider.tsx"],"sourcesContent":["import { normalizeRadialValue, useMergedRef, useRadialMove, useUncontrolled } from '@raikou/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 {\n  AngleSliderLabelStyle,\n  AngleSliderMarksStyle,\n  AngleSliderMarkStyle,\n  AngleSliderRootStyle,\n  AngleSliderThumbStyle,\n} from './AngleSlider.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,\n    StylesApiProps<AngleSliderFactory>,\n    ElementProps<'div', 'onChange'> {\n  /** Step between values, used when the component is controlled with keyboard, `1` by default */\n  step?: number;\n\n  /** Value of the controlled component */\n  value?: number;\n\n  /** Default value for uncontrolled component */\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` events */\n  onScrubStart?: () => void;\n\n  /** Called in `onMouseUp` and `onTouchEnd` events */\n  onScrubEnd?: () => void;\n\n  /** Determines whether the label should be displayed inside the slider, `true` by default */\n  withLabel?: boolean;\n\n  /** Array of marks that are displayed on the slider */\n  marks?: { value: number; label?: string }[];\n\n  /** Slider size in px, `60px` */\n  size?: number;\n\n  /** Size of the thumb in px, by default is calculated based on the `size` value */\n  thumbSize?: number;\n\n  /** Formats label based on the current value */\n  formatLabel?: (value: number) => React.ReactNode;\n\n  /** Disables interactions */\n  disabled?: boolean;\n\n  /** Determines whether the selection should be only allowed from the given marks array, `false` by default */\n  restrictToMarks?: boolean;\n\n  /** Props passed down to the hidden input */\n  hiddenInputProps?: React.ComponentPropsWithoutRef<'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: Partial<AngleSliderProps> = {\n  step: 1,\n  withLabel: true,\n};\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, ref) => {\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    ...others\n  } = props;\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) {\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: rootRef } = useRadialMove(update, {\n    step,\n    onChangeEnd,\n    onScrubStart,\n    onScrubEnd,\n  });\n\n  const getStyles = useStyles<AngleSliderFactory>({\n    name: 'AngleSlider',\n    classes: {\n      root: AngleSliderRootStyle,\n      marks: AngleSliderMarksStyle,\n      mark: AngleSliderMarkStyle,\n      thumb: AngleSliderThumbStyle,\n      label: AngleSliderLabelStyle,\n    },\n    props,\n    className,\n    style,\n    classNames,\n    styles,\n    unstyled,\n    vars,\n    varsResolver,\n  });\n\n  const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n    if (disabled) {\n      return;\n    }\n\n    if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {\n      const normalized = normalizeRadialValue(_value - step!, step!);\n      setValue(normalized);\n      onChangeEnd?.(normalized);\n    }\n\n    if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {\n      const normalized = normalizeRadialValue(_value + step!, step!);\n      setValue(normalized);\n      onChangeEnd?.(normalized);\n    }\n\n    if (event.key === 'Home') {\n      setValue(0);\n      onChangeEnd?.(0);\n    }\n\n    if (event.key === 'End') {\n      setValue(359);\n      onChangeEnd?.(359);\n    }\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 ref={useMergedRef(ref, rootRef)} {...getStyles('root', { focusable: true })} {...others}>\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 = '@raikou/core/AngleSlider';\n"],"names":["createVarsResolver","rem","factory","useProps","useUncontrolled","findClosestNumber","useRadialMove","useStyles","AngleSliderRootStyle","AngleSliderMarksStyle","AngleSliderMarkStyle","AngleSliderThumbStyle","AngleSliderLabelStyle","normalizeRadialValue","createElement","Box","useMergedRef","jsx"],"mappings":"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"}