@atlaskit/editor-plugin-table 5.7.10 → 5.8.0

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.
Files changed (67) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/dist/cjs/commands/column-resize.js +155 -0
  4. package/dist/cjs/commands/go-to-next-cell.js +15 -0
  5. package/dist/cjs/commands/selection.js +16 -3
  6. package/dist/cjs/plugin.js +2 -1
  7. package/dist/cjs/pm-plugins/keymap.js +9 -0
  8. package/dist/cjs/pm-plugins/table-resizing/event-handlers.js +18 -7
  9. package/dist/cjs/pm-plugins/table-resizing/utils/index.js +6 -0
  10. package/dist/cjs/types.js +2 -0
  11. package/dist/cjs/ui/FloatingDragMenu/DragMenu.js +187 -17
  12. package/dist/cjs/ui/FloatingDragMenu/index.js +4 -2
  13. package/dist/cjs/ui/FloatingDragMenu/styles.js +19 -0
  14. package/dist/cjs/ui/consts.js +2 -1
  15. package/dist/es2019/commands/column-resize.js +149 -0
  16. package/dist/es2019/commands/go-to-next-cell.js +13 -0
  17. package/dist/es2019/commands/selection.js +16 -3
  18. package/dist/es2019/plugin.js +2 -1
  19. package/dist/es2019/pm-plugins/keymap.js +10 -1
  20. package/dist/es2019/pm-plugins/table-resizing/event-handlers.js +19 -8
  21. package/dist/es2019/pm-plugins/table-resizing/utils/index.js +1 -1
  22. package/dist/es2019/types.js +2 -0
  23. package/dist/es2019/ui/FloatingDragMenu/DragMenu.js +177 -7
  24. package/dist/es2019/ui/FloatingDragMenu/index.js +4 -2
  25. package/dist/es2019/ui/FloatingDragMenu/styles.js +62 -0
  26. package/dist/es2019/ui/consts.js +2 -1
  27. package/dist/esm/commands/column-resize.js +149 -0
  28. package/dist/esm/commands/go-to-next-cell.js +15 -0
  29. package/dist/esm/commands/selection.js +16 -3
  30. package/dist/esm/plugin.js +2 -1
  31. package/dist/esm/pm-plugins/keymap.js +10 -1
  32. package/dist/esm/pm-plugins/table-resizing/event-handlers.js +19 -8
  33. package/dist/esm/pm-plugins/table-resizing/utils/index.js +1 -1
  34. package/dist/esm/types.js +2 -0
  35. package/dist/esm/ui/FloatingDragMenu/DragMenu.js +177 -7
  36. package/dist/esm/ui/FloatingDragMenu/index.js +4 -2
  37. package/dist/esm/ui/FloatingDragMenu/styles.js +12 -0
  38. package/dist/esm/ui/consts.js +2 -1
  39. package/dist/types/commands/column-resize.d.ts +5 -0
  40. package/dist/types/pm-plugins/table-resizing/utils/index.d.ts +1 -1
  41. package/dist/types/types.d.ts +2 -0
  42. package/dist/types/ui/FloatingDragMenu/DragMenu.d.ts +1 -2
  43. package/dist/types/ui/FloatingDragMenu/index.d.ts +3 -2
  44. package/dist/types/ui/FloatingDragMenu/styles.d.ts +3 -0
  45. package/dist/types/ui/consts.d.ts +1 -1
  46. package/dist/types-ts4.5/commands/column-resize.d.ts +5 -0
  47. package/dist/types-ts4.5/pm-plugins/table-resizing/utils/index.d.ts +1 -1
  48. package/dist/types-ts4.5/types.d.ts +2 -0
  49. package/dist/types-ts4.5/ui/FloatingDragMenu/DragMenu.d.ts +1 -2
  50. package/dist/types-ts4.5/ui/FloatingDragMenu/index.d.ts +3 -2
  51. package/dist/types-ts4.5/ui/FloatingDragMenu/styles.d.ts +3 -0
  52. package/dist/types-ts4.5/ui/consts.d.ts +1 -1
  53. package/package.json +6 -2
  54. package/src/__tests__/unit/ui/FloatingDragMenu.tsx +295 -0
  55. package/src/commands/column-resize.ts +257 -0
  56. package/src/commands/go-to-next-cell.ts +21 -0
  57. package/src/commands/selection.ts +19 -2
  58. package/src/plugin.tsx +1 -0
  59. package/src/pm-plugins/keymap.ts +35 -0
  60. package/src/pm-plugins/table-resizing/event-handlers.ts +33 -21
  61. package/src/pm-plugins/table-resizing/utils/index.ts +1 -0
  62. package/src/types.ts +3 -0
  63. package/src/ui/FloatingDragMenu/DragMenu.tsx +226 -7
  64. package/src/ui/FloatingDragMenu/index.tsx +4 -1
  65. package/src/ui/FloatingDragMenu/styles.ts +71 -0
  66. package/src/ui/consts.ts +6 -1
  67. package/tsconfig.app.json +3 -0
