{
  "version": 3,
  "sources": ["../../src/focal-point-picker/index.tsx"],
  "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n/**\n * WordPress dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport { useEffect, useRef, useState } from '@wordpress/element';\nimport { __experimentalUseDragging as useDragging, useIsomorphicLayoutEffect } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport Controls from './controls';\nimport FocalPoint from './focal-point';\nimport Grid from './grid';\nimport Media from './media';\nimport { Container, MediaWrapper, MediaContainer } from './styles/focal-point-picker-style';\nimport { INITIAL_BOUNDS } from './utils';\nimport { useUpdateEffect } from '../utils/hooks';\nimport { StyledLabel, StyledHelp } from '../base-control/styles/base-control-styles';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { jsx as _jsx, jsxs as _jsxs } from \"react/jsx-runtime\";\nconst GRID_OVERLAY_TIMEOUT = 600;\n\n/**\n * Focal Point Picker is a component which creates a UI for identifying the most important visual point of an image.\n *\n * This component addresses a specific problem: with large background images it is common to see undesirable crops,\n * especially when viewing on smaller viewports such as mobile phones. This component allows the selection of\n * the point with the most important visual information and returns it as a pair of numbers between 0 and 1.\n * This value can be easily converted into the CSS `background-position` attribute, and will ensure that the\n * focal point is never cropped out, regardless of viewport.\n *\n * - Example focal point picker value: `{ x: 0.5, y: 0.1 }`\n * - Corresponding CSS: `background-position: 50% 10%;`\n *\n * ```jsx\n * import { FocalPointPicker } from '@wordpress/components';\n * import { useState } from '@wordpress/element';\n *\n * const Example = () => {\n * \tconst [ focalPoint, setFocalPoint ] = useState( {\n * \t\tx: 0.5,\n * \t\ty: 0.5,\n * \t} );\n *\n * \tconst url = '/path/to/image';\n *\n * \t// Example function to render the CSS styles based on Focal Point Picker value\n * \tconst style = {\n * \t\tbackgroundImage: `url(${ url })`,\n * \t\tbackgroundPosition: `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`,\n * \t};\n *\n * \treturn (\n * \t\t<>\n * \t\t\t<FocalPointPicker\n * \t\t\t\turl={ url }\n * \t\t\t\tvalue={ focalPoint }\n * \t\t\t\tonDragStart={ setFocalPoint }\n * \t\t\t\tonDrag={ setFocalPoint }\n * \t\t\t\tonChange={ setFocalPoint }\n * \t\t\t/>\n * \t\t\t<div style={ style } />\n * \t\t</>\n * \t);\n * };\n * ```\n */\nexport function FocalPointPicker({\n  // Prevent passing to internal component.\n  __nextHasNoMarginBottom: _,\n  autoPlay = true,\n  className,\n  help,\n  hideLabelFromVision,\n  label,\n  onChange,\n  onDrag,\n  onDragEnd,\n  onDragStart,\n  resolvePoint,\n  url,\n  value: valueProp = {\n    x: 0.5,\n    y: 0.5\n  },\n  ...restProps\n}) {\n  const [point, setPoint] = useState(valueProp);\n  const [showGridOverlay, setShowGridOverlay] = useState(false);\n  const {\n    startDrag,\n    endDrag,\n    isDragging\n  } = useDragging({\n    onDragStart: event => {\n      dragAreaRef.current?.focus();\n      const value = getValueWithinDragArea(event);\n\n      // `value` can technically be undefined if getValueWithinDragArea() is\n      // called before dragAreaRef is set, but this shouldn't happen in reality.\n      if (!value) {\n        return;\n      }\n      onDragStart?.(value, event);\n      setPoint(value);\n    },\n    onDragMove: event => {\n      // Prevents text-selection when dragging.\n      event.preventDefault();\n      const value = getValueWithinDragArea(event);\n      if (!value) {\n        return;\n      }\n      onDrag?.(value, event);\n      setPoint(value);\n    },\n    onDragEnd: () => {\n      onDragEnd?.();\n      onChange?.(point);\n    }\n  });\n\n  // Uses the internal point while dragging or else the value from props.\n  const {\n    x,\n    y\n  } = isDragging ? point : valueProp;\n  const dragAreaRef = useRef(null);\n  const [bounds, setBounds] = useState(INITIAL_BOUNDS);\n  const refUpdateBounds = useRef(() => {\n    if (!dragAreaRef.current) {\n      return;\n    }\n    const {\n      clientWidth: width,\n      clientHeight: height\n    } = dragAreaRef.current;\n    // Falls back to initial bounds if the ref has no size. Since styles\n    // give the drag area dimensions even when the media has not loaded\n    // this should only happen in unit tests (jsdom).\n    setBounds(width > 0 && height > 0 ? {\n      width,\n      height\n    } : {\n      ...INITIAL_BOUNDS\n    });\n  });\n  useEffect(() => {\n    const updateBounds = refUpdateBounds.current;\n    if (!dragAreaRef.current) {\n      return;\n    }\n    const {\n      defaultView\n    } = dragAreaRef.current.ownerDocument;\n    defaultView?.addEventListener('resize', updateBounds);\n    return () => defaultView?.removeEventListener('resize', updateBounds);\n  }, []);\n\n  // Updates the bounds to cover cases of unspecified media or load failures.\n  useIsomorphicLayoutEffect(() => void refUpdateBounds.current(), []);\n\n  // TODO: Consider refactoring getValueWithinDragArea() into a pure function.\n  // https://github.com/WordPress/gutenberg/pull/43872#discussion_r963455173\n  const getValueWithinDragArea = ({\n    clientX,\n    clientY,\n    shiftKey\n  }) => {\n    if (!dragAreaRef.current) {\n      return;\n    }\n    const {\n      top,\n      left\n    } = dragAreaRef.current.getBoundingClientRect();\n    let nextX = (clientX - left) / bounds.width;\n    let nextY = (clientY - top) / bounds.height;\n    // Enables holding shift to jump values by 10%.\n    if (shiftKey) {\n      nextX = Math.round(nextX / 0.1) * 0.1;\n      nextY = Math.round(nextY / 0.1) * 0.1;\n    }\n    return getFinalValue({\n      x: nextX,\n      y: nextY\n    });\n  };\n  const getFinalValue = value => {\n    const resolvedValue = resolvePoint?.(value) ?? value;\n    resolvedValue.x = Math.max(0, Math.min(resolvedValue.x, 1));\n    resolvedValue.y = Math.max(0, Math.min(resolvedValue.y, 1));\n    const roundToTwoDecimalPlaces = n => Math.round(n * 1e2) / 1e2;\n    return {\n      x: roundToTwoDecimalPlaces(resolvedValue.x),\n      y: roundToTwoDecimalPlaces(resolvedValue.y)\n    };\n  };\n  const arrowKeyStep = event => {\n    const {\n      code,\n      shiftKey\n    } = event;\n    if (!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(code)) {\n      return;\n    }\n    event.preventDefault();\n    const value = {\n      x,\n      y\n    };\n    const step = shiftKey ? 0.1 : 0.01;\n    const delta = code === 'ArrowUp' || code === 'ArrowLeft' ? -1 * step : step;\n    const axis = code === 'ArrowUp' || code === 'ArrowDown' ? 'y' : 'x';\n    value[axis] = value[axis] + delta;\n    onChange?.(getFinalValue(value));\n  };\n  const focalPointPosition = {\n    left: x !== undefined ? x * bounds.width : 0.5 * bounds.width,\n    top: y !== undefined ? y * bounds.height : 0.5 * bounds.height\n  };\n  const classes = clsx('components-focal-point-picker-control', className);\n  const Label = hideLabelFromVision ? VisuallyHidden : StyledLabel;\n  useUpdateEffect(() => {\n    setShowGridOverlay(true);\n    const timeout = window.setTimeout(() => {\n      setShowGridOverlay(false);\n    }, GRID_OVERLAY_TIMEOUT);\n    return () => window.clearTimeout(timeout);\n  }, [x, y]);\n  return /*#__PURE__*/_jsxs(Container, {\n    ...restProps,\n    as: \"fieldset\",\n    className: classes,\n    children: [!!label && /*#__PURE__*/_jsx(Label, {\n      as: \"legend\",\n      children: label\n    }), /*#__PURE__*/_jsx(MediaWrapper, {\n      className: \"components-focal-point-picker-wrapper\",\n      children: /*#__PURE__*/_jsxs(MediaContainer, {\n        className: \"components-focal-point-picker\",\n        onKeyDown: arrowKeyStep,\n        onMouseDown: startDrag,\n        onBlur: () => {\n          if (isDragging) {\n            endDrag();\n          }\n        },\n        ref: dragAreaRef,\n        role: \"button\",\n        tabIndex: -1,\n        children: [/*#__PURE__*/_jsx(Grid, {\n          bounds: bounds,\n          showOverlay: showGridOverlay\n        }), /*#__PURE__*/_jsx(Media, {\n          alt: __('Media preview'),\n          autoPlay: autoPlay,\n          onLoad: refUpdateBounds.current,\n          src: url\n        }), /*#__PURE__*/_jsx(FocalPoint, {\n          ...focalPointPosition,\n          isDragging: isDragging\n        })]\n      })\n    }), /*#__PURE__*/_jsx(Controls, {\n      hasHelpText: !!help,\n      point: {\n        x,\n        y\n      },\n      onChange: value => {\n        onChange?.(getFinalValue(value));\n      }\n    }), !!help && /*#__PURE__*/_jsx(StyledHelp, {\n      children: help\n    })]\n  });\n}\nexport default FocalPointPicker;"],
  "mappings": "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",
  "names": ["useDragging", "clsx", "_jsxs", "_jsx", "Grid", "Media", "FocalPoint", "Controls"]
}
