UNPKG

@wordpress/format-library

Version:
218 lines (216 loc) 6.32 kB
/** * External dependencies */ import { useNavigation, useRoute } from '@react-navigation/native'; /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { useState, useContext, useEffect, useMemo } from '@wordpress/element'; import { prependHTTP } from '@wordpress/url'; import { BottomSheet, BottomSheetContext } from '@wordpress/components'; import { create, insert, isCollapsed, applyFormat, getTextContent, slice } from '@wordpress/rich-text'; import { external, textColor } from '@wordpress/icons'; /** * Internal dependencies */ import { createLinkFormat, isValidHref } from '../utils'; import linkSettingsScreens from './screens'; import styles from '../modal.scss'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; const LinkSettingsScreen = ({ onRemove, onClose, onChange, speak, value, isActive, activeAttributes, isVisible }) => { const [text, setText] = useState(getTextContent(slice(value))); const [opensInNewWindow, setOpensInNewWindows] = useState(activeAttributes.target === '_blank'); const [linkValues, setLinkValues] = useState({ isActiveLink: isActive, isRemovingLink: false }); const { shouldEnableBottomSheetMaxHeight, onHandleClosingBottomSheet, listProps } = useContext(BottomSheetContext); const navigation = useNavigation(); const route = useRoute(); const { inputValue = activeAttributes.url || '' } = route.params || {}; const onLinkCellPressed = () => { shouldEnableBottomSheetMaxHeight(false); navigation.navigate(linkSettingsScreens.picker, { inputValue }); }; useEffect(() => { onHandleClosingBottomSheet(() => { submit(inputValue, { skipStateUpdates: true }); }); }, [inputValue, opensInNewWindow, text]); useEffect(() => { const { isActiveLink, isRemovingLink } = linkValues; if (!!inputValue && !isActiveLink && isVisible) { submitLink({ shouldCloseBottomSheet: false }); } else if ((inputValue === '' && isActiveLink || isRemovingLink) && isVisible) { removeLink({ shouldCloseBottomSheet: false }); } }, [inputValue, isVisible, linkValues.isActiveLink, linkValues.isRemovingLink]); const clearFormat = ({ skipStateUpdates = false } = {}) => { onChange({ ...value, activeFormats: [] }); if (!skipStateUpdates) { setLinkValues({ isActiveLink: false, isRemovingLink: true }); } }; const submitLink = ({ shouldCloseBottomSheet = true, skipStateUpdates = false } = {}) => { const url = prependHTTP(inputValue); const linkText = text || inputValue; const format = createLinkFormat({ url, opensInNewWindow, text: linkText }); let newAttributes; if (isCollapsed(value) && !isActive) { // Insert link. const toInsert = applyFormat(create({ text: linkText }), format, 0, linkText.length); newAttributes = insert(value, toInsert); } else if (text !== getTextContent(slice(value))) { // Edit text in selected link. const toInsert = applyFormat(create({ text }), format, 0, text.length); newAttributes = insert(value, toInsert, value.start, value.end); } else { // Transform selected text into link. newAttributes = applyFormat(value, format); } // Move selection to end of link. const textLength = newAttributes.text.length; // check for zero width spaces if (newAttributes.end > textLength) { newAttributes.start = textLength; newAttributes.end = textLength; } else { newAttributes.start = newAttributes.end; } newAttributes.activeFormats = []; onChange({ ...newAttributes, needsSelectionUpdate: true }); if (!skipStateUpdates) { setLinkValues({ isActiveLink: true, isRemovingLink: false }); } if (!isValidHref(url)) { speak(__('Warning: the link has been inserted but may have errors. Please test it.'), 'assertive'); } else if (isActive) { speak(__('Link edited.'), 'assertive'); } else { speak(__('Link inserted'), 'assertive'); } if (shouldCloseBottomSheet) { onClose(); } }; const removeLink = ({ shouldCloseBottomSheet = true, skipStateUpdates = false } = {}) => { clearFormat({ skipStateUpdates }); onRemove(); if (shouldCloseBottomSheet) { onClose(); } }; const submit = (submitValue, { skipStateUpdates = false } = {}) => { if (submitValue === '') { removeLink({ skipStateUpdates }); } else { submitLink({ skipStateUpdates }); } }; useEffect(() => { const unsubscribe = navigation.addListener('focus', () => { const { params = {} } = route; if (!text && params.text) { setText(params.text); } }); return unsubscribe; }, [navigation, route.params?.text, text]); return useMemo(() => { const shouldShowLinkOptions = !!inputValue; return /*#__PURE__*/_jsxs(_Fragment, { children: [/*#__PURE__*/_jsx(BottomSheet.LinkCell, { value: inputValue, onPress: onLinkCellPressed }), /*#__PURE__*/_jsx(BottomSheet.Cell, { icon: textColor, label: __('Link text'), value: text, placeholder: __('Add link text'), onChangeValue: setText, onSubmit: submit, separatorType: shouldShowLinkOptions ? undefined : 'none' }), shouldShowLinkOptions && /*#__PURE__*/_jsxs(_Fragment, { children: [/*#__PURE__*/_jsx(BottomSheet.SwitchCell, { icon: external, label: __('Open in new tab'), value: opensInNewWindow, onValueChange: setOpensInNewWindows, separatorType: "fullWidth" }), /*#__PURE__*/_jsx(BottomSheet.Cell, { label: __('Remove link'), labelStyle: styles.clearLinkButton, separatorType: "none", onPress: removeLink })] })] }); }, [inputValue, text, opensInNewWindow, listProps.safeAreaBottomInset]); }; export default LinkSettingsScreen; //# sourceMappingURL=link-settings-screen.native.js.map