UNPKG

@wordpress/block-library

Version:
253 lines (250 loc) 8.29 kB
/** * External dependencies */ import clsx from 'clsx'; /** * WordPress dependencies */ import { DELETE, BACKSPACE, ENTER } from '@wordpress/keycodes'; import { useDispatch, useSelect } from '@wordpress/data'; import { BlockControls, InspectorControls, URLPopover, URLInput, useBlockEditingMode, useBlockProps, store as blockEditorStore } from '@wordpress/block-editor'; import { useState, useRef } from '@wordpress/element'; import { Icon, Button, Dropdown, TextControl, ToolbarButton, __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem, __experimentalInputControlSuffixWrapper as InputControlSuffixWrapper } from '@wordpress/components'; import { useMergeRefs } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; import { keyboardReturn } from '@wordpress/icons'; import { store as blocksStore } from '@wordpress/blocks'; /** * Internal dependencies */ import { getSocialService } from './social-list'; import { useToolsPanelDropdownMenuProps } from '../utils/hooks'; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; const SocialLinkURLPopover = ({ url, setAttributes, setPopover, popoverAnchor, clientId }) => { const { removeBlock } = useDispatch(blockEditorStore); return /*#__PURE__*/_jsx(URLPopover, { anchor: popoverAnchor, "aria-label": __('Edit social link'), onClose: () => { setPopover(false); popoverAnchor?.focus(); }, children: /*#__PURE__*/_jsx("form", { className: "block-editor-url-popover__link-editor", onSubmit: event => { event.preventDefault(); setPopover(false); popoverAnchor?.focus(); }, children: /*#__PURE__*/_jsx("div", { className: "block-editor-url-input", children: /*#__PURE__*/_jsx(URLInput, { value: url, onChange: nextURL => setAttributes({ url: nextURL }), placeholder: __('Enter social link'), label: __('Enter social link'), hideLabelFromVision: true, disableSuggestions: true, onKeyDown: event => { if (!!url || event.defaultPrevented || ![BACKSPACE, DELETE].includes(event.keyCode)) { return; } removeBlock(clientId); }, suffix: /*#__PURE__*/_jsx(InputControlSuffixWrapper, { variant: "control", children: /*#__PURE__*/_jsx(Button, { icon: keyboardReturn, label: __('Apply'), type: "submit", size: "small" }) }) }) }) }) }); }; const SocialLinkEdit = ({ attributes, context, isSelected, setAttributes, clientId, name }) => { const { url, service, label = '', rel } = attributes; const dropdownMenuProps = useToolsPanelDropdownMenuProps(); const { showLabels, iconColor, iconColorValue, iconBackgroundColor, iconBackgroundColorValue } = context; const [showURLPopover, setPopover] = useState(false); const wrapperClasses = clsx('wp-social-link', // Manually adding this class for backwards compatibility of CSS when moving the // blockProps from the li to the button: https://github.com/WordPress/gutenberg/pull/64883 'wp-block-social-link', 'wp-social-link-' + service, { 'wp-social-link__is-incomplete': !url, [`has-${iconColor}-color`]: iconColor, [`has-${iconBackgroundColor}-background-color`]: iconBackgroundColor }); // 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 isContentOnlyMode = useBlockEditingMode() === 'contentOnly'; const { activeVariation } = useSelect(select => { const { getActiveBlockVariation } = select(blocksStore); return { activeVariation: getActiveBlockVariation(name, attributes) }; }, [name, attributes]); const { icon, label: socialLinkName } = getSocialService(activeVariation); // The initial label (ie. the link text) is an empty string. // We want to prevent empty links so that the link text always fallbacks to // the social name, even when users enter and save an empty string or only // spaces. The PHP render callback fallbacks to the social name as well. const socialLinkText = label.trim() === '' ? socialLinkName : label; const ref = useRef(); const blockProps = useBlockProps({ className: 'wp-block-social-link-anchor', ref: useMergeRefs([setPopoverAnchor, ref]), onClick: () => setPopover(true), onKeyDown: event => { if (event.keyCode === ENTER) { event.preventDefault(); setPopover(true); } } }); return /*#__PURE__*/_jsxs(_Fragment, { children: [isContentOnlyMode && showLabels && /*#__PURE__*/ // Add an extra control to modify the label attribute when content only mode is active. // With content only mode active, the inspector is hidden, so users need another way // to edit this attribute. _jsx(BlockControls, { group: "other", children: /*#__PURE__*/_jsx(Dropdown, { popoverProps: { placement: 'bottom-start' }, renderToggle: ({ isOpen, onToggle }) => /*#__PURE__*/_jsx(ToolbarButton, { onClick: onToggle, "aria-haspopup": "true", "aria-expanded": isOpen, children: __('Text') }), renderContent: () => /*#__PURE__*/_jsx(TextControl, { __next40pxDefaultSize: true, __nextHasNoMarginBottom: true, className: "wp-block-social-link__toolbar_content_text", label: __('Text'), help: __('Provide a text label or use the default.'), value: label, onChange: value => setAttributes({ label: value }), placeholder: socialLinkName }) }) }), /*#__PURE__*/_jsx(InspectorControls, { children: /*#__PURE__*/_jsx(ToolsPanel, { label: __('Settings'), resetAll: () => { setAttributes({ label: undefined }); }, dropdownMenuProps: dropdownMenuProps, children: /*#__PURE__*/_jsx(ToolsPanelItem, { isShownByDefault: true, label: __('Text'), hasValue: () => !!label, onDeselect: () => { setAttributes({ label: undefined }); }, children: /*#__PURE__*/_jsx(TextControl, { __next40pxDefaultSize: true, __nextHasNoMarginBottom: true, label: __('Text'), help: __('The text is visible when enabled from the parent Social Icons block.'), value: label, onChange: value => setAttributes({ label: value }), placeholder: socialLinkName }) }) }) }), /*#__PURE__*/_jsx(InspectorControls, { group: "advanced", children: /*#__PURE__*/_jsx(TextControl, { __next40pxDefaultSize: true, __nextHasNoMarginBottom: true, label: __('Link rel'), value: rel || '', onChange: value => setAttributes({ rel: value }) }) }), /*#__PURE__*/_jsxs("li", { role: "presentation", className: wrapperClasses, style: { color: iconColorValue, backgroundColor: iconBackgroundColorValue }, children: [/*#__PURE__*/_jsxs("button", { "aria-haspopup": "dialog", ...blockProps, role: "button", children: [/*#__PURE__*/_jsx(Icon, { icon: icon }), /*#__PURE__*/_jsx("span", { className: clsx('wp-block-social-link-label', { 'screen-reader-text': !showLabels }), children: socialLinkText })] }), isSelected && showURLPopover && /*#__PURE__*/_jsx(SocialLinkURLPopover, { url: url, setAttributes: setAttributes, setPopover: setPopover, popoverAnchor: popoverAnchor, clientId: clientId })] })] }); }; export default SocialLinkEdit; //# sourceMappingURL=edit.js.map