UNPKG

@atlaskit/editor-plugin-text-formatting

Version:

Text-formatting plugin for @atlaskit/editor-core

214 lines (212 loc) 8.6 kB
/** * @jsxRuntime classic * @jsx jsx */ import { useEffect, useMemo, useState } from 'react'; // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 import { jsx } from '@emotion/react'; import { injectIntl } from 'react-intl'; import { usePreviousState } from '@atlaskit/editor-common/hooks'; import { toolbarMessages } from '@atlaskit/editor-common/messages'; import { buttonGroupStyle, separatorStyles, wrapperStyle } from '@atlaskit/editor-common/styles'; import { Announcer } from '@atlaskit/editor-common/ui'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import { compareItemsArrays, isArrayContainsContent } from '../../editor-commands/utils'; import { FormattingTextDropdownMenu } from './dropdown-menu'; import { useClearIcon } from './hooks/clear-formatting-icon'; import { useFormattingIcons, useHasFormattingActived } from './hooks/formatting-icons'; import { useResponsiveIconTypeMenu, useResponsiveToolbarButtons } from './hooks/responsive-toolbar-buttons'; import { MoreButton } from './more-button'; import { SingleToolbarButtons } from './single-toolbar-buttons'; const ToolbarFormatting = ({ shouldUseResponsiveToolbar, popupsMountPoint, popupsBoundariesElement, popupsScrollableElement, editorView, toolbarSize, isReducedSpacing, isToolbarDisabled, intl, editorAnalyticsAPI, textFormattingState, api, toolbarType }) => { var _usePreviousState; const [message, setMessage] = useState(''); const { formattingIsPresent, ...formattingIconState } = textFormattingState; const defaultIcons = useFormattingIcons({ schema: editorView.state.schema, intl, isToolbarDisabled, editorAnalyticsAPI, textFormattingState: formattingIconState, toolbarType }); const clearIcon = useClearIcon({ formattingPluginInitialised: textFormattingState.isInitialised, formattingIsPresent, intl, editorAnalyticsAPI, toolbarType }); const menuIconTypeList = useResponsiveIconTypeMenu({ toolbarSize, responsivenessEnabled: shouldUseResponsiveToolbar }); const hasFormattingActive = useHasFormattingActived({ iconTypeList: menuIconTypeList, textFormattingState }); const { dropdownItems, singleItems } = useResponsiveToolbarButtons({ icons: defaultIcons, toolbarSize, responsivenessEnabled: shouldUseResponsiveToolbar }); const clearFormattingStatus = intl.formatMessage(toolbarMessages.textFormattingOff); const superscriptOffSubscriptOnStatus = intl.formatMessage(toolbarMessages.superscriptOffSubscriptOn); const subscriptOffSuperscriptOnStatus = intl.formatMessage(toolbarMessages.subscriptOffSuperscriptOn); // eslint-disable-next-line @atlassian/perf-linting/no-expensive-computations-in-render -- Ignored via go/ees017 (to be fixed) const activeItems = [...dropdownItems, ...singleItems].filter(item => item.isActive); const prevActiveItems = (_usePreviousState = usePreviousState(activeItems)) !== null && _usePreviousState !== void 0 ? _usePreviousState : []; const fromSuperscriptToSubscript = isArrayContainsContent(activeItems, 'Subscript') && isArrayContainsContent(prevActiveItems, 'Superscript'); const fromSubscriptToSuperscript = isArrayContainsContent(activeItems, 'Superscript') && isArrayContainsContent(prevActiveItems, 'Subscript'); let comparedItems; let screenReaderMessage = ''; if (prevActiveItems && activeItems.length > prevActiveItems.length) { comparedItems = compareItemsArrays(activeItems, prevActiveItems); screenReaderMessage = intl.formatMessage(toolbarMessages.on, { formattingType: comparedItems[0].content }); } else { comparedItems = compareItemsArrays(prevActiveItems, activeItems); if (comparedItems && comparedItems.length) { var _activeItems$; screenReaderMessage = intl.formatMessage(toolbarMessages.off, { formattingType: comparedItems[0].content }); if (((_activeItems$ = activeItems[0]) === null || _activeItems$ === void 0 ? void 0 : _activeItems$.content) === 'Code') { screenReaderMessage = intl.formatMessage(toolbarMessages.codeOn, { textFormattingOff: (prevActiveItems === null || prevActiveItems === void 0 ? void 0 : prevActiveItems.length) > 1 ? clearFormattingStatus : screenReaderMessage }); } if (fromSuperscriptToSubscript) { screenReaderMessage = superscriptOffSubscriptOnStatus; } if (fromSubscriptToSuperscript) { screenReaderMessage = subscriptOffSuperscriptOnStatus; } } } // handle 'Clear formatting' status for screen readers if (!(activeItems !== null && activeItems !== void 0 && activeItems.length) && (prevActiveItems === null || prevActiveItems === void 0 ? void 0 : prevActiveItems.length) > 1) { screenReaderMessage = clearFormattingStatus; } const items = useMemo(() => { if (!clearIcon) { return [{ items: dropdownItems }]; } return [{ items: dropdownItems }, { items: [clearIcon] }]; }, [clearIcon, dropdownItems]); const moreFormattingButtonLabel = intl.formatMessage(toolbarMessages.moreFormatting); const labelTextFormat = intl.formatMessage(toolbarMessages.textFormatting); useEffect(() => { if (screenReaderMessage) { setMessage(screenReaderMessage); } }, [screenReaderMessage]); return ( // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766 jsx("span", { css: // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values buttonGroupStyle }, jsx("div", { role: "group" // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766 , className: 'js-text-format-wrap', "aria-label": labelTextFormat }, message && jsx(Announcer, { ariaLive: "assertive", text: message, ariaRelevant: "additions", delay: 250 }), jsx(SingleToolbarButtons, { items: singleItems, editorView: editorView, isReducedSpacing: isReducedSpacing }), jsx("span", { // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage css: wrapperStyle }, isToolbarDisabled && !editorExperiment('platform_editor_controls', 'variant1') ? jsx("div", null, jsx(MoreButton, { label: moreFormattingButtonLabel, isReducedSpacing: isReducedSpacing, isDisabled: true, isSelected: false, "aria-expanded": undefined, "aria-pressed": undefined })) : jsx(FormattingTextDropdownMenu, { popupsMountPoint: popupsMountPoint, popupsBoundariesElement: popupsBoundariesElement, popupsScrollableElement: popupsScrollableElement, editorView: editorView, isReducedSpacing: isReducedSpacing, moreButtonLabel: moreFormattingButtonLabel, hasFormattingActive: hasFormattingActive, hasMoreButton: !editorExperiment('platform_editor_controls', 'variant1'), items: items, intl: intl, toolbarType: toolbarType, isDisabled: editorExperiment('platform_editor_controls', 'variant1') ? isToolbarDisabled : false }))), !(api !== null && api !== void 0 && api.primaryToolbar) && /* eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage */ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 jsx("span", { css: separatorStyles })) ); }; const Toolbar = ({ popupsMountPoint, popupsScrollableElement, toolbarSize, isReducedSpacing, editorView, isToolbarDisabled, shouldUseResponsiveToolbar, intl, editorAnalyticsAPI, textFormattingState, api, toolbarType }) => { return jsx(ToolbarFormatting, { textFormattingState: textFormattingState, popupsMountPoint: popupsMountPoint, popupsScrollableElement: popupsScrollableElement, toolbarSize: toolbarSize, isReducedSpacing: isReducedSpacing, editorView: editorView, isToolbarDisabled: isToolbarDisabled, shouldUseResponsiveToolbar: shouldUseResponsiveToolbar, intl: intl, editorAnalyticsAPI: editorAnalyticsAPI, api: api, toolbarType: toolbarType }); }; const _default_1 = injectIntl(Toolbar); export default _default_1;