UNPKG

@wordpress/block-library

Version:
239 lines (216 loc) 7.26 kB
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