@wordpress/block-editor
Version:
189 lines (185 loc) • 6.68 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _reactNative = require("react-native");
var _element = require("@wordpress/element");
var _data = require("@wordpress/data");
var _blocks = require("@wordpress/blocks");
var _components = require("@wordpress/components");
var _searchResults = _interopRequireDefault(require("./search-results"));
var _store = require("../../store");
var _tabs = _interopRequireDefault(require("./tabs"));
var _style = _interopRequireDefault(require("./style.scss"));
var _utils = require("./utils");
var _jsxRuntime = require("react/jsx-runtime");
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const MIN_ITEMS_FOR_SEARCH = 2;
function InserterMenu({
onSelect,
onDismiss,
rootClientId,
clientId,
isAppender,
shouldReplaceBlock,
insertionIndex
}) {
const [filterValue, setFilterValue] = (0, _element.useState)('');
const [showTabs, setShowTabs] = (0, _element.useState)(true);
const [tabIndex, setTabIndex] = (0, _element.useState)(0);
const isIOS = _reactNative.Platform.OS === 'ios';
const {
showInsertionPoint,
hideInsertionPoint,
clearSelectedBlock,
insertBlock,
removeBlock,
resetBlocks,
insertDefaultBlock
} = (0, _data.useDispatch)(_store.store);
const {
items,
destinationRootClientId,
showReusableBlocks
} = (0, _data.useSelect)(select => {
const {
getInserterItems,
getBlockRootClientId,
getBlockSelectionEnd
} = select(_store.store);
let targetRootClientId = rootClientId;
if (!targetRootClientId && !clientId && !isAppender) {
const end = getBlockSelectionEnd();
if (end) {
targetRootClientId = getBlockRootClientId(end) || undefined;
}
}
const allItems = getInserterItems(targetRootClientId);
const reusableBlockItems = (0, _utils.filterInserterItems)(allItems, {
onlyReusable: true
});
return {
items: allItems,
destinationRootClientId: targetRootClientId,
showReusableBlocks: !!reusableBlockItems.length
};
});
const {
getBlockOrder,
getBlockCount
} = (0, _data.useSelect)(_store.store);
(0, _element.useEffect)(() => {
// Show/Hide insertion point on Mount/Dismount
if (shouldReplaceBlock) {
const count = getBlockCount();
// Check if there is a rootClientId because that means it is a nested replaceable block
// and we don't want to clear/reset all blocks.
if (count === 1 && !rootClientId) {
// Removing the last block is not possilble with `removeBlock` action.
// It always inserts a default block if the last of the blocks have been removed.
clearSelectedBlock();
resetBlocks([]);
} else {
const blockToReplace = getBlockOrder(destinationRootClientId)[insertionIndex];
removeBlock(blockToReplace, false);
}
}
showInsertionPoint(destinationRootClientId, insertionIndex);
return hideInsertionPoint;
}, []);
const onClose = (0, _element.useCallback)(() => {
// If should replace but didn't insert any block
// re-insert default block.
if (shouldReplaceBlock) {
insertDefaultBlock({}, destinationRootClientId, insertionIndex);
}
onDismiss();
}, [shouldReplaceBlock, destinationRootClientId, insertionIndex]);
const onInsert = (0, _element.useCallback)(item => {
const {
name,
initialAttributes,
innerBlocks
} = item;
const newBlock = (0, _blocks.createBlock)(name, initialAttributes, innerBlocks);
insertBlock(newBlock, insertionIndex, destinationRootClientId, true, {
source: 'inserter_menu'
});
}, [insertBlock, destinationRootClientId, insertionIndex]);
const onSelectItem = (0, _element.useCallback)(item => {
// Avoid a focus loop, see https://github.com/WordPress/gutenberg/issues/30562
if (_reactNative.Platform.OS === 'ios') {
_reactNative.AccessibilityInfo.isScreenReaderEnabled().then(enabled => {
// In testing, the bug focus loop needed a longer timeout when VoiceOver was enabled.
const timeout = enabled ? 200 : 100;
// eslint-disable-next-line @wordpress/react-no-unsafe-timeout
setTimeout(() => {
onInsert(item);
}, timeout);
});
} else {
onInsert(item);
}
onSelect(item);
}, [onInsert, onSelect]);
const onChangeSearch = (0, _element.useCallback)(value => {
setFilterValue(value);
}, [setFilterValue]);
const onKeyboardShow = (0, _element.useCallback)(() => setShowTabs(false), [setShowTabs]);
const onKeyboardHide = (0, _element.useCallback)(() => setShowTabs(true), [setShowTabs]);
const showSearchForm = items.length > MIN_ITEMS_FOR_SEARCH;
const isFullScreen = !isIOS && showSearchForm;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.BottomSheet, {
isVisible: true,
onClose: onClose,
onKeyboardShow: onKeyboardShow,
onKeyboardHide: onKeyboardHide,
header: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [showSearchForm && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.SearchControl, {
onChange: onChangeSearch,
value: filterValue
}), showTabs && !filterValue && /*#__PURE__*/(0, _jsxRuntime.jsx)(_tabs.default.Control, {
onChangeTab: setTabIndex,
showReusableBlocks: showReusableBlocks
})]
}),
hasNavigation: true,
setMinHeightToMaxHeight: true,
contentStyle: _style.default['inserter-menu__list'],
isFullScreen: isFullScreen,
allowDragIndicator: true,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.BottomSheetConsumer, {
children: ({
listProps
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableHighlight, {
accessible: false,
style: _style.default['inserter-menu__list-wrapper'],
children: !showTabs || filterValue ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_searchResults.default, {
rootClientId: rootClientId,
filterValue: filterValue,
onSelect: onSelectItem,
listProps: listProps,
isFullScreen: isFullScreen
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_tabs.default, {
rootClientId: rootClientId,
listProps: listProps,
tabIndex: tabIndex,
onSelect: onSelectItem,
showReusableBlocks: showReusableBlocks
})
})
})
});
}
var _default = exports.default = InserterMenu;
//# sourceMappingURL=menu.native.js.map