@wordpress/block-library
Version:
Block library for the WordPress editor.
239 lines (216 loc) • 7.26 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { createElement, Fragment } from "@wordpress/element";
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useCallback, useEffect, useState, useRef } from '@wordpress/element';
import { Button, ButtonGroup, PanelBody, TextControl, ToolbarButton, Popover } from '@wordpress/components';
import { BlockControls, InspectorControls, RichText, useBlockProps, __experimentalUseBorderProps as useBorderProps, __experimentalUseColorProps as useColorProps, __experimentalGetSpacingClassesAndStyles as useSpacingProps, __experimentalLinkControl as LinkControl, __experimentalGetElementClassName } from '@wordpress/block-editor';
import { displayShortcut, isKeyboardEvent } from '@wordpress/keycodes';
import { link, linkOff } from '@wordpress/icons';
import { createBlock } from '@wordpress/blocks';
import { useMergeRefs } from '@wordpress/compose';
const NEW_TAB_REL = 'noreferrer noopener';
function WidthPanel(_ref) {
let {
selectedWidth,
setAttributes
} = _ref;
function handleChange(newWidth) {
// Check if we are toggling the width off
const width = selectedWidth === newWidth ? undefined : newWidth; // Update attributes.
setAttributes({
width
});
}
return createElement(PanelBody, {
title: __('Width settings')
}, createElement(ButtonGroup, {
"aria-label": __('Button width')
}, [25, 50, 75, 100].map(widthValue => {
return createElement(Button, {
key: widthValue,
isSmall: true,
variant: widthValue === selectedWidth ? 'primary' : undefined,
onClick: () => handleChange(widthValue)
}, widthValue, "%");
})));
}
function ButtonEdit(props) {
var _style$border;
const {
attributes,
setAttributes,
className,
isSelected,
onReplace,
mergeBlocks
} = props;
const {
linkTarget,
placeholder,
rel,
style,
text,
url,
width
} = attributes;
const onSetLinkRel = useCallback(value => {
setAttributes({
rel: value
});
}, [setAttributes]);
function onToggleOpenInNewTab(value) {
const newLinkTarget = value ? '_blank' : undefined;
let updatedRel = rel;
if (newLinkTarget && !rel) {
updatedRel = NEW_TAB_REL;
} else if (!newLinkTarget && rel === NEW_TAB_REL) {
updatedRel = undefined;
}
setAttributes({
linkTarget: newLinkTarget,
rel: updatedRel
});
}
function setButtonText(newText) {
// Remove anchor tags from button text content.
setAttributes({
text: newText.replace(/<\/?a[^>]*>/g, '')
});
}
function onKeyDown(event) {
if (isKeyboardEvent.primary(event, 'k')) {
startEditing(event);
} else if (isKeyboardEvent.primaryShift(event, 'k')) {
var _richTextRef$current;
unlink();
(_richTextRef$current = richTextRef.current) === null || _richTextRef$current === void 0 ? void 0 : _richTextRef$current.focus();
}
} // Use internal state instead of a ref to make sure that the component
// re-renders when the popover's anchor updates.
const [popoverAnchor, setPopoverAnchor] = useState(null);
const borderProps = useBorderProps(attributes);
const colorProps = useColorProps(attributes);
const spacingProps = useSpacingProps(attributes);
const ref = useRef();
const richTextRef = useRef();
const blockProps = useBlockProps({
ref: useMergeRefs([setPopoverAnchor, ref]),
onKeyDown
});
const [isEditingURL, setIsEditingURL] = useState(false);
const isURLSet = !!url;
const opensInNewTab = linkTarget === '_blank';
function startEditing(event) {
event.preventDefault();
setIsEditingURL(true);
}
function unlink() {
setAttributes({
url: undefined,
linkTarget: undefined,
rel: undefined
});
setIsEditingURL(false);
}
useEffect(() => {
if (!isSelected) {
setIsEditingURL(false);
}
}, [isSelected]);
return createElement(Fragment, null, createElement("div", _extends({}, blockProps, {
className: classnames(blockProps.className, {
[`has-custom-width wp-block-button__width-${width}`]: width,
[`has-custom-font-size`]: blockProps.style.fontSize
})
}), createElement(RichText, {
ref: richTextRef,
"aria-label": __('Button text'),
placeholder: placeholder || __('Add text…'),
value: text,
onChange: value => setButtonText(value),
withoutInteractiveFormatting: true,
className: classnames(className, 'wp-block-button__link', colorProps.className, borderProps.className, {
// For backwards compatibility add style that isn't
// provided via block support.
'no-border-radius': (style === null || style === void 0 ? void 0 : (_style$border = style.border) === null || _style$border === void 0 ? void 0 : _style$border.radius) === 0
}, __experimentalGetElementClassName('button')),
style: { ...borderProps.style,
...colorProps.style,
...spacingProps.style
},
onSplit: value => createBlock('core/button', { ...attributes,
text: value
}),
onReplace: onReplace,
onMerge: mergeBlocks,
identifier: "text"
})), createElement(BlockControls, {
group: "block"
}, !isURLSet && createElement(ToolbarButton, {
name: "link",
icon: link,
title: __('Link'),
shortcut: displayShortcut.primary('k'),
onClick: startEditing
}), isURLSet && createElement(ToolbarButton, {
name: "link",
icon: linkOff,
title: __('Unlink'),
shortcut: displayShortcut.primaryShift('k'),
onClick: unlink,
isActive: true
})), isSelected && (isEditingURL || isURLSet) && createElement(Popover, {
position: "bottom center",
onClose: () => {
var _richTextRef$current2;
setIsEditingURL(false);
(_richTextRef$current2 = richTextRef.current) === null || _richTextRef$current2 === void 0 ? void 0 : _richTextRef$current2.focus();
},
anchor: popoverAnchor,
focusOnMount: isEditingURL ? 'firstElement' : false,
__unstableSlotName: '__unstable-block-tools-after',
shift: true
}, createElement(LinkControl, {
className: "wp-block-navigation-link__inline-link-input",
value: {
url,
opensInNewTab
},
onChange: _ref2 => {
let {
url: newURL = '',
opensInNewTab: newOpensInNewTab
} = _ref2;
setAttributes({
url: newURL
});
if (opensInNewTab !== newOpensInNewTab) {
onToggleOpenInNewTab(newOpensInNewTab);
}
},
onRemove: () => {
var _richTextRef$current3;
unlink();
(_richTextRef$current3 = richTextRef.current) === null || _richTextRef$current3 === void 0 ? void 0 : _richTextRef$current3.focus();
},
forceIsEditingLink: isEditingURL
})), createElement(InspectorControls, null, createElement(WidthPanel, {
selectedWidth: width,
setAttributes: setAttributes
})), createElement(InspectorControls, {
__experimentalGroup: "advanced"
}, createElement(TextControl, {
label: __('Link rel'),
value: rel || '',
onChange: onSetLinkRel
})));
}
export default ButtonEdit;
//# sourceMappingURL=edit.js.map