@atlaskit/editor-plugin-table 1.1.5 → 1.2.1
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 +32 -0
- package/dist/cjs/plugins/table/index.js +2 -1
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +1 -2
- package/dist/cjs/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +39 -17
- package/dist/cjs/plugins/table/pm-plugins/table-resizing/event-handlers.js +1 -5
- package/dist/cjs/plugins/table/pm-plugins/table-resizing/utils/misc.js +3 -38
- package/dist/cjs/plugins/table/toolbar.js +3 -2
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +20 -4
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/index.js +6 -3
- package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
- package/dist/cjs/plugins/table/ui/messages.js +5 -0
- package/dist/cjs/plugins/table/ui/ui-styles.js +2 -2
- package/dist/cjs/types/i18n.js +5 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/plugins/table/index.js +2 -1
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +1 -2
- package/dist/es2019/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +39 -17
- package/dist/es2019/plugins/table/pm-plugins/table-resizing/event-handlers.js +1 -5
- package/dist/es2019/plugins/table/pm-plugins/table-resizing/utils/misc.js +1 -37
- package/dist/es2019/plugins/table/toolbar.js +3 -2
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +23 -6
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/index.js +6 -3
- package/dist/es2019/plugins/table/ui/common-styles.js +10 -3
- package/dist/es2019/plugins/table/ui/messages.js +5 -0
- package/dist/es2019/plugins/table/ui/ui-styles.js +8 -4
- package/dist/es2019/types/i18n.js +1 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/plugins/table/index.js +2 -1
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +1 -2
- package/dist/esm/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +39 -17
- package/dist/esm/plugins/table/pm-plugins/table-resizing/event-handlers.js +1 -5
- package/dist/esm/plugins/table/pm-plugins/table-resizing/utils/misc.js +1 -35
- package/dist/esm/plugins/table/toolbar.js +3 -2
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +22 -6
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/index.js +6 -3
- package/dist/esm/plugins/table/ui/common-styles.js +1 -1
- package/dist/esm/plugins/table/ui/messages.js +5 -0
- package/dist/esm/plugins/table/ui/ui-styles.js +3 -3
- package/dist/esm/types/i18n.js +1 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/plugins/table/index.d.ts +3 -1
- package/dist/types/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.d.ts +2 -2
- package/dist/types/plugins/table/pm-plugins/table-resizing/utils/misc.d.ts +1 -2
- package/dist/types/plugins/table/ui/FloatingContextualMenu/ContextualMenu.d.ts +2 -1
- package/dist/types/plugins/table/ui/FloatingContextualMenu/index.d.ts +3 -2
- package/dist/types/plugins/table/ui/messages.d.ts +5 -0
- package/dist/types/types/i18n.d.ts +5 -0
- package/package.json +10 -10
- package/report.api.md +3 -2
- package/src/__tests__/integration/__fixtures__/large-table-with-sticky-header.ts +2311 -0
- package/src/__tests__/integration/horizontal-scroll.ts +4 -9
- package/src/__tests__/integration/sticky-header.ts +220 -0
- package/src/__tests__/unit/commands/insert.ts +8 -8
- package/src/__tests__/unit/nodeviews/cell.ts +14 -0
- package/src/__tests__/unit/pm-plugins/sticky-headers/tableRow.tsx +2 -2
- package/src/__tests__/unit/ui/ContextualMenu.tsx +2 -0
- package/src/__tests__/unit/ui/FloatingContextualMenu.tsx +1 -0
- package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-column-menu-item-visual-hints-should-be-added-to-the-table-column-on-hover-1-snap.png +2 -2
- package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-row-menu-item-visual-hints-should-be-added-to-the-table-row-on-hover-1-snap.png +2 -2
- package/src/__tests__/visual-regression/__image_snapshots__/index-ts-snapshot-test-table-numbered-list-should-not-overflow-table-cell-when-there-are-more-than-100-ordered-list-items-3-snap.png +2 -2
- package/src/plugins/table/index.tsx +7 -2
- package/src/plugins/table/nodeviews/TableComponent.tsx +1 -2
- package/src/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.ts +47 -25
- package/src/plugins/table/pm-plugins/table-resizing/event-handlers.ts +1 -9
- package/src/plugins/table/pm-plugins/table-resizing/utils/misc.ts +1 -57
- package/src/plugins/table/toolbar.tsx +6 -2
- package/src/plugins/table/ui/FloatingContextualMenu/ContextualMenu.tsx +29 -4
- package/src/plugins/table/ui/FloatingContextualMenu/index.tsx +8 -1
- package/src/plugins/table/ui/common-styles.ts +10 -3
- package/src/plugins/table/ui/messages.ts +5 -0
- package/src/plugins/table/ui/ui-styles.ts +8 -4
- package/src/types/i18n.ts +5 -0
|
@@ -55,10 +55,9 @@ const assertTableDoesScroll = async (page: WebdriverPage) => {
|
|
|
55
55
|
expect(tableScrollWidth).toBeGreaterThan(tableOffsetWidth);
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
// insertColumn helper doesn't work in Safari
|
|
59
58
|
BrowserTestCase(
|
|
60
59
|
'Table: Does not scroll when column is resized and a new column is inserted',
|
|
61
|
-
{ skip: [
|
|
60
|
+
{ skip: [] },
|
|
62
61
|
async (client: any, testName: string) => {
|
|
63
62
|
for (const screenWidth of screenWidths) {
|
|
64
63
|
const page = await goToEditorTestingWDExample(
|
|
@@ -84,7 +83,6 @@ BrowserTestCase(
|
|
|
84
83
|
},
|
|
85
84
|
);
|
|
86
85
|
|
|
87
|
-
// insertColumn helper doesn't work in Safari
|
|
88
86
|
BrowserTestCase(
|
|
89
87
|
'Table: Does not scroll when column is resized and breakout button is clicked 3x',
|
|
90
88
|
{ skip: ['safari'] },
|
|
@@ -281,10 +279,9 @@ BrowserTestCase(
|
|
|
281
279
|
},
|
|
282
280
|
);
|
|
283
281
|
|
|
284
|
-
// insertColumn helper doesn't work in Safari
|
|
285
282
|
BrowserTestCase(
|
|
286
283
|
'Table: Scrolls when there are more columns added than can fit the current width',
|
|
287
|
-
{ skip: [
|
|
284
|
+
{ skip: [] },
|
|
288
285
|
async (client: any, testName: string) => {
|
|
289
286
|
for (const screenWidth of screenWidths) {
|
|
290
287
|
const page = await goToEditorTestingWDExample(
|
|
@@ -315,10 +312,9 @@ BrowserTestCase(
|
|
|
315
312
|
},
|
|
316
313
|
);
|
|
317
314
|
|
|
318
|
-
// insertColumn helper doesn't work in Safari
|
|
319
315
|
BrowserTestCase(
|
|
320
316
|
'Table: Does not scroll when nested in Bodied Macro, column is resized and breakout button is clicked',
|
|
321
|
-
{ skip: [
|
|
317
|
+
{ skip: [] },
|
|
322
318
|
async (client: any, testName: string) => {
|
|
323
319
|
for (const screenWidth of screenWidths) {
|
|
324
320
|
const page = await goToEditorTestingWDExample(
|
|
@@ -451,10 +447,9 @@ BrowserTestCase(
|
|
|
451
447
|
},
|
|
452
448
|
);
|
|
453
449
|
|
|
454
|
-
// insertColumn helper doesn't work in Safari
|
|
455
450
|
BrowserTestCase(
|
|
456
451
|
'Table: Does not scroll when nested in full-width layout, columns is resized and new column is inserted',
|
|
457
|
-
{ skip: [
|
|
452
|
+
{ skip: [] },
|
|
458
453
|
async (client: any, testName: string) => {
|
|
459
454
|
for (const screenWidth of screenWidths) {
|
|
460
455
|
const page = await goToEditorTestingWDExample(
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import WebdriverPage from '@atlaskit/webdriver-runner/wd-wrapper';
|
|
2
|
+
import { BrowserTestCase } from '@atlaskit/webdriver-runner/runner';
|
|
3
|
+
import {
|
|
4
|
+
fullpage,
|
|
5
|
+
tableSelectors,
|
|
6
|
+
toggleBreakout,
|
|
7
|
+
} from '@atlaskit/editor-test-helpers/integration/helpers';
|
|
8
|
+
import {
|
|
9
|
+
goToEditorTestingWDExample,
|
|
10
|
+
mountEditor,
|
|
11
|
+
} from '@atlaskit/editor-test-helpers/testing-example-page';
|
|
12
|
+
import stickyTable from './__fixtures__/large-table-with-sticky-header';
|
|
13
|
+
|
|
14
|
+
const scrollTo = async (page: WebdriverPage, height: number) => {
|
|
15
|
+
const editorScrollParentSelector = '.fabric-editor-popup-scroll-parent';
|
|
16
|
+
await page.execute(
|
|
17
|
+
(editorScrollParentSelector: string, height: number) => {
|
|
18
|
+
const editor = document.querySelector(editorScrollParentSelector);
|
|
19
|
+
editor && editor.scroll(0, height);
|
|
20
|
+
},
|
|
21
|
+
editorScrollParentSelector,
|
|
22
|
+
height,
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// const resizeScrollParent = async (page: WebdriverPage) => {
|
|
27
|
+
// const editorScrollParentSelector = '.ak-editor-fp-content-area';
|
|
28
|
+
// await page.execute((editorScrollParentSelector: string) => {
|
|
29
|
+
// const editor = document.querySelector(editorScrollParentSelector);
|
|
30
|
+
// console.log('editort', editor);
|
|
31
|
+
// editor && editor.setAttribute('width', '1000px');
|
|
32
|
+
// }, editorScrollParentSelector);
|
|
33
|
+
// };
|
|
34
|
+
|
|
35
|
+
const insertColumn = async (page: any, cell: 'first' | 'last') => {
|
|
36
|
+
const columnControl = tableSelectors.nthColumnControl(1);
|
|
37
|
+
const insertButton = tableSelectors.insertButton;
|
|
38
|
+
const firstCell = tableSelectors.topLeftCell;
|
|
39
|
+
const firstCellLastRow = `table > tbody > tr:nth-child(48) > td:nth-child(1)`;
|
|
40
|
+
|
|
41
|
+
if (cell === 'first') {
|
|
42
|
+
await page.click(firstCell);
|
|
43
|
+
} else if (cell === 'last') {
|
|
44
|
+
await page.click(firstCellLastRow);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const columnDecorationSelector = columnControl;
|
|
48
|
+
await page.hover(columnDecorationSelector);
|
|
49
|
+
|
|
50
|
+
await page.waitForSelector(insertButton);
|
|
51
|
+
await page.click(insertButton);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// FIXME: This test was automatically skipped due to failure on 01/04/2023: https://product-fabric.atlassian.net/browse/ED-17364
|
|
55
|
+
BrowserTestCase(
|
|
56
|
+
'Sticky header should correctly toggle on and off',
|
|
57
|
+
{
|
|
58
|
+
skip: ['*'],
|
|
59
|
+
},
|
|
60
|
+
async (client: any, testName: string) => {
|
|
61
|
+
const page = await goToEditorTestingWDExample(
|
|
62
|
+
client,
|
|
63
|
+
'editor-plugin-table',
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
await mountEditor(page, {
|
|
67
|
+
appearance: fullpage.appearance,
|
|
68
|
+
defaultValue: JSON.stringify(stickyTable),
|
|
69
|
+
allowTables: {
|
|
70
|
+
advanced: true,
|
|
71
|
+
stickyHeaders: true,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await page.waitForSelector('table');
|
|
76
|
+
|
|
77
|
+
expect(
|
|
78
|
+
await page.waitForSelector(tableSelectors.stickyTable, {}, true),
|
|
79
|
+
).toBeTruthy();
|
|
80
|
+
expect(
|
|
81
|
+
await page.waitForSelector(tableSelectors.stickyTr, {}, true),
|
|
82
|
+
).toBeTruthy();
|
|
83
|
+
|
|
84
|
+
await scrollTo(page, window.innerHeight * 100);
|
|
85
|
+
|
|
86
|
+
expect(await page.waitForSelector(tableSelectors.stickyTable)).toBeTruthy();
|
|
87
|
+
expect(await page.waitForSelector(tableSelectors.stickyTr)).toBeTruthy();
|
|
88
|
+
|
|
89
|
+
await scrollTo(page, 0);
|
|
90
|
+
|
|
91
|
+
expect(
|
|
92
|
+
await page.waitForSelector(tableSelectors.stickyTable, {}, true),
|
|
93
|
+
).toBeTruthy();
|
|
94
|
+
expect(
|
|
95
|
+
await page.waitForSelector(tableSelectors.stickyTr, {}, true),
|
|
96
|
+
).toBeTruthy();
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
BrowserTestCase(
|
|
101
|
+
'Sticky header should still correctly toggle on and off, after a column has been added',
|
|
102
|
+
{ skip: ['safari'] },
|
|
103
|
+
async (client: any, testName: string) => {
|
|
104
|
+
const page = await goToEditorTestingWDExample(
|
|
105
|
+
client,
|
|
106
|
+
'editor-plugin-table',
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
await mountEditor(page, {
|
|
110
|
+
appearance: fullpage.appearance,
|
|
111
|
+
defaultValue: JSON.stringify(stickyTable),
|
|
112
|
+
allowTables: {
|
|
113
|
+
advanced: true,
|
|
114
|
+
stickyHeaders: true,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
await page.waitForSelector('table');
|
|
119
|
+
|
|
120
|
+
expect(
|
|
121
|
+
await page.waitForSelector(tableSelectors.stickyTable, {}, true),
|
|
122
|
+
).toBeTruthy();
|
|
123
|
+
expect(
|
|
124
|
+
await page.waitForSelector(tableSelectors.stickyTr, {}, true),
|
|
125
|
+
).toBeTruthy();
|
|
126
|
+
|
|
127
|
+
await insertColumn(page, 'first');
|
|
128
|
+
|
|
129
|
+
await scrollTo(page, window.innerHeight * 100);
|
|
130
|
+
|
|
131
|
+
expect(await page.waitForSelector(tableSelectors.stickyTable)).toBeTruthy();
|
|
132
|
+
expect(await page.waitForSelector(tableSelectors.stickyTr)).toBeTruthy();
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
BrowserTestCase(
|
|
137
|
+
'Sticky header should correctly toggle on and off, after table is scrolled to the bottom and a column has been added',
|
|
138
|
+
{ skip: ['safari'] },
|
|
139
|
+
async (client: any, testName: string) => {
|
|
140
|
+
const page = await goToEditorTestingWDExample(
|
|
141
|
+
client,
|
|
142
|
+
'editor-plugin-table',
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
await mountEditor(page, {
|
|
146
|
+
appearance: fullpage.appearance,
|
|
147
|
+
defaultValue: JSON.stringify(stickyTable),
|
|
148
|
+
allowTables: {
|
|
149
|
+
advanced: true,
|
|
150
|
+
stickyHeaders: true,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
await page.waitForSelector('table');
|
|
155
|
+
|
|
156
|
+
await scrollTo(page, window.innerHeight * 100);
|
|
157
|
+
|
|
158
|
+
await insertColumn(page, 'last');
|
|
159
|
+
|
|
160
|
+
expect(
|
|
161
|
+
await page.waitForSelector(tableSelectors.stickyTable, {}, true),
|
|
162
|
+
).toBeTruthy();
|
|
163
|
+
expect(
|
|
164
|
+
await page.waitForSelector(tableSelectors.stickyTr, {}, true),
|
|
165
|
+
).toBeTruthy();
|
|
166
|
+
|
|
167
|
+
// ED-16817 This checks for a bug where the table row would become not sticky
|
|
168
|
+
// but the numbered column header would stay sticky
|
|
169
|
+
const numberedCol = await page.$(tableSelectors.numberedColumnTopLeftCell);
|
|
170
|
+
const numberedColStyle = await numberedCol.getAttribute('style');
|
|
171
|
+
expect(!numberedColStyle.includes('top')).toBeTruthy();
|
|
172
|
+
},
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
BrowserTestCase(
|
|
176
|
+
'Sticky header should resize when the width of parent scroll container changes',
|
|
177
|
+
{},
|
|
178
|
+
async (client: any, testName: string) => {
|
|
179
|
+
const page = await goToEditorTestingWDExample(
|
|
180
|
+
client,
|
|
181
|
+
'editor-plugin-table',
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
await mountEditor(page, {
|
|
185
|
+
appearance: fullpage.appearance,
|
|
186
|
+
defaultValue: JSON.stringify(stickyTable),
|
|
187
|
+
allowTables: {
|
|
188
|
+
advanced: true,
|
|
189
|
+
stickyHeaders: true,
|
|
190
|
+
},
|
|
191
|
+
featureFlags: {
|
|
192
|
+
stickyHeadersOptimization: true,
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
await page.waitForSelector('table');
|
|
197
|
+
|
|
198
|
+
await toggleBreakout(page, 2);
|
|
199
|
+
|
|
200
|
+
await scrollTo(page, window.innerHeight * 100);
|
|
201
|
+
|
|
202
|
+
await page.execute(() => {
|
|
203
|
+
const editorScrollParentSelector = '.fabric-editor-popup-scroll-parent';
|
|
204
|
+
const editor = document.querySelector(
|
|
205
|
+
editorScrollParentSelector,
|
|
206
|
+
) as HTMLElement;
|
|
207
|
+
if (editor) {
|
|
208
|
+
editor.style.flexGrow = '0';
|
|
209
|
+
editor.style.width = '750px';
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const table = await page.$(tableSelectors.stickyTable);
|
|
214
|
+
const tableWidth = await table.getSize();
|
|
215
|
+
const stickyHeader = await page.$(tableSelectors.stickyTr);
|
|
216
|
+
const stickyHeaderWidth = await stickyHeader.getSize();
|
|
217
|
+
|
|
218
|
+
expect(tableWidth.width).toEqual(stickyHeaderWidth.width);
|
|
219
|
+
},
|
|
220
|
+
);
|
|
@@ -37,14 +37,14 @@ describe('table plugin: insert', () => {
|
|
|
37
37
|
|
|
38
38
|
const createEditor = createProsemirrorEditorFactory();
|
|
39
39
|
|
|
40
|
-
const preset = new Preset<LightEditorPlugin>()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
const preset = new Preset<LightEditorPlugin>()
|
|
41
|
+
.add([
|
|
42
|
+
tablePlugin,
|
|
43
|
+
{
|
|
44
|
+
tableOptions: {},
|
|
45
|
+
},
|
|
46
|
+
])
|
|
47
|
+
.add(widthPlugin);
|
|
48
48
|
|
|
49
49
|
const editor = (doc: DocBuilder) =>
|
|
50
50
|
createEditor<TablePluginState, PluginKey>({
|
|
@@ -39,6 +39,20 @@ jest.mock('@atlaskit/editor-common/utils', () => ({
|
|
|
39
39
|
},
|
|
40
40
|
}));
|
|
41
41
|
|
|
42
|
+
jest.mock('@atlaskit/editor-palette', () => ({
|
|
43
|
+
...jest.requireActual<Object>('@atlaskit/editor-palette'),
|
|
44
|
+
hexToEditorBackgroundPaletteColorTokenName: jest.fn((hexColor: string) => {
|
|
45
|
+
return hexColor;
|
|
46
|
+
}),
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
jest.mock('@atlaskit/tokens', () => ({
|
|
50
|
+
...jest.requireActual<Object>('@atlaskit/tokens'),
|
|
51
|
+
getTokenValue: jest.fn((tokenId: string, fallback: string = '') => {
|
|
52
|
+
return tokenId || fallback;
|
|
53
|
+
}),
|
|
54
|
+
}));
|
|
55
|
+
|
|
42
56
|
describe('table -> nodeviews -> tableCell.tsx', () => {
|
|
43
57
|
const TABLE_LOCAL_ID = 'test-table-local-id';
|
|
44
58
|
const createEditor = createProsemirrorEditorFactory();
|
|
@@ -472,7 +472,7 @@ describe('TableRowNodeView', () => {
|
|
|
472
472
|
triggerElementIntersect({
|
|
473
473
|
target: sentinelTop,
|
|
474
474
|
isIntersecting: false,
|
|
475
|
-
rootBounds: { bottom: 0, top:
|
|
475
|
+
rootBounds: { bottom: 0, top: 56 },
|
|
476
476
|
boundingClientRect: { bottom: 0, top: 0 },
|
|
477
477
|
});
|
|
478
478
|
|
|
@@ -507,7 +507,7 @@ describe('TableRowNodeView', () => {
|
|
|
507
507
|
triggerElementIntersect({
|
|
508
508
|
target: sentinelBottom,
|
|
509
509
|
isIntersecting: true,
|
|
510
|
-
rootBounds: { bottom: 0, top:
|
|
510
|
+
rootBounds: { bottom: 0, top: 56 },
|
|
511
511
|
boundingClientRect: { bottom: 0, top: -100 },
|
|
512
512
|
});
|
|
513
513
|
|
|
@@ -22,6 +22,7 @@ import { ContextualMenu } from '../../../plugins/table/ui/FloatingContextualMenu
|
|
|
22
22
|
|
|
23
23
|
describe('ContextualMenu', () => {
|
|
24
24
|
const getEditorContainerWidth = () => ({ width: 500 });
|
|
25
|
+
const getEditorFeatureFlags = () => ({});
|
|
25
26
|
const createEditor = createProsemirrorEditorFactory();
|
|
26
27
|
describe('with right table cell position in plugin state', () => {
|
|
27
28
|
let editorView: EditorView;
|
|
@@ -44,6 +45,7 @@ describe('ContextualMenu', () => {
|
|
|
44
45
|
isOpen
|
|
45
46
|
selectionRect={{ bottom: 0, left: 0, right: 0, top: 0 }}
|
|
46
47
|
getEditorContainerWidth={getEditorContainerWidth}
|
|
48
|
+
getEditorFeatureFlags={getEditorFeatureFlags}
|
|
47
49
|
/>,
|
|
48
50
|
);
|
|
49
51
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
version https://git-lfs.github.com/spec/v1
|
|
2
|
-
oid sha256:
|
|
3
|
-
size
|
|
2
|
+
oid sha256:ac570fb3172970569166ac27d43c4d4330ed10407894ae2882fc91268b7c6543
|
|
3
|
+
size 29647
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
version https://git-lfs.github.com/spec/v1
|
|
2
|
-
oid sha256:
|
|
3
|
-
size
|
|
2
|
+
oid sha256:91b791b54bbda59e690dbec1a779bbba00ccdfdd2b1658def547de0edb8164c5
|
|
3
|
+
size 29662
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
version https://git-lfs.github.com/spec/v1
|
|
2
|
-
oid sha256:
|
|
3
|
-
size
|
|
2
|
+
oid sha256:918d6eca1f77862b22c2530a59567a7bed80e221c1d1050a3e45c0803112437e
|
|
3
|
+
size 42897
|
|
@@ -79,8 +79,9 @@ const defaultGetEditorFeatureFlags = () => ({});
|
|
|
79
79
|
|
|
80
80
|
const tablesPlugin: NextEditorPlugin<
|
|
81
81
|
'table',
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
{
|
|
83
|
+
pluginConfiguration: TablePluginOptions | undefined;
|
|
84
|
+
}
|
|
84
85
|
> = (options?: TablePluginOptions) => {
|
|
85
86
|
const editorViewRef: Record<'current', EditorView | null> = { current: null };
|
|
86
87
|
const defaultGetEditorContainerWidth: GetEditorContainerWidth = () => {
|
|
@@ -370,6 +371,10 @@ const tablesPlugin: NextEditorPlugin<
|
|
|
370
371
|
pluginConfig={pluginConfig}
|
|
371
372
|
editorAnalyticsAPI={options?.editorAnalyticsAPI}
|
|
372
373
|
getEditorContainerWidth={defaultGetEditorContainerWidth}
|
|
374
|
+
getEditorFeatureFlags={
|
|
375
|
+
options?.getEditorFeatureFlags ||
|
|
376
|
+
defaultGetEditorFeatureFlags
|
|
377
|
+
}
|
|
373
378
|
/>
|
|
374
379
|
{allowControls && (
|
|
375
380
|
<FloatingDeleteButton
|
|
@@ -55,7 +55,6 @@ import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
|
|
|
55
55
|
|
|
56
56
|
import memoizeOne from 'memoize-one';
|
|
57
57
|
import { OverflowShadowsObserver } from './OverflowShadowsObserver';
|
|
58
|
-
import { getParentWidthWithoutPadding } from '../pm-plugins/table-resizing/utils/misc';
|
|
59
58
|
|
|
60
59
|
const isIE11 = browser.ie_version === 11;
|
|
61
60
|
const NOOP = () => undefined;
|
|
@@ -689,7 +688,7 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
|
|
|
689
688
|
options && options.isFullWidthModeEnabled,
|
|
690
689
|
);
|
|
691
690
|
|
|
692
|
-
return
|
|
691
|
+
return parentNodeWith;
|
|
693
692
|
};
|
|
694
693
|
|
|
695
694
|
private updateParentWidth = (width?: number) => {
|
|
@@ -170,7 +170,7 @@ export class TableRowNodeView implements NodeView {
|
|
|
170
170
|
this.topPosEditorElement = getTop(this.editorScrollableElement);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
this.eventDispatcher.on('widthPlugin', this.
|
|
173
|
+
this.eventDispatcher.on('widthPlugin', this.updateStickyHeaderWidth);
|
|
174
174
|
|
|
175
175
|
this.eventDispatcher.on(
|
|
176
176
|
(tablePluginKey as any).key,
|
|
@@ -190,9 +190,15 @@ export class TableRowNodeView implements NodeView {
|
|
|
190
190
|
if (!this.listening) {
|
|
191
191
|
return;
|
|
192
192
|
}
|
|
193
|
-
|
|
194
193
|
if (this.intersectionObserver) {
|
|
195
194
|
this.intersectionObserver.disconnect();
|
|
195
|
+
// ED-16211 Once intersection observer is disconnected, we need to remove the isObserved from the sentinels
|
|
196
|
+
// Otherwise when new intersection observer is created it will not observe because it thinks its already being observed
|
|
197
|
+
[this.sentinels.top, this.sentinels.bottom].forEach((el) => {
|
|
198
|
+
if (el) {
|
|
199
|
+
delete el.dataset.isObserved;
|
|
200
|
+
}
|
|
201
|
+
});
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
if (this.resizeObserver) {
|
|
@@ -203,7 +209,7 @@ export class TableRowNodeView implements NodeView {
|
|
|
203
209
|
this.editorScrollableElement.removeEventListener('scroll', this.onScroll);
|
|
204
210
|
}
|
|
205
211
|
|
|
206
|
-
this.eventDispatcher.off('widthPlugin', this.
|
|
212
|
+
this.eventDispatcher.off('widthPlugin', this.updateStickyHeaderWidth);
|
|
207
213
|
this.eventDispatcher.off(
|
|
208
214
|
(tablePluginKey as any).key,
|
|
209
215
|
this.onTablePluginState,
|
|
@@ -229,6 +235,9 @@ export class TableRowNodeView implements NodeView {
|
|
|
229
235
|
}
|
|
230
236
|
|
|
231
237
|
this.resizeObserver.observe(this.dom);
|
|
238
|
+
if (this.editorScrollableElement) {
|
|
239
|
+
this.resizeObserver.observe(this.editorScrollableElement as HTMLElement);
|
|
240
|
+
}
|
|
232
241
|
|
|
233
242
|
window.requestAnimationFrame(() => {
|
|
234
243
|
// we expect tree to be defined after animation frame
|
|
@@ -262,22 +271,31 @@ export class TableRowNodeView implements NodeView {
|
|
|
262
271
|
}
|
|
263
272
|
const { table } = this.tree;
|
|
264
273
|
entries.forEach((entry) => {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
: (entry.target as HTMLElement).offsetHeight;
|
|
268
|
-
|
|
274
|
+
// On resize of the parent scroll element we need to adjust the width
|
|
275
|
+
// of the sticky header
|
|
269
276
|
if (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
// So we adding this check to allow a 1px difference.
|
|
273
|
-
Math.abs(newHeight - (this.stickyRowHeight || 0)) >
|
|
274
|
-
stickyHeaderBorderBottomWidth
|
|
277
|
+
entry.target.className ===
|
|
278
|
+
(this.editorScrollableElement as HTMLElement)?.className
|
|
275
279
|
) {
|
|
276
|
-
this.
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
280
|
+
this.updateStickyHeaderWidth();
|
|
281
|
+
} else {
|
|
282
|
+
const newHeight = entry.contentRect
|
|
283
|
+
? entry.contentRect.height
|
|
284
|
+
: (entry.target as HTMLElement).offsetHeight;
|
|
285
|
+
|
|
286
|
+
if (
|
|
287
|
+
this.sentinels.bottom &&
|
|
288
|
+
// When the table header is sticky, it would be taller by a 1px (border-bottom),
|
|
289
|
+
// So we adding this check to allow a 1px difference.
|
|
290
|
+
Math.abs(newHeight - (this.stickyRowHeight || 0)) >
|
|
291
|
+
stickyHeaderBorderBottomWidth
|
|
292
|
+
) {
|
|
293
|
+
this.stickyRowHeight = newHeight;
|
|
294
|
+
this.sentinels.bottom.style.bottom = `${
|
|
295
|
+
tableScrollbarOffset + stickyRowOffsetTop + newHeight
|
|
296
|
+
}px`;
|
|
297
|
+
updateTableMargin(table);
|
|
298
|
+
}
|
|
281
299
|
}
|
|
282
300
|
});
|
|
283
301
|
});
|
|
@@ -303,7 +321,8 @@ export class TableRowNodeView implements NodeView {
|
|
|
303
321
|
(entry.rootBounds?.bottom || 0) < entry.boundingClientRect.bottom;
|
|
304
322
|
|
|
305
323
|
if (!entry.isIntersecting && !sentinelIsBelowScrollArea) {
|
|
306
|
-
this.tree &&
|
|
324
|
+
this.tree &&
|
|
325
|
+
this.makeHeaderRowSticky(this.tree, entry.rootBounds?.top);
|
|
307
326
|
} else {
|
|
308
327
|
table && this.makeRowHeaderNotSticky(table);
|
|
309
328
|
}
|
|
@@ -319,7 +338,8 @@ export class TableRowNodeView implements NodeView {
|
|
|
319
338
|
if (table && !entry.isIntersecting && sentinelIsAboveScrollArea) {
|
|
320
339
|
this.makeRowHeaderNotSticky(table);
|
|
321
340
|
} else if (entry.isIntersecting && sentinelIsAboveScrollArea) {
|
|
322
|
-
this.tree &&
|
|
341
|
+
this.tree &&
|
|
342
|
+
this.makeHeaderRowSticky(this.tree, entry?.rootBounds?.top);
|
|
323
343
|
}
|
|
324
344
|
}
|
|
325
345
|
});
|
|
@@ -543,7 +563,7 @@ export class TableRowNodeView implements NodeView {
|
|
|
543
563
|
}, 0);
|
|
544
564
|
};
|
|
545
565
|
|
|
546
|
-
|
|
566
|
+
updateStickyHeaderWidth = () => {
|
|
547
567
|
// table width might have changed, sync that back to sticky row
|
|
548
568
|
const tree = this.tree;
|
|
549
569
|
if (!tree) {
|
|
@@ -585,7 +605,7 @@ export class TableRowNodeView implements NodeView {
|
|
|
585
605
|
return false;
|
|
586
606
|
};
|
|
587
607
|
|
|
588
|
-
makeHeaderRowSticky = (tree: TableDOMElements) => {
|
|
608
|
+
makeHeaderRowSticky = (tree: TableDOMElements, scrollTop?: number) => {
|
|
589
609
|
// If header row height is more than 50% of viewport height don't do this
|
|
590
610
|
if (this.stickyRowHeight && this.stickyRowHeight > window.innerHeight / 2) {
|
|
591
611
|
return;
|
|
@@ -601,10 +621,13 @@ export class TableRowNodeView implements NodeView {
|
|
|
601
621
|
}
|
|
602
622
|
|
|
603
623
|
const currentTableTop = this.getCurrentTableTop(tree);
|
|
624
|
+
|
|
625
|
+
if (!scrollTop) {
|
|
626
|
+
scrollTop = getTop(this.editorScrollableElement);
|
|
627
|
+
}
|
|
628
|
+
|
|
604
629
|
const domTop =
|
|
605
|
-
currentTableTop > 0
|
|
606
|
-
? this.topPosEditorElement
|
|
607
|
-
: this.topPosEditorElement + currentTableTop;
|
|
630
|
+
currentTableTop > 0 ? scrollTop : scrollTop + currentTableTop;
|
|
608
631
|
|
|
609
632
|
if (!this.isSticky) {
|
|
610
633
|
syncStickyRowToTable(table);
|
|
@@ -633,7 +656,6 @@ export class TableRowNodeView implements NodeView {
|
|
|
633
656
|
table.classList.remove(ClassName.TABLE_STICKY);
|
|
634
657
|
|
|
635
658
|
this.isSticky = false;
|
|
636
|
-
|
|
637
659
|
this.dom.style.top = '';
|
|
638
660
|
table.style.removeProperty('margin-top');
|
|
639
661
|
|
|
@@ -31,7 +31,6 @@ import type {
|
|
|
31
31
|
GetEditorContainerWidth,
|
|
32
32
|
GetEditorFeatureFlags,
|
|
33
33
|
} from '@atlaskit/editor-common/types';
|
|
34
|
-
import { getParentWidthWithoutPadding } from './utils/misc';
|
|
35
34
|
|
|
36
35
|
export const handleMouseDown = (
|
|
37
36
|
view: EditorView,
|
|
@@ -68,15 +67,8 @@ export const handleMouseDown = (
|
|
|
68
67
|
const containerWidth = getEditorContainerWidth();
|
|
69
68
|
const parentWidth = getParentNodeWidth(start, state, containerWidth);
|
|
70
69
|
|
|
71
|
-
// TODO - refactor this logic into getParentNodeWidth() in editor-common [ED-16718]
|
|
72
|
-
const parentActualWidth = getParentWidthWithoutPadding(
|
|
73
|
-
parentWidth,
|
|
74
|
-
start,
|
|
75
|
-
state,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
70
|
let maxSize =
|
|
79
|
-
|
|
71
|
+
parentWidth ||
|
|
80
72
|
getLayoutSize(
|
|
81
73
|
dom.getAttribute('data-layout') as TableLayout,
|
|
82
74
|
containerWidth.width,
|
|
@@ -21,8 +21,6 @@ import { Node as PMNode } from 'prosemirror-model';
|
|
|
21
21
|
import { EditorState } from 'prosemirror-state';
|
|
22
22
|
import type { GetEditorContainerWidth } from '@atlaskit/editor-common/types';
|
|
23
23
|
import { getParentNodeWidth } from '@atlaskit/editor-common/node-width';
|
|
24
|
-
import { gridSize } from '@atlaskit/theme/constants';
|
|
25
|
-
import { findParentNodeOfTypeClosestToPos } from 'prosemirror-utils';
|
|
26
24
|
|
|
27
25
|
export const tableLayoutToSize: Record<string, number> = {
|
|
28
26
|
default: akEditorDefaultLayoutWidth,
|
|
@@ -124,15 +122,7 @@ export const getTableMaxWidth = ({
|
|
|
124
122
|
const containerWidth = getEditorContainerWidth();
|
|
125
123
|
const parentWidth = getParentNodeWidth(tableStart, state, containerWidth);
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
const parentActualWidth = getParentWidthWithoutPadding(
|
|
129
|
-
parentWidth,
|
|
130
|
-
tableStart,
|
|
131
|
-
state,
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
let maxWidth =
|
|
135
|
-
parentActualWidth || getLayoutSize(layout, containerWidth.width, {});
|
|
125
|
+
let maxWidth = parentWidth || getLayoutSize(layout, containerWidth.width, {});
|
|
136
126
|
|
|
137
127
|
if (table.attrs.isNumberColumnEnabled) {
|
|
138
128
|
maxWidth -= akEditorTableNumberColumnWidth;
|
|
@@ -140,49 +130,3 @@ export const getTableMaxWidth = ({
|
|
|
140
130
|
|
|
141
131
|
return maxWidth;
|
|
142
132
|
};
|
|
143
|
-
|
|
144
|
-
export const getParentWidthWithoutPadding = (
|
|
145
|
-
parentWidth: number,
|
|
146
|
-
tableStartPos: number,
|
|
147
|
-
state: EditorState,
|
|
148
|
-
) => {
|
|
149
|
-
const node = getNestedParentNode(tableStartPos, state);
|
|
150
|
-
if (!node) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const { schema } = state;
|
|
155
|
-
|
|
156
|
-
if (node.type === schema.nodes.expand) {
|
|
157
|
-
// padding
|
|
158
|
-
parentWidth -= gridSize() * 2;
|
|
159
|
-
// gutter offset
|
|
160
|
-
parentWidth += gridSize() * 1.5 * 2;
|
|
161
|
-
// padding right
|
|
162
|
-
parentWidth -= gridSize();
|
|
163
|
-
// padding left
|
|
164
|
-
parentWidth -= gridSize() * 4 - gridSize() / 2;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return parentWidth;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
// copy of getNestedParentNode() from packages/editor/editor-common/src/node-width/index.ts
|
|
171
|
-
// to be removed later when we will move getParentWidthWithoutPadding() logic to editor-common
|
|
172
|
-
const getNestedParentNode = (
|
|
173
|
-
tablePos: number,
|
|
174
|
-
state: EditorState,
|
|
175
|
-
): PMNode | null => {
|
|
176
|
-
if (tablePos === undefined) {
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const $pos = state.doc.resolve(tablePos);
|
|
181
|
-
const parent = findParentNodeOfTypeClosestToPos($pos, [
|
|
182
|
-
state.schema.nodes.bodiedExtension,
|
|
183
|
-
state.schema.nodes.layoutSection,
|
|
184
|
-
state.schema.nodes.expand,
|
|
185
|
-
]);
|
|
186
|
-
|
|
187
|
-
return parent ? parent.node : null;
|
|
188
|
-
};
|