@atlaskit/editor-plugin-table 1.2.0 → 1.2.2
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 +26 -0
- package/dist/cjs/i18n/en.js +43 -0
- package/dist/cjs/i18n/en_GB.js +43 -0
- package/dist/cjs/plugins/table/index.js +2 -1
- package/dist/cjs/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +18 -3
- package/dist/cjs/plugins/table/nodeviews/table.js +7 -0
- package/dist/cjs/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +32 -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/transforms/delete-rows.js +1 -1
- package/dist/cjs/plugins/table/transforms/index.js +3 -3
- package/dist/cjs/plugins/table/transforms/merge.js +39 -54
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +16 -3
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/index.js +6 -3
- package/dist/cjs/plugins/table/ui/common-styles.js +2 -2
- package/dist/cjs/plugins/table/utils/row-controls.js +3 -2
- package/dist/cjs/types/i18n.js +5 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/i18n/en.js +36 -0
- package/dist/es2019/i18n/en_GB.js +36 -0
- package/dist/es2019/plugins/table/index.js +2 -1
- package/dist/es2019/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +22 -3
- package/dist/es2019/plugins/table/nodeviews/table.js +7 -0
- package/dist/es2019/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +32 -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/transforms/delete-rows.js +2 -2
- package/dist/es2019/plugins/table/transforms/index.js +1 -1
- package/dist/es2019/plugins/table/transforms/merge.js +39 -43
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +18 -4
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/index.js +6 -3
- package/dist/es2019/plugins/table/ui/common-styles.js +21 -1
- package/dist/es2019/plugins/table/utils/row-controls.js +3 -2
- package/dist/es2019/types/i18n.js +1 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/i18n/en.js +36 -0
- package/dist/esm/i18n/en_GB.js +36 -0
- package/dist/esm/plugins/table/index.js +2 -1
- package/dist/esm/plugins/table/nodeviews/OverflowShadowsObserver.js +13 -26
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +18 -3
- package/dist/esm/plugins/table/nodeviews/table.js +7 -0
- package/dist/esm/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +32 -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/transforms/delete-rows.js +2 -2
- package/dist/esm/plugins/table/transforms/index.js +1 -1
- package/dist/esm/plugins/table/transforms/merge.js +38 -53
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +17 -4
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/index.js +6 -3
- package/dist/esm/plugins/table/ui/common-styles.js +2 -2
- package/dist/esm/plugins/table/utils/row-controls.js +3 -2
- package/dist/esm/types/i18n.js +1 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/i18n/en.d.ts +35 -0
- package/dist/types/i18n/en_GB.d.ts +35 -0
- package/dist/types/plugins/table/nodeviews/OverflowShadowsObserver.d.ts +4 -5
- package/dist/types/plugins/table/nodeviews/TableComponent.d.ts +1 -0
- package/dist/types/plugins/table/nodeviews/__mocks__/OverflowShadowsObserver.d.ts +3 -3
- 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/transforms/index.d.ts +1 -1
- package/dist/types/plugins/table/transforms/merge.d.ts +1 -1
- package/dist/types/plugins/table/types.d.ts +2 -0
- 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/types/i18n.d.ts +5 -0
- package/package.json +10 -9
- package/src/__tests__/integration/__fixtures__/table-and-paragraph-adf.ts +130 -0
- package/src/__tests__/integration/horizontal-scroll-shadows.ts +199 -0
- package/src/__tests__/integration/horizontal-scroll.ts +4 -9
- package/src/__tests__/integration/meta-arrowup-cursor-in-first-row.ts +4 -2
- package/src/__tests__/integration/sticky-header.ts +61 -1
- package/src/__tests__/unit/commands/insert.ts +8 -8
- package/src/__tests__/unit/commands/sort.ts +4 -0
- package/src/__tests__/unit/commands.ts +2 -0
- package/src/__tests__/unit/index.ts +2 -0
- package/src/__tests__/unit/keymap.ts +4 -2
- package/src/__tests__/unit/layout.ts +2 -0
- package/src/__tests__/unit/nodeviews/OverflowShadowsObserver.ts +20 -11
- package/src/__tests__/unit/nodeviews/cell.ts +14 -0
- package/src/__tests__/unit/pm-plugins/main-with-allow-collapse.ts +2 -0
- package/src/__tests__/unit/pm-plugins/sticky-headers/tableRow.tsx +2 -2
- package/src/__tests__/unit/transforms/delete-rows.ts +45 -0
- package/src/__tests__/unit/ui/ContextualMenu.tsx +2 -0
- package/src/__tests__/unit/ui/FloatingContextualMenu.tsx +1 -0
- package/src/__tests__/unit/utils/collapse.ts +4 -1
- package/src/i18n/en.ts +36 -0
- package/src/i18n/en_GB.ts +36 -0
- package/src/plugins/table/index.tsx +4 -0
- package/src/plugins/table/nodeviews/OverflowShadowsObserver.ts +24 -40
- package/src/plugins/table/nodeviews/TableComponent.tsx +20 -4
- package/src/plugins/table/nodeviews/__mocks__/OverflowShadowsObserver.ts +3 -3
- package/src/plugins/table/nodeviews/table.tsx +12 -0
- package/src/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.ts +40 -23
- 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/transforms/delete-rows.ts +2 -2
- package/src/plugins/table/transforms/index.ts +1 -1
- package/src/plugins/table/transforms/merge.ts +41 -43
- package/src/plugins/table/ui/FloatingContextualMenu/ContextualMenu.tsx +21 -2
- package/src/plugins/table/ui/FloatingContextualMenu/index.tsx +8 -1
- package/src/plugins/table/ui/common-styles.ts +21 -0
- package/src/plugins/table/utils/row-controls.ts +3 -2
- package/src/types/i18n.ts +5 -0
- package/src/__tests__/integration/__fixtures__/table-and-paragraph-adf.json +0 -130
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
goToEditorTestingWDExample,
|
|
9
9
|
mountEditor,
|
|
10
10
|
} from '@atlaskit/editor-test-helpers/testing-example-page';
|
|
11
|
-
import tableAdf from './__fixtures__/table-and-paragraph-adf
|
|
11
|
+
import tableAdf from './__fixtures__/table-and-paragraph-adf';
|
|
12
12
|
|
|
13
13
|
BrowserTestCase(
|
|
14
14
|
'meta-arrowup-cursor-in-first-row.ts: pressing command/ctrl + arrow up should move cursor into first row',
|
|
@@ -20,7 +20,9 @@ BrowserTestCase(
|
|
|
20
20
|
);
|
|
21
21
|
await mountEditor(page, {
|
|
22
22
|
appearance: fullpage.appearance,
|
|
23
|
-
allowTables: {
|
|
23
|
+
allowTables: {
|
|
24
|
+
advanced: true,
|
|
25
|
+
},
|
|
24
26
|
defaultValue: tableAdf,
|
|
25
27
|
});
|
|
26
28
|
|
|
@@ -3,6 +3,7 @@ import { BrowserTestCase } from '@atlaskit/webdriver-runner/runner';
|
|
|
3
3
|
import {
|
|
4
4
|
fullpage,
|
|
5
5
|
tableSelectors,
|
|
6
|
+
toggleBreakout,
|
|
6
7
|
} from '@atlaskit/editor-test-helpers/integration/helpers';
|
|
7
8
|
import {
|
|
8
9
|
goToEditorTestingWDExample,
|
|
@@ -22,6 +23,15 @@ const scrollTo = async (page: WebdriverPage, height: number) => {
|
|
|
22
23
|
);
|
|
23
24
|
};
|
|
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
|
+
|
|
25
35
|
const insertColumn = async (page: any, cell: 'first' | 'last') => {
|
|
26
36
|
const columnControl = tableSelectors.nthColumnControl(1);
|
|
27
37
|
const insertButton = tableSelectors.insertButton;
|
|
@@ -41,9 +51,12 @@ const insertColumn = async (page: any, cell: 'first' | 'last') => {
|
|
|
41
51
|
await page.click(insertButton);
|
|
42
52
|
};
|
|
43
53
|
|
|
54
|
+
// FIXME: This test was automatically skipped due to failure on 01/04/2023: https://product-fabric.atlassian.net/browse/ED-17364
|
|
44
55
|
BrowserTestCase(
|
|
45
56
|
'Sticky header should correctly toggle on and off',
|
|
46
|
-
{
|
|
57
|
+
{
|
|
58
|
+
skip: ['*'],
|
|
59
|
+
},
|
|
47
60
|
async (client: any, testName: string) => {
|
|
48
61
|
const page = await goToEditorTestingWDExample(
|
|
49
62
|
client,
|
|
@@ -158,3 +171,50 @@ BrowserTestCase(
|
|
|
158
171
|
expect(!numberedColStyle.includes('top')).toBeTruthy();
|
|
159
172
|
},
|
|
160
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>({
|
|
@@ -22,8 +22,10 @@ import { TableSortOrder as SortOrder } from '@atlaskit/adf-schema/steps';
|
|
|
22
22
|
import tablePlugin from '../../../plugins/table-plugin';
|
|
23
23
|
import statusPlugin from '@atlaskit/editor-core/src/plugins/status';
|
|
24
24
|
import mentionsPlugin from '@atlaskit/editor-core/src/plugins/mentions';
|
|
25
|
+
import editorDisabledPlugin from '@atlaskit/editor-core/src/plugins/editor-disabled';
|
|
25
26
|
import hyperlinkPlugin from '@atlaskit/editor-core/src/plugins/hyperlink';
|
|
26
27
|
import datePlugin from '@atlaskit/editor-core/src/plugins/date';
|
|
28
|
+
import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
27
29
|
|
|
28
30
|
const TABLE_LOCAL_ID = 'test-table-local-id';
|
|
29
31
|
|
|
@@ -118,6 +120,8 @@ describe('Sort Table', () => {
|
|
|
118
120
|
beforeEach(() => {
|
|
119
121
|
({ editorView } = createEditor({
|
|
120
122
|
preset: new Preset<LightEditorPlugin>()
|
|
123
|
+
.add([featureFlagsPlugin, {}])
|
|
124
|
+
.add(editorDisabledPlugin)
|
|
121
125
|
.add([tablePlugin, { tableOptions: { allowHeaderRow: true } }])
|
|
122
126
|
.add([statusPlugin, { menuDisabled: false }])
|
|
123
127
|
.add(mentionsPlugin)
|
|
@@ -60,6 +60,7 @@ import expandPlugin from '@atlaskit/editor-core/src/plugins/expand';
|
|
|
60
60
|
import extensionPlugin from '@atlaskit/editor-core/src/plugins/extension';
|
|
61
61
|
import mediaPlugin from '@atlaskit/editor-core/src/plugins/media';
|
|
62
62
|
import textFormattingPlugin from '@atlaskit/editor-core/src/plugins/text-formatting';
|
|
63
|
+
import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
63
64
|
|
|
64
65
|
const TABLE_LOCAL_ID = 'test-table-local-id';
|
|
65
66
|
|
|
@@ -78,6 +79,7 @@ describe('table plugin: actions', () => {
|
|
|
78
79
|
doc,
|
|
79
80
|
attachTo: document.body,
|
|
80
81
|
preset: new Preset<LightEditorPlugin>()
|
|
82
|
+
.add([featureFlagsPlugin, {}])
|
|
81
83
|
.add(tablePlugin)
|
|
82
84
|
.add(panelPlugin)
|
|
83
85
|
.add(textFormattingPlugin)
|
|
@@ -62,6 +62,7 @@ import { getPluginState } from '../../plugins/table/pm-plugins/plugin-factory';
|
|
|
62
62
|
import { pluginKey } from '../../plugins/table/pm-plugins/plugin-key';
|
|
63
63
|
import type { GetEditorContainerWidth } from '@atlaskit/editor-common/types';
|
|
64
64
|
import tablePlugin from '../../plugins/table-plugin';
|
|
65
|
+
import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
65
66
|
|
|
66
67
|
const TABLE_LOCAL_ID = 'test-table-local-id';
|
|
67
68
|
|
|
@@ -91,6 +92,7 @@ describe('table plugin', () => {
|
|
|
91
92
|
} as PluginConfig;
|
|
92
93
|
|
|
93
94
|
const preset = new Preset<LightEditorPlugin>()
|
|
95
|
+
.add([featureFlagsPlugin, {}])
|
|
94
96
|
.add([tablePlugin, { tableOptions }])
|
|
95
97
|
.add([mediaPlugin, { allowMediaSingle: true }])
|
|
96
98
|
.add([analyticsPlugin, {}])
|
|
@@ -56,8 +56,9 @@ import statusPlugin from '@atlaskit/editor-core/src/plugins/status';
|
|
|
56
56
|
import tablePlugin from '../../plugins/table';
|
|
57
57
|
import { TablePluginState } from '../../plugins/table/types';
|
|
58
58
|
import { pluginKey } from '../../plugins/table/pm-plugins/plugin-key';
|
|
59
|
-
import featureFlagsPlugin from '@atlaskit/editor-core/src/plugins/feature-flags-context';
|
|
60
59
|
import widthPlugin from '@atlaskit/editor-core/src/plugins/width';
|
|
60
|
+
import editorDisabledPlugin from '@atlaskit/editor-core/src/plugins/editor-disabled';
|
|
61
|
+
import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
61
62
|
|
|
62
63
|
const TABLE_LOCAL_ID = 'test-table-local-id';
|
|
63
64
|
|
|
@@ -81,6 +82,7 @@ describe('table keymap', () => {
|
|
|
81
82
|
|
|
82
83
|
const createEditor = createProsemirrorEditorFactory();
|
|
83
84
|
const preset = new Preset<LightEditorPlugin>()
|
|
85
|
+
.add([featureFlagsPlugin, {}])
|
|
84
86
|
.add(selectionPlugin)
|
|
85
87
|
.add([
|
|
86
88
|
tablePlugin,
|
|
@@ -97,12 +99,12 @@ describe('table keymap', () => {
|
|
|
97
99
|
.add(emojiPlugin)
|
|
98
100
|
.add(jiraIssuePlugin)
|
|
99
101
|
.add(extensionPlugin)
|
|
102
|
+
.add(editorDisabledPlugin)
|
|
100
103
|
.add(datePlugin)
|
|
101
104
|
.add(layoutPlugin)
|
|
102
105
|
.add([statusPlugin, { menuDisabled: false }])
|
|
103
106
|
.add([mediaPlugin, { allowMediaSingle: true }])
|
|
104
107
|
.add([analyticsPlugin, { createAnalyticsEvent }])
|
|
105
|
-
.add([featureFlagsPlugin, {}])
|
|
106
108
|
.add(widthPlugin);
|
|
107
109
|
|
|
108
110
|
const editor = (doc: DocBuilder) =>
|
|
@@ -35,6 +35,7 @@ import expandPlugin from '@atlaskit/editor-core/src/plugins/expand';
|
|
|
35
35
|
import extensionPlugin from '@atlaskit/editor-core/src/plugins/extension';
|
|
36
36
|
import layoutPlugin from '@atlaskit/editor-core/src/plugins/layout';
|
|
37
37
|
import { PluginKey } from 'prosemirror-state';
|
|
38
|
+
import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
38
39
|
|
|
39
40
|
describe('table toolbar', () => {
|
|
40
41
|
const tableOptions = {
|
|
@@ -46,6 +47,7 @@ describe('table toolbar', () => {
|
|
|
46
47
|
|
|
47
48
|
const createEditor = createProsemirrorEditorFactory();
|
|
48
49
|
const preset = new Preset<LightEditorPlugin>()
|
|
50
|
+
.add([featureFlagsPlugin, {}])
|
|
49
51
|
.add([tablePlugin, { tableOptions }])
|
|
50
52
|
.add(expandPlugin)
|
|
51
53
|
.add(extensionPlugin)
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { MockIntersectionObserver } from '@atlaskit/editor-test-helpers/mock-intersection-observer';
|
|
2
2
|
|
|
3
3
|
import { OverflowShadowsObserver } from '../../../plugins/table/nodeviews/OverflowShadowsObserver';
|
|
4
|
+
import { TableCssClassName as className } from '../../../plugins/table/types';
|
|
4
5
|
import { ShadowEvent } from '../../../plugins/table/types';
|
|
5
6
|
|
|
6
7
|
describe('OverflowShadowsObserver', () => {
|
|
7
8
|
let table: HTMLTableElement;
|
|
8
9
|
let td1: HTMLTableDataCellElement;
|
|
9
10
|
let td2: HTMLTableDataCellElement;
|
|
11
|
+
let shadowSentinelLeft: HTMLDivElement;
|
|
12
|
+
let shadowSentinelRight: HTMLDivElement;
|
|
10
13
|
let wrapper: HTMLDivElement;
|
|
11
14
|
const updateSpy = jest.fn();
|
|
12
15
|
const observeSpy = jest.fn();
|
|
@@ -37,15 +40,15 @@ describe('OverflowShadowsObserver', () => {
|
|
|
37
40
|
});
|
|
38
41
|
|
|
39
42
|
it('observes on first and last table cells', () => {
|
|
40
|
-
overflowShadowsObserver.
|
|
41
|
-
expect(observeSpy).toHaveBeenCalledWith(
|
|
42
|
-
expect(observeSpy).toHaveBeenCalledWith(
|
|
43
|
+
overflowShadowsObserver.observeShadowSentinels();
|
|
44
|
+
expect(observeSpy).toHaveBeenCalledWith(shadowSentinelLeft);
|
|
45
|
+
expect(observeSpy).toHaveBeenCalledWith(shadowSentinelRight);
|
|
43
46
|
});
|
|
44
47
|
|
|
45
|
-
it('does not re-observe if
|
|
46
|
-
overflowShadowsObserver.
|
|
48
|
+
it('does not re-observe if shadow sentinels are already observed', () => {
|
|
49
|
+
overflowShadowsObserver.observeShadowSentinels();
|
|
47
50
|
observeSpy.mockClear();
|
|
48
|
-
overflowShadowsObserver.
|
|
51
|
+
overflowShadowsObserver.observeShadowSentinels();
|
|
49
52
|
expect(observeSpy).not.toHaveBeenCalled();
|
|
50
53
|
});
|
|
51
54
|
|
|
@@ -61,14 +64,14 @@ describe('OverflowShadowsObserver', () => {
|
|
|
61
64
|
|
|
62
65
|
describe('calls the provided update function when intersecting', () => {
|
|
63
66
|
beforeEach(() => {
|
|
64
|
-
overflowShadowsObserver.
|
|
67
|
+
overflowShadowsObserver.observeShadowSentinels();
|
|
65
68
|
});
|
|
66
69
|
|
|
67
70
|
it.each([
|
|
68
71
|
[
|
|
69
72
|
'hides first shadow when first cell fully intersects',
|
|
70
73
|
{
|
|
71
|
-
getTarget: () =>
|
|
74
|
+
getTarget: () => shadowSentinelLeft,
|
|
72
75
|
intersectionRatio: 1,
|
|
73
76
|
isIntersecting: true,
|
|
74
77
|
expectedShadow: ShadowEvent.SHOW_BEFORE_SHADOW,
|
|
@@ -78,7 +81,7 @@ describe('OverflowShadowsObserver', () => {
|
|
|
78
81
|
[
|
|
79
82
|
'hides last shadow when last cell fully intersects',
|
|
80
83
|
{
|
|
81
|
-
getTarget: () =>
|
|
84
|
+
getTarget: () => shadowSentinelRight,
|
|
82
85
|
intersectionRatio: 1,
|
|
83
86
|
isIntersecting: true,
|
|
84
87
|
expectedShadow: ShadowEvent.SHOW_AFTER_SHADOW,
|
|
@@ -88,7 +91,7 @@ describe('OverflowShadowsObserver', () => {
|
|
|
88
91
|
[
|
|
89
92
|
'shows first shadow when first cell partially intersects',
|
|
90
93
|
{
|
|
91
|
-
getTarget: () =>
|
|
94
|
+
getTarget: () => shadowSentinelLeft,
|
|
92
95
|
intersectionRatio: 0,
|
|
93
96
|
isIntersecting: true,
|
|
94
97
|
expectedShadow: ShadowEvent.SHOW_BEFORE_SHADOW,
|
|
@@ -98,7 +101,7 @@ describe('OverflowShadowsObserver', () => {
|
|
|
98
101
|
[
|
|
99
102
|
'shows last shadow when last cell partially intersects',
|
|
100
103
|
{
|
|
101
|
-
getTarget: () =>
|
|
104
|
+
getTarget: () => shadowSentinelRight,
|
|
102
105
|
intersectionRatio: 0,
|
|
103
106
|
isIntersecting: true,
|
|
104
107
|
expectedShadow: ShadowEvent.SHOW_AFTER_SHADOW,
|
|
@@ -140,6 +143,12 @@ describe('OverflowShadowsObserver', () => {
|
|
|
140
143
|
function buildTable() {
|
|
141
144
|
wrapper = document.createElement('div');
|
|
142
145
|
table = document.createElement('table');
|
|
146
|
+
shadowSentinelLeft = document.createElement('div');
|
|
147
|
+
shadowSentinelLeft.className = className.TABLE_SHADOW_SENTINEL_LEFT;
|
|
148
|
+
shadowSentinelRight = document.createElement('div');
|
|
149
|
+
shadowSentinelRight.className = className.TABLE_SHADOW_SENTINEL_RIGHT;
|
|
150
|
+
table.prepend(shadowSentinelLeft);
|
|
151
|
+
table.prepend(shadowSentinelRight);
|
|
143
152
|
wrapper.appendChild(table);
|
|
144
153
|
const tbody = document.createElement('tbody');
|
|
145
154
|
table.appendChild(tbody);
|
|
@@ -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();
|
|
@@ -21,6 +21,7 @@ import { TablePluginState } from '../../../plugins/table/types';
|
|
|
21
21
|
import { handleDocOrSelectionChanged } from '../../../plugins/table/handlers';
|
|
22
22
|
import expandPlugin from '@atlaskit/editor-core/src/plugins/expand';
|
|
23
23
|
import extensionPlugin from '@atlaskit/editor-core/src/plugins/extension';
|
|
24
|
+
import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
24
25
|
|
|
25
26
|
describe('tables: main plugin with allowCollapse: true', () => {
|
|
26
27
|
const createEditor = createProsemirrorEditorFactory();
|
|
@@ -28,6 +29,7 @@ describe('tables: main plugin with allowCollapse: true', () => {
|
|
|
28
29
|
createEditor({
|
|
29
30
|
doc,
|
|
30
31
|
preset: new Preset<LightEditorPlugin>()
|
|
32
|
+
.add([featureFlagsPlugin, {}])
|
|
31
33
|
.add(tablePlugin)
|
|
32
34
|
.add(expandPlugin)
|
|
33
35
|
.add(extensionPlugin),
|
|
@@ -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
|
|
|
@@ -241,6 +241,51 @@ describe('table plugin -> transforms -> delete rows', () => {
|
|
|
241
241
|
});
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
+
describe('when delete the row in between rows that have merged cells with an extra row underneath', () => {
|
|
245
|
+
it('should decrement colspan of these cells', () => {
|
|
246
|
+
const { editorView } = editor(
|
|
247
|
+
doc(
|
|
248
|
+
p('text'),
|
|
249
|
+
table()(
|
|
250
|
+
tr(td({ colspan: 5 })(p('a1')), td({})(p('a6'))),
|
|
251
|
+
tr(
|
|
252
|
+
td({})(p('b1{<cell}')),
|
|
253
|
+
td({})(p('b2')),
|
|
254
|
+
td({})(p('b3')),
|
|
255
|
+
td({})(p('b4')),
|
|
256
|
+
td({})(p('b5')),
|
|
257
|
+
td({})(p('b6{cell>}')),
|
|
258
|
+
),
|
|
259
|
+
tr(td({})(p('c1')), td({ colspan: 5 })(p('c6'))),
|
|
260
|
+
tr(
|
|
261
|
+
td({ colspan: 3 })(p('d1')),
|
|
262
|
+
td({})(p('d4')),
|
|
263
|
+
td({})(p('d5')),
|
|
264
|
+
td({})(p('d6')),
|
|
265
|
+
),
|
|
266
|
+
),
|
|
267
|
+
),
|
|
268
|
+
);
|
|
269
|
+
const { state, dispatch } = editorView;
|
|
270
|
+
dispatch(deleteRows(getSelectionRect(state.selection)!)(state.tr));
|
|
271
|
+
expect(editorView.state.doc).toEqualDocument(
|
|
272
|
+
doc(
|
|
273
|
+
p('text'),
|
|
274
|
+
table({ localId: TABLE_LOCAL_ID })(
|
|
275
|
+
tr(td({ colspan: 4 })(p('a1')), td({})(p('a6'))),
|
|
276
|
+
tr(td({})(p('c1')), td({ colspan: 4 })(p('c6'))),
|
|
277
|
+
tr(
|
|
278
|
+
td({ colspan: 2 })(p('d1')),
|
|
279
|
+
td({})(p('d4')),
|
|
280
|
+
td({})(p('d5')),
|
|
281
|
+
td({})(p('d6')),
|
|
282
|
+
),
|
|
283
|
+
),
|
|
284
|
+
),
|
|
285
|
+
);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
|
|
244
289
|
describe('when after deleting the first row table has columns where all cells have colspan > 1', () => {
|
|
245
290
|
it('should decrement colspan of these cells', () => {
|
|
246
291
|
const { editorView } = editor(
|
|
@@ -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
|
|
|
@@ -18,12 +18,15 @@ import {
|
|
|
18
18
|
isTableCollapsible,
|
|
19
19
|
collapseSelectedTable,
|
|
20
20
|
} from '../../../plugins/table/utils/collapse';
|
|
21
|
+
import featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
21
22
|
|
|
22
23
|
describe('collapse', () => {
|
|
23
24
|
const createEditor = createProsemirrorEditorFactory();
|
|
24
25
|
|
|
25
26
|
const editor = (doc: DocBuilder, expandInPlugins?: boolean) => {
|
|
26
|
-
const preset = new Preset<LightEditorPlugin>()
|
|
27
|
+
const preset = new Preset<LightEditorPlugin>()
|
|
28
|
+
.add([featureFlagsPlugin, {}])
|
|
29
|
+
.add(tablePlugin);
|
|
27
30
|
|
|
28
31
|
const finalPreset = expandInPlugins ? preset.add(expandPlugin) : preset;
|
|
29
32
|
|
package/src/i18n/en.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* prettier-ignore */
|
|
2
|
+
/**
|
|
3
|
+
* NOTE:
|
|
4
|
+
*
|
|
5
|
+
* This file is automatically generated by Traduki 2.0.
|
|
6
|
+
* DO NOT CHANGE IT BY HAND or your changes will be lost.
|
|
7
|
+
*/
|
|
8
|
+
//
|
|
9
|
+
export default {
|
|
10
|
+
'fabric.editor.canNotSortTable': "⚠️ You can't sort a table with merged cells",
|
|
11
|
+
'fabric.editor.cellBackground': 'Cell background',
|
|
12
|
+
'fabric.editor.cellOptions': 'Cell options',
|
|
13
|
+
'fabric.editor.clearCells': 'Clear {0, plural, one {cell} other {cells}}',
|
|
14
|
+
'fabric.editor.collapseTable': 'Collapse table',
|
|
15
|
+
'fabric.editor.cornerControl': 'Highlight table',
|
|
16
|
+
'fabric.editor.distributeColumns': 'Distribute columns',
|
|
17
|
+
'fabric.editor.extension.confirmDeleteLinkedModalMessagePrefix': 'Deleting',
|
|
18
|
+
'fabric.editor.extension.deleteElementTitle': 'Delete element',
|
|
19
|
+
'fabric.editor.extension.sourceNoTitledName': 'this element',
|
|
20
|
+
'fabric.editor.floatingToolbar.confirmModalCheckboxLabel': 'Also delete connected elements',
|
|
21
|
+
'fabric.editor.headerColumn': 'Header column',
|
|
22
|
+
'fabric.editor.headerRow': 'Header row',
|
|
23
|
+
'fabric.editor.insertColumn': 'Insert column right',
|
|
24
|
+
'fabric.editor.insertRow': 'Insert row below',
|
|
25
|
+
'fabric.editor.mergeCells': 'Merge cells',
|
|
26
|
+
'fabric.editor.numberedColumn': 'Numbered column',
|
|
27
|
+
'fabric.editor.removeColumns': 'Delete {0, plural, one {column} other {columns}}',
|
|
28
|
+
'fabric.editor.removeRows': 'Delete {0, plural, one {row} other {rows}}',
|
|
29
|
+
'fabric.editor.rowControl': 'Highlight row',
|
|
30
|
+
'fabric.editor.sortColumnASC': 'Sort column A → Z',
|
|
31
|
+
'fabric.editor.sortColumnDESC': 'Sort column Z → A',
|
|
32
|
+
'fabric.editor.splitCell': 'Split cell',
|
|
33
|
+
'fabric.editor.tableOptions': 'Table options',
|
|
34
|
+
'fabric.editor.tables.confirmDeleteLinkedModalMessage': 'Deleting {nodeName} will break anything connected to it.',
|
|
35
|
+
'fabric.editor.tables.confirmDeleteLinkedModalOKButton': 'Delete',
|
|
36
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* prettier-ignore */
|
|
2
|
+
/**
|
|
3
|
+
* NOTE:
|
|
4
|
+
*
|
|
5
|
+
* This file is automatically generated by Traduki 2.0.
|
|
6
|
+
* DO NOT CHANGE IT BY HAND or your changes will be lost.
|
|
7
|
+
*/
|
|
8
|
+
//English (United Kingdom)
|
|
9
|
+
export default {
|
|
10
|
+
'fabric.editor.canNotSortTable': "⚠️ You can't sort a table with merged cells",
|
|
11
|
+
'fabric.editor.cellBackground': 'Cell background',
|
|
12
|
+
'fabric.editor.cellOptions': 'Cell options',
|
|
13
|
+
'fabric.editor.clearCells': 'Clear {0, plural, one {cell} other {cells}}',
|
|
14
|
+
'fabric.editor.collapseTable': 'Collapse table',
|
|
15
|
+
'fabric.editor.cornerControl': 'Highlight table',
|
|
16
|
+
'fabric.editor.distributeColumns': 'Distribute columns',
|
|
17
|
+
'fabric.editor.extension.confirmDeleteLinkedModalMessagePrefix': 'Deleting',
|
|
18
|
+
'fabric.editor.extension.deleteElementTitle': 'Delete element',
|
|
19
|
+
'fabric.editor.extension.sourceNoTitledName': 'this element',
|
|
20
|
+
'fabric.editor.floatingToolbar.confirmModalCheckboxLabel': 'Also delete connected elements',
|
|
21
|
+
'fabric.editor.headerColumn': 'Header column',
|
|
22
|
+
'fabric.editor.headerRow': 'Header row',
|
|
23
|
+
'fabric.editor.insertColumn': 'Insert column right',
|
|
24
|
+
'fabric.editor.insertRow': 'Insert row below',
|
|
25
|
+
'fabric.editor.mergeCells': 'Merge cells',
|
|
26
|
+
'fabric.editor.numberedColumn': 'Numbered column',
|
|
27
|
+
'fabric.editor.removeColumns': 'Delete {0, plural, one {column} other {columns}}',
|
|
28
|
+
'fabric.editor.removeRows': 'Delete {0, plural, one {row} other {rows}}',
|
|
29
|
+
'fabric.editor.rowControl': 'Highlight row',
|
|
30
|
+
'fabric.editor.sortColumnASC': 'Sort column A → Z',
|
|
31
|
+
'fabric.editor.sortColumnDESC': 'Sort column Z → A',
|
|
32
|
+
'fabric.editor.splitCell': 'Split cell',
|
|
33
|
+
'fabric.editor.tableOptions': 'Table options',
|
|
34
|
+
'fabric.editor.tables.confirmDeleteLinkedModalMessage': 'Deleting {nodeName} will break anything connected to it.',
|
|
35
|
+
'fabric.editor.tables.confirmDeleteLinkedModalOKButton': 'Delete',
|
|
36
|
+
};
|
|
@@ -371,6 +371,10 @@ const tablesPlugin: NextEditorPlugin<
|
|
|
371
371
|
pluginConfig={pluginConfig}
|
|
372
372
|
editorAnalyticsAPI={options?.editorAnalyticsAPI}
|
|
373
373
|
getEditorContainerWidth={defaultGetEditorContainerWidth}
|
|
374
|
+
getEditorFeatureFlags={
|
|
375
|
+
options?.getEditorFeatureFlags ||
|
|
376
|
+
defaultGetEditorFeatureFlags
|
|
377
|
+
}
|
|
374
378
|
/>
|
|
375
379
|
{allowControls && (
|
|
376
380
|
<FloatingDeleteButton
|
|
@@ -8,25 +8,9 @@ export class OverflowShadowsObserver {
|
|
|
8
8
|
private table: HTMLElement;
|
|
9
9
|
private wrapper: HTMLDivElement;
|
|
10
10
|
|
|
11
|
-
private
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
private getFirstCell: (
|
|
15
|
-
isSticky?: boolean,
|
|
16
|
-
hasHeaderRow?: boolean,
|
|
17
|
-
) => HTMLElement | null = (isSticky, hasHeaderRow) =>
|
|
18
|
-
this.table?.querySelector(
|
|
19
|
-
isSticky || !hasHeaderRow ? 'table tbody tr td' : 'table tbody tr th',
|
|
20
|
-
);
|
|
21
|
-
private getLastCell: (
|
|
22
|
-
isSticky?: boolean,
|
|
23
|
-
hasHeaderRow?: boolean,
|
|
24
|
-
) => HTMLElement | null = (isSticky, hasHeaderRow) =>
|
|
25
|
-
this.table?.querySelector(
|
|
26
|
-
isSticky || !hasHeaderRow
|
|
27
|
-
? 'table tbody tr td:last-child'
|
|
28
|
-
: 'table tbody tr th:last-child',
|
|
29
|
-
);
|
|
11
|
+
private leftShadowSentinel: HTMLElement | null = null;
|
|
12
|
+
private rightShadowSentinel: HTMLElement | null = null;
|
|
13
|
+
private shadowsObserved: boolean = false;
|
|
30
14
|
|
|
31
15
|
private isSticky = false;
|
|
32
16
|
private stickyRowHeight = 0;
|
|
@@ -58,13 +42,16 @@ export class OverflowShadowsObserver {
|
|
|
58
42
|
if (!entry.rootBounds?.height && !entry.rootBounds?.width) {
|
|
59
43
|
return;
|
|
60
44
|
}
|
|
61
|
-
if (
|
|
45
|
+
if (
|
|
46
|
+
entry.target !== this.leftShadowSentinel &&
|
|
47
|
+
entry.target !== this.rightShadowSentinel
|
|
48
|
+
) {
|
|
62
49
|
return;
|
|
63
50
|
}
|
|
64
51
|
this.updateStickyShadowsHeightIfChanged();
|
|
65
52
|
this.checkIntersectionEvent(
|
|
66
53
|
entry,
|
|
67
|
-
this.
|
|
54
|
+
this.leftShadowSentinel === entry.target
|
|
68
55
|
? ShadowEvent.SHOW_BEFORE_SHADOW
|
|
69
56
|
: ShadowEvent.SHOW_AFTER_SHADOW,
|
|
70
57
|
);
|
|
@@ -123,32 +110,29 @@ export class OverflowShadowsObserver {
|
|
|
123
110
|
return stickyCell;
|
|
124
111
|
}
|
|
125
112
|
|
|
126
|
-
|
|
127
|
-
const stickyChanged = !!isSticky !== this.isSticky;
|
|
113
|
+
observeShadowSentinels = (isSticky?: boolean) => {
|
|
128
114
|
this.isSticky = !!isSticky;
|
|
129
115
|
|
|
130
116
|
// update sticky shadows
|
|
131
117
|
this.updateStickyShadowsHeightIfChanged();
|
|
132
118
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
(firstCell === this.firstCell && lastCell === this.lastCell)
|
|
140
|
-
) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
this.firstCell = this.getFirstCell(isSticky, hasHeaderRow);
|
|
146
|
-
this.lastCell = this.getLastCell(isSticky, hasHeaderRow);
|
|
119
|
+
this.leftShadowSentinel = this.table?.querySelector(
|
|
120
|
+
`.${ClassName.TABLE_SHADOW_SENTINEL_LEFT}`,
|
|
121
|
+
);
|
|
122
|
+
this.rightShadowSentinel = this.table?.querySelector(
|
|
123
|
+
`.${ClassName.TABLE_SHADOW_SENTINEL_RIGHT}`,
|
|
124
|
+
);
|
|
147
125
|
|
|
148
|
-
if (
|
|
126
|
+
if (
|
|
127
|
+
this.tableIntersectionObserver &&
|
|
128
|
+
this.leftShadowSentinel &&
|
|
129
|
+
this.rightShadowSentinel &&
|
|
130
|
+
!this.shadowsObserved
|
|
131
|
+
) {
|
|
149
132
|
this.tableIntersectionObserver.disconnect();
|
|
150
|
-
this.tableIntersectionObserver.observe(this.
|
|
151
|
-
this.tableIntersectionObserver.observe(this.
|
|
133
|
+
this.tableIntersectionObserver.observe(this.leftShadowSentinel);
|
|
134
|
+
this.tableIntersectionObserver.observe(this.rightShadowSentinel);
|
|
135
|
+
this.shadowsObserved = true;
|
|
152
136
|
}
|
|
153
137
|
};
|
|
154
138
|
|