UNPKG

@wordpress/components

Version:
264 lines (262 loc) 9.1 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // packages/components/src/focal-point-picker/index.tsx var focal_point_picker_exports = {}; __export(focal_point_picker_exports, { FocalPointPicker: () => FocalPointPicker, default: () => focal_point_picker_default }); module.exports = __toCommonJS(focal_point_picker_exports); var import_clsx = __toESM(require("clsx")); var import_i18n = require("@wordpress/i18n"); var import_element = require("@wordpress/element"); var import_compose = require("@wordpress/compose"); var import_deprecated = __toESM(require("@wordpress/deprecated")); var import_controls = __toESM(require("./controls")); var import_focal_point = __toESM(require("./focal-point")); var import_grid = __toESM(require("./grid")); var import_media = __toESM(require("./media")); var import_focal_point_picker_style = require("./styles/focal-point-picker-style"); var import_utils = require("./utils"); var import_hooks = require("../utils/hooks"); var import_base_control_styles = require("../base-control/styles/base-control-styles"); var import_visually_hidden = require("../visually-hidden"); var import_jsx_runtime = require("react/jsx-runtime"); var GRID_OVERLAY_TIMEOUT = 600; function FocalPointPicker({ __nextHasNoMarginBottom, autoPlay = true, className, help, hideLabelFromVision, label, onChange, onDrag, onDragEnd, onDragStart, resolvePoint, url, value: valueProp = { x: 0.5, y: 0.5 }, ...restProps }) { const [point, setPoint] = (0, import_element.useState)(valueProp); const [showGridOverlay, setShowGridOverlay] = (0, import_element.useState)(false); if (!__nextHasNoMarginBottom) { (0, import_deprecated.default)("Bottom margin styles for wp.components.FocalPointPicker", { since: "6.7", version: "7.0", hint: "Set the `__nextHasNoMarginBottom` prop to true to start opting into the new styles, which will become the default in a future version." }); } const { startDrag, endDrag, isDragging } = (0, import_compose.__experimentalUseDragging)({ onDragStart: (event) => { dragAreaRef.current?.focus(); const value = getValueWithinDragArea(event); if (!value) { return; } onDragStart?.(value, event); setPoint(value); }, onDragMove: (event) => { event.preventDefault(); const value = getValueWithinDragArea(event); if (!value) { return; } onDrag?.(value, event); setPoint(value); }, onDragEnd: () => { onDragEnd?.(); onChange?.(point); } }); const { x, y } = isDragging ? point : valueProp; const dragAreaRef = (0, import_element.useRef)(null); const [bounds, setBounds] = (0, import_element.useState)(import_utils.INITIAL_BOUNDS); const refUpdateBounds = (0, import_element.useRef)(() => { if (!dragAreaRef.current) { return; } const { clientWidth: width, clientHeight: height } = dragAreaRef.current; setBounds(width > 0 && height > 0 ? { width, height } : { ...import_utils.INITIAL_BOUNDS }); }); (0, import_element.useEffect)(() => { const updateBounds = refUpdateBounds.current; if (!dragAreaRef.current) { return; } const { defaultView } = dragAreaRef.current.ownerDocument; defaultView?.addEventListener("resize", updateBounds); return () => defaultView?.removeEventListener("resize", updateBounds); }, []); (0, import_compose.useIsomorphicLayoutEffect)(() => void refUpdateBounds.current(), []); const getValueWithinDragArea = ({ clientX, clientY, shiftKey }) => { if (!dragAreaRef.current) { return; } const { top, left } = dragAreaRef.current.getBoundingClientRect(); let nextX = (clientX - left) / bounds.width; let nextY = (clientY - top) / bounds.height; if (shiftKey) { nextX = Math.round(nextX / 0.1) * 0.1; nextY = Math.round(nextY / 0.1) * 0.1; } return getFinalValue({ x: nextX, y: nextY }); }; const getFinalValue = (value) => { var _resolvePoint; const resolvedValue = (_resolvePoint = resolvePoint?.(value)) !== null && _resolvePoint !== void 0 ? _resolvePoint : value; resolvedValue.x = Math.max(0, Math.min(resolvedValue.x, 1)); resolvedValue.y = Math.max(0, Math.min(resolvedValue.y, 1)); const roundToTwoDecimalPlaces = (n) => Math.round(n * 100) / 100; return { x: roundToTwoDecimalPlaces(resolvedValue.x), y: roundToTwoDecimalPlaces(resolvedValue.y) }; }; const arrowKeyStep = (event) => { const { code, shiftKey } = event; if (!["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(code)) { return; } event.preventDefault(); const value = { x, y }; const step = shiftKey ? 0.1 : 0.01; const delta = code === "ArrowUp" || code === "ArrowLeft" ? -1 * step : step; const axis = code === "ArrowUp" || code === "ArrowDown" ? "y" : "x"; value[axis] = value[axis] + delta; onChange?.(getFinalValue(value)); }; const focalPointPosition = { left: x !== void 0 ? x * bounds.width : 0.5 * bounds.width, top: y !== void 0 ? y * bounds.height : 0.5 * bounds.height }; const classes = (0, import_clsx.default)("components-focal-point-picker-control", className); const Label = hideLabelFromVision ? import_visually_hidden.VisuallyHidden : import_base_control_styles.StyledLabel; (0, import_hooks.useUpdateEffect)(() => { setShowGridOverlay(true); const timeout = window.setTimeout(() => { setShowGridOverlay(false); }, GRID_OVERLAY_TIMEOUT); return () => window.clearTimeout(timeout); }, [x, y]); return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_focal_point_picker_style.Container, { ...restProps, as: "fieldset", className: classes, children: [!!label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Label, { as: "legend", children: label }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_focal_point_picker_style.MediaWrapper, { className: "components-focal-point-picker-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_focal_point_picker_style.MediaContainer, { className: "components-focal-point-picker", onKeyDown: arrowKeyStep, onMouseDown: startDrag, onBlur: () => { if (isDragging) { endDrag(); } }, ref: dragAreaRef, role: "button", tabIndex: -1, children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_grid.default, { bounds, showOverlay: showGridOverlay }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_media.default, { alt: (0, import_i18n.__)("Media preview"), autoPlay, onLoad: refUpdateBounds.current, src: url }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_focal_point.default, { ...focalPointPosition, isDragging })] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_controls.default, { __nextHasNoMarginBottom, hasHelpText: !!help, point: { x, y }, onChange: (value) => { onChange?.(getFinalValue(value)); } }), !!help && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_base_control_styles.StyledHelp, { __nextHasNoMarginBottom, children: help })] }); } var focal_point_picker_default = FocalPointPicker; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { FocalPointPicker }); //# sourceMappingURL=index.js.map