@@ -1,16 +1,28 @@
1
+ /* eslint-disable @atlaskit/design-system/prefer-primitives */
1
2
  /** @jsx jsx */
3
+ import { useState } from 'react';
4
+
2
5
  import { jsx } from '@emotion/react';
3
6
 
4
7
  import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
8
+ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
9
+ import { DropdownMenuSharedCssClassName } from '@atlaskit/editor-common/styles';
5
10
  import type {
6
11
  Command,
7
12
  GetEditorContainerWidth,
8
13
  } from '@atlaskit/editor-common/types';
14
+ import {
15
+ backgroundPaletteTooltipMessages,
16
+ cellBackgroundColorPalette,
17
+ ColorPalette,
18
+ } from '@atlaskit/editor-common/ui-color';
9
19
  import {
10
20
  ArrowKeyNavigationType,
11
21
  DropdownMenu,
12
22
  } from '@atlaskit/editor-common/ui-menu';
13
23
  import type { MenuItem } from '@atlaskit/editor-common/ui-menu';
24
+ import { closestElement } from '@atlaskit/editor-common/utils';
25
+ import { hexToEditorBackgroundPaletteColor } from '@atlaskit/editor-palette';
14
26
  import type { Node as PmNode } from '@atlaskit/editor-prosemirror/model';
15
27
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
16
28
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
@@ -21,13 +33,26 @@ import {
21
33
  getSelectionRect,
22
34
  isSelectionType,
23
35
  } from '@atlaskit/editor-tables/utils';
24
- import { token } from '@atlaskit/tokens';
36
+ import EditorBackgroundColorIcon from '@atlaskit/icon/glyph/editor/background-color';
37
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
38
+ import Toggle from '@atlaskit/toggle';
25
39
 
26
40
  import { clearHoverSelection, hoverColumns, hoverRows } from '../../commands';
41
+ import {
42
+ setColorWithAnalytics,
43
+ toggleHeaderColumnWithAnalytics,
44
+ toggleHeaderRowWithAnalytics,
45
+ toggleNumberColumnWithAnalytics,
46
+ } from '../../commands-with-analytics';
27
47
  import { toggleDragMenu } from '../../pm-plugins/drag-and-drop/commands';
28
48
  import { getPluginState } from '../../pm-plugins/drag-and-drop/plugin-factory';
49
+ import { getPluginState as getTablePluginState } from '../../pm-plugins/plugin-factory';
29
50
  import type { PluginConfig, TableDirection } from '../../types';
