@atlaskit/editor-plugin-floating-toolbar
Version:
Floating toolbar plugin for @atlaskit/editor-core
777 lines (768 loc) • 36.5 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/* eslint-disable @atlaskit/design-system/no-css-tagged-template-expression -- needs manual remediation */
/**
* @jsxRuntime classic
* @jsx jsx
*/
import React, { Component } from 'react';
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
import { css, jsx } from '@emotion/react';
import { injectIntl } from 'react-intl';
import ButtonGroup from '@atlaskit/button/button-group';
import { areSameItems, messages } from '@atlaskit/editor-common/floating-toolbar';
import commonMessages from '@atlaskit/editor-common/messages';
import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
import { Announcer, FloatingToolbarButton as Button, FloatingToolbarSeparator as Separator } from '@atlaskit/editor-common/ui';
import { backgroundPaletteTooltipMessages } from '@atlaskit/editor-common/ui-color';
import { ColorPickerButton, ToolbarArrowKeyNavigationProvider } from '@atlaskit/editor-common/ui-menu';
import { hexToEditorBackgroundPaletteColor } from '@atlaskit/editor-palette';
import ShowMoreHorizontalIcon from '@atlaskit/icon/core/show-more-horizontal';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { checkShouldForceFocusAndApply, forceFocusSelector } from '../pm-plugins/force-focus';
import { showConfirmDialog } from '../pm-plugins/toolbar-data/commands';
import Dropdown from './Dropdown';
import { EmojiPickerButton } from './EmojiPickerButton';
import { ExtensionsPlaceholder } from './ExtensionsPlaceholder';
import { Input } from './Input';
import { ScrollButton } from './ScrollButton';
import { ScrollButtons } from './ScrollButtons';
import Select from './Select';
// eslint-disable-next-line jsdoc/require-jsdoc
export function groupItems(items, areAnyNewToolbarFlagsEnabled) {
var groupItems = items.reduce(function (accumulator, item, i) {
var finalOutput = accumulator.finalOutput,
buttonGroup = accumulator.buttonGroup;
if (item.type === 'button') {
var notLastItem = i < items.length - 1;
var nextItemIsButton = items[i + 1] && items[i + 1].type === 'button';
var wasPreviousButton = items[i - 1] && items[i - 1].type === 'button';
var shouldBeRadioButton = notLastItem && nextItemIsButton || wasPreviousButton;
// Only group as radio button if not explicitly set to false
var isRadioButton = !expValEquals('platform_editor_august_a11y', 'isEnabled', true) ? shouldBeRadioButton : shouldBeRadioButton && item.isRadioButton !== false;
if (isRadioButton) {
item.isRadioButton = true;
buttonGroup.push(item);
if (!nextItemIsButton && wasPreviousButton) {
finalOutput.push(buttonGroup);
accumulator.buttonGroup = [];
}
} else {
finalOutput.push(item);
}
} else if (item.type === 'separator' && areAnyNewToolbarFlagsEnabled) {
var _items;
var isLeadingSeparator = i === 0;
var isTrailingSeparator = i === items.length - 1;
var isDuplicateSeparator = ((_items = items[i - 1]) === null || _items === void 0 ? void 0 : _items.type) === 'separator';
!isLeadingSeparator && !isTrailingSeparator && !isDuplicateSeparator && finalOutput.push(item);
} else {
finalOutput.push(item);
}
return accumulator;
}, {
buttonGroup: [],
finalOutput: []
});
return groupItems.finalOutput;
}
var ToolbarItems = /*#__PURE__*/React.memo(function (_ref) {
var items = _ref.items,
groupLabel = _ref.groupLabel,
dispatchCommand = _ref.dispatchCommand,
popupsMountPoint = _ref.popupsMountPoint,
popupsBoundariesElement = _ref.popupsBoundariesElement,
editorView = _ref.editorView,
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent,
popupsScrollableElement = _ref.popupsScrollableElement,
scrollable = _ref.scrollable,
providerFactory = _ref.providerFactory,
extensionsProvider = _ref.extensionsProvider,
node = _ref.node,
setDisableScroll = _ref.setDisableScroll,
mountRef = _ref.mountRef,
api = _ref.api,
intl = _ref.intl;
var emojiAndColourPickerMountPoint = scrollable ? popupsMountPoint || (editorView === null || editorView === void 0 ? void 0 : editorView.dom.closest('.fabric-editor-popup-scroll-parent')) || (editorView === null || editorView === void 0 ? void 0 : editorView.dom.closest('.ak-editor-content-area')) || undefined : popupsMountPoint;
var areAnyNewToolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar));
var renderItem = function renderItem(item, idx) {
var _api$contextPanel, _api$extension;
switch (item.type) {
case 'button':
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var ButtonIcon = item.icon;
var onClickHandler = function onClickHandler() {
if (item.confirmDialog) {
dispatchCommand(showConfirmDialog(idx));
} else {
dispatchCommand(item.onClick);
if (item.focusEditoronEnter && !(editorView !== null && editorView !== void 0 && editorView.hasFocus())) {
editorView === null || editorView === void 0 || editorView.focus();
}
}
};
var getIconColor = function getIconColor(disabled, selected) {
if (disabled) {
return "var(--ds-icon-disabled, #080F214A)";
}
if (selected) {
return "var(--ds-icon-selected, #1868DB)";
}
return 'currentColor';
};
return jsx(Button
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @atlaskit/design-system/no-unsafe-style-overrides -- Ignored via go/DSP-18766
, {
className: item.className,
key: idx,
title: item.title,
href: item.href,
icon: item.icon ? jsx(ButtonIcon, {
color: getIconColor(item.disabled, item.selected),
spacing: "spacious",
label: undefined,
"aria-hidden": true // Icon is described by the button for screen readers
}) : undefined,
iconAfter: item.iconAfter ? jsx(item.iconAfter, {
label: ""
}) : undefined,
appearance: item.appearance,
target: item.target,
onClick: onClickHandler
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onMouseEnter: function onMouseEnter() {
return dispatchCommand(item.onMouseEnter);
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onMouseLeave: function onMouseLeave() {
return dispatchCommand(item.onMouseLeave);
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onFocus: function onFocus() {
return dispatchCommand(item.onFocus);
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onBlur: function onBlur() {
return dispatchCommand(item.onBlur);
},
onMount: item.onMount,
onUnmount: item.onUnmount,
selected: item.selected,
disabled: item.disabled,
tooltipContent: item.tooltipContent,
testId: item.testId,
hideTooltipOnClick: item.hideTooltipOnClick,
ariaHasPopup: item.ariaHasPopup,
tabIndex: item.tabIndex,
isRadioButton: item.isRadioButton,
ariaLabel: expValEquals('platform_editor_floating_toolbar_button_aria_label', 'isEnabled', true) ? item === null || item === void 0 ? void 0 : item.ariaLabel : undefined,
pulse: item.pulse,
interactionName: item.interactionName,
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
}, item.showTitle && item.title);
case 'input':
return jsx(Input, {
key: idx,
mountPoint: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
defaultValue: item.defaultValue,
placeholder: item.placeholder
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onSubmit: function onSubmit(value) {
return dispatchCommand(item.onSubmit(value));
}
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onBlur: function onBlur(value) {
return dispatchCommand(item.onBlur(value));
}
});
case 'custom':
{
return item.render(editorView, idx, dispatchAnalyticsEvent);
}
case 'overflow-dropdown':
// if an option has a confirmDialog, we need to replace its onClick handler
// to set the state to show the confirm dialog
// crudely done here to avoid greater coupling with DropdownMenuItem from `floating-toolbar`
// which would need knowledge of indexes, showConfirmDialog etc.
var options = item.options.map(function (option, optionIndex) {
if (!('type' in option) && option.confirmDialog) {
var onClick = option.confirmDialog ? showConfirmDialog(idx, optionIndex) : option.onClick;
return _objectSpread(_objectSpread({}, option), {}, {
onClick: onClick
});
}
return option;
});
return jsx(Dropdown, {
alignX: areAnyNewToolbarFlagsEnabled ? 'right' : undefined,
key: idx,
title: intl.formatMessage(commonMessages.viewMore),
icon: jsx(ShowMoreHorizontalIcon, {
label: "",
spacing: "spacious"
}),
dispatchCommand: dispatchCommand,
options: options,
disabled: item.disabled,
tooltip: item.tooltip,
hideExpandIcon: true,
mountPoint: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
scrollableElement: popupsScrollableElement,
dropdownWidth: item.dropdownWidth,
showSelected: item.showSelected,
buttonTestId: item.testId,
editorView: editorView,
setDisableParentScroll: scrollable ? setDisableScroll : undefined,
dropdownListId: (item === null || item === void 0 ? void 0 : item.id) && "".concat(item.id, "-dropdownList"),
alignDropdownWithToolbar: items.length === 1,
onClick: item.onClick,
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
});
case 'dropdown':
var DropdownIcon = item.icon;
var BeforeIcon = item.iconBefore;
return jsx(Dropdown, {
key: idx,
title: item.title,
icon: DropdownIcon && jsx(DropdownIcon, {
label: item.title
}),
iconBefore: BeforeIcon && jsx(BeforeIcon, {
label: ""
}),
dispatchCommand: dispatchCommand,
options: item.options,
disabled: item.disabled,
tooltip: item.tooltip,
hideExpandIcon: item.hideExpandIcon,
mountPoint: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
scrollableElement: popupsScrollableElement,
dropdownWidth: item.dropdownWidth,
showSelected: item.showSelected,
buttonTestId: item.testId,
editorView: editorView,
setDisableParentScroll: scrollable ? setDisableScroll : undefined,
dropdownListId: (item === null || item === void 0 ? void 0 : item.id) && "".concat(item.id, "-dropdownList"),
alignDropdownWithToolbar: items.length === 1,
onToggle: item.onToggle,
footer: item.footer,
onMount: item.onMount,
onClick: item.onClick,
pulse: item.pulse,
shouldFitContainer: item.shouldFitContainer,
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
});
case 'select':
if (item.selectType === 'list') {
var ariaLabel = item.title || item.placeholder;
return jsx(Select, {
key: idx,
dispatchCommand: dispatchCommand,
options: item.options,
hideExpandIcon: item.hideExpandIcon
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
,
mountPoint: scrollable ? mountRef.current : undefined,
boundariesElement: popupsBoundariesElement,
scrollableElement: popupsScrollableElement,
defaultValue: item.defaultValue,
placeholder: item.placeholder
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onChange: function onChange(selected) {
return dispatchCommand(item.onChange(selected));
},
ariaLabel: ariaLabel,
filterOption: item.filterOption,
setDisableParentScroll: scrollable ? setDisableScroll : undefined,
classNamePrefix: 'floating-toolbar-select'
});
}
if (item.selectType === 'color') {
return jsx(ColorPickerButton, {
skipFocusButtonAfterPick: true,
key: idx,
isAriaExpanded: item.isAriaExpanded,
title: item.title
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onChange: function onChange(selected) {
dispatchCommand(item.onChange(selected));
},
colorPalette: item.options,
currentColor: item.defaultValue ? item.defaultValue.value : undefined,
placement: "Panels",
mountPoint: emojiAndColourPickerMountPoint,
setDisableParentScroll: scrollable ? setDisableScroll : undefined
// Currently in floating toolbar, color picker is only
// used in panel and table cell background color.
// Both uses same color palette.
// That's why hard-coding hexToEditorBackgroundPaletteColor
// and paletteColorTooltipMessages.
// When we need to support different color palette
// in floating toolbar, we need to set hexToPaletteColor
// and paletteColorTooltipMessages in item options.
,
hexToPaletteColor: hexToEditorBackgroundPaletteColor,
paletteColorTooltipMessages: backgroundPaletteTooltipMessages,
returnEscToButton: item.returnEscToButton
});
}
if (item.selectType === 'emoji') {
return jsx(EmojiPickerButton, {
key: idx,
editorView: editorView,
title: item.title,
providerFactory: providerFactory,
isSelected: item.selected
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
onChange: function onChange(selected) {
return dispatchCommand(item.onChange(selected));
},
mountPoint: emojiAndColourPickerMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
setDisableParentScroll: scrollable ? setDisableScroll : undefined,
pluginInjectionApi: api
});
}
return null;
case 'extensions-placeholder':
if (!editorView || !extensionsProvider) {
return null;
}
return jsx(ExtensionsPlaceholder, {
key: idx,
node: node,
editorView: editorView,
extensionProvider: extensionsProvider,
separator: item.separator,
applyChangeToContextPanel: api === null || api === void 0 || (_api$contextPanel = api.contextPanel) === null || _api$contextPanel === void 0 ? void 0 : _api$contextPanel.actions.applyChange,
extensionApi: api === null || api === void 0 || (_api$extension = api.extension) === null || _api$extension === void 0 ? void 0 : _api$extension.actions.api(),
dispatchCommand: dispatchCommand,
popupsMountPoint: popupsMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement,
alignDropdownWithToolbar: items.length === 1,
scrollable: scrollable,
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
});
case 'separator':
if (areAnyNewToolbarFlagsEnabled) {
return item.fullHeight ? jsx(Separator, {
key: idx,
fullHeight: true,
areAnyNewToolbarFlagsEnabled: true
}) : null;
}
return jsx(Separator, {
key: idx,
fullHeight: item.fullHeight,
areAnyNewToolbarFlagsEnabled: false
});
}
};
var groupedItems = groupItems(
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- Ignored via go/ees017 (to be fixed)
items.filter(function (item) {
return !item.hidden;
}), areAnyNewToolbarFlagsEnabled);
return jsx(ButtonGroup, {
testId: "editor-floating-toolbar-items"
}, groupedItems.map(function (element, index) {
var isGroup = Array.isArray(element);
if (isGroup) {
return jsx("div", {
// Ignored via go/ees005
// eslint-disable-next-line react/no-array-index-key
key: index,
css: areAnyNewToolbarFlagsEnabled ? buttonGroupStylesNew : buttonGroupStyles,
role: "radiogroup",
"aria-label": groupLabel !== null && groupLabel !== void 0 ? groupLabel : undefined,
"data-testid": "editor-floating-toolbar-grouped-buttons"
}, element.map(function (element) {
var indexInAllItems = items.findIndex(function (item) {
return item === element;
});
return renderItem(element, indexInAllItems);
}));
} else {
var indexInAllItems = items.findIndex(function (item) {
return item === element;
});
return renderItem(element, indexInAllItems);
}
}));
}, function (prevProps, nextProps) {
if (!nextProps.node) {
return false;
}
// only rerender toolbar items if the node is different
// otherwise it causes an issue where multiple popups stays open
return !(prevProps.node.type !== nextProps.node.type || prevProps.node.attrs.localId !== nextProps.node.attrs.localId || !areSameItems(prevProps.items, nextProps.items) || !prevProps.mounted !== !nextProps.mounted);
});
var buttonGroupStyles = css({
display: 'flex',
gap: "var(--ds-space-050, 4px)"
});
var buttonGroupStylesNew = css({
display: 'flex',
gap: "var(--ds-space-075, 6px)"
});
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
var toolbarContainer = function toolbarContainer(areAnyNewToolbarFlagsEnabled, scrollable, hasSelect, firstElementIsSelect) {
return css({
backgroundColor: "var(--ds-surface-overlay, #FFFFFF)",
borderRadius: "var(--ds-radius-small, 3px)",
boxShadow: "var(--ds-shadow-overlay, 0px 8px 12px #1E1F2126, 0px 0px 1px #1E1F214f)",
display: 'flex',
// eslint-disable-next-line @atlaskit/design-system/use-tokens-typography
lineHeight: 1,
boxSizing: 'border-box',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
'& > div > div': {
alignItems: 'center'
}
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
scrollable ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css(
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
hasSelect ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
height: '40px'
}) :
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
height: '32px'
}), {
overflow: 'hidden'
}) :
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
areAnyNewToolbarFlagsEnabled ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
padding: "var(--ds-space-0, 0px)".concat(" 4px ", "var(--ds-space-0, 0px)", " 4px")
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
firstElementIsSelect &&
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
paddingLeft: "var(--ds-space-050, 4px)"
})) :
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
padding: "var(--ds-space-050, 4px)".concat(" ", "var(--ds-space-100, 8px)")
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
firstElementIsSelect &&
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
paddingLeft: "var(--ds-space-050, 4px)"
})),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
areAnyNewToolbarFlagsEnabled ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
css({
minHeight: "var(--ds-space-500, 40px)"
}) : undefined);
};
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
var toolbarOverflow = function toolbarOverflow(_ref2) {
var scrollable = _ref2.scrollable,
scrollDisabled = _ref2.scrollDisabled,
firstElementIsSelect = _ref2.firstElementIsSelect,
areAnyNewToolbarFlagsEnabled = _ref2.areAnyNewToolbarFlagsEnabled;
return css(
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
scrollable ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css(
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
scrollDisabled ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
overflow: 'hidden'
}) :
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
css({
overflowX: 'auto',
overflowY: 'hidden',
// When scrollable is true, ScrollButtons will be shown, hence we want to hide show default horizontal scrollbar
scrollbarWidth: 'none'
}), {
WebkitOverflowScrolling: 'touch',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
padding: "var(--ds-space-050, 4px)".concat(" 0 ", "var(--ds-space-050, 4px)"),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
'> div': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
'> div:first-child': firstElementIsSelect ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
marginLeft: "var(--ds-space-050, 4px)"
}) :
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
marginLeft: "var(--ds-space-100, 8px)"
}),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
'> div:last-child': {
marginRight: "var(--ds-space-100, 8px)"
}
}
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
areAnyNewToolbarFlagsEnabled ?
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values
css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
padding: "var(--ds-space-0, 0px)".concat(" 4px ", "var(--ds-space-600, 48px)", " 4px"),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'> div': {
minHeight: "var(--ds-space-500, 40px)",
gap: "var(--ds-space-075, 6px)",
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
'> div:first-child': {
marginLeft: 0
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
'> div:last-child': {
marginRight: 0
}
}
}) : undefined) :
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
css({
display: 'flex'
}));
};
// eslint-disable-next-line @repo/internal/react/no-class-components
var Toolbar = /*#__PURE__*/function (_Component) {
function Toolbar(props) {
var _this;
_classCallCheck(this, Toolbar);
_this = _callSuper(this, Toolbar, [props]);
_defineProperty(_this, "shouldHandleArrowKeys", function () {
var _this$props$items;
//To prevent the keydown handling of arrow keys for custom toolbar items with 'disableArrowNavigation' prop enabled,
//Usually the button which has menus or popups
return !((_this$props$items = _this.props.items) !== null && _this$props$items !== void 0 && _this$props$items.find(function (item) {
return item.type === 'custom' && item.disableArrowNavigation;
}));
});
_defineProperty(_this, "handleEscape", function (event) {
var _this$props$editorVie;
// If any menu is open inside the floating toolbar 'Esc' key should not
// focus the editorview.
// Event can't be stopped as they are not childnodes of floating toolbar
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
var isDropdownOpen = !!document.querySelector('[data-role="droplistContent"]');
// eslint-disable-next-line @atlaskit/platform/no-direct-document-usage
var isSelectMenuOpen = !!document.querySelector('.floating-toolbar-select__menu');
if (isDropdownOpen || isSelectMenuOpen) {
return;
}
(_this$props$editorVie = _this.props.editorView) === null || _this$props$editorVie === void 0 || _this$props$editorVie.focus();
event.preventDefault();
event.stopPropagation();
});
_defineProperty(_this, "captureMouseEvent", function (event) {
var _this$props$items2;
// Don't capture mouse event for custom toolbars e.g. insert hyperlink
if (((_this$props$items2 = _this.props.items) === null || _this$props$items2 === void 0 ? void 0 : _this$props$items2.length) === 1 && _this.props.items[0].type === 'custom') {
return;
}
// Prevents toolbar from closing when clicking on the toolbar itself and not on the buttons
event.stopPropagation();
event.preventDefault();
});
_defineProperty(_this, "isShortcutToFocusToolbar", function (event) {
//Alt + F10 to reach first element in this floating toolbar
return event.altKey && (event.key === 'F10' || event.keyCode === 121);
});
_defineProperty(_this, "doesNodeRequireAssitiveMessage", function (node) {
// Code blocks have an assistive message to announce the content of the code block to screen readers, so we don't need to announce the floating toolbar for those nodes
var nodesWithAlternativeRoles = ['codeBlock'];
if (nodesWithAlternativeRoles.includes(node.type.name)) {
return false;
}
return true;
});
_this.scrollContainerRef = /*#__PURE__*/React.createRef();
_this.mountRef = /*#__PURE__*/React.createRef();
_this.toolbarContainerRef = /*#__PURE__*/React.createRef();
_this.state = {
scrollDisabled: false,
mounted: false
};
return _this;
}
// remove any decorations added by toolbar buttons i.e danger and selected styling
// this prevents https://product-fabric.atlassian.net/browse/ED-10207
_inherits(Toolbar, _Component);
return _createClass(Toolbar, [{
key: "resetStyling",
value: function resetStyling() {
if (this.props.editorView) {
var _this$props$api;
var _this$props$editorVie2 = this.props.editorView,
state = _this$props$editorVie2.state,
dispatch = _this$props$editorVie2.dispatch;
(_this$props$api = this.props.api) === null || _this$props$api === void 0 || (_this$props$api = _this$props$api.decorations) === null || _this$props$api === void 0 || _this$props$api.actions.removeDecoration(state, dispatch);
}
}
}, {
key: "setDisableScroll",
value: function setDisableScroll(disabled) {
var _this2 = this;
// wait before setting disabled state incase users jumping from one popup to another
if (disabled) {
requestAnimationFrame(function () {
_this2.setState({
scrollDisabled: disabled
});
});
} else {
this.setState({
scrollDisabled: disabled
});
}
}
}, {
key: "componentDidMount",
value: function componentDidMount() {
this.setState({
mounted: true
});
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var _this$props;
checkShouldForceFocusAndApply((_this$props = this.props) === null || _this$props === void 0 ? void 0 : _this$props.editorView);
if (this.props.node !== prevProps.node) {
this.resetStyling();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
var editorView = this.props.editorView;
if (editorView) {
var tr = editorView.state.tr,
dispatch = editorView.dispatch;
dispatch(forceFocusSelector(null)(tr));
}
this.resetStyling();
}
}, {
key: "render",
value: function render() {
var _this$props$api2;
var _this$props2 = this.props,
items = _this$props2.items,
className = _this$props2.className,
node = _this$props2.node,
intl = _this$props2.intl,
scrollable = _this$props2.scrollable,
mediaAssistiveMessage = _this$props2.mediaAssistiveMessage;
var areAnyNewToolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean((_this$props$api2 = this.props.api) === null || _this$props$api2 === void 0 ? void 0 : _this$props$api2.toolbar));
if (!items || !items.length) {
return null;
}
// Select has left padding of 4px to the border, everything else 8px
var firstElementIsSelect = items[0].type === 'select';
var hasSelect = items.find(function (item) {
return item.type === 'select' && item.selectType === 'list';
});
var shouldRenderAssistiveAnnouncer = expValEquals('editor_a11y_role_textbox', 'isEnabled', true) ? this.doesNodeRequireAssitiveMessage(node) : true;
return jsx(React.Fragment, null, jsx(ToolbarArrowKeyNavigationProvider, {
editorView: this.props.editorView,
handleEscape: this.handleEscape,
disableArrowKeyNavigation: !this.shouldHandleArrowKeys(),
childComponentSelector: "[data-testid='editor-floating-toolbar']",
isShortcutToFocusToolbar: this.isShortcutToFocusToolbar,
intl: intl
}, jsx("div", {
ref: this.toolbarContainerRef,
css: function css() {
return [toolbarContainer(areAnyNewToolbarFlagsEnabled, scrollable, hasSelect !== undefined, firstElementIsSelect)];
},
"aria-label": intl.formatMessage(messages.floatingToolbarAriaLabel),
role: "toolbar",
"data-testid": "editor-floating-toolbar"
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
,
className: className,
onMouseDown: areAnyNewToolbarFlagsEnabled ? this.captureMouseEvent : undefined
}, shouldRenderAssistiveAnnouncer && jsx(Announcer, {
text: mediaAssistiveMessage ? "".concat(mediaAssistiveMessage, ", ").concat(intl.formatMessage(messages.floatingToolbarAnnouncer)) : intl.formatMessage(messages.floatingToolbarAnnouncer),
delay: 250
}), scrollable && areAnyNewToolbarFlagsEnabled && jsx(ScrollButton, {
intl: intl,
scrollContainerRef: this.scrollContainerRef,
node: node,
disabled: this.state.scrollDisabled,
side: "left"
}), jsx("div", {
"data-testid": "floating-toolbar-items",
ref: this.scrollContainerRef
// eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
,
css: toolbarOverflow({
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled,
scrollable: scrollable,
scrollDisabled: this.state.scrollDisabled,
firstElementIsSelect: firstElementIsSelect
})
}, jsx(ToolbarItems
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, this.props, {
setDisableScroll: this.setDisableScroll.bind(this),
mountRef: this.mountRef,
mounted: this.state.mounted
}))), scrollable && (areAnyNewToolbarFlagsEnabled ? jsx(ScrollButton, {
intl: intl,
scrollContainerRef: this.scrollContainerRef,
node: node,
disabled: this.state.scrollDisabled,
side: "right"
}) : jsx(ScrollButtons, {
intl: intl,
scrollContainerRef: this.scrollContainerRef,
node: node,
disabled: this.state.scrollDisabled,
areAnyNewToolbarFlagsEnabled: areAnyNewToolbarFlagsEnabled
}))), jsx("div", {
ref: this.mountRef
})));
}
}]);
}(Component); // eslint-disable-next-line @typescript-eslint/ban-types
var _default_1 = injectIntl(Toolbar);
export default _default_1;