@wordpress/block-editor
Version:
284 lines (247 loc) • 9.02 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.__experimentalImageURLInputUI = void 0;
var _element = require("@wordpress/element");
var _lodash = require("lodash");
var _i18n = require("@wordpress/i18n");
var _components = require("@wordpress/components");
var _icons = require("@wordpress/icons");
var _index = _interopRequireDefault(require("./index"));
/**
* External dependencies
*/
/**
* 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 icon = (0, _element.createElement)(_components.SVG, {
viewBox: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg"
}, (0, _element.createElement)(_components.Path, {
d: "M0,0h24v24H0V0z",
fill: "none"
}), (0, _element.createElement)(_components.Path, {
d: "m19 5v14h-14v-14h14m0-2h-14c-1.1 0-2 0.9-2 2v14c0 1.1 0.9 2 2 2h14c1.1 0 2-0.9 2-2v-14c0-1.1-0.9-2-2-2z"
}), (0, _element.createElement)(_components.Path, {
d: "m14.14 11.86l-3 3.87-2.14-2.59-3 3.86h12l-3.86-5.14z"
}));
const ImageURLInputUI = ({
linkDestination,
onChangeUrl,
url,
mediaType = 'image',
mediaUrl,
mediaLink,
linkTarget,
linkClass,
rel
}) => {
const [isOpen, setIsOpen] = (0, _element.useState)(false);
const openLinkUI = (0, _element.useCallback)(() => {
setIsOpen(true);
});
const [isEditingLink, setIsEditingLink] = (0, _element.useState)(false);
const [urlInput, setUrlInput] = (0, _element.useState)(null);
const autocompleteRef = (0, _element.useRef)(null);
const startEditLink = (0, _element.useCallback)(() => {
if (linkDestination === LINK_DESTINATION_MEDIA || linkDestination === LINK_DESTINATION_ATTACHMENT) {
setUrlInput('');
}
setIsEditingLink(true);
});
const stopEditLink = (0, _element.useCallback)(() => {
setIsEditingLink(false);
});
const closeLinkUI = (0, _element.useCallback)(() => {
setUrlInput(null);
stopEditLink();
setIsOpen(false);
});
const removeNewTabRel = currentRel => {
let newRel = currentRel;
if (currentRel !== undefined && !(0, _lodash.isEmpty)(newRel)) {
if (!(0, _lodash.isEmpty)(newRel)) {
(0, _lodash.each)(NEW_TAB_REL, relVal => {
const regExp = new RegExp('\\b' + relVal + '\\b', 'gi');
newRel = newRel.replace(regExp, '');
}); // Only trim if NEW_TAB_REL values was replaced.
if (newRel !== currentRel) {
newRel = newRel.trim();
}
if ((0, _lodash.isEmpty)(newRel)) {
newRel = undefined;
}
}
}
return newRel;
};
const getUpdatedLinkTargetSettings = value => {
const newLinkTarget = value ? '_blank' : undefined;
let updatedRel;
if (!newLinkTarget && !rel) {
updatedRel = undefined;
} else {
updatedRel = removeNewTabRel(rel);
}
return {
linkTarget: newLinkTarget,
rel: updatedRel
};
};
const onFocusOutside = (0, _element.useCallback)(() => {
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 = (0, _element.useCallback)(() => {
return event => {
if (urlInput) {
var _getLinkDestinations$;
// It is possible the entered URL actually matches a named link destination.
// This check will ensure our link destination is correct.
const selectedDestination = ((_getLinkDestinations$ = getLinkDestinations().find(destination => destination.url === urlInput)) === null || _getLinkDestinations$ === void 0 ? void 0 : _getLinkDestinations$.linkDestination) || LINK_DESTINATION_CUSTOM;
onChangeUrl({
href: urlInput,
linkDestination: selectedDestination
});
}
stopEditLink();
setUrlInput(null);
event.preventDefault();
};
});
const onLinkRemove = (0, _element.useCallback)(() => {
onChangeUrl({
linkDestination: LINK_DESTINATION_NONE,
href: ''
});
});
const getLinkDestinations = () => {
const linkDestinations = [{
linkDestination: LINK_DESTINATION_MEDIA,
title: (0, _i18n.__)('Media File'),
url: mediaType === 'image' ? mediaUrl : undefined,
icon
}];
if (mediaType === 'image' && mediaLink) {
linkDestinations.push({
linkDestination: LINK_DESTINATION_ATTACHMENT,
title: (0, _i18n.__)('Attachment Page'),
url: mediaType === 'image' ? mediaLink : undefined,
icon: (0, _element.createElement)(_components.SVG, {
viewBox: "0 0 24 24",
xmlns: "http://www.w3.org/2000/svg"
}, (0, _element.createElement)(_components.Path, {
d: "M0 0h24v24H0V0z",
fill: "none"
}), (0, _element.createElement)(_components.Path, {
d: "M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6z"
}))
});
}
return linkDestinations;
};
const onSetHref = value => {
const linkDestinations = getLinkDestinations();
let linkDestinationInput;
if (!value) {
linkDestinationInput = LINK_DESTINATION_NONE;
} else {
linkDestinationInput = ((0, _lodash.find)(linkDestinations, 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 = (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_components.ToggleControl, {
label: (0, _i18n.__)('Open in new tab'),
onChange: onSetNewTab,
checked: linkTarget === '_blank'
}), (0, _element.createElement)(_components.TextControl, {
label: (0, _i18n.__)('Link Rel'),
value: removeNewTabRel(rel) || '',
onChange: onSetLinkRel
}), (0, _element.createElement)(_components.TextControl, {
label: (0, _i18n.__)('Link CSS Class'),
value: linkClass || '',
onChange: onSetLinkClass
}));
const linkEditorValue = urlInput !== null ? urlInput : url;
const urlLabel = ((0, _lodash.find)(getLinkDestinations(), ['linkDestination', linkDestination]) || {}).title;
return (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_components.ToolbarButton, {
icon: _icons.link,
className: "components-toolbar__control",
label: url ? (0, _i18n.__)('Edit link') : (0, _i18n.__)('Insert link'),
"aria-expanded": isOpen,
onClick: openLinkUI
}), isOpen && (0, _element.createElement)(_index.default, {
onFocusOutside: onFocusOutside(),
onClose: closeLinkUI,
renderSettings: () => advancedOptions,
additionalControls: !linkEditorValue && (0, _element.createElement)(_components.NavigableMenu, null, (0, _lodash.map)(getLinkDestinations(), link => (0, _element.createElement)(_components.MenuItem, {
key: link.linkDestination,
icon: link.icon,
onClick: () => {
setUrlInput(null);
onSetHref(link.url);
stopEditLink();
}
}, link.title)))
}, (!url || isEditingLink) && (0, _element.createElement)(_index.default.LinkEditor, {
className: "block-editor-format-toolbar__link-container-content",
value: linkEditorValue,
onChangeInputValue: setUrlInput,
onSubmit: onSubmitLinkChange(),
autocompleteRef: autocompleteRef
}), url && !isEditingLink && (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_index.default.LinkViewer, {
className: "block-editor-format-toolbar__link-container-content",
url: url,
onEditLinkClick: startEditLink,
urlLabel: urlLabel
}), (0, _element.createElement)(_components.Button, {
icon: _icons.close,
label: (0, _i18n.__)('Remove link'),
onClick: onLinkRemove
}))));
};
exports.__experimentalImageURLInputUI = ImageURLInputUI;
//# sourceMappingURL=image-url-input-ui.js.map