@wordpress/components
Version:
UI components for WordPress.
281 lines (277 loc) • 10.4 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _reactNative = require("react-native");
var _clipboard = _interopRequireDefault(require("@react-native-clipboard/clipboard"));
var _compose = require("@wordpress/compose");
var _data = require("@wordpress/data");
var _url = require("@wordpress/url");
var _element = require("@wordpress/element");
var _icons = require("@wordpress/icons");
var _bottomSheet = _interopRequireDefault(require("../bottom-sheet"));
var _bottomSheetContext = require("../bottom-sheet/bottom-sheet-context");
var _body = _interopRequireDefault(require("../../panel/body"));
var _textControl = _interopRequireDefault(require("../../text-control"));
var _toggleControl = _interopRequireDefault(require("../../toggle-control"));
var _footerMessageControl = _interopRequireDefault(require("../../footer-message-control"));
var _actions = _interopRequireDefault(require("../../panel/actions"));
var _linkRel = _interopRequireDefault(require("./link-rel"));
var _style = _interopRequireDefault(require("./style.scss"));
var _jsxRuntime = require("react/jsx-runtime");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
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] = (0, _element.useState)('');
const [labelInputValue, setLabelInputValue] = (0, _element.useState)('');
const [linkRelInputValue, setLinkRelInputValue] = (0, _element.useState)('');
const onCloseSettingsSheetConsumed = (0, _element.useRef)(false);
const prevEditorSidebarOpenedRef = (0, _element.useRef)();
const {
onHandleClosingBottomSheet
} = (0, _element.useContext)(_bottomSheetContext.BottomSheetContext);
(0, _element.useEffect)(() => {
if (onHandleClosingBottomSheet) {
onHandleClosingBottomSheet(onCloseSettingsSheet);
}
// See https://github.com/WordPress/gutenberg/pull/41166
}, [urlInputValue, labelInputValue, linkRelInputValue]);
(0, _element.useEffect)(() => {
prevEditorSidebarOpenedRef.current = editorSidebarOpened;
});
const prevEditorSidebarOpened = prevEditorSidebarOpenedRef.current;
(0, _element.useEffect)(() => {
if (url !== urlInputValue) {
setUrlInputValue(url || '');
}
// See https://github.com/WordPress/gutenberg/pull/41166
}, [url]);
(0, _element.useEffect)(() => {
setLabelInputValue(label || '');
}, [label]);
(0, _element.useEffect)(() => {
setLinkRelInputValue(rel || '');
}, [rel]);
(0, _element.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]);
(0, _element.useEffect)(() => {
if (!urlValue && onEmptyURL) {
onEmptyURL();
}
if ((0, _url.prependHTTP)(urlValue) !== url) {
setAttributes({
url: (0, _url.prependHTTP)(urlValue)
});
}
// See https://github.com/WordPress/gutenberg/pull/41166
}, [urlValue]);
const onChangeURL = (0, _element.useCallback)(value => {
if (!value && onEmptyURL) {
onEmptyURL();
}
setUrlInputValue(value);
}, [onEmptyURL]);
const onChangeLabel = (0, _element.useCallback)(value => {
setLabelInputValue(value);
}, []);
const onSetAttributes = (0, _element.useCallback)(() => {
const newURL = (0, _url.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 = (0, _element.useCallback)(() => {
if (onCloseSettingsSheetConsumed.current) {
return;
}
onCloseSettingsSheetConsumed.current = true;
onSetAttributes();
if (onClose) {
onClose();
}
}, [onClose, onSetAttributes]);
const onChangeOpenInNewTab = (0, _element.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 = (0, _element.useCallback)(value => {
setLinkRelInputValue(value);
}, []);
async function getURLFromClipboard() {
const clipboardText = await _clipboard.default.getString();
if (!clipboardText) {
return;
}
// Check if pasted text is URL.
if (!(0, _url.isURL)(clipboardText)) {
return;
}
setAttributes({
url: clipboardText
});
}
function getSettings() {
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [options.url && (onLinkCellPressed ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_bottomSheet.default.LinkCell, {
showIcon: showIcon,
value: url,
valueMask: options.url.valueMask,
onPress: onLinkCellPressed
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_textControl.default, {
icon: showIcon && _icons.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: _reactNative.Platform.OS === 'ios' && options.url.autoFocus,
keyboardType: "url"
})), options.linkLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_textControl.default, {
label: options.linkLabel.label,
value: labelInputValue,
valuePlaceholder: options.linkLabel.placeholder,
onChange: onChangeLabel
}), !!urlInputValue && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [options.openInNewTab && /*#__PURE__*/(0, _jsxRuntime.jsx)(_toggleControl.default, {
icon: showIcon && _icons.external,
label: options.openInNewTab.label,
checked: linkTarget === '_blank',
onChange: onChangeOpenInNewTab
}), options.linkRel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_textControl.default, {
icon: showIcon && _linkRel.default,
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__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_body.default, {
style: _style.default.linkSettingsPanel,
children: getSettings()
}), options.footer && /*#__PURE__*/(0, _jsxRuntime.jsx)(_body.default, {
style: _style.default.linkSettingsPanel,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_footerMessageControl.default, {
label: options.footer.label,
separatorType: options.footer.separatorType
})
}), actions && /*#__PURE__*/(0, _jsxRuntime.jsx)(_actions.default, {
actions: actions
})]
});
}
var _default = exports.default = (0, _compose.compose)([(0, _data.withSelect)(select => {
const {
isEditorSidebarOpened
} = select('core/edit-post');
return {
editorSidebarOpened: isEditorSidebarOpened()
};
})])(LinkSettings);
//# sourceMappingURL=index.native.js.map