@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
441 lines (430 loc) • 19.7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _react2 = require("@emotion/react");
var _reactIntlNext = require("react-intl-next");
var _withAnalyticsContext = _interopRequireDefault(require("@atlaskit/analytics-next/withAnalyticsContext"));
var _withAnalyticsEvents = _interopRequireDefault(require("@atlaskit/analytics-next/withAnalyticsEvents"));
var _analytics = require("../../analytics");
var _getEditorUgcToken = _interopRequireDefault(require("../../ugc-tokens/get-editor-ugc-token"));
var _constants = require("../constants");
var _useContainerWidth2 = _interopRequireDefault(require("../hooks/use-container-width"));
var _useSelectAndFocusOnArrowNavigation = _interopRequireDefault(require("../hooks/use-select-and-focus-on-arrow-navigation"));
var _ViewMore = require("../ViewMore");
var _CategoryList = _interopRequireDefault(require("./CategoryList"));
var _ElementList = _interopRequireDefault(require("./ElementList/ElementList"));
var _ElementSearch = _interopRequireDefault(require("./ElementSearch"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
* @jsxRuntime classic
* @jsx jsx
*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
var wrapper = (0, _react2.css)({
width: '100%',
maxHeight: 'inherit',
overflow: 'hidden'
});
var baseBrowserContainerStyles = (0, _react2.css)({
display: 'flex',
height: '100%',
minHeight: '-webkit-fill-available'
});
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
var mobileElementBrowserContainer = (0, _react2.css)(baseBrowserContainerStyles, {
flexDirection: 'column'
});
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
var elementBrowserContainer = (0, _react2.css)(baseBrowserContainerStyles, {
flexDirection: 'row'
});
var baseSidebarStyles = (0, _react2.css)({
display: 'flex',
flexDirection: 'column',
overflowX: 'auto',
overflowY: 'hidden'
});
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
var mobileSideBar = (0, _react2.css)(baseSidebarStyles, {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
flex: "0 0 ".concat(_constants.INLINE_SIDEBAR_HEIGHT),
padding: "var(--ds-space-150, 12px)".concat(" ", "var(--ds-space-150, 12px)", " 0 ", "var(--ds-space-150, 12px)")
});
var mobileSideBarShowCategories = (0, _react2.css)({
flex: '0 0 auto'
});
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
var sideBar = (0, _react2.css)(baseSidebarStyles, {
flex: "0 0 'auto'"
});
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
var sideBarShowCategories = (0, _react2.css)(baseSidebarStyles, {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
flex: "0 0 ".concat(_constants.SIDEBAR_WIDTH)
});
var sidebarHeading = (0, _react2.css)({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
flex: "0 0 ".concat(_constants.SIDEBAR_HEADING_WRAPPER_HEIGHT),
display: 'inline-flex',
alignItems: 'center',
paddingLeft: "var(--ds-space-150, 12px)",
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
font: (0, _getEditorUgcToken.default)('editor.font.heading.h1', 'typography-modernized') // use editor h1 modernized here as the style matches
});
var mobileMainContent = (0, _react2.css)({
flex: '1 1 auto',
display: 'flex',
flexDirection: 'column',
overflowY: 'auto',
height: '100%'
});
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
var mainContent = (0, _react2.css)(mobileMainContent, {
marginLeft: "var(--ds-space-200, 16px)",
height: 'auto'
});
var searchContainer = (0, _react2.css)({
paddingBottom: "var(--ds-space-200, 16px)"
});
var mobileCategoryListWrapper = (0, _react2.css)({
display: 'flex',
overflowX: 'auto',
padding: "var(--ds-space-200, 8px)".concat(" 0 ", "var(--ds-space-200, 16px)", " 0"),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
minHeight: "".concat(_constants.GRID_SIZE * 4, "px"),
overflow: '-moz-scrollbars-none',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
'&::-webkit-scrollbar': {
display: 'none'
},
scrollbarWidth: 'none',
MsOverflowStyle: 'none'
});
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
var categoryListWrapper = (0, _react2.css)(mobileCategoryListWrapper, {
padding: 0,
marginTop: "var(--ds-space-200, 24px)",
flexDirection: 'column'
});
function StatelessElementBrowser(props) {
var _props$categories;
var items = props.items,
onSelectItem = props.onSelectItem,
onInsertItem = props.onInsertItem,
viewMoreItem = props.viewMoreItem,
selectedCategory = props.selectedCategory,
onSelectCategory = props.onSelectCategory,
searchTerm = props.searchTerm,
showCategories = props.showCategories,
cache = props.cache;
var _useContainerWidth = (0, _useContainerWidth2.default)(),
containerWidth = _useContainerWidth.containerWidth,
ContainerWidthMonitor = _useContainerWidth.ContainerWidthMonitor;
var categoryBeenChosen = (0, _react.useRef)(false);
var _useState = (0, _react.useState)(1),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
columnCount = _useState2[0],
setColumnCount = _useState2[1];
var isFocusSearch;
var selectedCategoryIndex = (_props$categories = props.categories) === null || _props$categories === void 0 ? void 0 : _props$categories.findIndex(function (category) {
return category.name === selectedCategory;
});
if (showCategories) {
var isEmptySearchTerm = !searchTerm || (searchTerm === null || searchTerm === void 0 ? void 0 : searchTerm.length) === 0;
if (!isEmptySearchTerm) {
// clear the flag if the search happens after a user has chosen the category
categoryBeenChosen.current = false;
}
// A11Y: if categories exists, on the initial render search element should receive focus.
// After user pick some category the category should stay focused.
isFocusSearch = !categoryBeenChosen.current || !isEmptySearchTerm;
}
var itemIsDisabled = (0, _react.useCallback)(function (index) {
var _items$index$isDisabl, _items$index;
return (_items$index$isDisabl = (_items$index = items[index]) === null || _items$index === void 0 ? void 0 : _items$index.isDisabled) !== null && _items$index$isDisabl !== void 0 ? _items$index$isDisabl : false;
}, [items]);
var _useSelectAndFocusOnA = (0, _useSelectAndFocusOnArrowNavigation.default)(items.length - 1, columnCount, !!viewMoreItem, itemIsDisabled, isFocusSearch),
selectedItemIndex = _useSelectAndFocusOnA.selectedItemIndex,
focusedItemIndex = _useSelectAndFocusOnA.focusedItemIndex,
setFocusedItemIndex = _useSelectAndFocusOnA.setFocusedItemIndex,
setFocusedCategoryIndex = _useSelectAndFocusOnA.setFocusedCategoryIndex,
focusedCategoryIndex = _useSelectAndFocusOnA.focusedCategoryIndex,
focusOnSearch = _useSelectAndFocusOnA.focusOnSearch,
focusOnViewMore = _useSelectAndFocusOnA.focusOnViewMore,
onKeyDown = _useSelectAndFocusOnA.onKeyDown,
setFocusOnSearch = _useSelectAndFocusOnA.setFocusOnSearch;
(0, _react.useEffect)(function () {
(0, _analytics.fireAnalyticsEvent)(props.createAnalyticsEvent)({
payload: {
action: _analytics.ACTION.OPENED,
actionSubject: _analytics.ACTION_SUBJECT.ELEMENT_BROWSER,
eventType: _analytics.EVENT_TYPE.UI,
attributes: {
mode: props.mode
}
}
});
return function () {
(0, _analytics.fireAnalyticsEvent)(props.createAnalyticsEvent)({
payload: {
action: _analytics.ACTION.CLOSED,
actionSubject: _analytics.ACTION_SUBJECT.ELEMENT_BROWSER,
eventType: _analytics.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 onItemsEnterTabKeyPress = (0, _react.useCallback)(function (e) {
var _selectedItem$isDisab;
if (e.key !== 'Enter' && (e.key !== 'Tab' || !showCategories)) {
return;
}
if (showCategories && e.key === 'Tab' && selectedCategoryIndex !== undefined) {
// A11Y: Set focus on first category if tab pressed on search
setFocusedCategoryIndex(selectedCategoryIndex);
e.preventDefault();
return;
}
if (onInsertItem && selectedItem != null && !((_selectedItem$isDisab = selectedItem.isDisabled) !== null && _selectedItem$isDisab !== void 0 ? _selectedItem$isDisab : false)) {
onInsertItem(selectedItem);
}
e.preventDefault();
}, [onInsertItem, selectedItem, setFocusedCategoryIndex, showCategories, selectedCategoryIndex]);
/**
* On arrow key selection and clicks the selectedItemIndex will change.
* Making sure to update parent component.
*/
(0, _react.useEffect)(function () {
if (onSelectItem && selectedItem != null) {
onSelectItem(selectedItem);
}
}, [onSelectItem, selectedItem]);
var onSelectCategoryCB = (0, _react.useCallback)(function (category) {
onSelectCategory(category);
categoryBeenChosen.current = true;
}, [categoryBeenChosen, onSelectCategory]);
return (0, _react2.jsx)("div", {
css: wrapper,
"data-testid": "element-browser",
id: _constants.ELEMENT_BROWSER_ID
}, (0, _react2.jsx)(ContainerWidthMonitor, null), containerWidth < _constants.DEVICE_BREAKPOINT_NUMBERS.medium ? (0, _react2.jsx)(MobileBrowser
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, (0, _extends2.default)({}, props, {
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
focusedCategoryIndex: focusedCategoryIndex,
setFocusedCategoryIndex: setFocusedCategoryIndex,
focusOnSearch: focusOnSearch,
columnCount: columnCount,
setColumnCount: setColumnCount,
setFocusOnSearch: setFocusOnSearch,
onKeyPress: onItemsEnterTabKeyPress,
onKeyDown: onKeyDown,
viewMoreItem: viewMoreItem,
focusOnViewMore: focusOnViewMore,
cache: cache
})) : (0, _react2.jsx)(DesktopBrowser
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, (0, _extends2.default)({}, props, {
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
focusOnSearch: focusOnSearch,
setColumnCount: setColumnCount,
columnCount: columnCount,
setFocusOnSearch: setFocusOnSearch,
onKeyPress: onItemsEnterTabKeyPress,
onKeyDown: onKeyDown,
focusedCategoryIndex: focusedCategoryIndex,
setFocusedCategoryIndex: setFocusedCategoryIndex,
selectedCategoryIndex: selectedCategoryIndex,
onSelectCategory: onSelectCategoryCB,
cache: cache
})));
}
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,
focusedCategoryIndex = _ref.focusedCategoryIndex,
setFocusedCategoryIndex = _ref.setFocusedCategoryIndex,
focusOnSearch = _ref.focusOnSearch,
focusOnViewMore = _ref.focusOnViewMore,
columnCount = _ref.columnCount,
setColumnCount = _ref.setColumnCount,
setFocusOnSearch = _ref.setFocusOnSearch,
onKeyPress = _ref.onKeyPress,
onKeyDown = _ref.onKeyDown,
searchTerm = _ref.searchTerm,
createAnalyticsEvent = _ref.createAnalyticsEvent,
emptyStateHandler = _ref.emptyStateHandler,
viewMoreItem = _ref.viewMoreItem,
cache = _ref.cache;
return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
(0, _react2.jsx)("div", {
css: mobileElementBrowserContainer,
onKeyDown: onKeyDown,
"data-testid": "mobile__element-browser"
}, (0, _react2.jsx)("div", {
css: showCategories ? [mobileSideBar, mobileSideBarShowCategories] : mobileSideBar
}, showSearch && (0, _react2.jsx)(_ElementSearch.default, {
onSearch: onSearch,
onKeyDown: onKeyPress,
mode: mode,
focus: focusOnSearch,
onClick: setFocusOnSearch,
searchTerm: searchTerm,
items: items,
selectedItemIndex: selectedItemIndex
}), showCategories && (0, _react2.jsx)("nav", {
css: mobileCategoryListWrapper,
tabIndex: -1
}, (0, _react2.jsx)(_CategoryList.default, {
categories: categories,
onSelectCategory: onSelectCategory,
selectedCategory: selectedCategory,
focusedCategoryIndex: focusedCategoryIndex,
setFocusedCategoryIndex: setFocusedCategoryIndex,
setFocusedItemIndex: setFocusedItemIndex,
setFocusOnSearch: setFocusOnSearch
}))), (0, _react2.jsx)("div", {
css: mobileMainContent
}, (0, _react2.jsx)(_ElementList.default, {
items: items,
mode: mode,
onInsertItem: onInsertItem,
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
columnCount: columnCount,
setColumnCount: setColumnCount,
createAnalyticsEvent: createAnalyticsEvent,
emptyStateHandler: emptyStateHandler,
selectedCategory: selectedCategory,
searchTerm: searchTerm,
cache: cache
})), viewMoreItem && (0, _react2.jsx)(_ViewMore.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,
focusedCategoryIndex = _ref2.focusedCategoryIndex,
setFocusedCategoryIndex = _ref2.setFocusedCategoryIndex,
selectedCategoryIndex = _ref2.selectedCategoryIndex,
focusOnSearch = _ref2.focusOnSearch,
columnCount = _ref2.columnCount,
setColumnCount = _ref2.setColumnCount,
setFocusOnSearch = _ref2.setFocusOnSearch,
onKeyPress = _ref2.onKeyPress,
onKeyDown = _ref2.onKeyDown,
searchTerm = _ref2.searchTerm,
createAnalyticsEvent = _ref2.createAnalyticsEvent,
emptyStateHandler = _ref2.emptyStateHandler,
cache = _ref2.cache;
return (0, _react2.jsx)("div", {
css: elementBrowserContainer,
"data-testid": "desktop__element-browser"
}, showCategories && (0, _react2.jsx)("div", {
css: showCategories ? sideBarShowCategories : sideBar
}, (0, _react2.jsx)("div", {
css: sidebarHeading,
"data-testid": "sidebar-heading",
id: "sidebar-heading"
}, (0, _react2.jsx)(_reactIntlNext.FormattedMessage, {
id: "fabric.editor.elementbrowser.sidebar.heading",
defaultMessage: "Browse",
description: "Sidebar heading"
})), (0, _react2.jsx)("nav", {
role: "tablist",
"aria-labelledby": "sidebar-heading",
css: categoryListWrapper
}, (0, _react2.jsx)(_CategoryList.default, {
categories: categories,
onSelectCategory: onSelectCategory,
selectedCategory: selectedCategory,
createAnalyticsEvent: createAnalyticsEvent,
focusedCategoryIndex: focusedCategoryIndex,
setFocusedCategoryIndex: setFocusedCategoryIndex,
setFocusedItemIndex: setFocusedItemIndex,
setFocusOnSearch: setFocusOnSearch
}))), (0, _react2.jsx)("div", {
css: mainContent,
onKeyDown: onKeyDown,
"data-testid": "main-content"
}, showSearch &&
// eslint-disable-next-line
(0, _react2.jsx)("div", {
css: searchContainer
}, (0, _react2.jsx)(_ElementSearch.default, {
onSearch: onSearch,
onKeyDown: onKeyPress,
mode: mode,
focus: focusOnSearch,
onClick: setFocusOnSearch,
searchTerm: searchTerm,
items: items,
selectedItemIndex: selectedItemIndex
})), (0, _react2.jsx)(_ElementList.default, {
items: items,
mode: mode,
onInsertItem: onInsertItem,
selectedItemIndex: selectedItemIndex,
focusedItemIndex: focusedItemIndex,
setFocusedItemIndex: setFocusedItemIndex,
columnCount: columnCount,
setColumnCount: setColumnCount,
createAnalyticsEvent: createAnalyticsEvent,
emptyStateHandler: emptyStateHandler,
selectedCategory: selectedCategory,
selectedCategoryIndex: selectedCategoryIndex,
searchTerm: searchTerm,
setFocusedCategoryIndex: showCategories ? setFocusedCategoryIndex : undefined,
cache: cache
})));
}
var MemoizedElementBrowser = /*#__PURE__*/(0, _react.memo)((0, _withAnalyticsContext.default)({
source: 'ElementBrowser'
})((0, _withAnalyticsEvents.default)()(StatelessElementBrowser)));
var _default = exports.default = MemoizedElementBrowser;