@atlaskit/editor-plugin-table 2.1.7 → 2.2.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 (132) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cjs/plugins/table/handlers.js +1 -0
  3. package/dist/cjs/plugins/table/index.js +1 -1
  4. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +4 -2
  5. package/dist/cjs/plugins/table/nodeviews/TableContainer.js +50 -47
  6. package/dist/cjs/plugins/table/nodeviews/TableResizer.js +64 -28
  7. package/dist/cjs/plugins/table/nodeviews/table.js +5 -3
  8. package/dist/cjs/plugins/table/pm-plugins/decorations/utils/column-controls.js +2 -0
  9. package/dist/cjs/plugins/table/pm-plugins/main.js +2 -2
  10. package/dist/cjs/plugins/table/pm-plugins/table-resizing/plugin-factory.js +1 -1
  11. package/dist/cjs/plugins/table/ui/consts.js +6 -2
  12. package/dist/cjs/plugins/table/utils/collapse.js +2 -0
  13. package/dist/cjs/plugins/table/utils/decoration.js +2 -0
  14. package/dist/cjs/plugins/table/utils/guidelines.js +12 -0
  15. package/dist/cjs/plugins/table/utils/snapping.js +37 -0
  16. package/dist/cjs/version.json +1 -1
  17. package/dist/es2019/plugins/table/handlers.js +1 -0
  18. package/dist/es2019/plugins/table/index.js +1 -1
  19. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +4 -2
  20. package/dist/es2019/plugins/table/nodeviews/TableContainer.js +25 -23
  21. package/dist/es2019/plugins/table/nodeviews/TableResizer.js +59 -29
  22. package/dist/es2019/plugins/table/nodeviews/table.js +5 -3
  23. package/dist/es2019/plugins/table/pm-plugins/decorations/plugin.js +4 -1
  24. package/dist/es2019/plugins/table/pm-plugins/decorations/utils/column-controls.js +2 -0
  25. package/dist/es2019/plugins/table/pm-plugins/main.js +2 -2
  26. package/dist/es2019/plugins/table/pm-plugins/table-resizing/plugin-factory.js +2 -0
  27. package/dist/es2019/plugins/table/ui/consts.js +3 -1
  28. package/dist/es2019/plugins/table/utils/collapse.js +2 -0
  29. package/dist/es2019/plugins/table/utils/decoration.js +2 -0
  30. package/dist/es2019/plugins/table/utils/guidelines.js +4 -0
  31. package/dist/es2019/plugins/table/utils/snapping.js +27 -0
  32. package/dist/es2019/version.json +1 -1
  33. package/dist/esm/plugins/table/handlers.js +1 -0
  34. package/dist/esm/plugins/table/index.js +1 -1
  35. package/dist/esm/plugins/table/nodeviews/TableComponent.js +4 -2
  36. package/dist/esm/plugins/table/nodeviews/TableContainer.js +50 -47
  37. package/dist/esm/plugins/table/nodeviews/TableResizer.js +61 -28
  38. package/dist/esm/plugins/table/nodeviews/table.js +5 -3
  39. package/dist/esm/plugins/table/pm-plugins/decorations/plugin.js +4 -1
  40. package/dist/esm/plugins/table/pm-plugins/decorations/utils/column-controls.js +2 -0
  41. package/dist/esm/plugins/table/pm-plugins/main.js +2 -2
  42. package/dist/esm/plugins/table/pm-plugins/table-resizing/plugin-factory.js +2 -0
  43. package/dist/esm/plugins/table/ui/consts.js +3 -1
  44. package/dist/esm/plugins/table/utils/collapse.js +2 -0
  45. package/dist/esm/plugins/table/utils/decoration.js +2 -0
  46. package/dist/esm/plugins/table/utils/guidelines.js +4 -0
  47. package/dist/esm/plugins/table/utils/snapping.js +30 -0
  48. package/dist/esm/version.json +1 -1
  49. package/dist/types/plugins/table/index.d.ts +3 -1
  50. package/dist/types/plugins/table/nodeviews/TableComponent.d.ts +2 -1
  51. package/dist/types/plugins/table/nodeviews/TableContainer.d.ts +5 -2
  52. package/dist/types/plugins/table/nodeviews/TableResizer.d.ts +3 -1
  53. package/dist/types/plugins/table/nodeviews/table.d.ts +2 -1
  54. package/dist/types/plugins/table/nodeviews/types.d.ts +2 -0
  55. package/dist/types/plugins/table/pm-plugins/main.d.ts +2 -1
  56. package/dist/types/plugins/table/types.d.ts +3 -0
  57. package/dist/types/plugins/table/ui/consts.d.ts +2 -0
  58. package/dist/types/plugins/table/utils/guidelines.d.ts +3 -0
  59. package/dist/types/plugins/table/utils/snapping.d.ts +8 -0
  60. package/dist/types-ts4.5/plugins/table/index.d.ts +3 -1
  61. package/dist/types-ts4.5/plugins/table/nodeviews/TableComponent.d.ts +2 -1
  62. package/dist/types-ts4.5/plugins/table/nodeviews/TableContainer.d.ts +5 -2
  63. package/dist/types-ts4.5/plugins/table/nodeviews/TableResizer.d.ts +3 -1
  64. package/dist/types-ts4.5/plugins/table/nodeviews/table.d.ts +2 -1
  65. package/dist/types-ts4.5/plugins/table/nodeviews/types.d.ts +2 -0
  66. package/dist/types-ts4.5/plugins/table/pm-plugins/main.d.ts +2 -1
  67. package/dist/types-ts4.5/plugins/table/types.d.ts +3 -0
  68. package/dist/types-ts4.5/plugins/table/ui/consts.d.ts +2 -0
  69. package/dist/types-ts4.5/plugins/table/utils/guidelines.d.ts +3 -0
  70. package/dist/types-ts4.5/plugins/table/utils/snapping.d.ts +8 -0
  71. package/package.json +3 -2
  72. package/report.api.md +2 -0
  73. package/src/__tests__/unit/analytics.ts +2 -0
  74. package/src/__tests__/unit/collab.ts +2 -0
  75. package/src/__tests__/unit/commands/go-to-next-cell.ts +2 -0
  76. package/src/__tests__/unit/commands/insert.ts +2 -0
  77. package/src/__tests__/unit/commands/misc.ts +2 -0
  78. package/src/__tests__/unit/commands/sort.ts +4 -0
  79. package/src/__tests__/unit/commands.ts +2 -0
  80. package/src/__tests__/unit/copy-paste.ts +2 -0
  81. package/src/__tests__/unit/event-handlers/index.ts +3 -0
  82. package/src/__tests__/unit/event-handlers.ts +3 -0
  83. package/src/__tests__/unit/fix-tables.ts +2 -0
  84. package/src/__tests__/unit/get-toolbar-config.ts +2 -0
  85. package/src/__tests__/unit/handlers.ts +2 -0
  86. package/src/__tests__/unit/hover-selection.ts +2 -0
  87. package/src/__tests__/unit/index.ts +2 -0
  88. package/src/__tests__/unit/layout.ts +2 -0
  89. package/src/__tests__/unit/nodeviews/cell.ts +2 -0
  90. package/src/__tests__/unit/nodeviews/table.ts +2 -0
  91. package/src/__tests__/unit/pm-plugins/decorations/column-resizing.ts +2 -0
  92. package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +2 -0
  93. package/src/__tests__/unit/pm-plugins/main.ts +2 -0
  94. package/src/__tests__/unit/pm-plugins/safari-delete-composition-text-issue-workaround.ts +2 -0
  95. package/src/__tests__/unit/pm-plugins/sticky-headers/tableRow.tsx +3 -0
  96. package/src/__tests__/unit/pm-plugins/table-resizing/event-handlers.ts +2 -0
  97. package/src/__tests__/unit/sort-column.ts +2 -0
  98. package/src/__tests__/unit/toolbar.ts +2 -0
  99. package/src/__tests__/unit/transforms/delete-columns.ts +2 -0
  100. package/src/__tests__/unit/transforms/delete-rows.ts +2 -0
  101. package/src/__tests__/unit/transforms/merging.ts +2 -0
  102. package/src/__tests__/unit/ui/ContextualMenu.tsx +2 -0
  103. package/src/__tests__/unit/ui/CornerControls.tsx +2 -0
  104. package/src/__tests__/unit/ui/FloatingContextualButton.tsx +2 -0
  105. package/src/__tests__/unit/ui/FloatingContextualMenu.tsx +2 -0
  106. package/src/__tests__/unit/ui/RowControls.tsx +2 -0
  107. package/src/__tests__/unit/ui/TableFloatingControls.tsx +2 -0
  108. package/src/__tests__/unit/undo-redo.ts +2 -0
  109. package/src/__tests__/unit/utils/collapse.ts +2 -0
  110. package/src/__tests__/unit/utils/nodes.ts +2 -0
  111. package/src/__tests__/unit/utils/row-controls.ts +2 -0
  112. package/src/__tests__/unit/utils.ts +2 -0
  113. package/src/plugins/table/handlers.ts +1 -0
  114. package/src/plugins/table/index.tsx +3 -1
  115. package/src/plugins/table/nodeviews/TableComponent.tsx +4 -0
  116. package/src/plugins/table/nodeviews/TableContainer.tsx +31 -22
  117. package/src/plugins/table/nodeviews/TableResizer.tsx +100 -34
  118. package/src/plugins/table/nodeviews/table.tsx +4 -0
  119. package/src/plugins/table/nodeviews/types.ts +2 -0
  120. package/src/plugins/table/pm-plugins/decorations/plugin.ts +1 -0
  121. package/src/plugins/table/pm-plugins/decorations/utils/column-controls.ts +1 -0
  122. package/src/plugins/table/pm-plugins/decorations/utils/types.ts +1 -0
  123. package/src/plugins/table/pm-plugins/main.ts +3 -0
  124. package/src/plugins/table/pm-plugins/table-resizing/plugin-factory.ts +1 -0
  125. package/src/plugins/table/pm-plugins/table-resizing/utils/dom.ts +1 -0
  126. package/src/plugins/table/types.ts +4 -0
  127. package/src/plugins/table/ui/consts.ts +3 -0
  128. package/src/plugins/table/utils/collapse.ts +1 -0
  129. package/src/plugins/table/utils/decoration.ts +1 -0
  130. package/src/plugins/table/utils/guidelines.ts +17 -0
  131. package/src/plugins/table/utils/snapping.ts +38 -0
  132. package/tmp/api-report-tmp.d.ts +3 -1
