UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

323 lines (321 loc) • 11.2 kB
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;