{"version":3,"sources":["../src/components/ColorArea/useColorArea.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useId, slot, useMergedRefs, mergeCallbacks, getIntrinsicElementProps } from '@fluentui/react-utilities';\nimport type { ColorAreaBaseProps, ColorAreaBaseState, ColorAreaProps, ColorAreaState } from './ColorArea.types';\nimport type { HsvColor } from '../../types/color';\nimport { colorAreaCSSVars } from './ColorArea.constants';\nimport { useEventCallback, useControllableState } from '@fluentui/react-utilities';\nimport { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';\nimport { useFocusWithin } from '@fluentui/react-tabster';\nimport { INITIAL_COLOR_HSV } from '../../utils/constants';\nimport { getCoordinates } from '../../utils/getCoordinates';\nimport { useColorPickerContextValue_unstable } from '../../contexts/colorPicker';\nimport { createHslColorString } from '../../utils/createHslColor';\n\n/**\n * Create the state required to render unstyled ColorArea.\n *\n * The returned state can be modified with hooks before being passed to renderColorArea_unstable.\n *\n * @param props - props from this instance of ColorArea\n * @param ref - reference to root HTMLDivElement of ColorArea\n */\nexport const useColorAreaBase_unstable = (\n  props: ColorAreaBaseProps,\n  ref: React.Ref<HTMLDivElement>,\n): ColorAreaBaseState => {\n  const { targetDocument } = useFluent();\n  const rootRef = React.useRef<HTMLDivElement>(null);\n  const xRef = React.useRef<HTMLInputElement>(null);\n  const yRef = React.useRef<HTMLInputElement>(null);\n  const focusWithinRef = useFocusWithin();\n  const onChangeFromContext = useColorPickerContextValue_unstable(ctx => ctx.requestChange);\n  const colorFromContext = useColorPickerContextValue_unstable(ctx => ctx.color);\n\n  const {\n    onChange = onChangeFromContext as unknown as ColorAreaProps['onChange'],\n    // Slots\n    inputX,\n    inputY,\n    thumb,\n    color,\n    ...rest\n  } = props;\n\n  const [hsvColor, setColor] = useControllableState<HsvColor>({\n    defaultState: props.defaultColor,\n    state: color || colorFromContext,\n    initialState: INITIAL_COLOR_HSV,\n  });\n  const saturation = Math.round(hsvColor.s * 100);\n  const value = Math.round(hsvColor.v * 100);\n\n  const [activeAxis, setActiveAxis] = React.useState<'x' | 'y' | null>(null);\n\n  const requestColorChange = useEventCallback((event: PointerEvent) => {\n    if (!rootRef.current) {\n      return;\n    }\n\n    const coordinates = getCoordinates(rootRef.current, event);\n    const newColor: HsvColor = {\n      ...hsvColor,\n      s: coordinates.x,\n      v: coordinates.y,\n    };\n\n    setColor(newColor);\n    onChange?.(event, {\n      type: 'change',\n      event,\n      color: newColor,\n    });\n  });\n\n  const handleDocumentPointerMove = React.useCallback(\n    (event: PointerEvent) => {\n      requestColorChange(event);\n    },\n    [requestColorChange],\n  );\n\n  const handleDocumentPointerUp = useEventCallback(() => {\n    targetDocument?.removeEventListener('pointermove', handleDocumentPointerMove);\n  });\n\n  const handleRootOnPointerDown: React.PointerEventHandler<HTMLDivElement> = useEventCallback(event => {\n    event.stopPropagation();\n    event.preventDefault();\n\n    requestColorChange(event.nativeEvent);\n\n    targetDocument?.addEventListener('pointermove', handleDocumentPointerMove);\n    targetDocument?.addEventListener('pointerup', handleDocumentPointerUp, { once: true });\n  });\n\n  const handleInputOnChange: React.ChangeEventHandler<HTMLInputElement> = useEventCallback(event => {\n    const targetValue = Number(event.target.value) / 100;\n    const newColor: HsvColor = {\n      ...hsvColor,\n      ...(event.target === xRef.current && { s: targetValue }),\n      ...(event.target === yRef.current && { v: targetValue }),\n    };\n\n    setColor(newColor);\n    onChange?.(event, { type: 'change', event, color: newColor });\n  });\n\n  const handleRootOnKeyDown = useEventCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n    let deltaX = 0;\n    let deltaY = 0;\n    let axis: 'x' | 'y' = 'x';\n\n    switch (event.key) {\n      case 'ArrowUp':\n        event.preventDefault();\n\n        axis = 'y';\n        deltaY = 1;\n\n        break;\n      case 'ArrowDown':\n        event.preventDefault();\n\n        axis = 'y';\n        deltaY = -1;\n\n        break;\n      case 'ArrowLeft':\n        event.preventDefault();\n\n        axis = 'x';\n        deltaX = -1;\n\n        break;\n      case 'ArrowRight':\n        event.preventDefault();\n\n        axis = 'x';\n        deltaX = 1;\n\n        break;\n    }\n\n    if (deltaX === 0 && deltaY === 0) {\n      return;\n    }\n\n    const newColor: HsvColor = {\n      ...hsvColor,\n      s: Math.min(Math.max(hsvColor.s + deltaX / 100, 0), 1),\n      v: Math.min(Math.max(hsvColor.v + deltaY / 100, 0), 1),\n    };\n\n    setColor(newColor);\n    setActiveAxis(axis);\n\n    onChange?.(event, { type: 'change', event, color: newColor });\n  });\n\n  const rootVariables = {\n    [colorAreaCSSVars.areaXProgressVar]: `${saturation}%`,\n    [colorAreaCSSVars.areaYProgressVar]: `${value}%`,\n    [colorAreaCSSVars.thumbColorVar]: createHslColorString(hsvColor),\n    [colorAreaCSSVars.mainColorVar]: `hsl(${hsvColor.h}, 100%, 50%)`,\n  };\n  const state: ColorAreaBaseState = {\n    components: {\n      inputX: 'input',\n      inputY: 'input',\n      root: 'div',\n      thumb: 'div',\n    },\n    root: slot.always(\n      getIntrinsicElementProps('div', {\n        ref,\n        ...rest,\n      }),\n      { elementType: 'div' },\n    ),\n    inputX: slot.always(inputX, {\n      defaultProps: {\n        id: useId('sliderX-'),\n        type: 'range',\n        ...(activeAxis && { tabIndex: activeAxis === 'x' ? 0 : -1 }),\n      },\n      elementType: 'input',\n    }),\n    inputY: slot.always(inputY, {\n      defaultProps: {\n        id: useId('sliderY-'),\n        type: 'range',\n        tabIndex: activeAxis && activeAxis === 'y' ? 0 : -1,\n      },\n      elementType: 'input',\n    }),\n    thumb: slot.always(thumb, { elementType: 'div' }),\n  };\n\n  state.root.ref = useMergedRefs(state.root.ref, rootRef);\n  state.thumb.ref = useMergedRefs(state.thumb.ref, focusWithinRef);\n  state.inputX.ref = useMergedRefs(state.inputX.ref, xRef);\n  state.inputY.ref = useMergedRefs(state.inputY.ref, yRef);\n\n  state.root.style = {\n    ...state.root.style,\n    ...rootVariables,\n  };\n\n  state.root.onPointerDown = useEventCallback(mergeCallbacks(state.root.onPointerDown, handleRootOnPointerDown));\n  state.root.onKeyDown = useEventCallback(mergeCallbacks(state.root.onKeyDown, handleRootOnKeyDown));\n  state.inputX.onChange = useEventCallback(mergeCallbacks(state.inputX.onChange, handleInputOnChange));\n  state.inputY.onChange = useEventCallback(mergeCallbacks(state.inputY.onChange, handleInputOnChange));\n\n  state.inputX.value = saturation;\n  state.inputY.value = value;\n\n  return state;\n};\n\n/**\n * Create the state required to render ColorArea.\n *\n * The returned state can be modified with hooks such as useColorAreaStyles_unstable,\n * before being passed to renderColorArea_unstable.\n *\n * @param props - props from this instance of ColorArea\n * @param ref - reference to root HTMLDivElement of ColorArea\n */\nexport const useColorArea_unstable = (props: ColorAreaProps, ref: React.Ref<HTMLDivElement>): ColorAreaState => {\n  const shapeFromContext = useColorPickerContextValue_unstable(ctx => ctx.shape);\n\n  const { shape = shapeFromContext, ...rest } = props;\n\n  const state: ColorAreaState = {\n    ...useColorAreaBase_unstable(rest, ref),\n    shape,\n  };\n\n  return state;\n};\n"],"names":["React","useId","slot","useMergedRefs","mergeCallbacks","getIntrinsicElementProps","colorAreaCSSVars","useEventCallback","useControllableState","useFluent_unstable","useFluent","useFocusWithin","INITIAL_COLOR_HSV","getCoordinates","useColorPickerContextValue_unstable","createHslColorString","useColorAreaBase_unstable","props","ref","targetDocument","rootRef","useRef","xRef","yRef","focusWithinRef","onChangeFromContext","ctx","requestChange","colorFromContext","color","onChange","inputX","inputY","thumb","rest","hsvColor","setColor","defaultState","defaultColor","state","initialState","saturation","Math","round","s","value","v","activeAxis","setActiveAxis","useState","requestColorChange","event","current","coordinates","newColor","x","y","type","handleDocumentPointerMove","useCallback","handleDocumentPointerUp","removeEventListener","handleRootOnPointerDown","stopPropagation","preventDefault","nativeEvent","addEventListener","once","handleInputOnChange","targetValue","Number","target","handleRootOnKeyDown","deltaX","deltaY","axis","key","min","max","rootVariables","areaXProgressVar","areaYProgressVar","thumbColorVar","mainColorVar","h","components","root","always","elementType","defaultProps","id","tabIndex","style","onPointerDown","onKeyDown","useColorArea_unstable","shapeFromContext","shape"],"mappings":"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"}