UNPKG

@wordpress/components

Version:
272 lines (271 loc) 9.31 kB
/** * External dependencies */ import { Platform } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; /** * WordPress dependencies */ import { compose } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; import { isURL, prependHTTP } from '@wordpress/url'; import { useEffect, useState, useRef, useContext, useCallback } from '@wordpress/element'; import { link, external } from '@wordpress/icons'; /** * Internal dependencies */ import BottomSheet from '../bottom-sheet'; import { BottomSheetContext } from '../bottom-sheet/bottom-sheet-context'; import PanelBody from '../../panel/body'; import TextControl from '../../text-control'; import ToggleControl from '../../toggle-control'; import FooterMessageControl from '../../footer-message-control'; import PanelActions from '../../panel/actions'; import LinkRelIcon from './link-rel'; import styles from './style.scss'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; const NEW_TAB_REL = 'noreferrer noopener'; function LinkSettings({ // Control link settings `BottomSheet` visibility isVisible, // Callback that is called on closing bottom sheet onClose, // Function called to set attributes setAttributes, // Callback that is called when url input field is empty onEmptyURL, // Object of available options along with specific, customizable properties. // Available options keys: // * url - uses `TextControl` component to set `attributes.url` // * linkLabel - uses `TextControl` component to set `attributes.label` // * openInNewTab - uses `ToggleControl` component to set `attributes.linkTarget` and `attributes.rel` // * linkRel - uses `TextControl` component to set `attributes.rel` // * footer - uses `FooterMessageControl` component to display message, e.g. about missing functionality // Available properties: // * label - control component label, e.g. `Button Link URL` // * placeholder - control component placeholder, e.g. `Add URL` // * autoFocus (url only) - whether url input should be focused on sheet opening // * autoFill (url only) - whether url input should be filled with url from clipboard // Example: // const options = { // url: { // label: __( 'Button Link URL' ), // placeholder: __( 'Add URL' ), // autoFocus: true, // autoFill: true, // } // } options, // Specifies whether settings should be wrapped into `BottomSheet` withBottomSheet, // Defines buttons which will be displayed below the all options. // It's an array of objects with following properties: // * label - button title // * onPress - callback that is called on pressing button // Example: // const actions = [ // { // label: __( 'Remove link' ), // onPress: () => setAttributes({ url: '' }), // }, // ]; actions, // Specifies whether general `BottomSheet` is opened editorSidebarOpened, // Specifies whether icon should be displayed next to the label showIcon, onLinkCellPressed, urlValue, // Attributes properties url, label = '', linkTarget, rel = '' }) { const [urlInputValue, setUrlInputValue] = useState(''); const [labelInputValue, setLabelInputValue] = useState(''); const [linkRelInputValue, setLinkRelInputValue] = useState(''); const onCloseSettingsSheetConsumed = useRef(false); const prevEditorSidebarOpenedRef = useRef(); const { onHandleClosingBottomSheet } = useContext(BottomSheetContext); useEffect(() => { if (onHandleClosingBottomSheet) { onHandleClosingBottomSheet(onCloseSettingsSheet); } // See https://github.com/WordPress/gutenberg/pull/41166 }, [urlInputValue, labelInputValue, linkRelInputValue]); useEffect(() => { prevEditorSidebarOpenedRef.current = editorSidebarOpened; }); const prevEditorSidebarOpened = prevEditorSidebarOpenedRef.current; useEffect(() => { if (url !== urlInputValue) { setUrlInputValue(url || ''); } // See https://github.com/WordPress/gutenberg/pull/41166 }, [url]); useEffect(() => { setLabelInputValue(label || ''); }, [label]); useEffect(() => { setLinkRelInputValue(rel || ''); }, [rel]); useEffect(() => { const isSettingSheetOpen = isVisible || editorSidebarOpened; if (isSettingSheetOpen) { onCloseSettingsSheetConsumed.current = false; } if (options.url.autoFill && isSettingSheetOpen && !url) { getURLFromClipboard(); } if (prevEditorSidebarOpened && !editorSidebarOpened) { onSetAttributes(); } // See https://github.com/WordPress/gutenberg/pull/41166 }, [editorSidebarOpened, isVisible]); useEffect(() => { if (!urlValue && onEmptyURL) { onEmptyURL(); } if (prependHTTP(urlValue) !== url) { setAttributes({ url: prependHTTP(urlValue) }); } // See https://github.com/WordPress/gutenberg/pull/41166 }, [urlValue]); const onChangeURL = useCallback(value => { if (!value && onEmptyURL) { onEmptyURL(); } setUrlInputValue(value); }, [onEmptyURL]); const onChangeLabel = useCallback(value => { setLabelInputValue(value); }, []); const onSetAttributes = useCallback(() => { const newURL = prependHTTP(urlInputValue); if (url !== newURL || labelInputValue !== label || linkRelInputValue !== rel) { setAttributes({ url: newURL, label: labelInputValue, rel: linkRelInputValue }); } // See https://github.com/WordPress/gutenberg/pull/41166 }, [urlInputValue, labelInputValue, linkRelInputValue, setAttributes]); const onCloseSettingsSheet = useCallback(() => { if (onCloseSettingsSheetConsumed.current) { return; } onCloseSettingsSheetConsumed.current = true; onSetAttributes(); if (onClose) { onClose(); } }, [onClose, onSetAttributes]); const onChangeOpenInNewTab = useCallback(value => { const newLinkTarget = value ? '_blank' : undefined; let updatedRel = linkRelInputValue; if (newLinkTarget && !linkRelInputValue) { updatedRel = NEW_TAB_REL; } else if (!newLinkTarget && linkRelInputValue === NEW_TAB_REL) { updatedRel = undefined; } setAttributes({ linkTarget: newLinkTarget, rel: updatedRel }); }, // See https://github.com/WordPress/gutenberg/pull/41166 [linkRelInputValue]); const onChangeLinkRel = useCallback(value => { setLinkRelInputValue(value); }, []); async function getURLFromClipboard() { const clipboardText = await Clipboard.getString(); if (!clipboardText) { return; } // Check if pasted text is URL. if (!isURL(clipboardText)) { return; } setAttributes({ url: clipboardText }); } function getSettings() { return /*#__PURE__*/_jsxs(_Fragment, { children: [options.url && (onLinkCellPressed ? /*#__PURE__*/_jsx(BottomSheet.LinkCell, { showIcon: showIcon, value: url, valueMask: options.url.valueMask, onPress: onLinkCellPressed }) : /*#__PURE__*/_jsx(TextControl, { icon: showIcon && link, label: options.url.label, value: urlInputValue, valuePlaceholder: options.url.placeholder, onChange: onChangeURL, onSubmit: onCloseSettingsSheet, autoCapitalize: "none", autoCorrect: false // eslint-disable-next-line jsx-a11y/no-autofocus , autoFocus: Platform.OS === 'ios' && options.url.autoFocus, keyboardType: "url" })), options.linkLabel && /*#__PURE__*/_jsx(TextControl, { label: options.linkLabel.label, value: labelInputValue, valuePlaceholder: options.linkLabel.placeholder, onChange: onChangeLabel }), !!urlInputValue && /*#__PURE__*/_jsxs(_Fragment, { children: [options.openInNewTab && /*#__PURE__*/_jsx(ToggleControl, { icon: showIcon && external, label: options.openInNewTab.label, checked: linkTarget === '_blank', onChange: onChangeOpenInNewTab }), options.linkRel && /*#__PURE__*/_jsx(TextControl, { icon: showIcon && LinkRelIcon, label: options.linkRel.label, value: linkRelInputValue, valuePlaceholder: options.linkRel.placeholder, onChange: onChangeLinkRel, onSubmit: onCloseSettingsSheet, autoCapitalize: "none", autoCorrect: false, keyboardType: "default" })] })] }); } if (!withBottomSheet) { return getSettings(); } return /*#__PURE__*/_jsxs(_Fragment, { children: [/*#__PURE__*/_jsx(PanelBody, { style: styles.linkSettingsPanel, children: getSettings() }), options.footer && /*#__PURE__*/_jsx(PanelBody, { style: styles.linkSettingsPanel, children: /*#__PURE__*/_jsx(FooterMessageControl, { label: options.footer.label, separatorType: options.footer.separatorType }) }), actions && /*#__PURE__*/_jsx(PanelActions, { actions: actions })] }); } export default compose([withSelect(select => { const { isEditorSidebarOpened } = select('core/edit-post'); return { editorSidebarOpened: isEditorSidebarOpened() }; })])(LinkSettings); //# sourceMappingURL=index.native.js.map