@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
232 lines • 14.8 kB
JavaScript
import React from 'react';
import { ACTION_SUBJECT, ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics';
import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
import { getDomRefFromSelection } from '@atlaskit/editor-common/get-dom-ref-from-selection';
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
import { ResizerBreakoutModeLabel } from '@atlaskit/editor-common/resizer';
import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import FloatingContextualButton from './FloatingContextualButton';
import FloatingContextualMenu from './FloatingContextualMenu';
import FloatingDeleteButton from './FloatingDeleteButton';
import FloatingDragMenu from './FloatingDragMenu';
// Ignored via go/ees005
// eslint-disable-next-line import/no-named-as-default
import FloatingInsertButton from './FloatingInsertButton';
import { FloatingToolbarLabel } from './FloatingToolbarLabel/FloatingToolbarLabel';
import { GlobalStylesWrapper } from './global-styles';
import { SizeSelector } from './SizeSelector';
import { FullWidthDisplay } from './TableFullWidthLabel';
const selector = states => {
var _states$tableState, _states$tableState2, _states$tableState3, _states$tableState4, _states$tableState5, _states$tableState6, _states$tableState7, _states$tableState8, _states$tableState9, _states$tableState0, _states$tableState1, _states$tableState10, _states$tableState11, _states$tableState12, _states$tableState13, _states$tableState14, _states$tableState15, _states$tableState16, _states$tableState17, _states$tableState18, _states$tableState19, _states$tableState20, _states$tableState21, _states$tableState22, _states$tableState23, _states$tableState24;
return {
resizingTableLocalId: (_states$tableState = states.tableState) === null || _states$tableState === void 0 ? void 0 : _states$tableState.resizingTableLocalId,
resizingTableRef: (_states$tableState2 = states.tableState) === null || _states$tableState2 === void 0 ? void 0 : _states$tableState2.resizingTableRef,
isTableResizing: (_states$tableState3 = states.tableState) === null || _states$tableState3 === void 0 ? void 0 : _states$tableState3.isTableResizing,
isResizing: (_states$tableState4 = states.tableState) === null || _states$tableState4 === void 0 ? void 0 : _states$tableState4.isResizing,
widthToWidest: (_states$tableState5 = states.tableState) === null || _states$tableState5 === void 0 ? void 0 : _states$tableState5.widthToWidest,
tableNode: (_states$tableState6 = states.tableState) === null || _states$tableState6 === void 0 ? void 0 : _states$tableState6.tableNode,
targetCellPosition: (_states$tableState7 = states.tableState) === null || _states$tableState7 === void 0 ? void 0 : _states$tableState7.targetCellPosition,
isContextualMenuOpen: (_states$tableState8 = states.tableState) === null || _states$tableState8 === void 0 ? void 0 : _states$tableState8.isContextualMenuOpen,
tableRef: (_states$tableState9 = states.tableState) === null || _states$tableState9 === void 0 ? void 0 : _states$tableState9.tableRef,
pluginConfig: (_states$tableState0 = states.tableState) === null || _states$tableState0 === void 0 ? void 0 : _states$tableState0.pluginConfig,
insertColumnButtonIndex: (_states$tableState1 = states.tableState) === null || _states$tableState1 === void 0 ? void 0 : _states$tableState1.insertColumnButtonIndex,
insertRowButtonIndex: (_states$tableState10 = states.tableState) === null || _states$tableState10 === void 0 ? void 0 : _states$tableState10.insertRowButtonIndex,
isHeaderColumnEnabled: (_states$tableState11 = states.tableState) === null || _states$tableState11 === void 0 ? void 0 : _states$tableState11.isHeaderColumnEnabled,
isHeaderRowEnabled: (_states$tableState12 = states.tableState) === null || _states$tableState12 === void 0 ? void 0 : _states$tableState12.isHeaderRowEnabled,
isDragAndDropEnabled: (_states$tableState13 = states.tableState) === null || _states$tableState13 === void 0 ? void 0 : _states$tableState13.isDragAndDropEnabled,
tableWrapperTarget: (_states$tableState14 = states.tableState) === null || _states$tableState14 === void 0 ? void 0 : _states$tableState14.tableWrapperTarget,
isCellMenuOpenByKeyboard: (_states$tableState15 = states.tableState) === null || _states$tableState15 === void 0 ? void 0 : _states$tableState15.isCellMenuOpenByKeyboard,
stickyHeader: (_states$tableState16 = states.tableState) === null || _states$tableState16 === void 0 ? void 0 : _states$tableState16.stickyHeader,
dragMenuDirection: (_states$tableState17 = states.tableState) === null || _states$tableState17 === void 0 ? void 0 : _states$tableState17.dragMenuDirection,
dragMenuIndex: (_states$tableState18 = states.tableState) === null || _states$tableState18 === void 0 ? void 0 : _states$tableState18.dragMenuIndex,
isDragMenuOpen: (_states$tableState19 = states.tableState) === null || _states$tableState19 === void 0 ? void 0 : _states$tableState19.isDragMenuOpen,
isSizeSelectorOpen: (_states$tableState20 = states.tableState) === null || _states$tableState20 === void 0 ? void 0 : _states$tableState20.isSizeSelectorOpen,
sizeSelectorTargetRef: (_states$tableState21 = states.tableState) === null || _states$tableState21 === void 0 ? void 0 : _states$tableState21.sizeSelectorTargetRef,
// IMPORTANT: hovered states are used by FloatingDragMenu component to render popup in the correct location
hoveredRows: (_states$tableState22 = states.tableState) === null || _states$tableState22 === void 0 ? void 0 : _states$tableState22.hoveredRows,
hoveredColumns: (_states$tableState23 = states.tableState) === null || _states$tableState23 === void 0 ? void 0 : _states$tableState23.hoveredColumns,
hoveredCell: (_states$tableState24 = states.tableState) === null || _states$tableState24 === void 0 ? void 0 : _states$tableState24.hoveredCell
};
};
const ContentComponentInternal = ({
api,
editorView,
dispatchAnalyticsEvent,
options,
popupsMountPoint,
popupsBoundariesElement,
popupsScrollableElement,
isTableSelectorEnabled,
defaultGetEditorContainerWidth,
defaultGetEditorFeatureFlags
}) => {
var _api$analytics, _api$accessibilityUti, _api$analytics2;
const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
const ariaNotifyPlugin = api === null || api === void 0 ? void 0 : (_api$accessibilityUti = api.accessibilityUtils) === null || _api$accessibilityUti === void 0 ? void 0 : _api$accessibilityUti.actions.ariaNotify;
const {
resizingTableLocalId,
resizingTableRef,
isTableResizing,
isResizing,
widthToWidest,
tableNode,
targetCellPosition,
isContextualMenuOpen,
tableRef,
pluginConfig,
insertColumnButtonIndex,
insertRowButtonIndex,
isHeaderColumnEnabled,
isHeaderRowEnabled,
isDragAndDropEnabled,
tableWrapperTarget,
isCellMenuOpenByKeyboard,
stickyHeader,
dragMenuDirection,
dragMenuIndex,
isDragMenuOpen,
isSizeSelectorOpen,
sizeSelectorTargetRef
} = useSharedPluginStateWithSelector(api, ['table'], selector);
const {
allowControls
} = pluginConfig !== null && pluginConfig !== void 0 ? pluginConfig : {};
if (!editorView) {
return null;
}
return /*#__PURE__*/React.createElement(React.Fragment, null, targetCellPosition && (tableRef || isCellMenuOpenByKeyboard) && !isResizing && options && options.allowContextualMenu && /*#__PURE__*/React.createElement(FloatingContextualButton, {
isNumberColumnEnabled: tableNode && tableNode.attrs.isNumberColumnEnabled,
editorView: editorView,
tableNode: tableNode,
mountPoint: popupsMountPoint,
targetCellPosition: targetCellPosition,
scrollableElement: popupsScrollableElement,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
isContextualMenuOpen: isContextualMenuOpen,
stickyHeader: stickyHeader,
tableWrapper: tableWrapperTarget,
isCellMenuOpenByKeyboard: isCellMenuOpenByKeyboard,
isDragAndDropEnabled: isDragAndDropEnabled
}), allowControls && /*#__PURE__*/React.createElement(FloatingInsertButton, {
tableNode: tableNode,
tableRef: tableRef,
insertColumnButtonIndex: insertColumnButtonIndex,
insertRowButtonIndex: insertRowButtonIndex,
isHeaderColumnEnabled: isHeaderColumnEnabled,
isHeaderRowEnabled: isHeaderRowEnabled,
isDragAndDropEnabled: isDragAndDropEnabled,
isTableScalingEnabled: options === null || options === void 0 ? void 0 : options.isTableScalingEnabled,
editorView: editorView,
mountPoint: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
scrollableElement: popupsScrollableElement,
hasStickyHeaders: stickyHeader && stickyHeader.sticky,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
editorAnalyticsAPI: editorAnalyticsAPI,
getEditorContainerWidth: defaultGetEditorContainerWidth,
getEditorFeatureFlags: (options === null || options === void 0 ? void 0 : options.getEditorFeatureFlags) || defaultGetEditorFeatureFlags,
isChromelessEditor: options === null || options === void 0 ? void 0 : options.isChromelessEditor,
api: api,
isCommentEditor: options === null || options === void 0 ? void 0 : options.isCommentEditor
}), (options === null || options === void 0 ? void 0 : options.allowContextualMenu) && /*#__PURE__*/React.createElement(FloatingContextualMenu, {
editorView: editorView,
mountPoint: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
targetCellPosition: targetCellPosition,
isOpen: Boolean(isContextualMenuOpen) && !isResizing,
pluginConfig: pluginConfig,
editorAnalyticsAPI: editorAnalyticsAPI,
getEditorContainerWidth: defaultGetEditorContainerWidth,
getEditorFeatureFlags: (options === null || options === void 0 ? void 0 : options.getEditorFeatureFlags) || defaultGetEditorFeatureFlags,
isCellMenuOpenByKeyboard: isCellMenuOpenByKeyboard,
isCommentEditor: options === null || options === void 0 ? void 0 : options.isCommentEditor,
api: api,
isDragMenuOpen: isDragMenuOpen
}), isDragAndDropEnabled && /*#__PURE__*/React.createElement(FloatingDragMenu, {
editorView: editorView,
mountPoint: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
tableRef: tableRef,
tableNode: tableNode,
targetCellPosition: targetCellPosition,
direction: dragMenuDirection,
index: dragMenuIndex,
isOpen: !!isDragMenuOpen && !isResizing,
getEditorContainerWidth: defaultGetEditorContainerWidth,
editorAnalyticsAPI: editorAnalyticsAPI,
stickyHeaders: stickyHeader,
pluginConfig: pluginConfig,
isTableScalingEnabled: options === null || options === void 0 ? void 0 : options.isTableScalingEnabled,
getEditorFeatureFlags: (options === null || options === void 0 ? void 0 : options.getEditorFeatureFlags) || defaultGetEditorFeatureFlags,
ariaNotifyPlugin: ariaNotifyPlugin,
api: api,
isCommentEditor: options === null || options === void 0 ? void 0 : options.isCommentEditor,
tableWrapper: tableWrapperTarget
}), allowControls && !isDragAndDropEnabled && !isResizing && /*#__PURE__*/React.createElement(FloatingDeleteButton, {
editorView: editorView,
selection: editorView.state.selection,
tableRef: tableRef,
mountPoint: popupsMountPoint,
boundariesElement: popupsBoundariesElement,
scrollableElement: popupsScrollableElement,
stickyHeaders: stickyHeader,
isNumberColumnEnabled: tableNode && tableNode.attrs.isNumberColumnEnabled,
editorAnalyticsAPI: editorAnalyticsAPI,
api: api
}), ((options === null || options === void 0 ? void 0 : options.isTableScalingEnabled) || (options === null || options === void 0 ? void 0 : options.tableOptions.allowTableResizing) && options.isCommentEditor) && isTableResizing && widthToWidest && resizingTableLocalId && resizingTableRef && widthToWidest[resizingTableLocalId] && /*#__PURE__*/React.createElement(FloatingToolbarLabel, {
target: resizingTableRef,
content: editorExperiment('single_column_layouts', true) ? /*#__PURE__*/React.createElement(ResizerBreakoutModeLabel, {
layout: "full-width"
}) : /*#__PURE__*/React.createElement(FullWidthDisplay, null),
alignX: 'center',
alignY: 'bottom',
stick: true,
forcePlacement: true,
zIndex: akEditorFloatingPanelZIndex
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
,
offset: [0, 10]
}), isTableSelectorEnabled && isSizeSelectorOpen && /*#__PURE__*/React.createElement(SizeSelector, {
api: api,
isOpenedByKeyboard: false,
popupsMountPoint: popupsMountPoint,
target: sizeSelectorTargetRef !== null && sizeSelectorTargetRef !== void 0 ? sizeSelectorTargetRef : getDomRefFromSelection(editorView, ACTION_SUBJECT_ID.PICKER_TABLE_SIZE, api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions),
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement
}));
};
export const ContentComponent = ({
api,
editorView,
dispatchAnalyticsEvent,
options,
popupsMountPoint,
popupsBoundariesElement,
popupsScrollableElement,
isTableSelectorEnabled,
defaultGetEditorContainerWidth,
defaultGetEditorFeatureFlags
}) => {
var _api$featureFlags;
return /*#__PURE__*/React.createElement(ErrorBoundary, {
component: ACTION_SUBJECT.TABLES_PLUGIN,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
fallbackComponent: null
}, /*#__PURE__*/React.createElement(GlobalStylesWrapper, {
featureFlags: api === null || api === void 0 ? void 0 : (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState(),
isDragAndDropEnabledOption: options === null || options === void 0 ? void 0 : options.dragAndDropEnabled,
api: api
}), /*#__PURE__*/React.createElement(ContentComponentInternal, {
api: api,
editorView: editorView,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
options: options,
popupsMountPoint: popupsMountPoint,
popupsBoundariesElement: popupsBoundariesElement,
popupsScrollableElement: popupsScrollableElement,
isTableSelectorEnabled: isTableSelectorEnabled,
defaultGetEditorContainerWidth: defaultGetEditorContainerWidth,
defaultGetEditorFeatureFlags: defaultGetEditorFeatureFlags
}));
};