@gechiui/block-editor
Version:
206 lines (181 loc) • 6.51 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _element = require("@gechiui/element");
var _reactNative = require("react-native");
var _data = require("@gechiui/data");
var _blocks = require("@gechiui/blocks");
var _components = require("@gechiui/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");
/**
* External dependencies
*/
/**
* GeChiUI dependencies
*/
/**
* Internal dependencies
*/
const MIN_ITEMS_FOR_SEARCH = 2;
function InserterMenu(_ref) {
let {
onSelect,
onDismiss,
rootClientId,
clientId,
isAppender,
shouldReplaceBlock,
insertionIndex
} = _ref;
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/GeChiUI/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 @gechiui/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 (0, _element.createElement)(_components.BottomSheet, {
isVisible: true,
onClose: onClose,
onKeyboardShow: onKeyboardShow,
onKeyboardHide: onKeyboardHide,
header: (0, _element.createElement)(_element.Fragment, null, showSearchForm && (0, _element.createElement)(_components.SearchControl, {
onChange: onChangeSearch,
value: filterValue
}), showTabs && !filterValue && (0, _element.createElement)(_tabs.default.Control, {
onChangeTab: setTabIndex,
showReusableBlocks: showReusableBlocks
})),
hasNavigation: true,
setMinHeightToMaxHeight: true,
contentStyle: _style.default['inserter-menu__list'],
isFullScreen: isFullScreen,
allowDragIndicator: true
}, (0, _element.createElement)(_components.BottomSheetConsumer, null, _ref2 => {
let {
listProps
} = _ref2;
return (0, _element.createElement)(_reactNative.TouchableHighlight, {
accessible: false,
style: _style.default['inserter-menu__list-wrapper']
}, !showTabs || filterValue ? (0, _element.createElement)(_searchResults.default, {
rootClientId: rootClientId,
filterValue: filterValue,
onSelect: onSelectItem,
listProps: listProps,
isFullScreen: isFullScreen
}) : (0, _element.createElement)(_tabs.default, {
rootClientId: rootClientId,
listProps: listProps,
tabIndex: tabIndex,
onSelect: onSelectItem,
showReusableBlocks: showReusableBlocks
}));
}));
}
var _default = InserterMenu;
exports.default = _default;
//# sourceMappingURL=menu.native.js.map