UNPKG

@wordpress/block-editor

Version:
306 lines (303 loc) 10.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.__experimentalImageURLInputUI = void 0; var _i18n = require("@wordpress/i18n"); var _element = require("@wordpress/element"); var _dom = require("@wordpress/dom"); var _components = require("@wordpress/components"); var _icons = require("@wordpress/icons"); var _index = _interopRequireDefault(require("./index")); var _jsxRuntime = require("react/jsx-runtime"); /** * WordPress dependencies */ /** * Internal dependencies */ const LINK_DESTINATION_NONE = 'none'; const LINK_DESTINATION_CUSTOM = 'custom'; const LINK_DESTINATION_MEDIA = 'media'; const LINK_DESTINATION_ATTACHMENT = 'attachment'; const NEW_TAB_REL = ['noreferrer', 'noopener']; const ImageURLInputUI = ({ linkDestination, onChangeUrl, url, mediaType = 'image', mediaUrl, mediaLink, linkTarget, linkClass, rel, showLightboxSetting, lightboxEnabled, onSetLightbox, resetLightbox }) => { const [isOpen, setIsOpen] = (0, _element.useState)(false); // Use internal state instead of a ref to make sure that the component // re-renders when the popover's anchor updates. const [popoverAnchor, setPopoverAnchor] = (0, _element.useState)(null); const openLinkUI = () => { setIsOpen(true); }; const [isEditingLink, setIsEditingLink] = (0, _element.useState)(false); const [urlInput, setUrlInput] = (0, _element.useState)(null); const autocompleteRef = (0, _element.useRef)(null); const wrapperRef = (0, _element.useRef)(); (0, _element.useEffect)(() => { if (!wrapperRef.current) { return; } const nextFocusTarget = _dom.focus.focusable.find(wrapperRef.current)[0] || wrapperRef.current; nextFocusTarget.focus(); }, [isEditingLink, url, lightboxEnabled]); const startEditLink = () => { if (linkDestination === LINK_DESTINATION_MEDIA || linkDestination === LINK_DESTINATION_ATTACHMENT) { setUrlInput(''); } setIsEditingLink(true); }; const stopEditLink = () => { setIsEditingLink(false); }; const closeLinkUI = () => { setUrlInput(null); stopEditLink(); setIsOpen(false); }; const getUpdatedLinkTargetSettings = value => { const newLinkTarget = value ? '_blank' : undefined; let updatedRel; if (newLinkTarget) { const rels = (rel !== null && rel !== void 0 ? rel : '').split(' '); NEW_TAB_REL.forEach(relVal => { if (!rels.includes(relVal)) { rels.push(relVal); } }); updatedRel = rels.join(' '); } else { const rels = (rel !== null && rel !== void 0 ? rel : '').split(' ').filter(relVal => NEW_TAB_REL.includes(relVal) === false); updatedRel = rels.length ? rels.join(' ') : undefined; } return { linkTarget: newLinkTarget, rel: updatedRel }; }; const onFocusOutside = () => { return event => { // The autocomplete suggestions list renders in a separate popover (in a portal), // so onFocusOutside fails to detect that a click on a suggestion occurred in the // LinkContainer. Detect clicks on autocomplete suggestions using a ref here, and // return to avoid the popover being closed. const autocompleteElement = autocompleteRef.current; if (autocompleteElement && autocompleteElement.contains(event.target)) { return; } setIsOpen(false); setUrlInput(null); stopEditLink(); }; }; const onSubmitLinkChange = () => { return event => { if (urlInput) { // It is possible the entered URL actually matches a named link destination. // This check will ensure our link destination is correct. const selectedDestination = getLinkDestinations().find(destination => destination.url === urlInput)?.linkDestination || LINK_DESTINATION_CUSTOM; onChangeUrl({ href: urlInput, linkDestination: selectedDestination, lightbox: { enabled: false } }); } stopEditLink(); setUrlInput(null); event.preventDefault(); }; }; const onLinkRemove = () => { onChangeUrl({ linkDestination: LINK_DESTINATION_NONE, href: '' }); }; const getLinkDestinations = () => { const linkDestinations = [{ linkDestination: LINK_DESTINATION_MEDIA, title: (0, _i18n.__)('Link to image file'), url: mediaType === 'image' ? mediaUrl : undefined, icon: _icons.image }]; if (mediaType === 'image' && mediaLink) { linkDestinations.push({ linkDestination: LINK_DESTINATION_ATTACHMENT, title: (0, _i18n.__)('Link to attachment page'), url: mediaType === 'image' ? mediaLink : undefined, icon: _icons.page }); } return linkDestinations; }; const onSetHref = value => { const linkDestinations = getLinkDestinations(); let linkDestinationInput; if (!value) { linkDestinationInput = LINK_DESTINATION_NONE; } else { linkDestinationInput = (linkDestinations.find(destination => { return destination.url === value; }) || { linkDestination: LINK_DESTINATION_CUSTOM }).linkDestination; } onChangeUrl({ linkDestination: linkDestinationInput, href: value }); }; const onSetNewTab = value => { const updatedLinkTarget = getUpdatedLinkTargetSettings(value); onChangeUrl(updatedLinkTarget); }; const onSetLinkRel = value => { onChangeUrl({ rel: value }); }; const onSetLinkClass = value => { onChangeUrl({ linkClass: value }); }; const advancedOptions = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalVStack, { spacing: "3", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToggleControl, { __nextHasNoMarginBottom: true, label: (0, _i18n.__)('Open in new tab'), onChange: onSetNewTab, checked: linkTarget === '_blank' }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.TextControl, { __next40pxDefaultSize: true, __nextHasNoMarginBottom: true, label: (0, _i18n.__)('Link rel'), value: rel !== null && rel !== void 0 ? rel : '', onChange: onSetLinkRel }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.TextControl, { __next40pxDefaultSize: true, __nextHasNoMarginBottom: true, label: (0, _i18n.__)('Link CSS class'), value: linkClass || '', onChange: onSetLinkClass })] }); const linkEditorValue = urlInput !== null ? urlInput : url; const hideLightboxPanel = !lightboxEnabled || lightboxEnabled && !showLightboxSetting; const showLinkEditor = !linkEditorValue && hideLightboxPanel; const urlLabel = (getLinkDestinations().find(destination => destination.linkDestination === linkDestination) || {}).title; const PopoverChildren = () => { if (lightboxEnabled && showLightboxSetting && !url && !isEditingLink) { return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { className: "block-editor-url-popover__expand-on-click", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.Icon, { icon: _icons.fullscreen }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { className: "text", children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", { children: (0, _i18n.__)('Enlarge on click') }), /*#__PURE__*/(0, _jsxRuntime.jsx)("p", { className: "description", children: (0, _i18n.__)('Scales the image with a lightbox effect') })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, { icon: _icons.linkOff, label: (0, _i18n.__)('Disable enlarge on click'), onClick: () => { onSetLightbox?.(false); }, size: "compact" })] }); } else if (!url || isEditingLink) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.default.LinkEditor, { className: "block-editor-format-toolbar__link-container-content", value: linkEditorValue, onChangeInputValue: setUrlInput, onSubmit: onSubmitLinkChange(), autocompleteRef: autocompleteRef }); } else if (url && !isEditingLink) { return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index.default.LinkViewer, { className: "block-editor-format-toolbar__link-container-content", url: url, onEditLinkClick: startEditLink, urlLabel: urlLabel }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, { icon: _icons.linkOff, label: (0, _i18n.__)('Remove link'), onClick: () => { onLinkRemove(); resetLightbox?.(); }, size: "compact" })] }); } }; return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarButton, { icon: _icons.link, className: "components-toolbar__control", label: (0, _i18n.__)('Link'), "aria-expanded": isOpen, onClick: openLinkUI, ref: setPopoverAnchor, isActive: !!url || lightboxEnabled && showLightboxSetting }), isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.default, { ref: wrapperRef, anchor: popoverAnchor, onFocusOutside: onFocusOutside(), onClose: closeLinkUI, renderSettings: hideLightboxPanel ? () => advancedOptions : null, additionalControls: showLinkEditor && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.NavigableMenu, { children: [getLinkDestinations().map(link => /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, { icon: link.icon, iconPosition: "left", onClick: () => { setUrlInput(null); onSetHref(link.url); stopEditLink(); }, children: link.title }, link.linkDestination)), showLightboxSetting && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.MenuItem, { className: "block-editor-url-popover__expand-on-click", icon: _icons.fullscreen, info: (0, _i18n.__)('Scale the image with a lightbox effect.'), iconPosition: "left", onClick: () => { setUrlInput(null); onChangeUrl({ linkDestination: LINK_DESTINATION_NONE, href: '' }); onSetLightbox?.(true); stopEditLink(); }, children: (0, _i18n.__)('Enlarge on click') }, "expand-on-click")] }), offset: 13, children: PopoverChildren() })] }); }; exports.__experimentalImageURLInputUI = ImageURLInputUI; //# sourceMappingURL=image-url-input-ui.js.map