@wordpress/block-library
Version:
Block library for the WordPress editor.
253 lines (250 loc) • 8.29 kB
JavaScript
/**
* 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