@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
323 lines (321 loc) • 11.2 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
/** @jsx jsx */
import React, { memo, useCallback, useEffect, useState } from 'react';
import { css, jsx } from '@emotion/react';
import { FormattedMessage } from 'react-intl-next';
import { withAnalyticsContext, withAnalyticsEvents } from '@atlaskit/analytics-next';
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent } from '../../analytics';
import { DEVICE_BREAKPOINT_NUMBERS, GRID_SIZE, INLINE_SIDEBAR_HEIGHT, SIDEBAR_HEADING_WRAPPER_HEIGHT, SIDEBAR_WIDTH } from '../constants';
import useContainerWidth from '../hooks/use-container-width';
import useSelectAndFocusOnArrowNavigation from '../hooks/use-select-and-focus-on-arrow-navigation';
import { ViewMore } from '../ViewMore';
import CategoryList from './CategoryList';
import ElementList from './ElementList/ElementList';
import ElementSearch from './ElementSearch';
var wrapper = css({
width: '100%',
maxHeight: 'inherit',
overflow: 'hidden'
});
var baseBrowserContainerStyles = css({
display: 'flex',
height: '100%',
minHeight: '-webkit-fill-available'
});
var mobileElementBrowserContainer = css(baseBrowserContainerStyles, {
flexDirection: 'column'
});
var elementBrowserContainer = css(baseBrowserContainerStyles, {
flexDirection: 'row'
});
var baseSidebarStyles = css({
display: 'flex',
flexDirection: 'column',
overflowX: 'auto',
overflowY: 'hidden'
});
var mobileSideBar = css(baseSidebarStyles, {
flex: "0 0 ".concat(INLINE_SIDEBAR_HEIGHT),
padding: "var(--ds-space-150, 12px)".concat(" ", "var(--ds-space-150, 12px)", " 0 ", "var(--ds-space-150, 12px)")
});
var mobileSideBarShowCategories = css({
flex: '0 0 auto'
});
var sideBar = css(baseSidebarStyles, {
flex: "0 0 'auto'"
});
var sideBarShowCategories = css(baseSidebarStyles, {
flex: "0 0 ".concat(SIDEBAR_WIDTH)
});
var sidebarHeading = css({
flex: "0 0 ".concat(SIDEBAR_HEADING_WRAPPER_HEIGHT),
display: 'inline-flex',
alignItems: 'center',
paddingLeft: "var(--ds-space-150, 12px)",
fontWeight: 700
});
var mobileMainContent = css({
flex: '1 1 auto',
display: 'flex',
flexDirection: 'column',
overflowY: 'auto',
height: '100%'
});
var mainContent = css(mobileMainContent, {
marginLeft: "var(--ds-space-200, 16px)",
height: 'auto'
});
var searchContainer = css({
paddingBottom: "var(--ds-space-200, 16px)"
});
var mobileCategoryListWrapper = css({
display: 'flex',
overflowX: 'auto',
padding: "var(--ds-space-200, 8px)".concat(" 0 ", "var(--ds-space-200, 16px)", " 0"),
minHeight: "".concat(GRID_SIZE * 4, "px"),
overflow: '-moz-scrollbars-none',
'::-webkit-scrollbar': {
display: 'none'
},
scrollbarWidth: 'none',
MsOverflowStyle: 'none'
});
var categoryListWrapper = css(mobileCategoryListWrapper, {
padding: 0,
marginTop: "var(--ds-space-200, 24px)",
flexDirection: 'column'
});
function StatelessElementBrowser(props) {
var items = props.items,
onSelectItem = props.onSelectItem,
onInsertItem = props.onInsertItem,
viewMoreItem = props.viewMoreItem;
var _useContainerWidth = useContainerWidth(),
containerWidth = _useContainerWidth.containerWidth,
ContainerWidthMonitor = _useContainerWidth.ContainerWidthMonitor;
var _useState = useState(1),
_useState2 = _slicedToArray(_useState, 2),
columnCount = _useState2[0],
setColumnCount = _useState2[1];
var _useSelectAndFocusOnA = useSelectAndFocusOnArrowNavigation(items.length - 1, columnCount, !!viewMoreItem),
selectedItemIndex = _useSelectAndFocusOnA.selectedItemIndex,
focusedItemIndex = _useSelectAndFocusOnA.focusedItemIndex,
setFocusedItemIndex = _useSelectAndFocusOnA.setFocusedItemIndex,
focusOnSearch = _useSelectAndFocusOnA.focusOnSearch,
focusOnViewMore = _useSelectAndFocusOnA.focusOnViewMore,
onKeyDown = _useSelectAndFocusOnA.onKeyDown,
setFocusOnSearch = _useSelectAndFocusOnA.setFocusOnSearch;
useEffect(function () {
fireAnalyticsEvent(props.createAnalyticsEvent)({
payload: {
action: ACTION.OPENED,
actionSubject: ACTION_SUBJECT.ELEMENT_BROWSER,
eventType: EVENT_TYPE.UI,
attributes: {
mode: props.mode
}
}
});
return function () {
fireAnalyticsEvent(props.createAnalyticsEvent)({
payload: {
action: ACTION.CLOSED,
actionSubject: ACTION_SUBJECT.ELEMENT_BROWSER,
eventType: EVENT_TYPE.UI,
attributes: {
mode: props.mode
}
}
});
};
}, [props.createAnalyticsEvent, props.mode]);
/* Only for hitting enter to select item when focused on search bar,
* The actual enter key press is handled on individual items level.
*/
var selectedItem = selectedItemIndex !== undefined ? items[selectedItemIndex] : null;
var onItemsEnterKeyPress = useCallback(function (e) {
if (e.key !== 'Enter') {
return;
}
if (onInsertItem && selectedItem != null) {
onInsertItem(selectedItem);
}
e.preventDefault();
}, [onInsertItem, selectedItem]);
/**
* On arrow key selection and clicks the selectedItemIndex will change.
* Making sure to update parent component.
*/
useEffect(function () {
if (onSelectItem && selectedItem != null) {
onSelectItem(selectedItem);
}
}, [onSelectItem, selectedItem]);
return jsx("div", {
css: wrapper,
"data-testid": "element-browser"
}, jsx(ContainerWidthMonitor, null), containerWidth < DEVICE_BREAKPOINT_NUMBERS.medium ? jsx(MobileBrowser, _extends({}, props, {
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
focusOnSearch: focusOnSearch,
setColumnCount: setColumnCount,
setFocusOnSearch: setFocusOnSearch,
onKeyPress: onItemsEnterKeyPress,
onKeyDown: onKeyDown,
viewMoreItem: viewMoreItem,
focusOnViewMore: focusOnViewMore
})) : jsx(DesktopBrowser, _extends({}, props, {
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
focusOnSearch: focusOnSearch,
setColumnCount: setColumnCount,
setFocusOnSearch: setFocusOnSearch,
onKeyPress: onItemsEnterKeyPress,
onKeyDown: onKeyDown
})));
}
function MobileBrowser(_ref) {
var showCategories = _ref.showCategories,
showSearch = _ref.showSearch,
onSearch = _ref.onSearch,
mode = _ref.mode,
categories = _ref.categories,
onSelectCategory = _ref.onSelectCategory,
items = _ref.items,
onInsertItem = _ref.onInsertItem,
selectedCategory = _ref.selectedCategory,
selectedItemIndex = _ref.selectedItemIndex,
focusedItemIndex = _ref.focusedItemIndex,
setFocusedItemIndex = _ref.setFocusedItemIndex,
focusOnSearch = _ref.focusOnSearch,
focusOnViewMore = _ref.focusOnViewMore,
setColumnCount = _ref.setColumnCount,
setFocusOnSearch = _ref.setFocusOnSearch,
onKeyPress = _ref.onKeyPress,
onKeyDown = _ref.onKeyDown,
searchTerm = _ref.searchTerm,
createAnalyticsEvent = _ref.createAnalyticsEvent,
emptyStateHandler = _ref.emptyStateHandler,
viewMoreItem = _ref.viewMoreItem;
return jsx("div", {
css: mobileElementBrowserContainer,
onKeyDown: onKeyDown,
"data-testid": "mobile__element-browser"
}, jsx("div", {
css: showCategories ? [mobileSideBar, mobileSideBarShowCategories] : mobileSideBar
}, showSearch && jsx(ElementSearch, {
onSearch: onSearch,
onKeyDown: onKeyPress,
mode: mode,
focus: focusOnSearch,
onClick: setFocusOnSearch,
searchTerm: searchTerm,
items: items,
selectedItemIndex: selectedItemIndex
}), showCategories && jsx("nav", {
css: mobileCategoryListWrapper,
tabIndex: -1
}, jsx(CategoryList, {
categories: categories,
onSelectCategory: onSelectCategory,
selectedCategory: selectedCategory
}))), jsx("div", {
css: mobileMainContent
}, jsx(ElementList, {
items: items,
mode: mode,
onInsertItem: onInsertItem,
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
setColumnCount: setColumnCount,
createAnalyticsEvent: createAnalyticsEvent,
emptyStateHandler: emptyStateHandler,
selectedCategory: selectedCategory,
searchTerm: searchTerm
})), viewMoreItem && jsx(ViewMore, {
item: viewMoreItem,
focus: focusOnViewMore
}));
}
function DesktopBrowser(_ref2) {
var showCategories = _ref2.showCategories,
showSearch = _ref2.showSearch,
onSearch = _ref2.onSearch,
mode = _ref2.mode,
categories = _ref2.categories,
onSelectCategory = _ref2.onSelectCategory,
items = _ref2.items,
onInsertItem = _ref2.onInsertItem,
selectedCategory = _ref2.selectedCategory,
selectedItemIndex = _ref2.selectedItemIndex,
focusedItemIndex = _ref2.focusedItemIndex,
setFocusedItemIndex = _ref2.setFocusedItemIndex,
focusOnSearch = _ref2.focusOnSearch,
setColumnCount = _ref2.setColumnCount,
setFocusOnSearch = _ref2.setFocusOnSearch,
onKeyPress = _ref2.onKeyPress,
onKeyDown = _ref2.onKeyDown,
searchTerm = _ref2.searchTerm,
createAnalyticsEvent = _ref2.createAnalyticsEvent,
emptyStateHandler = _ref2.emptyStateHandler;
return jsx("div", {
css: elementBrowserContainer,
"data-testid": "desktop__element-browser"
}, showCategories && jsx("div", {
css: showCategories ? sideBarShowCategories : sideBar
}, jsx("h2", {
css: sidebarHeading,
"data-testid": "sidebar-heading",
id: "sidebar-heading"
}, jsx(FormattedMessage, {
id: "fabric.editor.elementbrowser.sidebar.heading",
defaultMessage: "Browse",
description: "Sidebar heading"
})), jsx("nav", {
role: "tablist",
"aria-labelledby": "sidebar-heading",
css: categoryListWrapper
}, jsx(CategoryList, {
categories: categories,
onSelectCategory: onSelectCategory,
selectedCategory: selectedCategory,
createAnalyticsEvent: createAnalyticsEvent
}))), jsx("div", {
css: mainContent,
onKeyDown: onKeyDown,
"data-testid": "main-content"
}, showSearch &&
// eslint-disable-next-line
jsx("div", {
css: searchContainer
}, jsx(ElementSearch, {
onSearch: onSearch,
onKeyDown: onKeyPress,
mode: mode,
focus: focusOnSearch,
onClick: setFocusOnSearch,
searchTerm: searchTerm,
items: items,
selectedItemIndex: selectedItemIndex
})), jsx(ElementList, {
items: items,
mode: mode,
onInsertItem: onInsertItem,
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
setColumnCount: setColumnCount,
createAnalyticsEvent: createAnalyticsEvent,
emptyStateHandler: emptyStateHandler,
selectedCategory: selectedCategory,
searchTerm: searchTerm
})));
}
var MemoizedElementBrowser = /*#__PURE__*/memo(withAnalyticsContext({
source: 'ElementBrowser'
})(withAnalyticsEvents()(StatelessElementBrowser)));
export default MemoizedElementBrowser;