@@ -25,6 +25,7 @@ import sendKeyToPm from '@atlaskit/editor-test-helpers/send-key-to-pm';
25
25
  import clone from 'lodash/clone';
26
26
  import tablePlugin from '../../plugins/table';
27
27
  import { widthPlugin } from '@atlaskit/editor-plugin-width';
28
+ import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
28
29
  import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
29
30
  import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
30
31
  import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
@@ -66,6 +67,7 @@ describe('undo/redo with tables', () => {
66
67
  .add([analyticsPlugin, {}])
67
68
  .add(contentInsertionPlugin)
68
69
  .add(widthPlugin)
70
+ .add(guidelinePlugin)
69
71
  .add([tablePlugin, { tableOptions }]),
70
72
  pluginKey: tablePluginKey,
71
73
  });
@@ -13,6 +13,7 @@ import {
13
13
 
14
14
  import tablePlugin from '../../../plugins/table';
15
15
  import { widthPlugin } from '@atlaskit/editor-plugin-width';
16
+ import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
16
17
 
17
18
  import { isTableCollapsible } from '../../../plugins/table/utils/collapse';
18
19
  import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
@@ -28,6 +29,7 @@ describe('collapse', () => {
28
29
  .add([analyticsPlugin, {}])
29
30
  .add(contentInsertionPlugin)
30
31
  .add(widthPlugin)
32
+ .add(guidelinePlugin)
31
33
  .add(tablePlugin);
32
34
 
33
35
  return createEditor({ doc, preset });
@@ -22,6 +22,7 @@ import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
22
22
  import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
23
23
  import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
24
24
  import { widthPlugin } from '@atlaskit/editor-plugin-width';
25
+ import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
25
26
 
26
27
  describe('table merging logic', () => {
27
28
  const createEditor = createProsemirrorEditorFactory();
@@ -34,6 +35,7 @@ describe('table merging logic', () => {
34
35
  .add([analyticsPlugin, {}])
35
36
  .add(contentInsertionPlugin)
36
37
  .add(widthPlugin)
38
+ .add(guidelinePlugin)
37
39
  .add(tablePlugin),
38
40
  pluginKey,
39
41
  });
@@ -23,6 +23,7 @@ import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
23
23
  import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
24
24
  import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
25
25
  import { widthPlugin } from '@atlaskit/editor-plugin-width';
26
+ import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
26
27
 
27
28
  const TABLE_LOCAL_ID = 'test-table-local-id';
28
29
 
@@ -44,6 +45,7 @@ describe('table plugin: utils/row-controls.js', () => {
44
45
  .add([analyticsPlugin, {}])
45
46
  .add(contentInsertionPlugin)
46
47
  .add(widthPlugin)
48
+ .add(guidelinePlugin)
47
49
  .add(tablePlugin),
48
50
  pluginKey,
49
51
  });
@@ -32,6 +32,7 @@ import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
32
32
  import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
33
33
  import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
34
34
  import { widthPlugin } from '@atlaskit/editor-plugin-width';
35
+ import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
35
36
 
36
37
  describe('table plugin: utils', () => {
37
38
  const createEditor = createProsemirrorEditorFactory();
@@ -40,6 +41,7 @@ describe('table plugin: utils', () => {
40
41
  .add([analyticsPlugin, {}])
41
42
  .add(contentInsertionPlugin)
42
43
  .add(widthPlugin)
44
+ .add(guidelinePlugin)
43
45
  .add(tablePlugin);
44
46
 
45
47
  const editor = (doc: DocBuilder) =>
@@ -1,4 +1,5 @@
1
1
  // #region Imports
2
+ // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck
2
3
  import { Transaction, ReadonlyTransaction } from 'prosemirror-state';
3
4
  import { ContentNodeWithPos, findParentNodeOfType } from 'prosemirror-utils';
4
5
  import { findTable } from '@atlaskit/editor-tables/utils';
@@ -71,6 +71,7 @@ import type { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
71
71
  import type { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
72
72
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
73
73
  import type { widthPlugin } from '@atlaskit/editor-plugin-width';
74
+ import type { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
74
75
 
75
76
  interface TablePluginOptions {
76
77
  tableOptions: PluginConfig;
@@ -98,6 +99,7 @@ const tablesPlugin: NextEditorPlugin<
98
99
  typeof analyticsPlugin,
99
100
  typeof contentInsertionPlugin,
100
101
  typeof widthPlugin,
102
+ typeof guidelinePlugin,
101
103
  ];
102
104
  }
103
105
  > = (options?: TablePluginOptions, api?) => {
@@ -172,13 +174,13 @@ const tablesPlugin: NextEditorPlugin<
172
174
  portalProviderAPI,
173
175
  eventDispatcher,
174
176
  pluginConfig(tableOptions),
175
-
176
177
  defaultGetEditorContainerWidth,
177
178
  getEditorFeatureFlags || defaultGetEditorFeatureFlags,
178
179
  breakoutEnabled,
179
180
  fullWidthEnabled,
180
181
  wasFullWidthEnabled,
181
182
  editorAnalyticsAPI,
183
+ api,
182
184
  );
183
185
  },
184
186
  },
@@ -36,6 +36,7 @@ import {
36
36
  TableCssClassName as ClassName,
37
37
  ColumnResizingPluginState,
38
38
  ShadowEvent,
39
+ PluginInjectionAPI,
39
40
  } from '../types';
40
41
  import type { TableColumnOrdering } from '@atlaskit/adf-schema/steps';
41
42
  import TableFloatingControls from '../ui/TableFloatingControls';
@@ -74,6 +75,7 @@ export interface ComponentProps {
74
75
  ordering: TableColumnOrdering;
75
76
  tableResizingPluginState?: ColumnResizingPluginState;
76
77
  getEditorFeatureFlags: GetEditorFeatureFlags;
78
+ pluginInjectionApi?: PluginInjectionAPI;
77
79
  }
78
80
 
79
81
  interface TableState {
@@ -326,6 +328,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
326
328
  containerWidth,
327
329
  options,
328
330
  getPos,
331
+ pluginInjectionApi,
329
332
  } = this.props;
330
333
  const { isLoading, showBeforeShadow, showAfterShadow } = this.state;
331
334
  const node = getNode();
@@ -406,6 +409,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
406
409
  isFullWidthModeEnabled={options?.isFullWidthModeEnabled}
407
410
  isBreakoutEnabled={options?.isBreakoutEnabled}
408
411
  isNested={isNested}
412
+ pluginInjectionApi={pluginInjectionApi}
409
413
  >
410
414
  {stickyHeadersOptimization && (
411
415
  <div
@@ -11,17 +11,13 @@ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
11
11
  import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
12
12
  import { EditorContainerWidth } from '@atlaskit/editor-common/types';
13
13
  import { calcTableWidth } from '@atlaskit/editor-common/styles';
14
+ import type { GuidelineConfig } from '@atlaskit/editor-plugin-guideline';
14
15
 
15
- import { TableCssClassName as ClassName } from '../types';
16
+ import { PluginInjectionAPI, TableCssClassName as ClassName } from '../types';
16
17
  import { TableResizer } from './TableResizer';
17
18
  import { TABLE_MAX_WIDTH } from '../pm-plugins/table-resizing/utils';
18
19
 
19
- interface GetMarginLeftOpts {
20
- lineLength: number;
21
- tableWidth: number | 'inherit';
22
- }
23
-
24
- const getMarginLeft = ({ lineLength, tableWidth }: GetMarginLeftOpts) => {
20
+ const getMarginLeft = (lineLength: number, tableWidth: number | 'inherit') => {
25
21
  let marginLeft;
26
22
  if (tableWidth !== 'inherit' && lineLength) {
27
23
  const containerWidth = tableWidth;
@@ -69,6 +65,7 @@ type ResizableTableContainerProps = {
69
65
  editorView: EditorView;
70
66
  getPos: () => number | undefined;
71
67
  tableRef: HTMLTableElement;
68
+ pluginInjectionApi?: PluginInjectionAPI;
72
69
  };
73
70
 
74
71
  export const ResizableTableContainer = ({
@@ -80,9 +77,11 @@ export const ResizableTableContainer = ({
80
77
  editorView,
81
78
  getPos,
82
79
  tableRef,
80
+ pluginInjectionApi,
83
81
  }: PropsWithChildren<ResizableTableContainerProps>) => {
84
82
  const containerRef = useRef<HTMLDivElement | null>(null);
85
83
  const innerContainerRef = useRef<HTMLDivElement | null>(null);
84
+ const marginLeftRef = useRef<number | undefined>(0);
86
85
 
87
86
  const updateWidth = useCallback(
88
87
  (width: number) => {
@@ -90,18 +89,30 @@ export const ResizableTableContainer = ({
90
89
  return;
91
90
  }
92
91
 
93
- const marginLeft = getMarginLeft({
94
- lineLength,
95
- tableWidth: width,
96
- });
92
+ const marginLeft = getMarginLeft(lineLength, width);
93
+
94
+ if (marginLeftRef.current !== marginLeft) {
95
+ marginLeftRef.current = marginLeft;
97
96
 
98
- if (marginLeft) {
99
- containerRef.current.style.marginLeft = `${marginLeft}px`;
97
+ if (Number.isFinite(marginLeft)) {
98
+ containerRef.current.style.marginLeft = `${marginLeft}px`;
99
+ }
100
100
  }
101
101
  },
102
102
  [lineLength],
103
103
  );
104
104
 
105
+ const displayGuideline = useCallback(
106
+ (guidelines: GuidelineConfig[]) => {
107
+ return (
108
+ pluginInjectionApi?.dependencies?.guideline?.actions?.displayGuideline(
109
+ editorView,
110
+ )({ guidelines }) ?? false
111
+ );
112
+ },
113
+ [pluginInjectionApi, editorView],
114
+ );
115
+
105
116
  const tableWidth = getTableContainerWidth(node);
106
117
 
107
118
  // 76 is currently an accepted padding value considering the spacing for resizer handle
@@ -109,16 +120,13 @@ export const ResizableTableContainer = ({
109
120
 
110
121
  const width = Math.min(tableWidth, responsiveContainerWidth);
111
122
 
112
- const marginLeft = getMarginLeft({
113
- lineLength,
114
- tableWidth: width,
115
- });
123
+ marginLeftRef.current = getMarginLeft(lineLength, width);
116
124
 
117
125
  const maxResizerWidth = Math.min(responsiveContainerWidth, TABLE_MAX_WIDTH);
118
126
 
119
127
  return (
120
128
  <div
121
- style={{ marginLeft, width }}
129
+ style={{ marginLeft: marginLeftRef.current, width }}
122
130
  className={ClassName.TABLE_RESIZER_CONTAINER}
123
131
  ref={containerRef}
124
132
  >
@@ -130,6 +138,7 @@ export const ResizableTableContainer = ({
130
138
  getPos={getPos}
131
139
  node={node}
132
140
  tableRef={tableRef}
141
+ displayGuideline={displayGuideline}
133
142
  >
134
143
  <InnerContainer
135
144
  ref={innerContainerRef}
@@ -156,6 +165,7 @@ type TableContainerProps = {
156
165
  getPos: () => number | undefined;
157
166
  tableRef: HTMLTableElement;
158
167
  isNested: boolean;
168
+ pluginInjectionApi?: PluginInjectionAPI;
159
169
  };
160
170
 
161
171
  export const TableContainer = ({
@@ -169,6 +179,7 @@ export const TableContainer = ({
169
179
  getPos,
170
180
  tableRef,
171
181
  isNested,
182
+ pluginInjectionApi,
172
183
  }: PropsWithChildren<TableContainerProps>) => {
173
184
  if (
174
185
  (isFullWidthModeEnabled || isBreakoutEnabled) &&
@@ -184,6 +195,7 @@ export const TableContainer = ({
184
195
  editorView={editorView}
185
196
  getPos={getPos}
186
197
  tableRef={tableRef}
198
+ pluginInjectionApi={pluginInjectionApi}
187
199
  >
188
200
  {children}
189
201
  </ResizableTableContainer>
@@ -200,10 +212,7 @@ export const TableContainer = ({
200
212
  className={className}
201
213
  style={{
202
214
  width: tableWidth,
203
- marginLeft: getMarginLeft({
204
- lineLength: lineLength!,
205
- tableWidth,
206
- }),
215
+ marginLeft: getMarginLeft(lineLength!, tableWidth),
207
216
  }}
208
217
  >
209
218
  {children}
@@ -1,12 +1,21 @@
1
- import React, { PropsWithChildren } from 'react';
1
+ import React, {
2
+ PropsWithChildren,
3
+ useCallback,
4
+ useRef,
5
+ useMemo,
6
+ useState,
7
+ } from 'react';
2
8
  import { EditorView } from 'prosemirror-view';
3
9
  import { Node as PMNode } from 'prosemirror-model';
4
10
  import rafSchd from 'raf-schd';
5
11
 
6
12
  import {
7
13
  HandleHeightSizeType,
14
+ HandleResize,
8
15
  ResizerNext,
9
16
  } from '@atlaskit/editor-common/resizer';
17
+ import { getGuidelinesWithHighlights } from '@atlaskit/editor-common/guideline';
18
+ import type { GuidelineConfig } from '@atlaskit/editor-plugin-guideline';
10
19
 
11
20
  import {
12
21
  scaleTable,
@@ -14,6 +23,9 @@ import {
14
23
  getColgroupChildrenLength,
15
24
  COLUMN_MIN_WIDTH,
16
25
  } from '../pm-plugins/table-resizing/utils';
26
+ import { defaultGuidelines, defaultGuidelineWidths } from '../utils/guidelines';
27
+ import { findClosestSnap } from '../utils/snapping';
28
+ import { TABLE_SNAP_GAP, TABLE_HIGHLIGHT_GAP } from '../ui/consts';
17
29
 
18
30
  interface TableResizerProps {
19
31
  width: number;
@@ -23,6 +35,7 @@ interface TableResizerProps {
23
35
  getPos: () => number | undefined;
24
36
  node: PMNode;
25
37
  tableRef: HTMLTableElement;
38
+ displayGuideline: (guideline: GuidelineConfig[]) => boolean;
26
39
  }
27
40
 
28
41
  const handles = { right: true };
@@ -37,6 +50,7 @@ export const TableResizer = ({
37
50
  getPos,
38
51
  node,
39
52
  tableRef,
53
+ displayGuideline,
40
54
  }: PropsWithChildren<TableResizerProps>) => {
41
55
  const currentColumnCount = getColgroupChildrenLength(node);
42
56
  const minColumnWidth =
@@ -60,6 +74,78 @@ export const TableResizer = ({
60
74
  } else if (tableHeight && tableHeight >= 96) {
61
75
  handleHeightSize = 'large';
62
76
  }
77
+ const currentGap = useRef(0);
78
+ const [snappingEnabled, setSnappingEnabled] = useState(false);
79
+
80
+ const updateActiveGuidelines = useCallback(
81
+ ({ gap, keys }: { gap: number; keys: string[] }) => {
82
+ if (gap !== currentGap.current) {
83
+ currentGap.current = gap;
84
+ displayGuideline(
85
+ getGuidelinesWithHighlights(
86
+ gap,
87
+ TABLE_SNAP_GAP,
88
+ keys,
89
+ defaultGuidelines,
90
+ ),
91
+ );
92
+ }
93
+ },
94
+ [displayGuideline],
95
+ );
96
+
97
+ const guidelineSnaps = useMemo(
98
+ () =>
99
+ snappingEnabled
100
+ ? {
101
+ x: defaultGuidelineWidths,
102
+ }
103
+ : undefined,
104
+ [snappingEnabled],
105
+ );
106
+
107
+ const handleResizeStart = useCallback(() => {
108
+ setSnappingEnabled(displayGuideline(defaultGuidelines));
109
+ return width;
110
+ }, [width, displayGuideline]);
111
+
112
+ const handleResizeStop = useCallback<HandleResize>(
113
+ (originalState, delta) => {
114
+ const newWidth = originalState.width + delta.width;
115
+ const { state, dispatch } = editorView;
116
+ const pos = getPos();
117
+
118
+ if (typeof pos !== 'number') {
119
+ return;
120
+ }
121
+
122
+ let tr = state.tr.setNodeMarkup(pos, undefined, {
123
+ ...node.attrs,
124
+ width: newWidth,
125
+ });
126
+
127
+ const newNode = tr.doc.nodeAt(pos)!;
128
+ tr = scaleTable(
129
+ tableRef,
130
+ {
131
+ node: newNode,
132
+ prevNode: node,
133
+ start: pos + 1,
134
+ parentWidth: newWidth,
135
+ },
136
+ editorView.domAtPos.bind(editorView),
137
+ )(tr);
138
+
139
+ dispatch(tr);
140
+
141
+ // Hide guidelines when resizing stops
142
+ displayGuideline([]);
143
+
144
+ updateWidth(newWidth);
145
+ return newWidth;
146
+ },
147
+ [updateWidth, editorView, getPos, node, tableRef, displayGuideline],
148
+ );
63
149
 
64
150
  return (
65
151
  <ResizerNext
@@ -68,7 +154,7 @@ export const TableResizer = ({
68
154
  handleAlignmentMethod="sticky"
69
155
  handleHeightSize={handleHeightSize}
70
156
  handleMarginTop={tableHandleMarginTop}
71
- handleResizeStart={() => width}
157
+ handleResizeStart={handleResizeStart}
72
158
  handleResize={rafSchd((originalState, delta) => {
73
159
  const newWidth = originalState.width + delta.width;
74
160
  const pos = getPos();
@@ -87,44 +173,24 @@ export const TableResizer = ({
87
173
  editorView.domAtPos.bind(editorView),
88
174
  );
89
175
 
90
- updateWidth(newWidth);
91
- return newWidth;
92
- })}
93
- handleResizeStop={(originalState, delta) => {
94
- const newWidth = originalState.width + delta.width;
95
-
96
- const { state, dispatch } = editorView;
97
- const pos = getPos();
98
-
99
- if (typeof pos !== 'number') {
100
- return;
101
- }
102
-
103
- let tr = state.tr.setNodeMarkup(pos, undefined, {
104
- ...node.attrs,
105
- width: newWidth,
106
- });
107
-
108
- const newNode = tr.doc.nodeAt(pos)!;
109
- tr = scaleTable(
110
- tableRef,
111
- {
112
- node: newNode,
113
- prevNode: node,
114
- start: pos + 1,
115
- parentWidth: newWidth,
116
- },
117
- editorView.domAtPos.bind(editorView),
118
- )(tr);
119
-
120
- dispatch(tr);
176
+ updateActiveGuidelines(
177
+ findClosestSnap(
178
+ newWidth,
179
+ defaultGuidelineWidths,
180
+ defaultGuidelines,
181
+ TABLE_HIGHLIGHT_GAP,
182
+ ),
183
+ );
121
184
 
122
185
  updateWidth(newWidth);
123
186
  return newWidth;
124
- }}
187
+ })}
188
+ handleResizeStop={handleResizeStop}
125
189
  resizeRatio={2}
126
190
  minWidth={minColumnWidth}
127
191
  maxWidth={maxWidth}
192
+ snapGap={TABLE_SNAP_GAP}
193
+ snap={guidelineSnaps}
128
194
  >
129
195
  {children}
130
196
  </ResizerNext>
@@ -32,6 +32,7 @@ import type { TableColumnOrdering } from '@atlaskit/adf-schema/steps';
32
32
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
33
33
  import { getTableContainerWidth } from '@atlaskit/editor-common/node-width';
34
34
  import { isTableNested } from '../utils';
35
+ import { PluginInjectionAPI } from '../types';
35
36
 
36
37
  type ForwardRef = (node: HTMLElement | null) => void;
37
38
 
@@ -187,6 +188,7 @@ export default class TableView extends ReactNodeView<Props> {
187
188
  containerWidth={containerWidth!}
188
189
  contentDOM={forwardRef}
189
190
  getEditorFeatureFlags={props.getEditorFeatureFlags}
191
+ pluginInjectionApi={props.pluginInjectionApi}
190
192
  />
191
193
  );
192
194
  }}
@@ -280,6 +282,7 @@ export const createTableView = (
280
282
  options: TableOptions,
281
283
  getEditorContainerWidth: GetEditorContainerWidth,
282
284
  getEditorFeatureFlags: GetEditorFeatureFlags,
285
+ pluginInjectionApi?: PluginInjectionAPI,
283
286
  ): NodeView => {
284
287
  const { pluginConfig } = getPluginState(view.state);
285
288
  const { allowColumnResizing } = getPluginConfig(pluginConfig);
@@ -298,5 +301,6 @@ export const createTableView = (
298
301
  getEditorContainerWidth,
299
302
  getEditorFeatureFlags,
300
303
  hasIntlContext,
304
+ pluginInjectionApi,
301
305
  }).init();
302
306
  };
@@ -7,6 +7,7 @@ import type {
7
7
  } from '@atlaskit/editor-common/types';
8
8
  import { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
9
9
  import type { PortalProviderAPI } from '@atlaskit/editor-common/portal-provider';
10
+ import type { PluginInjectionAPI } from '../types';
10
11
 
11
12
  export type TableOptions = {
12
13
  isBreakoutEnabled?: boolean;
@@ -27,4 +28,5 @@ export interface Props {
27
28
  getEditorContainerWidth: GetEditorContainerWidth;
28
29
  getEditorFeatureFlags: GetEditorFeatureFlags;
29
30
  hasIntlContext: boolean;
31
+ pluginInjectionApi?: PluginInjectionAPI;
30
32
  }
@@ -3,6 +3,7 @@ import {
3
3
  EditorState,
4
4
  PluginKey,
5
5
  Transaction,
6
+ // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck
6
7
  ReadonlyTransaction,
7
8
  } from 'prosemirror-state';
8
9
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
@@ -1,3 +1,4 @@
1
+ // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck
1
2
  import { ReadonlyTransaction, Transaction } from 'prosemirror-state';
2
3
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
3
4
  import { findTable } from '@atlaskit/editor-tables/utils';
@@ -1,3 +1,4 @@
1
+ // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck
1
2
  import { ReadonlyTransaction, Transaction } from 'prosemirror-state';
2
3
  import { DecorationSet } from 'prosemirror-view';
3
4
 
@@ -80,6 +80,7 @@ import type {
80
80
  GetEditorFeatureFlags,
81
81
  } from '@atlaskit/editor-common/types';
82
82
  import type { getPosHandler } from '@atlaskit/editor-common/types';
83
+ import type { PluginInjectionAPI } from '../types';
83
84
 
84
85
  let isBreakoutEnabled: boolean | undefined;
85
86
  let isFullWidthModeEnabled: boolean | undefined;
@@ -97,6 +98,7 @@ export const createPlugin = (
97
98
  fullWidthModeEnabled?: boolean,
98
99
  previousFullWidthModeEnabled?: boolean,
99
100
  editorAnalyticsAPI?: EditorAnalyticsAPI,
101
+ pluginInjectionApi?: PluginInjectionAPI,
100
102
  ) => {
101
103
  isBreakoutEnabled = breakoutEnabled;
102
104
  isFullWidthModeEnabled = fullWidthModeEnabled;
@@ -374,6 +376,7 @@ export const createPlugin = (
374
376
  },
375
377
  getEditorContainerWidth,
376
378
  getEditorFeatureFlags,
379
+ pluginInjectionApi,
377
380
  ),
378
381
  },
379
382
 
@@ -1,3 +1,4 @@
1
+ // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck
1
2
  import { ReadonlyTransaction } from 'prosemirror-state';
2
3
 
3
4
  import { pluginFactory } from '@atlaskit/editor-common/utils';
@@ -118,6 +118,7 @@ export const updateStickyMargins = (table: HTMLElement) => {
118
118
  };
119
119
 
120
120
  export const applyColWidthsToStickyRow = (
121
+ // @ts-ignore - CCFE error TS6133: 'colGroup' is declared but its value is never read.
121
122
  colGroup: HTMLTableColElement | null,
122
123
  headerRow: HTMLTableRowElement,
123
124
  ) => {
@@ -14,6 +14,8 @@ import { TableSharedCssClassName } from '@atlaskit/editor-common/styles';
14
14
  import { TableColumnOrdering } from '@atlaskit/adf-schema/steps';
15
15
 
16
16
  import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
17
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
18
+ import type tablePlugin from './index';
17
19
 
18
20
  export const RESIZE_HANDLE_AREA_DECORATION_GAP = 30;
19
21
  export type RowInsertPosition = 'TOP' | 'BOTTOM';
@@ -27,6 +29,8 @@ export interface InsertRowOptions {
27
29
  moveCursorToInsertedRow: boolean;
28
30
  }
29
31
 
32
+ export type PluginInjectionAPI = ExtractInjectionAPI<typeof tablePlugin>;
33
+
30
34
  export type InsertRowMethods =
31
35
  | INPUT_METHOD.CONTEXT_MENU
32
36
  | INPUT_METHOD.BUTTON
@@ -104,3 +104,6 @@ export const contextualMenuDropdownWidth = 180;
104
104
  export const stickyRowZIndex = resizeHandlerZIndex + 2;
105
105
  export const stickyRowOffsetTop = 8;
106
106
  export const stickyHeaderBorderBottomWidth = 1;
107
+
108
+ export const TABLE_SNAP_GAP = 5;
109
+ export const TABLE_HIGHLIGHT_GAP = 10;
@@ -1,4 +1,5 @@
1
1
  import { NodeType, NodeRange } from 'prosemirror-model';
2
+ // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck
2
3
  import { Transaction, ReadonlyTransaction } from 'prosemirror-state';
3
4
  import { findWrapping } from 'prosemirror-transform';
4
5
 
@@ -1,4 +1,5 @@
1
1
  import { Node as PmNode } from 'prosemirror-model';
2
+ // @ts-ignore -- ReadonlyTransaction is a local declaration and will cause a TS2305 error in CCFE typecheck
2
3
  import { Selection, Transaction, ReadonlyTransaction } from 'prosemirror-state';
3
4
  import { Rect, TableMap } from '@atlaskit/editor-tables/table-map';
4
5
  import { ContentNodeWithPos } from 'prosemirror-utils';
@@ -0,0 +1,17 @@
1
+ import type { GuidelineConfig } from '@atlaskit/editor-plugin-guideline';
2
+ import { createFixedGuidelinesFromLengths } from '@atlaskit/editor-common/guideline';
3
+ import {
4
+ akEditorDefaultLayoutWidth,
5
+ akEditorWideLayoutWidth,
6
+ akEditorFullWidthLayoutWidth,
7
+ } from '@atlaskit/editor-shared-styles';
8
+
9
+ export const defaultGuidelineWidths = [
10
+ akEditorDefaultLayoutWidth,
11
+ akEditorWideLayoutWidth,
12
+ akEditorFullWidthLayoutWidth,
13
+ ];
14
+
15
+ export const defaultGuidelines = createFixedGuidelinesFromLengths(
16
+ defaultGuidelineWidths,
17
+ ) as GuidelineConfig[];