@wordpress/components
Version:
UI components for WordPress.
288 lines (249 loc) • 9.21 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@wordpress/element");
var _reactNative = require("react-native");
var _compose = require("@wordpress/compose");
var _data = require("@wordpress/data");
var _url = require("@wordpress/url");
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"));
/**
* 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 prevEditorSidebarOpenedRef = (0, _element.useRef)();
const {
onHandleClosingBottomSheet
} = (0, _element.useContext)(_bottomSheetContext.BottomSheetContext);
(0, _element.useEffect)(() => {
if (onHandleClosingBottomSheet) {
onHandleClosingBottomSheet(onCloseSettingsSheet);
}
}, [urlInputValue, labelInputValue, linkRelInputValue]);
(0, _element.useEffect)(() => {
prevEditorSidebarOpenedRef.current = editorSidebarOpened;
});
const prevEditorSidebarOpened = prevEditorSidebarOpenedRef.current;
(0, _element.useEffect)(() => {
if (url !== urlInputValue) {
setUrlInputValue(url || '');
}
}, [url]);
(0, _element.useEffect)(() => {
setLabelInputValue(label || '');
}, [label]);
(0, _element.useEffect)(() => {
setLinkRelInputValue(rel || '');
}, [rel]);
(0, _element.useEffect)(() => {
const isSettingSheetOpen = isVisible || editorSidebarOpened;
if (options.url.autoFill && isSettingSheetOpen && !url) {
getURLFromClipboard();
}
if (prevEditorSidebarOpened && !editorSidebarOpened) {
onSetAttributes();
}
}, [editorSidebarOpened, isVisible]);
(0, _element.useEffect)(() => {
if (!urlValue && onEmptyURL) {
onEmptyURL();
}
if ((0, _url.prependHTTP)(urlValue) !== url) {
setAttributes({
url: (0, _url.prependHTTP)(urlValue)
});
}
}, [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
});
}
}, [urlInputValue, labelInputValue, linkRelInputValue, setAttributes]);
const onCloseSettingsSheet = (0, _element.useCallback)(() => {
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
});
}, [linkRelInputValue]);
const onChangeLinkRel = (0, _element.useCallback)(value => {
setLinkRelInputValue(value);
}, []);
async function getURLFromClipboard() {
const clipboardText = await _reactNative.Clipboard.getString();
if (!clipboardText) {
return;
} // Check if pasted text is URL
if (!(0, _url.isURL)(clipboardText)) {
return;
}
setAttributes({
url: clipboardText
});
}
function getSettings() {
return (0, _element.createElement)(_element.Fragment, null, options.url && (onLinkCellPressed ? (0, _element.createElement)(_bottomSheet.default.LinkCell, {
showIcon: showIcon,
value: url,
onPress: onLinkCellPressed
}) : (0, _element.createElement)(_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 && (0, _element.createElement)(_textControl.default, {
label: options.linkLabel.label,
value: labelInputValue,
valuePlaceholder: options.linkLabel.placeholder,
onChange: onChangeLabel
}), !!urlInputValue && (0, _element.createElement)(_element.Fragment, null, options.openInNewTab && (0, _element.createElement)(_toggleControl.default, {
icon: showIcon && _icons.external,
label: options.openInNewTab.label,
checked: linkTarget === '_blank',
onChange: onChangeOpenInNewTab
}), options.linkRel && (0, _element.createElement)(_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 (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_body.default, {
style: _style.default.linkSettingsPanel
}, getSettings()), options.footer && (0, _element.createElement)(_body.default, {
style: _style.default.linkSettingsPanel
}, (0, _element.createElement)(_footerMessageControl.default, {
label: options.footer.label
})), actions && (0, _element.createElement)(_actions.default, {
actions: actions
}));
}
var _default = (0, _compose.compose)([(0, _data.withSelect)(select => {
const {
isEditorSidebarOpened
} = select('core/edit-post');
return {
editorSidebarOpened: isEditorSidebarOpened()
};
})])(LinkSettings);
exports.default = _default;
//# sourceMappingURL=index.native.js.map