UNPKG

@atlaskit/editor-plugin-quick-insert

Version:

Quick insert plugin for @atlaskit/editor-core

72 lines (70 loc) • 3.01 kB
import { logException } from '@atlaskit/editor-common/monitoring/error'; import { quickInsertProviderMenuItemKey } from '@atlaskit/editor-common/quick-insert/get-provider-menu-item-key'; import { defaultIsRecommendedItem } from '@atlaskit/editor-common/quick-insert/is-recommended-item'; import { isMenuFooterSectionKey } from '@atlaskit/editor-common/type-ahead-is-menu-footer-section-key'; import { isSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-is-section-overflow-item-key'; export const MAX_RECOMMENDED_ITEMS = 5; const isRecommendationCandidate = component => component.type === 'menu-item' && !isSectionOverflowItemKey(component.key) && !component.parents.some(parent => isMenuFooterSectionKey(parent.key)); /** Normalises a consumer-supplied limit to the supported number of recommended items. */ export const resolveMaxRecommendedItems = maxRecommendedItems => { if (maxRecommendedItems === undefined || !Number.isFinite(maxRecommendedItems)) { return MAX_RECOMMENDED_ITEMS; } if (maxRecommendedItems > MAX_RECOMMENDED_ITEMS) { void logException(new Error('Quick Insert maxRecommendedItems exceeds the supported maximum'), { location: 'editor-plugin-quick-insert/getRecommendedComponents' }); } return Math.min(Math.max(Math.floor(maxRecommendedItems), 1), MAX_RECOMMENDED_ITEMS); }; export const getRecommendedComponents = ({ components, context, isRecommendedItem = defaultIsRecommendedItem, maxRecommendedItems }) => { return components.filter(isRecommendationCandidate).flatMap((component, index) => { var _component$isHidden; // Provider items are namespaced in the registry; consumers rank them by their source key. const result = isRecommendedItem({ itemKey: quickInsertProviderMenuItemKey.getSourceKey(component.key) }); if (result === null) { return []; } if (Number.isNaN(result.rank)) { void logException(new Error('Invalid Quick Insert recommended item rank'), { location: 'editor-plugin-quick-insert/getRecommendedComponents' }); return []; } if ((_component$isHidden = component.isHidden) !== null && _component$isHidden !== void 0 && _component$isHidden.call(component, { surfaceContext: context })) { return []; } return [{ component, index, rank: result.rank }]; }).sort((first, second) => first.rank === second.rank ? first.index - second.index : first.rank - second.rank).slice(0, resolveMaxRecommendedItems(maxRecommendedItems)).map(({ component }) => component); }; /** * Resolves the Recommended section for a browse-mode menu. Callers memoise per components array, * so the resolver itself keeps no state. */ export const createRecommendedItemsResolver = ({ isRecommendedItem, maxRecommendedItems }) => ({ components, surfaceContext }) => surfaceContext ? getRecommendedComponents({ components, context: surfaceContext, isRecommendedItem, maxRecommendedItems }) : [];