@atlaskit/editor-plugin-table 1.6.1 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/plugins/table/index.js +2 -1
- package/dist/cjs/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +3 -1
- package/dist/cjs/plugins/table/types.js +1 -0
- package/dist/cjs/plugins/table/ui/FloatingContextualButton/FixedButton.js +133 -0
- package/dist/cjs/plugins/table/ui/FloatingContextualButton/index.js +73 -128
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/plugins/table/index.js +2 -1
- package/dist/es2019/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +3 -1
- package/dist/es2019/plugins/table/types.js +1 -0
- package/dist/es2019/plugins/table/ui/FloatingContextualButton/FixedButton.js +120 -0
- package/dist/es2019/plugins/table/ui/FloatingContextualButton/index.js +76 -108
- package/dist/es2019/version.json +1 -1
- package/dist/esm/plugins/table/index.js +2 -1
- package/dist/esm/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +3 -1
- package/dist/esm/plugins/table/types.js +1 -0
- package/dist/esm/plugins/table/ui/FloatingContextualButton/FixedButton.js +118 -0
- package/dist/esm/plugins/table/ui/FloatingContextualButton/index.js +73 -129
- package/dist/esm/version.json +1 -1
- package/dist/types/plugins/table/types.d.ts +1 -0
- package/dist/types/plugins/table/ui/FloatingContextualButton/FixedButton.d.ts +23 -0
- package/dist/types/plugins/table/ui/FloatingContextualButton/index.d.ts +1 -9
- package/dist/types-ts4.5/plugins/table/types.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/ui/FloatingContextualButton/FixedButton.d.ts +23 -0
- package/dist/types-ts4.5/plugins/table/ui/FloatingContextualButton/index.d.ts +1 -9
- package/package.json +5 -4
- package/src/__tests__/playwright/__fixtures__/base-adfs.ts +1486 -0
- package/src/__tests__/playwright/extensions.spec.ts +67 -0
- package/src/__tests__/unit/nodeviews/cell.ts +0 -14
- package/src/__tests__/unit/ui/FixedButton.tsx +214 -0
- package/src/plugins/table/index.tsx +1 -0
- package/src/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.ts +2 -1
- package/src/plugins/table/types.ts +1 -0
- package/src/plugins/table/ui/FloatingContextualButton/FixedButton.tsx +175 -0
- package/src/plugins/table/ui/FloatingContextualButton/index.tsx +41 -95
|
@@ -1,128 +1,96 @@
|
|
|
1
|
-
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
1
|
/** @jsx jsx */
|
|
3
2
|
import React from 'react';
|
|
4
3
|
import { jsx } from '@emotion/react';
|
|
5
4
|
import { findDomRefAtPos } from 'prosemirror-utils';
|
|
6
5
|
import { injectIntl } from 'react-intl-next';
|
|
7
6
|
import { Popup } from '@atlaskit/editor-common/ui';
|
|
8
|
-
import {
|
|
7
|
+
import { akEditorSmallZIndex } from '@atlaskit/editor-shared-styles';
|
|
9
8
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
10
9
|
import { ToolbarButton } from '@atlaskit/editor-common/ui-menu';
|
|
11
|
-
import { closestElement } from '@atlaskit/editor-common/utils';
|
|
12
10
|
import { toggleContextualMenu } from '../../commands';
|
|
13
11
|
import { TableCssClassName as ClassName } from '../../types';
|
|
14
12
|
import messages from '../../ui/messages';
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
13
|
+
import FixedButton from './FixedButton';
|
|
14
|
+
import { ACTION_SUBJECT } from '@atlaskit/editor-common/analytics';
|
|
17
15
|
import { tableFloatingCellButtonStyles, tableFloatingCellButtonSelectedStyles } from './styles';
|
|
18
16
|
import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// will be toggled appropriately
|
|
32
|
-
if (!this.props.isContextualMenuOpen) {
|
|
33
|
-
toggleContextualMenu()(state, dispatch);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
render() {
|
|
38
|
-
const {
|
|
39
|
-
mountPoint,
|
|
40
|
-
scrollableElement,
|
|
41
|
-
editorView,
|
|
42
|
-
targetCellPosition,
|
|
43
|
-
isContextualMenuOpen,
|
|
44
|
-
intl: {
|
|
45
|
-
formatMessage
|
|
46
|
-
},
|
|
47
|
-
dispatchAnalyticsEvent
|
|
48
|
-
} = this.props; // : Props & WrappedComponentProps
|
|
49
|
-
const domAtPos = editorView.domAtPos.bind(editorView);
|
|
50
|
-
let targetCellRef;
|
|
51
|
-
try {
|
|
52
|
-
targetCellRef = findDomRefAtPos(targetCellPosition, domAtPos);
|
|
53
|
-
} catch (error) {
|
|
54
|
-
// eslint-disable-next-line no-console
|
|
55
|
-
console.warn(error);
|
|
56
|
-
if (dispatchAnalyticsEvent) {
|
|
57
|
-
const payload = {
|
|
58
|
-
action: ACTION.ERRORED,
|
|
59
|
-
actionSubject: ACTION_SUBJECT.CONTENT_COMPONENT,
|
|
60
|
-
eventType: EVENT_TYPE.OPERATIONAL,
|
|
61
|
-
attributes: {
|
|
62
|
-
component: CONTENT_COMPONENT.FLOATING_CONTEXTUAL_BUTTON,
|
|
63
|
-
selection: editorView.state.selection.toJSON(),
|
|
64
|
-
position: targetCellPosition,
|
|
65
|
-
docSize: editorView.state.doc.nodeSize,
|
|
66
|
-
error: error instanceof Error ? error.message : String(error)
|
|
67
|
-
},
|
|
68
|
-
nonPrivacySafeAttributes: {
|
|
69
|
-
errorStack: error instanceof Error ? error.stack : undefined
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
dispatchAnalyticsEvent(payload);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (!targetCellRef || !(targetCellRef instanceof HTMLElement)) {
|
|
76
|
-
return null;
|
|
17
|
+
const BUTTON_OFFSET = 3;
|
|
18
|
+
const FloatingContextualButtonInner = /*#__PURE__*/React.memo(props => {
|
|
19
|
+
const {
|
|
20
|
+
editorView,
|
|
21
|
+
isContextualMenuOpen,
|
|
22
|
+
mountPoint,
|
|
23
|
+
scrollableElement,
|
|
24
|
+
stickyHeader,
|
|
25
|
+
tableWrapper,
|
|
26
|
+
targetCellPosition,
|
|
27
|
+
intl: {
|
|
28
|
+
formatMessage
|
|
77
29
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
label: ""
|
|
93
|
-
}),
|
|
94
|
-
"aria-label": labelCellOptions
|
|
95
|
-
}));
|
|
96
|
-
const parentSticky = targetCellRef.parentElement && targetCellRef.parentElement.className.indexOf('sticky') > -1;
|
|
97
|
-
if (this.props.stickyHeader && parentSticky) {
|
|
98
|
-
const pos = targetCellRef.getBoundingClientRect();
|
|
99
|
-
return jsx("div", {
|
|
100
|
-
style: {
|
|
101
|
-
position: 'fixed',
|
|
102
|
-
top: this.props.stickyHeader.top + this.props.stickyHeader.padding + 3 + 3,
|
|
103
|
-
zIndex: akEditorFloatingOverlapPanelZIndex,
|
|
104
|
-
left: pos.left + targetCellRef.clientWidth - 20 - 3
|
|
105
|
-
}
|
|
106
|
-
}, button);
|
|
30
|
+
} = props; // : Props & WrappedComponentProps
|
|
31
|
+
|
|
32
|
+
const handleClick = () => {
|
|
33
|
+
const {
|
|
34
|
+
state,
|
|
35
|
+
dispatch
|
|
36
|
+
} = editorView;
|
|
37
|
+
// Clicking outside the dropdown handles toggling the menu closed
|
|
38
|
+
// (otherwise these two toggles combat each other).
|
|
39
|
+
// In the event a user clicks the chevron button again
|
|
40
|
+
// That will count as clicking outside the dropdown and
|
|
41
|
+
// will be toggled appropriately
|
|
42
|
+
if (!isContextualMenuOpen) {
|
|
43
|
+
toggleContextualMenu()(state, dispatch);
|
|
107
44
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
scrollableElement: scrollableElement,
|
|
115
|
-
offset: [3, -3],
|
|
116
|
-
forcePlacement: true,
|
|
117
|
-
allowOutOfBounds: true,
|
|
118
|
-
zIndex: akEditorSmallZIndex
|
|
119
|
-
}, button);
|
|
45
|
+
};
|
|
46
|
+
const domAtPos = editorView.domAtPos.bind(editorView);
|
|
47
|
+
let targetCellRef;
|
|
48
|
+
targetCellRef = findDomRefAtPos(targetCellPosition, domAtPos);
|
|
49
|
+
if (!targetCellRef || !(targetCellRef instanceof HTMLElement)) {
|
|
50
|
+
return null;
|
|
120
51
|
}
|
|
121
|
-
|
|
122
|
-
|
|
52
|
+
const labelCellOptions = formatMessage(messages.cellOptions);
|
|
53
|
+
const button = jsx("div", {
|
|
54
|
+
css: theme => [tableFloatingCellButtonStyles({
|
|
55
|
+
theme
|
|
56
|
+
}), isContextualMenuOpen && tableFloatingCellButtonSelectedStyles({
|
|
57
|
+
theme
|
|
58
|
+
})]
|
|
59
|
+
}, jsx(ToolbarButton, {
|
|
60
|
+
className: ClassName.CONTEXTUAL_MENU_BUTTON,
|
|
61
|
+
selected: isContextualMenuOpen,
|
|
62
|
+
title: labelCellOptions,
|
|
63
|
+
onClick: handleClick,
|
|
64
|
+
iconBefore: jsx(ExpandIcon, {
|
|
65
|
+
label: ""
|
|
66
|
+
}),
|
|
67
|
+
"aria-label": labelCellOptions
|
|
68
|
+
}));
|
|
69
|
+
const parentSticky = targetCellRef.parentElement && targetCellRef.parentElement.className.indexOf('sticky') > -1;
|
|
70
|
+
if (stickyHeader && parentSticky && tableWrapper) {
|
|
71
|
+
return jsx(FixedButton, {
|
|
72
|
+
offset: BUTTON_OFFSET,
|
|
73
|
+
stickyHeader: stickyHeader,
|
|
74
|
+
tableWrapper: tableWrapper,
|
|
75
|
+
targetCellPosition: targetCellPosition,
|
|
76
|
+
targetCellRef: targetCellRef,
|
|
77
|
+
mountTo: tableWrapper,
|
|
78
|
+
isContextualMenuOpen: isContextualMenuOpen
|
|
79
|
+
}, button);
|
|
123
80
|
}
|
|
124
|
-
|
|
125
|
-
|
|
81
|
+
return jsx(Popup, {
|
|
82
|
+
alignX: "right",
|
|
83
|
+
alignY: "start",
|
|
84
|
+
target: targetCellRef,
|
|
85
|
+
mountTo: tableWrapper || mountPoint,
|
|
86
|
+
boundariesElement: targetCellRef,
|
|
87
|
+
scrollableElement: scrollableElement,
|
|
88
|
+
offset: [BUTTON_OFFSET, -BUTTON_OFFSET],
|
|
89
|
+
forcePlacement: true,
|
|
90
|
+
allowOutOfBounds: true,
|
|
91
|
+
zIndex: akEditorSmallZIndex
|
|
92
|
+
}, button);
|
|
93
|
+
});
|
|
126
94
|
const FloatingContextualButton = injectIntl(FloatingContextualButtonInner);
|
|
127
95
|
export default function (props) {
|
|
128
96
|
return jsx(ErrorBoundary, {
|
package/dist/es2019/version.json
CHANGED
|
@@ -254,7 +254,8 @@ var tablesPlugin = function tablesPlugin(options, api) {
|
|
|
254
254
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
255
255
|
isContextualMenuOpen: isContextualMenuOpen,
|
|
256
256
|
layout: layout,
|
|
257
|
-
stickyHeader: stickyHeader
|
|
257
|
+
stickyHeader: stickyHeader,
|
|
258
|
+
tableWrapper: tableWrapperTarget
|
|
258
259
|
}), allowControls && /*#__PURE__*/React.createElement(FloatingInsertButton, {
|
|
259
260
|
tableNode: tableNode,
|
|
260
261
|
tableRef: tableRef,
|
|
@@ -225,7 +225,8 @@ export var TableRowNodeView = /*#__PURE__*/function () {
|
|
|
225
225
|
if (_this.stickyRowHeight && _this.stickyRowHeight > window.innerHeight / 2) {
|
|
226
226
|
return;
|
|
227
227
|
}
|
|
228
|
-
var table = tree.table
|
|
228
|
+
var table = tree.table,
|
|
229
|
+
wrapper = tree.wrapper;
|
|
229
230
|
|
|
230
231
|
// ED-16035 Make sure sticky header is only applied to first row
|
|
231
232
|
var tbody = _this.dom.parentElement;
|
|
@@ -246,6 +247,7 @@ export var TableRowNodeView = /*#__PURE__*/function () {
|
|
|
246
247
|
}
|
|
247
248
|
_this.dom.style.top = "".concat(domTop, "px");
|
|
248
249
|
updateTableMargin(table);
|
|
250
|
+
_this.dom.scrollLeft = wrapper.scrollLeft;
|
|
249
251
|
_this.emitOn(domTop, _this.colControlsOffset);
|
|
250
252
|
});
|
|
251
253
|
_defineProperty(this, "makeRowHeaderNotSticky", function (table) {
|
|
@@ -90,6 +90,7 @@ export var TableCssClassName = _objectSpread(_objectSpread({}, TableSharedCssCla
|
|
|
90
90
|
CONTEXTUAL_SUBMENU: "".concat(tablePrefixSelector, "-contextual-submenu"),
|
|
91
91
|
CONTEXTUAL_MENU_BUTTON_WRAP: "".concat(tablePrefixSelector, "-contextual-menu-button-wrap"),
|
|
92
92
|
CONTEXTUAL_MENU_BUTTON: "".concat(tablePrefixSelector, "-contextual-menu-button"),
|
|
93
|
+
CONTEXTUAL_MENU_BUTTON_FIXED: "".concat(tablePrefixSelector, "-contextual-menu-button-fixed"),
|
|
93
94
|
CONTEXTUAL_MENU_ICON: "".concat(tablePrefixSelector, "-contextual-submenu-icon"),
|
|
94
95
|
// come from prosemirror-table
|
|
95
96
|
SELECTED_CELL: 'selectedCell',
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
3
|
+
import rafSchedule from 'raf-schd';
|
|
4
|
+
import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
|
|
5
|
+
import { insertColumnButtonOffset } from '../common-styles';
|
|
6
|
+
import { TableCssClassName as ClassName } from '../../types';
|
|
7
|
+
export var BUTTON_WIDTH = 20;
|
|
8
|
+
export var calcLeftPos = function calcLeftPos(_ref) {
|
|
9
|
+
var buttonWidth = _ref.buttonWidth,
|
|
10
|
+
cellRectLeft = _ref.cellRectLeft,
|
|
11
|
+
cellRefWidth = _ref.cellRefWidth,
|
|
12
|
+
offset = _ref.offset;
|
|
13
|
+
return cellRectLeft + cellRefWidth - buttonWidth - offset;
|
|
14
|
+
};
|
|
15
|
+
export var calcObserverTargetMargin = function calcObserverTargetMargin(tableWrapper, fixedButtonRefCurrent) {
|
|
16
|
+
var tableWrapperRect = tableWrapper.getBoundingClientRect();
|
|
17
|
+
var fixedButtonRect = fixedButtonRefCurrent.getBoundingClientRect();
|
|
18
|
+
var scrollLeft = tableWrapper.scrollLeft;
|
|
19
|
+
return fixedButtonRect.left - tableWrapperRect.left + scrollLeft;
|
|
20
|
+
};
|
|
21
|
+
export var FixedButton = function FixedButton(_ref2) {
|
|
22
|
+
var children = _ref2.children,
|
|
23
|
+
isContextualMenuOpen = _ref2.isContextualMenuOpen,
|
|
24
|
+
mountTo = _ref2.mountTo,
|
|
25
|
+
offset = _ref2.offset,
|
|
26
|
+
stickyHeader = _ref2.stickyHeader,
|
|
27
|
+
tableWrapper = _ref2.tableWrapper,
|
|
28
|
+
targetCellPosition = _ref2.targetCellPosition,
|
|
29
|
+
targetCellRef = _ref2.targetCellRef;
|
|
30
|
+
var fixedButtonRef = useRef(null);
|
|
31
|
+
var observerTargetRef = useRef(null);
|
|
32
|
+
|
|
33
|
+
// Using refs here rather than state to prevent heaps of renders on scroll
|
|
34
|
+
var scrollDataRef = useRef(0);
|
|
35
|
+
var leftPosDataRef = useRef(0);
|
|
36
|
+
useEffect(function () {
|
|
37
|
+
var observerTargetRefCurrent = observerTargetRef.current;
|
|
38
|
+
var fixedButtonRefCurrent = fixedButtonRef.current;
|
|
39
|
+
if (fixedButtonRefCurrent && observerTargetRefCurrent) {
|
|
40
|
+
scrollDataRef.current = tableWrapper.scrollLeft;
|
|
41
|
+
leftPosDataRef.current = 0;
|
|
42
|
+
// Hide the button initially in case there's a flash of the button being
|
|
43
|
+
// outside the table before the Intersection Observer fires
|
|
44
|
+
fixedButtonRefCurrent.style.visibility = 'hidden';
|
|
45
|
+
var margin = calcObserverTargetMargin(tableWrapper, fixedButtonRefCurrent);
|
|
46
|
+
|
|
47
|
+
// Much more simple and predictable to add this margin to the observer target
|
|
48
|
+
// rather than using it to calculate the rootMargin values
|
|
49
|
+
observerTargetRefCurrent.style.marginLeft = "".concat(margin, "px");
|
|
50
|
+
var observer = new IntersectionObserver(function (entries) {
|
|
51
|
+
entries.forEach(function (entry) {
|
|
52
|
+
if (entry.isIntersecting) {
|
|
53
|
+
fixedButtonRefCurrent.style.visibility = 'visible';
|
|
54
|
+
} else {
|
|
55
|
+
fixedButtonRefCurrent.style.visibility = 'hidden';
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}, {
|
|
59
|
+
root: tableWrapper,
|
|
60
|
+
rootMargin: "0px ".concat(insertColumnButtonOffset, "px 0px 0px"),
|
|
61
|
+
threshold: 1
|
|
62
|
+
});
|
|
63
|
+
var handleScroll = rafSchedule(function (event) {
|
|
64
|
+
if (fixedButtonRef.current) {
|
|
65
|
+
var delta = event.target.scrollLeft - scrollDataRef.current;
|
|
66
|
+
var style = "translateX(".concat(leftPosDataRef.current - delta, "px)");
|
|
67
|
+
fixedButtonRef.current.style.transform = style;
|
|
68
|
+
scrollDataRef.current = event.target.scrollLeft;
|
|
69
|
+
leftPosDataRef.current = leftPosDataRef.current - delta;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
observer.observe(observerTargetRefCurrent);
|
|
73
|
+
tableWrapper.addEventListener('scroll', handleScroll);
|
|
74
|
+
return function () {
|
|
75
|
+
tableWrapper.removeEventListener('scroll', handleScroll);
|
|
76
|
+
fixedButtonRefCurrent.style.transform = '';
|
|
77
|
+
observer.unobserve(observerTargetRefCurrent);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}, [fixedButtonRef, observerTargetRef, tableWrapper, targetCellPosition, targetCellRef, isContextualMenuOpen]);
|
|
81
|
+
var targetCellRect = targetCellRef.getBoundingClientRect();
|
|
82
|
+
|
|
83
|
+
// Using a portal here to ensure wrapperRef has the tableWrapper as an
|
|
84
|
+
// ancestor. This is required to make the Intersection Observer work.
|
|
85
|
+
return /*#__PURE__*/createPortal(
|
|
86
|
+
/*#__PURE__*/
|
|
87
|
+
// Using observerTargetRef here for our Intersection Observer. There is issues
|
|
88
|
+
// getting the observer to work just using the fixedButtonRef, possible due
|
|
89
|
+
// to using position fixed on this Element, or possibly due to its position
|
|
90
|
+
// being changed on scroll.
|
|
91
|
+
React.createElement("div", {
|
|
92
|
+
ref: observerTargetRef,
|
|
93
|
+
style: {
|
|
94
|
+
position: 'absolute',
|
|
95
|
+
top: '0px',
|
|
96
|
+
left: '0px',
|
|
97
|
+
width: "".concat(BUTTON_WIDTH, "px"),
|
|
98
|
+
height: "".concat(BUTTON_WIDTH, "px")
|
|
99
|
+
}
|
|
100
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
101
|
+
ref: fixedButtonRef,
|
|
102
|
+
style: {
|
|
103
|
+
position: 'fixed',
|
|
104
|
+
top: stickyHeader.top + stickyHeader.padding + offset * 2,
|
|
105
|
+
zIndex: akEditorFloatingPanelZIndex,
|
|
106
|
+
left: calcLeftPos({
|
|
107
|
+
buttonWidth: BUTTON_WIDTH,
|
|
108
|
+
cellRectLeft: targetCellRect.left,
|
|
109
|
+
cellRefWidth: targetCellRef.clientWidth,
|
|
110
|
+
offset: offset
|
|
111
|
+
}),
|
|
112
|
+
width: "".concat(BUTTON_WIDTH, "px"),
|
|
113
|
+
height: "".concat(BUTTON_WIDTH, "px")
|
|
114
|
+
},
|
|
115
|
+
className: ClassName.CONTEXTUAL_MENU_BUTTON_FIXED
|
|
116
|
+
}, children)), mountTo);
|
|
117
|
+
};
|
|
118
|
+
export default FixedButton;
|
|
@@ -1,148 +1,92 @@
|
|
|
1
|
-
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
-
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
-
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
|
|
4
|
-
import _inherits from "@babel/runtime/helpers/inherits";
|
|
5
|
-
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
6
|
-
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
7
|
-
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
8
|
-
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
9
|
-
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
10
1
|
/** @jsx jsx */
|
|
11
2
|
import React from 'react';
|
|
12
3
|
import { jsx } from '@emotion/react';
|
|
13
4
|
import { findDomRefAtPos } from 'prosemirror-utils';
|
|
14
5
|
import { injectIntl } from 'react-intl-next';
|
|
15
6
|
import { Popup } from '@atlaskit/editor-common/ui';
|
|
16
|
-
import {
|
|
7
|
+
import { akEditorSmallZIndex } from '@atlaskit/editor-shared-styles';
|
|
17
8
|
import ExpandIcon from '@atlaskit/icon/glyph/chevron-down';
|
|
18
9
|
import { ToolbarButton } from '@atlaskit/editor-common/ui-menu';
|
|
19
|
-
import { closestElement } from '@atlaskit/editor-common/utils';
|
|
20
10
|
import { toggleContextualMenu } from '../../commands';
|
|
21
11
|
import { TableCssClassName as ClassName } from '../../types';
|
|
22
12
|
import messages from '../../ui/messages';
|
|
23
|
-
import
|
|
24
|
-
import {
|
|
13
|
+
import FixedButton from './FixedButton';
|
|
14
|
+
import { ACTION_SUBJECT } from '@atlaskit/editor-common/analytics';
|
|
25
15
|
import { tableFloatingCellButtonStyles, tableFloatingCellButtonSelectedStyles } from './styles';
|
|
26
16
|
import { ErrorBoundary } from '@atlaskit/editor-common/error-boundary';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
var
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
17
|
+
var BUTTON_OFFSET = 3;
|
|
18
|
+
var FloatingContextualButtonInner = /*#__PURE__*/React.memo(function (props) {
|
|
19
|
+
var editorView = props.editorView,
|
|
20
|
+
isContextualMenuOpen = props.isContextualMenuOpen,
|
|
21
|
+
mountPoint = props.mountPoint,
|
|
22
|
+
scrollableElement = props.scrollableElement,
|
|
23
|
+
stickyHeader = props.stickyHeader,
|
|
24
|
+
tableWrapper = props.tableWrapper,
|
|
25
|
+
targetCellPosition = props.targetCellPosition,
|
|
26
|
+
formatMessage = props.intl.formatMessage; // : Props & WrappedComponentProps
|
|
27
|
+
|
|
28
|
+
var handleClick = function handleClick() {
|
|
29
|
+
var state = editorView.state,
|
|
30
|
+
dispatch = editorView.dispatch;
|
|
31
|
+
// Clicking outside the dropdown handles toggling the menu closed
|
|
32
|
+
// (otherwise these two toggles combat each other).
|
|
33
|
+
// In the event a user clicks the chevron button again
|
|
34
|
+
// That will count as clicking outside the dropdown and
|
|
35
|
+
// will be toggled appropriately
|
|
36
|
+
if (!isContextualMenuOpen) {
|
|
37
|
+
toggleContextualMenu()(state, dispatch);
|
|
35
38
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// (otherwise these two toggles combat each other).
|
|
43
|
-
// In the event a user clicks the chevron button again
|
|
44
|
-
// That will count as clicking outside the dropdown and
|
|
45
|
-
// will be toggled appropriately
|
|
46
|
-
if (!_this.props.isContextualMenuOpen) {
|
|
47
|
-
toggleContextualMenu()(state, dispatch);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
return _this;
|
|
39
|
+
};
|
|
40
|
+
var domAtPos = editorView.domAtPos.bind(editorView);
|
|
41
|
+
var targetCellRef;
|
|
42
|
+
targetCellRef = findDomRefAtPos(targetCellPosition, domAtPos);
|
|
43
|
+
if (!targetCellRef || !(targetCellRef instanceof HTMLElement)) {
|
|
44
|
+
return null;
|
|
51
45
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
isContextualMenuOpen = _this$props.isContextualMenuOpen,
|
|
61
|
-
formatMessage = _this$props.intl.formatMessage,
|
|
62
|
-
dispatchAnalyticsEvent = _this$props.dispatchAnalyticsEvent; // : Props & WrappedComponentProps
|
|
63
|
-
var domAtPos = editorView.domAtPos.bind(editorView);
|
|
64
|
-
var targetCellRef;
|
|
65
|
-
try {
|
|
66
|
-
targetCellRef = findDomRefAtPos(targetCellPosition, domAtPos);
|
|
67
|
-
} catch (error) {
|
|
68
|
-
// eslint-disable-next-line no-console
|
|
69
|
-
console.warn(error);
|
|
70
|
-
if (dispatchAnalyticsEvent) {
|
|
71
|
-
var payload = {
|
|
72
|
-
action: ACTION.ERRORED,
|
|
73
|
-
actionSubject: ACTION_SUBJECT.CONTENT_COMPONENT,
|
|
74
|
-
eventType: EVENT_TYPE.OPERATIONAL,
|
|
75
|
-
attributes: {
|
|
76
|
-
component: CONTENT_COMPONENT.FLOATING_CONTEXTUAL_BUTTON,
|
|
77
|
-
selection: editorView.state.selection.toJSON(),
|
|
78
|
-
position: targetCellPosition,
|
|
79
|
-
docSize: editorView.state.doc.nodeSize,
|
|
80
|
-
error: error instanceof Error ? error.message : String(error)
|
|
81
|
-
},
|
|
82
|
-
nonPrivacySafeAttributes: {
|
|
83
|
-
errorStack: error instanceof Error ? error.stack : undefined
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
dispatchAnalyticsEvent(payload);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (!targetCellRef || !(targetCellRef instanceof HTMLElement)) {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
var tableWrapper = closestElement(targetCellRef, ".".concat(ClassName.TABLE_NODE_WRAPPER));
|
|
93
|
-
var labelCellOptions = formatMessage(messages.cellOptions);
|
|
94
|
-
var button = jsx("div", {
|
|
95
|
-
css: function css(theme) {
|
|
96
|
-
return [tableFloatingCellButtonStyles({
|
|
97
|
-
theme: theme
|
|
98
|
-
}), isContextualMenuOpen && tableFloatingCellButtonSelectedStyles({
|
|
99
|
-
theme: theme
|
|
100
|
-
})];
|
|
101
|
-
}
|
|
102
|
-
}, jsx(ToolbarButton, {
|
|
103
|
-
className: ClassName.CONTEXTUAL_MENU_BUTTON,
|
|
104
|
-
selected: isContextualMenuOpen,
|
|
105
|
-
title: labelCellOptions,
|
|
106
|
-
onClick: this.handleClick,
|
|
107
|
-
iconBefore: jsx(ExpandIcon, {
|
|
108
|
-
label: ""
|
|
109
|
-
}),
|
|
110
|
-
"aria-label": labelCellOptions
|
|
111
|
-
}));
|
|
112
|
-
var parentSticky = targetCellRef.parentElement && targetCellRef.parentElement.className.indexOf('sticky') > -1;
|
|
113
|
-
if (this.props.stickyHeader && parentSticky) {
|
|
114
|
-
var pos = targetCellRef.getBoundingClientRect();
|
|
115
|
-
return jsx("div", {
|
|
116
|
-
style: {
|
|
117
|
-
position: 'fixed',
|
|
118
|
-
top: this.props.stickyHeader.top + this.props.stickyHeader.padding + 3 + 3,
|
|
119
|
-
zIndex: akEditorFloatingOverlapPanelZIndex,
|
|
120
|
-
left: pos.left + targetCellRef.clientWidth - 20 - 3
|
|
121
|
-
}
|
|
122
|
-
}, button);
|
|
123
|
-
}
|
|
124
|
-
return jsx(Popup, {
|
|
125
|
-
alignX: "right",
|
|
126
|
-
alignY: "start",
|
|
127
|
-
target: targetCellRef,
|
|
128
|
-
mountTo: tableWrapper || mountPoint,
|
|
129
|
-
boundariesElement: targetCellRef,
|
|
130
|
-
scrollableElement: scrollableElement,
|
|
131
|
-
offset: [3, -3],
|
|
132
|
-
forcePlacement: true,
|
|
133
|
-
allowOutOfBounds: true,
|
|
134
|
-
zIndex: akEditorSmallZIndex
|
|
135
|
-
}, button);
|
|
46
|
+
var labelCellOptions = formatMessage(messages.cellOptions);
|
|
47
|
+
var button = jsx("div", {
|
|
48
|
+
css: function css(theme) {
|
|
49
|
+
return [tableFloatingCellButtonStyles({
|
|
50
|
+
theme: theme
|
|
51
|
+
}), isContextualMenuOpen && tableFloatingCellButtonSelectedStyles({
|
|
52
|
+
theme: theme
|
|
53
|
+
})];
|
|
136
54
|
}
|
|
137
|
-
}, {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
55
|
+
}, jsx(ToolbarButton, {
|
|
56
|
+
className: ClassName.CONTEXTUAL_MENU_BUTTON,
|
|
57
|
+
selected: isContextualMenuOpen,
|
|
58
|
+
title: labelCellOptions,
|
|
59
|
+
onClick: handleClick,
|
|
60
|
+
iconBefore: jsx(ExpandIcon, {
|
|
61
|
+
label: ""
|
|
62
|
+
}),
|
|
63
|
+
"aria-label": labelCellOptions
|
|
64
|
+
}));
|
|
65
|
+
var parentSticky = targetCellRef.parentElement && targetCellRef.parentElement.className.indexOf('sticky') > -1;
|
|
66
|
+
if (stickyHeader && parentSticky && tableWrapper) {
|
|
67
|
+
return jsx(FixedButton, {
|
|
68
|
+
offset: BUTTON_OFFSET,
|
|
69
|
+
stickyHeader: stickyHeader,
|
|
70
|
+
tableWrapper: tableWrapper,
|
|
71
|
+
targetCellPosition: targetCellPosition,
|
|
72
|
+
targetCellRef: targetCellRef,
|
|
73
|
+
mountTo: tableWrapper,
|
|
74
|
+
isContextualMenuOpen: isContextualMenuOpen
|
|
75
|
+
}, button);
|
|
76
|
+
}
|
|
77
|
+
return jsx(Popup, {
|
|
78
|
+
alignX: "right",
|
|
79
|
+
alignY: "start",
|
|
80
|
+
target: targetCellRef,
|
|
81
|
+
mountTo: tableWrapper || mountPoint,
|
|
82
|
+
boundariesElement: targetCellRef,
|
|
83
|
+
scrollableElement: scrollableElement,
|
|
84
|
+
offset: [BUTTON_OFFSET, -BUTTON_OFFSET],
|
|
85
|
+
forcePlacement: true,
|
|
86
|
+
allowOutOfBounds: true,
|
|
87
|
+
zIndex: akEditorSmallZIndex
|
|
88
|
+
}, button);
|
|
89
|
+
});
|
|
146
90
|
var FloatingContextualButton = injectIntl(FloatingContextualButtonInner);
|
|
147
91
|
export default function (props) {
|
|
148
92
|
return jsx(ErrorBoundary, {
|
package/dist/esm/version.json
CHANGED
|
@@ -272,6 +272,7 @@ export declare const TableCssClassName: {
|
|
|
272
272
|
CONTEXTUAL_SUBMENU: string;
|
|
273
273
|
CONTEXTUAL_MENU_BUTTON_WRAP: string;
|
|
274
274
|
CONTEXTUAL_MENU_BUTTON: string;
|
|
275
|
+
CONTEXTUAL_MENU_BUTTON_FIXED: string;
|
|
275
276
|
CONTEXTUAL_MENU_ICON: string;
|
|
276
277
|
SELECTED_CELL: string;
|
|
277
278
|
NODEVIEW_WRAPPER: string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { RowStickyState } from '../../pm-plugins/sticky-headers';
|
|
3
|
+
export declare const BUTTON_WIDTH = 20;
|
|
4
|
+
export interface Props {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
mountTo: HTMLElement;
|
|
7
|
+
offset: number;
|
|
8
|
+
stickyHeader: RowStickyState;
|
|
9
|
+
targetCellPosition: number;
|
|
10
|
+
targetCellRef: HTMLElement;
|
|
11
|
+
tableWrapper: HTMLElement;
|
|
12
|
+
isContextualMenuOpen: boolean | undefined;
|
|
13
|
+
}
|
|
14
|
+
interface CalcLeftPosData {
|
|
15
|
+
buttonWidth: number;
|
|
16
|
+
cellRectLeft: number;
|
|
17
|
+
cellRefWidth: number;
|
|
18
|
+
offset: number;
|
|
19
|
+
}
|
|
20
|
+
export declare const calcLeftPos: ({ buttonWidth, cellRectLeft, cellRefWidth, offset, }: CalcLeftPosData) => number;
|
|
21
|
+
export declare const calcObserverTargetMargin: (tableWrapper: HTMLElement, fixedButtonRefCurrent: HTMLElement) => number;
|
|
22
|
+
export declare const FixedButton: ({ children, isContextualMenuOpen, mountTo, offset, stickyHeader, tableWrapper, targetCellPosition, targetCellRef, }: Props) => React.ReactPortal;
|
|
23
|
+
export default FixedButton;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
/** @jsx jsx */
|
|
2
|
-
import React from 'react';
|
|
3
1
|
import { jsx } from '@emotion/react';
|
|
4
2
|
import { EditorView } from 'prosemirror-view';
|
|
5
|
-
import { WrappedComponentProps } from 'react-intl-next';
|
|
6
3
|
import { TableLayout } from '@atlaskit/adf-schema';
|
|
7
4
|
import { RowStickyState } from '../../pm-plugins/sticky-headers';
|
|
8
5
|
import { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
9
6
|
import { Node as PMNode } from 'prosemirror-model';
|
|
10
7
|
export interface Props {
|
|
11
8
|
editorView: EditorView;
|
|
9
|
+
tableWrapper?: HTMLElement;
|
|
12
10
|
tableNode?: PMNode;
|
|
13
11
|
targetCellPosition: number;
|
|
14
12
|
isContextualMenuOpen?: boolean;
|
|
@@ -20,10 +18,4 @@ export interface Props {
|
|
|
20
18
|
stickyHeader?: RowStickyState;
|
|
21
19
|
dispatchAnalyticsEvent?: DispatchAnalyticsEvent;
|
|
22
20
|
}
|
|
23
|
-
export declare class FloatingContextualButtonInner extends React.Component<Props & WrappedComponentProps, any> {
|
|
24
|
-
static displayName: string;
|
|
25
|
-
render(): jsx.JSX.Element | null;
|
|
26
|
-
shouldComponentUpdate(nextProps: Props): boolean;
|
|
27
|
-
private handleClick;
|
|
28
|
-
}
|
|
29
21
|
export default function (props: Props): jsx.JSX.Element;
|