51
+ import { TableCssClassName as ClassName } from '../../types';
30
52
  import {
53
+ checkIfHeaderColumnEnabled,
54
+ checkIfHeaderRowEnabled,
55
+ checkIfNumberColumnEnabled,
31
56
  getMergedCellsPositions,
32
57
  getSelectedColumnIndexes,
33
58
  getSelectedRowIndexes,
@@ -38,6 +63,12 @@ import type { DragMenuConfig } from '../../utils/drag-menu';
38
63
  import { getDragMenuConfig } from '../../utils/drag-menu';
39
64
  import { dragMenuDropdownWidth } from '../consts';
40
65
 
66
+ import {
67
+ cellColourPreviewStyles,
68
+ dragMenuBackgroundColorStyles,
69
+ toggleStyles,
70
+ } from './styles';
71
+
41
72
  type DragMenuProps = {
42
73
  direction?: TableDirection;
43
74
  index?: number;
@@ -91,7 +122,6 @@ const convertToDropdownItems = (dragMenuConfig: DragMenuConfig[]) => {
91
122
  elemBefore: item.icon ? (
92
123
  <div
93
124
  style={{
94
- marginRight: token('space.negative.075', '-6px'),
95
125
  display: 'flex',
96
126
  }}
97
127
  >
@@ -125,11 +155,13 @@ export const DragMenu = ({
125
155
  getEditorContainerWidth,
126
156
  canDrag,
127
157
  editorAnalyticsAPI,
158
+ pluginConfig,
128
159
  }: DragMenuProps) => {
129
- const tableMap = tableNode ? TableMap.get(tableNode) : undefined;
130
-
131
160
  const { state, dispatch } = editorView;
132
161
  const { selection } = state;
162
+ const tableMap = tableNode ? TableMap.get(tableNode) : undefined;
163
+ const [isSubmenuOpen, setIsSubmenuOpen] = useState(false);
164
+
133
165
  const selectionRect = isSelectionType(selection, 'cell')
134
166
  ? getSelectionRect(selection)!
135
167
  : findCellRectClosestToPos(selection.$from);
@@ -141,6 +173,7 @@ export const DragMenu = ({
141
173
  index !== undefined && hasMergedCells(index)(selection);
142
174
 
143
175
  const hasMergedCellsInTable = getMergedCellsPositions(state.tr).length > 0;
176
+ const allowBackgroundColor = pluginConfig?.allowBackgroundColor ?? false;
144
177
 
145
178
  const dragMenuConfig = getDragMenuConfig(
146
179
  direction,
@@ -157,9 +190,136 @@ export const DragMenu = ({
157
190
 
158
191
  const { menuItems, menuCallback } = convertToDropdownItems(dragMenuConfig);
159
192
 
193
+ const handleSubMenuRef = (ref: HTMLDivElement | null) => {
194
+ const parent = closestElement(
195
+ editorView.dom as HTMLElement,
196
+ '.fabric-editor-popup-scroll-parent',
197
+ );
198
+ if (!(parent && ref)) {
199
+ return;
200
+ }
201
+ const boundariesRect = parent.getBoundingClientRect();
202
+ const rect = ref.getBoundingClientRect();
203
+ if (rect.left + rect.width > boundariesRect.width) {
204
+ ref.style.left = `-${rect.width}px`;
205
+ }
206
+ };
207
+
208
+ const setColor = (color: string) => {
209
+ const { targetCellPosition } = getTablePluginState(editorView.state);
210
+ const { state, dispatch } = editorView;
211
+ setColorWithAnalytics(editorAnalyticsAPI)(
212
+ INPUT_METHOD.CONTEXT_MENU,
213
+ color,
214
+ targetCellPosition,
215
+ )(state, dispatch);
216
+ closeMenu();
217
+ setIsSubmenuOpen(false);
218
+ };
219
+
220
+ const createBackgroundColorMenuItem = () => {
221
+ const { targetCellPosition } = getTablePluginState(editorView.state);
222
+ const node = targetCellPosition
223
+ ? state.doc.nodeAt(targetCellPosition)
224
+ : null;
225
+ const background = hexToEditorBackgroundPaletteColor(
226
+ node?.attrs?.background || '#ffffff',
227
+ );
228
+ return {
229
+ content: 'Background color',
230
+ value: { name: 'background' },
231
+ elemBefore: (
232
+ <EditorBackgroundColorIcon label={'background color'} size="medium" />
233
+ ),
234
+ elemAfter: (
235
+ <div
236
+ className={DropdownMenuSharedCssClassName.SUBMENU}
237
+ css={dragMenuBackgroundColorStyles}
238
+ >
239
+ <div
240
+ css={cellColourPreviewStyles(background)}
241
+ className={ClassName.DRAG_SUBMENU_ICON}
242
+ />
243
+ {isSubmenuOpen && (
244
+ <div className={ClassName.DRAG_SUBMENU} ref={handleSubMenuRef}>
245
+ <ColorPalette
246
+ cols={7}
247
+ onClick={setColor}
248
+ selectedColor={background}
249
+ paletteOptions={{
250
+ palette: cellBackgroundColorPalette,
251
+ paletteColorTooltipMessages: backgroundPaletteTooltipMessages,
252
+ hexToPaletteColor: hexToEditorBackgroundPaletteColor,
253
+ }}
254
+ />
255
+ </div>
256
+ )}
257
+ </div>
258
+ ),
259
+ } as MenuItem;
260
+ };
261
+
262
+ const toggleHeaderColumn = () => {
263
+ toggleHeaderColumnWithAnalytics(editorAnalyticsAPI)(state, dispatch);
264
+ };
265
+
266
+ const toggleHeaderRow = () => {
267
+ toggleHeaderRowWithAnalytics(editorAnalyticsAPI)(state, dispatch);
268
+ };
269
+
270
+ const toggleRowNumbers = () => {
271
+ toggleNumberColumnWithAnalytics(editorAnalyticsAPI)(state, dispatch);
272
+ };
273
+
274
+ const createhHeaderRowColumnMenuItem = (direction: TableDirection) => {
275
+ return direction === 'column'
276
+ ? ({
277
+ content: 'Header column',
278
+ value: { name: 'header_column' },
279
+ elemAfter: (
280
+ <div css={toggleStyles}>
281
+ <Toggle
282
+ id="toggle-header-column"
283
+ onChange={toggleHeaderColumn}
284
+ isChecked={checkIfHeaderColumnEnabled(selection)}
285
+ />
286
+ </div>
287
+ ),
288
+ } as MenuItem)
289
+ : ({
290
+ content: 'Header row',
291
+ value: { name: 'header_row' },
292
+ elemAfter: (
293
+ <div css={toggleStyles}>
294
+ <Toggle
295
+ id="toggle-header-row"
296
+ onChange={toggleHeaderRow}
297
+ isChecked={checkIfHeaderRowEnabled(selection)}
298
+ />
299
+ </div>
300
+ ),
301
+ } as MenuItem);
302
+ };
303
+
304
+ const createRowNumbersMenuItem = () => {
305
+ return {
306
+ content: 'Row numbers',
307
+ value: { name: 'row_numbers' },
308
+ elemAfter: (
309
+ <div css={toggleStyles}>
310
+ <Toggle
311
+ id="toggle-row-numbers"
312
+ onChange={toggleRowNumbers}
313
+ isChecked={checkIfNumberColumnEnabled(selection)}
314
+ />
315
+ </div>
316
+ ),
317
+ } as MenuItem;
318
+ };
319
+
160
320
  /**
161
321
  * This function is to check if the menu should be closed or not.
162
- * As when continously clicking on drag handle on different rows/columns,
322
+ * As when continously clicking on tyle handle on different rows/columns,
163
323
  * should open the menu corresponding to the position of the drag handle.
164
324
  * @returns true when the menu should be closed, false otherwise
165
325
  */
@@ -194,11 +354,40 @@ export const DragMenu = ({
194
354
 
195
355
  const handleMenuItemActivated = ({ item }: { item: MenuItem }) => {
196
356
  menuCallback[item.value.name]?.(state, dispatch);
197
- closeMenu();
357
+
358
+ switch (item.value.name) {
359
+ case 'header_column':
360
+ toggleHeaderColumn();
361
+ break;
362
+ case 'header_row':
363
+ toggleHeaderRow();
364
+ break;
365
+ case 'row_numbers':
366
+ toggleRowNumbers();
367
+ break;
368
+ default:
369
+ break;
370
+ }
371
+
372
+ if (
373
+ ['header_column', 'header_row', 'row_numbers', 'background'].indexOf(
374
+ item.value.name,
375
+ ) <= -1
376
+ ) {
377
+ closeMenu();
378
+ }
198
379
  };
199
380
 
200
381
  const handleItemMouseEnter = ({ item }: { item: MenuItem }) => {
201
- if (!selectionRect || !item.value.name?.startsWith('delete')) {
382
+ if (!selectionRect) {
383
+ return;
384
+ }
385
+
386
+ if (item.value.name === 'background' && !isSubmenuOpen) {
387
+ setIsSubmenuOpen(true);
388
+ }
389
+
390
+ if (!item.value.name?.startsWith('delete')) {
202
391
  return;
203
392
  }
204
393
 
@@ -208,6 +397,10 @@ export const DragMenu = ({
208
397
  };
209
398
 
210
399
  const handleItemMouseLeave = ({ item }: { item: any }) => {
400
+ if (item.value.name === 'background' && isSubmenuOpen) {
401
+ setIsSubmenuOpen(false);
402
+ }
403
+
211
404
  if (
212
405
  [
213
406
  'sort_column_asc',
@@ -224,6 +417,32 @@ export const DragMenu = ({
224
417
  return null;
225
418
  }
226
419
 
420
+ if (
421
+ allowBackgroundColor &&
422
+ getBooleanFF('platform.editor.table.new-cell-context-menu-styling')
423
+ ) {
424
+ menuItems[0].items.unshift(createBackgroundColorMenuItem());
425
+ }
426
+
427
+ // If first row, add toggle for Hearder row, default is true
428
+ // If first column, add toggle for Header column, default is false
429
+ if (
430
+ getBooleanFF('platform.editor.table.new-cell-context-menu-styling') &&
431
+ index === 0
432
+ ) {
433
+ menuItems.push({ items: [createhHeaderRowColumnMenuItem(direction)] });
434
+ }
435
+
436
+ // All rows, add toggle for numbered rows, default is false
437
+ if (
438
+ getBooleanFF('platform.editor.table.new-cell-context-menu-styling') &&
439
+ direction === 'row'
440
+ ) {
441
+ index === 0
442
+ ? menuItems[menuItems.length - 1].items.push(createRowNumbersMenuItem())
443
+ : menuItems.push({ items: [createRowNumbersMenuItem()] });
444
+ }
445
+
227
446
  return (
228
447
  <DropdownMenu
229
448
  mountTo={mountPoint}
@@ -12,7 +12,7 @@ import {
12
12
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
13
13
 
14
14
  import type { RowStickyState } from '../../pm-plugins/sticky-headers';
15
- import type { TableDirection } from '../../types';
15
+ import type { PluginConfig, TableDirection } from '../../types';
16
16
  import { dragMenuDropdownWidth } from '../consts';
17
17
 
18
18
  import { DragMenu } from './DragMenu';
@@ -32,6 +32,7 @@ export interface Props {
32
32
  canDrag?: boolean;
33
33
  editorAnalyticsAPI?: EditorAnalyticsAPI;
34
34
  stickyHeaders?: RowStickyState;
35
+ pluginConfig?: PluginConfig;
35
36
  }
36
37
 
37
38
  const FloatingDragMenu = ({
@@ -48,6 +49,7 @@ const FloatingDragMenu = ({
48
49
  canDrag,
49
50
  editorAnalyticsAPI,
50
51
  stickyHeaders,
52
+ pluginConfig,
51
53
  }: Props) => {
52
54
  if (
53
55
  !isOpen ||
@@ -105,6 +107,7 @@ const FloatingDragMenu = ({
105
107
  getEditorContainerWidth={getEditorContainerWidth}
106
108
  canDrag={canDrag}
107
109
  editorAnalyticsAPI={editorAnalyticsAPI}
110
+ pluginConfig={pluginConfig}
108
111
  />
109
112
  </Popup>
110
113
  );
@@ -0,0 +1,71 @@
1
+ import { css } from '@emotion/react';
2
+
3
+ import { tableBackgroundBorderColor } from '@atlaskit/adf-schema';
4
+ import { N60A, N90 } from '@atlaskit/theme/colors';
5
+ import { token } from '@atlaskit/tokens';
6
+
7
+ import { TableCssClassName as ClassName } from '../../types';
8
+ import { dragMenuDropdownWidth } from '../consts';
9
+
10
+ export const cellColourPreviewStyles = (selectedColor: string) => css`
11
+ &::before {
12
+ background: ${selectedColor};
13
+ }
14
+ `;
15
+
16
+ export const dragMenuBackgroundColorStyles = css`
17
+ .${ClassName.DRAG_SUBMENU} {
18
+ border-radius: ${token('border.radius', '3px')};
19
+ background: ${token('elevation.surface.overlay', 'white')};
20
+ box-shadow: ${token(
21
+ 'elevation.shadow.overlay',
22
+ `0 4px 8px -2px ${N60A}, 0 0 1px ${N60A}`,
23
+ )};
24
+ display: block;
25
+ position: absolute;
26
+ top: 0;
27
+ left: ${dragMenuDropdownWidth}px;
28
+ padding: ${token('space.100', '8px')};
29
+
30
+ > div {
31
+ padding: 0;
32
+ }
33
+ }
34
+
35
+ .${ClassName.DRAG_SUBMENU_ICON} {
36
+ display: flex;
37
+
38
+ &::before {
39
+ content: '';
40
+ display: block;
41
+ border: 1px solid ${tableBackgroundBorderColor};
42
+ border-radius: ${token('border.radius', '3px')};
43
+ width: 14px;
44
+ height: 14px;
45
+ }
46
+
47
+ &::after {
48
+ content: '›';
49
+ margin-left: ${token('space.050', '4px')};
50
+ line-height: 14px;
51
+ color: ${token('color.icon', N90)};
52
+ }
53
+ }
54
+ `;
55
+
56
+ export const toggleStyles = css`
57
+ display: flex;
58
+ input[type='checkbox'] {
59
+ width: 30px;
60
+ height: 14px;
61
+ pointer-events: initial;
62
+ cursor: pointer;
63
+ }
64
+ > label {
65
+ margin: 0px;
66
+ pointer-events: none;
67
+ > span {
68
+ pointer-events: none;
69
+ }
70
+ }
71
+ `;
package/src/ui/consts.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  akEditorUnitZIndex,
14
14
  akRichMediaResizeZIndex,
15
15
  } from '@atlaskit/editor-shared-styles';
16
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
16
17
  import {
17
18
  B200,
18
19
  N0,
@@ -118,7 +119,11 @@ export const resizeLineWidth = 2;
118
119
  export const resizeHandlerZIndex =
119
120
  columnControlsZIndex + akRichMediaResizeZIndex;
120
121
  export const contextualMenuTriggerSize = 16;
121
- export const contextualMenuDropdownWidth = 180;
122
+ export const contextualMenuDropdownWidth = getBooleanFF(
123
+ 'platform.editor.table.drag-and-drop',
124
+ )
125
+ ? 250
126
+ : 180;
122
127
  export const stickyRowZIndex = resizeHandlerZIndex + 2;
123
128
  export const stickyRowOffsetTop = 8;
124
129
  export const stickyHeaderBorderBottomWidth = 1;
package/tsconfig.app.json CHANGED
@@ -84,6 +84,9 @@
84
84
  {
85
85
  "path": "../../design-system/theme/tsconfig.app.json"
86
86
  },
87
+ {
88
+ "path": "../../design-system/toggle/tsconfig.app.json"
89
+ },
87
90
  {
88
91
  "path": "../../design-system/tokens/tsconfig.app.json"
89
92
  },