@atlaskit/editor-plugin-table 5.3.12 → 5.3.14
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 +18 -0
- package/dist/cjs/plugins/table/event-handlers.js +6 -3
- package/dist/cjs/plugins/table/index.js +16 -2
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +2 -1
- package/dist/cjs/plugins/table/pm-plugins/decorations/plugin.js +3 -7
- package/dist/cjs/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/actions.js +2 -1
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/commands.js +22 -1
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +54 -7
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/reducer.js +6 -0
- package/dist/cjs/plugins/table/types.js +9 -2
- package/dist/cjs/plugins/table/ui/DragHandle/index.js +2 -0
- package/dist/cjs/plugins/table/ui/FloatingDragMenu/DragMenu.js +80 -0
- package/dist/cjs/plugins/table/ui/FloatingDragMenu/index.js +62 -0
- package/dist/cjs/plugins/table/ui/FloatingInsertButton/InsertButton.js +52 -4
- package/dist/cjs/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +10 -8
- package/dist/cjs/plugins/table/ui/FloatingInsertButton/index.js +12 -3
- package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +44 -5
- package/dist/cjs/plugins/table/ui/TableFloatingColumnControls/index.js +6 -4
- package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +44 -20
- package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +4 -0
- package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
- package/dist/cjs/plugins/table/ui/consts.js +3 -2
- package/dist/cjs/plugins/table/ui/ui-styles.js +27 -24
- package/dist/cjs/plugins/table/utils/dom.js +12 -4
- package/dist/cjs/plugins/table/utils/drag-menu.js +59 -0
- package/dist/cjs/plugins/table/utils/index.js +12 -0
- package/dist/es2019/plugins/table/event-handlers.js +5 -4
- package/dist/es2019/plugins/table/index.js +16 -2
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +2 -1
- package/dist/es2019/plugins/table/pm-plugins/decorations/plugin.js +3 -7
- package/dist/es2019/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/actions.js +2 -1
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/commands.js +20 -0
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +54 -3
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/reducer.js +7 -0
- package/dist/es2019/plugins/table/types.js +9 -2
- package/dist/es2019/plugins/table/ui/DragHandle/index.js +2 -0
- package/dist/es2019/plugins/table/ui/FloatingDragMenu/DragMenu.js +77 -0
- package/dist/es2019/plugins/table/ui/FloatingDragMenu/index.js +56 -0
- package/dist/es2019/plugins/table/ui/FloatingInsertButton/InsertButton.js +53 -2
- package/dist/es2019/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +10 -8
- package/dist/es2019/plugins/table/ui/FloatingInsertButton/index.js +9 -3
- package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +46 -6
- package/dist/es2019/plugins/table/ui/TableFloatingColumnControls/index.js +7 -5
- package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +45 -22
- package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +4 -0
- package/dist/es2019/plugins/table/ui/common-styles.js +51 -3
- package/dist/es2019/plugins/table/ui/consts.js +2 -1
- package/dist/es2019/plugins/table/ui/ui-styles.js +23 -1
- package/dist/es2019/plugins/table/utils/dom.js +5 -1
- package/dist/es2019/plugins/table/utils/drag-menu.js +44 -0
- package/dist/es2019/plugins/table/utils/index.js +1 -1
- package/dist/esm/plugins/table/event-handlers.js +7 -4
- package/dist/esm/plugins/table/index.js +16 -2
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +2 -1
- package/dist/esm/plugins/table/pm-plugins/decorations/plugin.js +3 -7
- package/dist/esm/plugins/table/pm-plugins/decorations/utils/column-controls.js +1 -3
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/actions.js +2 -1
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/commands.js +21 -0
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +54 -7
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/reducer.js +6 -0
- package/dist/esm/plugins/table/types.js +9 -2
- package/dist/esm/plugins/table/ui/DragHandle/index.js +2 -0
- package/dist/esm/plugins/table/ui/FloatingDragMenu/DragMenu.js +73 -0
- package/dist/esm/plugins/table/ui/FloatingDragMenu/index.js +55 -0
- package/dist/esm/plugins/table/ui/FloatingInsertButton/InsertButton.js +51 -3
- package/dist/esm/plugins/table/ui/FloatingInsertButton/getPopupOptions.js +10 -8
- package/dist/esm/plugins/table/ui/FloatingInsertButton/index.js +9 -3
- package/dist/esm/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.js +45 -6
- package/dist/esm/plugins/table/ui/TableFloatingColumnControls/index.js +7 -5
- package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/DragControls.js +46 -22
- package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +4 -0
- package/dist/esm/plugins/table/ui/common-styles.js +2 -2
- package/dist/esm/plugins/table/ui/consts.js +2 -1
- package/dist/esm/plugins/table/ui/ui-styles.js +26 -23
- package/dist/esm/plugins/table/utils/dom.js +11 -3
- package/dist/esm/plugins/table/utils/drag-menu.js +52 -0
- package/dist/esm/plugins/table/utils/index.js +1 -1
- package/dist/types/plugins/table/pm-plugins/drag-and-drop/actions.d.ts +8 -1
- package/dist/types/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +2 -1
- package/dist/types/plugins/table/pm-plugins/drag-and-drop/types.d.ts +4 -0
- package/dist/types/plugins/table/types.d.ts +10 -2
- package/dist/types/plugins/table/ui/DragHandle/index.d.ts +4 -2
- package/dist/types/plugins/table/ui/DragPreview/index.d.ts +2 -1
- package/dist/types/plugins/table/ui/FloatingDeleteButton/index.d.ts +2 -1
- package/dist/types/plugins/table/ui/FloatingDeleteButton/types.d.ts +2 -1
- package/dist/types/plugins/table/ui/FloatingDragMenu/DragMenu.d.ts +19 -0
- package/dist/types/plugins/table/ui/FloatingDragMenu/index.d.ts +21 -0
- package/dist/types/plugins/table/ui/FloatingInsertButton/InsertButton.d.ts +6 -1
- package/dist/types/plugins/table/ui/FloatingInsertButton/getPopupOptions.d.ts +2 -1
- package/dist/types/plugins/table/ui/FloatingInsertButton/index.d.ts +5 -5
- package/dist/types/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
- package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +4 -0
- package/dist/types/plugins/table/ui/TableFloatingControls/index.d.ts +3 -0
- package/dist/types/plugins/table/ui/consts.d.ts +1 -0
- package/dist/types/plugins/table/ui/ui-styles.d.ts +1 -0
- package/dist/types/plugins/table/utils/dom.d.ts +4 -1
- package/dist/types/plugins/table/utils/drag-menu.d.ts +7 -0
- package/dist/types/plugins/table/utils/index.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/actions.d.ts +8 -1
- package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/commands.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/pm-plugins/drag-and-drop/types.d.ts +4 -0
- package/dist/types-ts4.5/plugins/table/types.d.ts +10 -2
- package/dist/types-ts4.5/plugins/table/ui/DragHandle/index.d.ts +4 -2
- package/dist/types-ts4.5/plugins/table/ui/DragPreview/index.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/ui/FloatingDeleteButton/index.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/ui/FloatingDeleteButton/types.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/ui/FloatingDragMenu/DragMenu.d.ts +19 -0
- package/dist/types-ts4.5/plugins/table/ui/FloatingDragMenu/index.d.ts +21 -0
- package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/InsertButton.d.ts +6 -1
- package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/getPopupOptions.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/ui/FloatingInsertButton/index.d.ts +5 -5
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/RowControls/DragControls.d.ts +4 -0
- package/dist/types-ts4.5/plugins/table/ui/TableFloatingControls/index.d.ts +3 -0
- package/dist/types-ts4.5/plugins/table/ui/consts.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/ui/ui-styles.d.ts +1 -0
- package/dist/types-ts4.5/plugins/table/utils/dom.d.ts +4 -1
- package/dist/types-ts4.5/plugins/table/utils/drag-menu.d.ts +7 -0
- package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
- package/package.json +3 -2
- package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +40 -194
- package/src/__tests__/unit/ui/RowDragControls.tsx +9 -11
- package/src/plugins/table/event-handlers.ts +15 -3
- package/src/plugins/table/index.tsx +18 -1
- package/src/plugins/table/nodeviews/TableComponent.tsx +2 -1
- package/src/plugins/table/pm-plugins/decorations/plugin.ts +2 -9
- package/src/plugins/table/pm-plugins/decorations/utils/column-controls.ts +1 -3
- package/src/plugins/table/pm-plugins/drag-and-drop/actions.ts +14 -1
- package/src/plugins/table/pm-plugins/drag-and-drop/commands.ts +32 -1
- package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +50 -2
- package/src/plugins/table/pm-plugins/drag-and-drop/reducer.ts +7 -0
- package/src/plugins/table/pm-plugins/drag-and-drop/types.ts +5 -0
- package/src/plugins/table/types.ts +14 -2
- package/src/plugins/table/ui/DragHandle/index.tsx +5 -1
- package/src/plugins/table/ui/DragPreview/index.tsx +2 -1
- package/src/plugins/table/ui/FloatingDeleteButton/index.tsx +2 -1
- package/src/plugins/table/ui/FloatingDeleteButton/types.ts +3 -1
- package/src/plugins/table/ui/FloatingDragMenu/DragMenu.tsx +99 -0
- package/src/plugins/table/ui/FloatingDragMenu/index.tsx +91 -0
- package/src/plugins/table/ui/FloatingInsertButton/InsertButton.tsx +79 -4
- package/src/plugins/table/ui/FloatingInsertButton/getPopupOptions.ts +31 -7
- package/src/plugins/table/ui/FloatingInsertButton/index.tsx +28 -13
- package/src/plugins/table/ui/TableFloatingColumnControls/ColumnControls/index.tsx +47 -3
- package/src/plugins/table/ui/TableFloatingColumnControls/index.tsx +11 -4
- package/src/plugins/table/ui/TableFloatingControls/RowControls/DragControls.tsx +65 -25
- package/src/plugins/table/ui/TableFloatingControls/index.tsx +7 -0
- package/src/plugins/table/ui/common-styles.ts +57 -2
- package/src/plugins/table/ui/consts.ts +2 -0
- package/src/plugins/table/ui/ui-styles.ts +27 -1
- package/src/plugins/table/utils/dom.ts +11 -4
- package/src/plugins/table/utils/drag-menu.ts +65 -0
- package/src/plugins/table/utils/index.ts +2 -0
- package/tsconfig.app.json +3 -0
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { WrappedComponentProps } from 'react-intl-next';
|
|
4
|
+
import { injectIntl } from 'react-intl-next';
|
|
4
5
|
|
|
5
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
AnalyticsEventPayload,
|
|
8
|
+
DispatchAnalyticsEvent,
|
|
9
|
+
EditorAnalyticsAPI,
|
|
10
|
+
} from '@atlaskit/editor-common/analytics';
|
|
6
11
|
import {
|
|
7
12
|
ACTION,
|
|
8
13
|
ACTION_SUBJECT,
|
|
9
|
-
AnalyticsEventPayload,
|
|
10
14
|
CONTENT_COMPONENT,
|
|
11
|
-
DispatchAnalyticsEvent,
|
|
12
15
|
EVENT_TYPE,
|
|
13
16
|
INPUT_METHOD,
|
|
14
17
|
} from '@atlaskit/editor-common/analytics';
|
|
15
18
|
import type { GetEditorContainerWidth } from '@atlaskit/editor-common/types';
|
|
16
19
|
import { Popup } from '@atlaskit/editor-common/ui';
|
|
17
20
|
import { closestElement } from '@atlaskit/editor-common/utils';
|
|
18
|
-
import { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
|
|
21
|
+
import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
|
|
19
22
|
import { findDomRefAtPos } from '@atlaskit/editor-prosemirror/utils';
|
|
20
|
-
import { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
23
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
21
24
|
import { akEditorTableCellOnStickyHeaderZIndex } from '@atlaskit/editor-shared-styles';
|
|
22
25
|
import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
|
|
23
26
|
import { TableMap } from '@atlaskit/editor-tables/table-map';
|
|
@@ -31,7 +34,7 @@ import { TableCssClassName as ClassName } from '../../types';
|
|
|
31
34
|
import { checkIfNumberColumnEnabled } from '../../utils';
|
|
32
35
|
|
|
33
36
|
import getPopupOptions from './getPopupOptions';
|
|
34
|
-
import InsertButton from './InsertButton';
|
|
37
|
+
import InsertButton, { DragAndDropInsertButton } from './InsertButton';
|
|
35
38
|
|
|
36
39
|
export interface Props {
|
|
37
40
|
editorView: EditorView;
|
|
@@ -42,6 +45,7 @@ export interface Props {
|
|
|
42
45
|
insertRowButtonIndex?: number;
|
|
43
46
|
isHeaderColumnEnabled?: boolean;
|
|
44
47
|
isHeaderRowEnabled?: boolean;
|
|
48
|
+
isDragAndDropEnabled?: boolean;
|
|
45
49
|
mountPoint?: HTMLElement;
|
|
46
50
|
boundariesElement?: HTMLElement;
|
|
47
51
|
scrollableElement?: HTMLElement;
|
|
@@ -73,6 +77,7 @@ export class FloatingInsertButton extends React.Component<
|
|
|
73
77
|
boundariesElement,
|
|
74
78
|
isHeaderColumnEnabled,
|
|
75
79
|
isHeaderRowEnabled,
|
|
80
|
+
isDragAndDropEnabled,
|
|
76
81
|
dispatchAnalyticsEvent,
|
|
77
82
|
} = this.props;
|
|
78
83
|
|
|
@@ -196,16 +201,26 @@ export class FloatingInsertButton extends React.Component<
|
|
|
196
201
|
type,
|
|
197
202
|
index,
|
|
198
203
|
hasNumberedColumns,
|
|
204
|
+
!!isDragAndDropEnabled,
|
|
199
205
|
tableContainerWrapper,
|
|
200
206
|
)}
|
|
201
207
|
zIndex={zIndex}
|
|
202
208
|
>
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
{isDragAndDropEnabled ? (
|
|
210
|
+
<DragAndDropInsertButton
|
|
211
|
+
type={type}
|
|
212
|
+
tableRef={tableRef}
|
|
213
|
+
onMouseDown={type === 'column' ? this.insertColumn : this.insertRow}
|
|
214
|
+
hasStickyHeaders={this.props.hasStickyHeaders || false}
|
|
215
|
+
/>
|
|
216
|
+
) : (
|
|
217
|
+
<InsertButton
|
|
218
|
+
type={type}
|
|
219
|
+
tableRef={tableRef}
|
|
220
|
+
onMouseDown={type === 'column' ? this.insertColumn : this.insertRow}
|
|
221
|
+
hasStickyHeaders={this.props.hasStickyHeaders || false}
|
|
222
|
+
/>
|
|
223
|
+
)}
|
|
209
224
|
</Popup>
|
|
210
225
|
);
|
|
211
226
|
}
|
|
@@ -5,15 +5,17 @@ import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
|
5
5
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
import { CellSelection } from '@atlaskit/editor-tables';
|
|
7
7
|
import { getSelectionRect } from '@atlaskit/editor-tables/utils';
|
|
8
|
+
import { token } from '@atlaskit/tokens';
|
|
8
9
|
|
|
9
10
|
import {
|
|
10
11
|
clearHoverSelection,
|
|
11
12
|
hoverColumns,
|
|
12
13
|
selectColumn,
|
|
13
14
|
} from '../../../commands';
|
|
15
|
+
import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
|
|
14
16
|
import type { CellHoverMeta } from '../../../types';
|
|
15
17
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
16
|
-
import { getSelectedColumnIndexes } from '../../../utils';
|
|
18
|
+
import { getRowsParams, getSelectedColumnIndexes } from '../../../utils';
|
|
17
19
|
import { DragHandle } from '../../DragHandle';
|
|
18
20
|
|
|
19
21
|
export interface ColumnControlsProps {
|
|
@@ -27,6 +29,7 @@ export interface ColumnControlsProps {
|
|
|
27
29
|
localId?: string;
|
|
28
30
|
rowHeights?: number[];
|
|
29
31
|
colWidths?: (number | undefined)[];
|
|
32
|
+
hasHeaderColumn?: boolean;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
const getSelectedColumns = (selection: Selection) => {
|
|
@@ -51,10 +54,13 @@ export const ColumnControls = ({
|
|
|
51
54
|
isInDanger,
|
|
52
55
|
rowHeights,
|
|
53
56
|
colWidths,
|
|
57
|
+
hasHeaderColumn,
|
|
54
58
|
}: ColumnControlsProps) => {
|
|
55
59
|
const widths =
|
|
56
60
|
colWidths?.map((width) => (width ? `${width - 1}px` : '0px')).join(' ') ??
|
|
57
61
|
'0px';
|
|
62
|
+
// TODO: reusing getRowsParams here because it's generic enough to work for columns -> rename
|
|
63
|
+
const columnParams = getRowsParams(colWidths ?? []);
|
|
58
64
|
const colIndex = hoveredCell?.colIndex;
|
|
59
65
|
const selectedColIndexes = getSelectedColumns(editorView.state.selection);
|
|
60
66
|
|
|
@@ -94,8 +100,13 @@ export const ColumnControls = ({
|
|
|
94
100
|
}
|
|
95
101
|
}, [editorView, tableActive]);
|
|
96
102
|
|
|
103
|
+
const handleMouseUp = useCallback(() => {
|
|
104
|
+
const { state, dispatch } = editorView;
|
|
105
|
+
toggleDragMenu(undefined, 'column', colIndex)(state, dispatch);
|
|
106
|
+
}, [editorView, colIndex]);
|
|
107
|
+
|
|
97
108
|
return (
|
|
98
|
-
<div className={ClassName.
|
|
109
|
+
<div className={ClassName.DRAG_COLUMN_CONTROLS}>
|
|
99
110
|
<div
|
|
100
111
|
className={ClassName.COLUMN_CONTROLS_INNER}
|
|
101
112
|
data-testid="table-floating-column-controls"
|
|
@@ -104,6 +115,33 @@ export const ColumnControls = ({
|
|
|
104
115
|
marginTop,
|
|
105
116
|
}}
|
|
106
117
|
>
|
|
118
|
+
{!isResizing &&
|
|
119
|
+
columnParams.map(({ startIndex, endIndex }, index) => (
|
|
120
|
+
<div
|
|
121
|
+
style={{
|
|
122
|
+
gridColumn: `${index + 1} / span 1`,
|
|
123
|
+
}}
|
|
124
|
+
data-start-index={startIndex}
|
|
125
|
+
data-end-index={endIndex}
|
|
126
|
+
className={ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT_WRAPPER}
|
|
127
|
+
contentEditable={false}
|
|
128
|
+
key={index}
|
|
129
|
+
>
|
|
130
|
+
{!hasHeaderColumn && index === 0 && (
|
|
131
|
+
<div
|
|
132
|
+
style={{
|
|
133
|
+
left: '0px',
|
|
134
|
+
right: 'unset',
|
|
135
|
+
}}
|
|
136
|
+
className={ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT}
|
|
137
|
+
/>
|
|
138
|
+
)}
|
|
139
|
+
<div
|
|
140
|
+
className={ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT}
|
|
141
|
+
style={columnParams.length - 1 === index ? { right: '0' } : {}}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
))}
|
|
107
145
|
{tableActive &&
|
|
108
146
|
!isResizing &&
|
|
109
147
|
!!hoveredCell &&
|
|
@@ -111,7 +149,12 @@ export const ColumnControls = ({
|
|
|
111
149
|
<div
|
|
112
150
|
style={{
|
|
113
151
|
gridColumn: gridColumnPosition,
|
|
114
|
-
|
|
152
|
+
zIndex: 99,
|
|
153
|
+
display: 'flex',
|
|
154
|
+
width: '100%',
|
|
155
|
+
justifyContent: 'center',
|
|
156
|
+
alignItems: 'center',
|
|
157
|
+
marginTop: token('space.negative.025', '-2px'),
|
|
115
158
|
}}
|
|
116
159
|
data-column-control-index={hoveredCell.colIndex}
|
|
117
160
|
data-testid="table-floating-column-control"
|
|
@@ -132,6 +175,7 @@ export const ColumnControls = ({
|
|
|
132
175
|
onClick={handleClick}
|
|
133
176
|
onMouseOver={handleMouseOver}
|
|
134
177
|
onMouseOut={handleMouseOut}
|
|
178
|
+
onMouseUp={handleMouseUp}
|
|
135
179
|
/>
|
|
136
180
|
</div>
|
|
137
181
|
)}
|
|
@@ -12,7 +12,11 @@ import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/el
|
|
|
12
12
|
import type { RowStickyState } from '../../pm-plugins/sticky-headers';
|
|
13
13
|
import type { CellHoverMeta, DraggableSourceData } from '../../types';
|
|
14
14
|
import { TableCssClassName as ClassName } from '../../types';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
containsHeaderColumn,
|
|
17
|
+
getColumnsWidths,
|
|
18
|
+
getRowHeights,
|
|
19
|
+
} from '../../utils';
|
|
16
20
|
|
|
17
21
|
import { ColumnControls } from './ColumnControls';
|
|
18
22
|
import { ColumnDropTargets } from './ColumnDropTargets';
|
|
@@ -53,6 +57,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
53
57
|
const [hasDropTargets, setHasDropTargets] = useState(false);
|
|
54
58
|
const node = getNode();
|
|
55
59
|
const currentNodeLocalId = node?.attrs.localId;
|
|
60
|
+
const hasHeaderColumn = containsHeaderColumn(node);
|
|
56
61
|
|
|
57
62
|
useEffect(() => {
|
|
58
63
|
if (tableRef && window?.ResizeObserver) {
|
|
@@ -118,12 +123,13 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
118
123
|
|
|
119
124
|
const mountTo = (tableRef && tableRef?.parentElement) || document.body;
|
|
120
125
|
|
|
126
|
+
if (!tableActive) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
|
|
121
130
|
return ReactDOM.createPortal(
|
|
122
131
|
<div
|
|
123
132
|
className={ClassName.COLUMN_CONTROLS_WRAPPER}
|
|
124
|
-
style={{
|
|
125
|
-
pointerEvents: 'none',
|
|
126
|
-
}}
|
|
127
133
|
data-testid="table-floating-column-controls-wrapper"
|
|
128
134
|
>
|
|
129
135
|
<ColumnControls
|
|
@@ -137,6 +143,7 @@ export const TableFloatingColumnControls: React.FC<Props> = ({
|
|
|
137
143
|
isInDanger={isInDanger}
|
|
138
144
|
rowHeights={rowHeights}
|
|
139
145
|
colWidths={colWidths}
|
|
146
|
+
hasHeaderColumn={hasHeaderColumn}
|
|
140
147
|
/>
|
|
141
148
|
{hasDropTargets && (
|
|
142
149
|
<ColumnDropTargets
|
|
@@ -4,23 +4,33 @@ import React, { useCallback, useMemo } from 'react';
|
|
|
4
4
|
import { injectIntl } from 'react-intl-next';
|
|
5
5
|
import type { WrappedComponentProps } from 'react-intl-next';
|
|
6
6
|
|
|
7
|
+
import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
|
|
7
8
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
8
9
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
9
10
|
import { CellSelection } from '@atlaskit/editor-tables';
|
|
10
|
-
import {
|
|
11
|
+
import { getSelectionRect } from '@atlaskit/editor-tables/utils';
|
|
12
|
+
import { token } from '@atlaskit/tokens';
|
|
11
13
|
|
|
12
14
|
import { clearHoverSelection } from '../../../commands';
|
|
15
|
+
import { toggleDragMenu } from '../../../pm-plugins/drag-and-drop/commands';
|
|
13
16
|
import type { CellHoverMeta } from '../../../types';
|
|
14
17
|
import { TableCssClassName as ClassName } from '../../../types';
|
|
15
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
getRowHeights,
|
|
20
|
+
getRowsParams,
|
|
21
|
+
getSelectedRowIndexes,
|
|
22
|
+
} from '../../../utils';
|
|
16
23
|
import { DragHandle } from '../../DragHandle';
|
|
17
24
|
|
|
18
25
|
type DragControlsProps = {
|
|
19
26
|
editorView: EditorView;
|
|
20
27
|
tableRef: HTMLTableElement;
|
|
28
|
+
tableNode?: PmNode;
|
|
21
29
|
tableActive?: boolean;
|
|
22
30
|
hoveredCell?: CellHoverMeta;
|
|
23
31
|
isInDanger?: boolean;
|
|
32
|
+
isResizing?: boolean;
|
|
33
|
+
hasHeaderRow?: boolean;
|
|
24
34
|
hoverRows: (rows: number[], danger?: boolean) => void;
|
|
25
35
|
selectRow: (row: number, expand: boolean) => void;
|
|
26
36
|
updateCellHoverLocation: (rowIndex: number) => void;
|
|
@@ -39,18 +49,31 @@ const getSelectedRows = (selection: Selection) => {
|
|
|
39
49
|
|
|
40
50
|
const DragControlsComponent = ({
|
|
41
51
|
tableRef,
|
|
52
|
+
tableNode,
|
|
42
53
|
hoveredCell,
|
|
43
54
|
tableActive,
|
|
44
55
|
editorView,
|
|
45
56
|
isInDanger,
|
|
57
|
+
isResizing,
|
|
58
|
+
hasHeaderRow,
|
|
46
59
|
hoverRows,
|
|
47
60
|
selectRow,
|
|
48
61
|
updateCellHoverLocation,
|
|
49
62
|
}: DragControlsProps & WrappedComponentProps) => {
|
|
50
63
|
const rowHeights = getRowHeights(tableRef);
|
|
64
|
+
const rowsParams = getRowsParams(rowHeights);
|
|
51
65
|
const heights = rowHeights.map((height) => `${height - 1}px`).join(' ');
|
|
52
66
|
const selectedRowIndexes = getSelectedRows(editorView.state.selection);
|
|
53
67
|
const rowWidth = tableRef.offsetWidth;
|
|
68
|
+
|
|
69
|
+
const onMouseUp = useCallback(() => {
|
|
70
|
+
toggleDragMenu(
|
|
71
|
+
undefined,
|
|
72
|
+
'row',
|
|
73
|
+
hoveredCell?.rowIndex,
|
|
74
|
+
)(editorView.state, editorView.dispatch);
|
|
75
|
+
}, [editorView, hoveredCell?.rowIndex]);
|
|
76
|
+
|
|
54
77
|
const rowIndex = hoveredCell?.rowIndex;
|
|
55
78
|
|
|
56
79
|
const gridRowPosition = useMemo(() => {
|
|
@@ -61,11 +84,6 @@ const DragControlsComponent = ({
|
|
|
61
84
|
return `${rowIndex! + 1} / span 1`;
|
|
62
85
|
}, [rowIndex, selectedRowIndexes]);
|
|
63
86
|
|
|
64
|
-
const getLocalId = () => {
|
|
65
|
-
const tableNode = findTable(editorView.state.selection);
|
|
66
|
-
return tableNode?.node?.attrs?.localId || '';
|
|
67
|
-
};
|
|
68
|
-
|
|
69
87
|
const handleMouseOut = useCallback(() => {
|
|
70
88
|
if (tableActive) {
|
|
71
89
|
const { state, dispatch } = editorView;
|
|
@@ -75,25 +93,21 @@ const DragControlsComponent = ({
|
|
|
75
93
|
|
|
76
94
|
const handleMouseMove = useCallback(
|
|
77
95
|
(e: MouseEvent) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)
|
|
96
|
+
const isParentDragControls = (e.nativeEvent.target as Element).closest(
|
|
97
|
+
`.${ClassName.DRAG_ROW_CONTROLS}`,
|
|
98
|
+
);
|
|
99
|
+
const rowIndex = (e.nativeEvent.target as Element).getAttribute(
|
|
100
|
+
'data-start-index',
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
// avoid updating if event target is not related
|
|
104
|
+
if (!isParentDragControls || !rowIndex) {
|
|
84
105
|
return;
|
|
85
106
|
}
|
|
86
107
|
|
|
87
|
-
|
|
88
|
-
let totalHeight = 0;
|
|
89
|
-
const rowIndex = rowHeights.findIndex((row) => {
|
|
90
|
-
totalHeight += row;
|
|
91
|
-
return hoverHeight <= totalHeight;
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
updateCellHoverLocation(rowIndex);
|
|
108
|
+
updateCellHoverLocation(Number(rowIndex));
|
|
95
109
|
},
|
|
96
|
-
[updateCellHoverLocation
|
|
110
|
+
[updateCellHoverLocation],
|
|
97
111
|
);
|
|
98
112
|
|
|
99
113
|
const handleMouseOver = useCallback(() => {
|
|
@@ -109,13 +123,37 @@ const DragControlsComponent = ({
|
|
|
109
123
|
|
|
110
124
|
return (
|
|
111
125
|
<div
|
|
112
|
-
className={ClassName.
|
|
126
|
+
className={ClassName.DRAG_ROW_CONTROLS}
|
|
113
127
|
style={{
|
|
114
128
|
gridTemplateRows: heights,
|
|
115
129
|
}}
|
|
116
130
|
onMouseMove={handleMouseMove}
|
|
117
131
|
>
|
|
118
|
-
{
|
|
132
|
+
{!isResizing &&
|
|
133
|
+
rowsParams.map(({ startIndex, endIndex }, index) => (
|
|
134
|
+
<div
|
|
135
|
+
style={{
|
|
136
|
+
gridRow: `${index + 1} / span 1`,
|
|
137
|
+
}}
|
|
138
|
+
data-start-index={startIndex}
|
|
139
|
+
data-end-index={endIndex}
|
|
140
|
+
className={ClassName.DRAG_ROW_FLOATING_INSERT_DOT_WRAPPER}
|
|
141
|
+
contentEditable={false}
|
|
142
|
+
key={index}
|
|
143
|
+
>
|
|
144
|
+
{!hasHeaderRow && index === 0 && (
|
|
145
|
+
<div
|
|
146
|
+
style={{
|
|
147
|
+
top: '0px',
|
|
148
|
+
left: token('space.075', '6px'),
|
|
149
|
+
}}
|
|
150
|
+
className={ClassName.DRAG_ROW_FLOATING_INSERT_DOT}
|
|
151
|
+
/>
|
|
152
|
+
)}
|
|
153
|
+
<div className={ClassName.DRAG_ROW_FLOATING_INSERT_DOT} />
|
|
154
|
+
</div>
|
|
155
|
+
))}
|
|
156
|
+
{!isResizing && Number.isFinite(rowIndex) && (
|
|
119
157
|
<div
|
|
120
158
|
style={{
|
|
121
159
|
gridRow: gridRowPosition,
|
|
@@ -124,9 +162,10 @@ const DragControlsComponent = ({
|
|
|
124
162
|
alignItems: 'center',
|
|
125
163
|
justifyContent: 'center',
|
|
126
164
|
}}
|
|
165
|
+
data-testid="table-floating-row-drag-handle"
|
|
127
166
|
>
|
|
128
167
|
<DragHandle
|
|
129
|
-
tableLocalId={
|
|
168
|
+
tableLocalId={tableNode?.attrs?.localId ?? ''}
|
|
130
169
|
indexes={[rowIndex!]}
|
|
131
170
|
previewWidth={rowWidth}
|
|
132
171
|
previewHeight={rowHeights[rowIndex!]}
|
|
@@ -140,6 +179,7 @@ const DragControlsComponent = ({
|
|
|
140
179
|
onClick={handleClick}
|
|
141
180
|
onMouseOver={handleMouseOver}
|
|
142
181
|
onMouseOut={handleMouseOut}
|
|
182
|
+
onMouseUp={onMouseUp}
|
|
143
183
|
/>
|
|
144
184
|
</div>
|
|
145
185
|
)}
|
|
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import type { TableColumnOrdering } from '@atlaskit/custom-steps';
|
|
4
4
|
import { browser } from '@atlaskit/editor-common/utils';
|
|
5
|
+
import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
|
|
5
6
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
6
7
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
7
8
|
|
|
@@ -19,6 +20,7 @@ export interface Props {
|
|
|
19
20
|
editorView: EditorView;
|
|
20
21
|
selection?: Selection;
|
|
21
22
|
tableRef?: HTMLTableElement;
|
|
23
|
+
tableNode?: PmNode;
|
|
22
24
|
tableActive?: boolean;
|
|
23
25
|
isInDanger?: boolean;
|
|
24
26
|
isResizing?: boolean;
|
|
@@ -32,6 +34,7 @@ export interface Props {
|
|
|
32
34
|
hoveredCell?: CellHoverMeta;
|
|
33
35
|
ordering?: TableColumnOrdering;
|
|
34
36
|
stickyHeader?: RowStickyState;
|
|
37
|
+
insertRowButtonIndex?: number;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
interface State {
|
|
@@ -111,6 +114,7 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
111
114
|
const {
|
|
112
115
|
editorView,
|
|
113
116
|
tableRef,
|
|
117
|
+
tableNode,
|
|
114
118
|
isInDanger,
|
|
115
119
|
isResizing,
|
|
116
120
|
isNumberColumnEnabled,
|
|
@@ -157,10 +161,13 @@ export default class TableFloatingControls extends Component<Props, State> {
|
|
|
157
161
|
{isDragAndDropEnabled ? (
|
|
158
162
|
<DragControls
|
|
159
163
|
tableRef={tableRef}
|
|
164
|
+
tableNode={tableNode}
|
|
160
165
|
hoveredCell={hoveredCell}
|
|
161
166
|
editorView={editorView}
|
|
162
167
|
tableActive={tableActive}
|
|
163
168
|
isInDanger={isInDanger}
|
|
169
|
+
isResizing={isResizing}
|
|
170
|
+
hasHeaderRow={hasHeaderRow}
|
|
164
171
|
hoverRows={this.hoverRows}
|
|
165
172
|
selectRow={this.selectRow}
|
|
166
173
|
updateCellHoverLocation={this.updateCellHoverLocation}
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
columnControlsDecoration,
|
|
57
57
|
columnControlsLineMarker,
|
|
58
58
|
DeleteButton,
|
|
59
|
+
dragInsertButtonWrapper,
|
|
59
60
|
floatingColumnControls,
|
|
60
61
|
HeaderButton,
|
|
61
62
|
HeaderButtonDanger,
|
|
@@ -357,6 +358,8 @@ export const tableStyles = (
|
|
|
357
358
|
${insertRowButtonWrapper(props)}
|
|
358
359
|
}
|
|
359
360
|
|
|
361
|
+
${dragInsertButtonWrapper(props)}
|
|
362
|
+
|
|
360
363
|
/* Delete button */
|
|
361
364
|
${DeleteButton(props)}
|
|
362
365
|
/* Ends Delete button */
|
|
@@ -700,12 +703,64 @@ export const tableStyles = (
|
|
|
700
703
|
)}
|
|
701
704
|
}
|
|
702
705
|
|
|
703
|
-
.${ClassName.
|
|
706
|
+
.${ClassName.DRAG_ROW_CONTROLS} {
|
|
704
707
|
display: grid;
|
|
705
708
|
align-items: center;
|
|
706
709
|
position: absolute;
|
|
707
710
|
left: -4px;
|
|
708
711
|
z-index: ${akEditorUnitZIndex};
|
|
712
|
+
|
|
713
|
+
.${ClassName.DRAG_ROW_FLOATING_INSERT_DOT_WRAPPER} {
|
|
714
|
+
align-self: end;
|
|
715
|
+
position: absolute;
|
|
716
|
+
height: 100%;
|
|
717
|
+
width: 24px;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
.${ClassName.DRAG_ROW_FLOATING_INSERT_DOT} {
|
|
721
|
+
position: absolute;
|
|
722
|
+
bottom: -3px;
|
|
723
|
+
left: 6px;
|
|
724
|
+
background-color: ${token(
|
|
725
|
+
'color.background.accent.gray.subtler',
|
|
726
|
+
'#C1C7D0',
|
|
727
|
+
)};
|
|
728
|
+
height: 4px;
|
|
729
|
+
width: 4px;
|
|
730
|
+
border-radius: 50%;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
.${ClassName.DRAG_COLUMN_CONTROLS} {
|
|
735
|
+
.${ClassName.COLUMN_CONTROLS_INNER} {
|
|
736
|
+
height: 24px;
|
|
737
|
+
position: absolute;
|
|
738
|
+
top: ${token('space.negative.150', '-12px')};
|
|
739
|
+
z-index: ${akEditorUnitZIndex};
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
.${ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT_WRAPPER} {
|
|
743
|
+
position: absolute;
|
|
744
|
+
height: 24px;
|
|
745
|
+
width: 100%;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
.${ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT} {
|
|
749
|
+
background-color: ${token(
|
|
750
|
+
'color.background.accent.gray.subtler',
|
|
751
|
+
'#C1C7D0',
|
|
752
|
+
)};
|
|
753
|
+
height: 4px;
|
|
754
|
+
width: 4px;
|
|
755
|
+
border-radius: 50%;
|
|
756
|
+
position: absolute;
|
|
757
|
+
right: -2px;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
.${ClassName.CONTROLS_FLOATING_BUTTON_ROW}
|
|
762
|
+
.${ClassName.DRAG_CONTROLS_INSERT_BUTTON_INNER} {
|
|
763
|
+
bottom: -1px;
|
|
709
764
|
}
|
|
710
765
|
|
|
711
766
|
.${ClassName.DRAG_HANDLE_BUTTON_CONTAINER} {
|
|
@@ -719,10 +774,10 @@ export const tableStyles = (
|
|
|
719
774
|
display: flex;
|
|
720
775
|
justify-content: center;
|
|
721
776
|
align-items: center;
|
|
777
|
+
outline: none !important;
|
|
722
778
|
|
|
723
779
|
svg {
|
|
724
780
|
rect {
|
|
725
|
-
//
|
|
726
781
|
fill: ${token('color.background.accent.gray.subtlest', '#F1F2F4')};
|
|
727
782
|
}
|
|
728
783
|
g {
|
|
@@ -180,6 +180,32 @@ const InsertButtonHover = () => css`
|
|
|
180
180
|
}
|
|
181
181
|
`;
|
|
182
182
|
|
|
183
|
+
export const dragInsertButtonWrapper = (props: ThemeProps) => css`
|
|
184
|
+
.${ClassName.DRAG_CONTROLS_INSERT_BUTTON_INNER} {
|
|
185
|
+
position: absolute;
|
|
186
|
+
z-index: ${akEditorUnitZIndex + 10};
|
|
187
|
+
bottom: -5px;
|
|
188
|
+
left: 3px;
|
|
189
|
+
}
|
|
190
|
+
.${ClassName.DRAG_CONTROLS_INSERT_BUTTON} {
|
|
191
|
+
${Button(`
|
|
192
|
+
background: ${token('elevation.surface.overlay', 'white')};
|
|
193
|
+
color: ${token('color.icon', N300)};
|
|
194
|
+
border: 1px solid ${token(
|
|
195
|
+
'color.background.accent.gray.subtler',
|
|
196
|
+
'#C1C7D0',
|
|
197
|
+
)};
|
|
198
|
+
border-radius: 50%;
|
|
199
|
+
`)}
|
|
200
|
+
}
|
|
201
|
+
.${ClassName.DRAG_CONTROLS_INSERT_BUTTON}:hover {
|
|
202
|
+
background: ${token('color.background.brand.bold', B300)};
|
|
203
|
+
border: 1px solid ${token('color.background.brand.bold', B300)};
|
|
204
|
+
color: ${token('color.icon.inverse', 'white')};
|
|
205
|
+
cursor: pointer;
|
|
206
|
+
}
|
|
207
|
+
`;
|
|
208
|
+
|
|
183
209
|
export const insertColumnButtonWrapper = (props: ThemeProps) => css`
|
|
184
210
|
${InsertButton()}
|
|
185
211
|
${InsertButtonHover()}
|
|
@@ -388,7 +414,7 @@ export const floatingColumnControls = (props: ThemeProps) => {
|
|
|
388
414
|
}
|
|
389
415
|
}
|
|
390
416
|
|
|
391
|
-
.${ClassName.
|
|
417
|
+
.${ClassName.DRAG_COLUMN_CONTROLS} {
|
|
392
418
|
box-sizing: border-box;
|
|
393
419
|
|
|
394
420
|
.${ClassName.COLUMN_CONTROLS_INNER} {
|
|
@@ -40,10 +40,6 @@ export const isRowControlsButton = (node: HTMLElement | null): boolean =>
|
|
|
40
40
|
containsClassName(node, ClassName.ROW_CONTROLS_BUTTON) ||
|
|
41
41
|
containsClassName(node, ClassName.NUMBERED_COLUMN_BUTTON);
|
|
42
42
|
|
|
43
|
-
export const isRowDragControlsButton = (node: HTMLElement | null) =>
|
|
44
|
-
containsClassName(node, ClassName.ROW_CONTROLS_WITH_DRAG) ||
|
|
45
|
-
closestElement(node, `.${ClassName.ROW_CONTROLS_WITH_DRAG}`);
|
|
46
|
-
|
|
47
43
|
export const isResizeHandleDecoration = (node: HTMLElement | null): boolean =>
|
|
48
44
|
containsClassName(node, ClassName.RESIZE_HANDLE_DECORATION);
|
|
49
45
|
|
|
@@ -55,6 +51,17 @@ export const isTableContainerOrWrapper = (node: HTMLElement | null): boolean =>
|
|
|
55
51
|
containsClassName(node, ClassName.TABLE_CONTAINER) ||
|
|
56
52
|
containsClassName(node, ClassName.TABLE_NODE_WRAPPER);
|
|
57
53
|
|
|
54
|
+
/** drag-and-drop classes */
|
|
55
|
+
export const isRowDragControlsButton = (node: HTMLElement | null) =>
|
|
56
|
+
containsClassName(node, ClassName.DRAG_ROW_CONTROLS) ||
|
|
57
|
+
closestElement(node, `.${ClassName.DRAG_ROW_CONTROLS}`);
|
|
58
|
+
|
|
59
|
+
export const isDragRowFloatingInsertDot = (node: HTMLElement | null) =>
|
|
60
|
+
containsClassName(node, ClassName.DRAG_ROW_FLOATING_INSERT_DOT_WRAPPER);
|
|
61
|
+
|
|
62
|
+
export const isDragColumnFloatingInsertDot = (node: HTMLElement | null) =>
|
|
63
|
+
containsClassName(node, ClassName.DRAG_COLUMN_FLOATING_INSERT_DOT_WRAPPER);
|
|
64
|
+
|
|
58
65
|
/*
|
|
59
66
|
* This function returns which side of a given element the mouse cursor is,
|
|
60
67
|
* using as a base the half of the width by default, for example:
|