@atlaskit/editor-plugin-table 0.0.7 → 0.0.9

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 (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/plugins/table/nodeviews/TableComponent.js +4 -2
  3. package/dist/cjs/plugins/table/nodeviews/table.js +4 -2
  4. package/dist/cjs/plugins/table/toolbar.js +0 -1
  5. package/dist/cjs/plugins/table/ui/TableFloatingControls/CornerControls/index.js +23 -10
  6. package/dist/cjs/plugins/table/ui/TableFloatingControls/RowControls/index.js +23 -10
  7. package/dist/cjs/plugins/table/ui/TableFloatingControls/index.js +4 -4
  8. package/dist/cjs/version.json +1 -1
  9. package/dist/es2019/plugins/table/nodeviews/TableComponent.js +4 -2
  10. package/dist/es2019/plugins/table/nodeviews/table.js +4 -2
  11. package/dist/es2019/plugins/table/toolbar.js +1 -2
  12. package/dist/es2019/plugins/table/ui/TableFloatingControls/CornerControls/index.js +18 -3
  13. package/dist/es2019/plugins/table/ui/TableFloatingControls/RowControls/index.js +18 -3
  14. package/dist/es2019/plugins/table/ui/TableFloatingControls/index.js +2 -2
  15. package/dist/es2019/version.json +1 -1
  16. package/dist/esm/plugins/table/nodeviews/TableComponent.js +4 -2
  17. package/dist/esm/plugins/table/nodeviews/table.js +4 -2
  18. package/dist/esm/plugins/table/toolbar.js +1 -2
  19. package/dist/esm/plugins/table/ui/TableFloatingControls/CornerControls/index.js +19 -9
  20. package/dist/esm/plugins/table/ui/TableFloatingControls/RowControls/index.js +19 -9
  21. package/dist/esm/plugins/table/ui/TableFloatingControls/index.js +2 -2
  22. package/dist/esm/version.json +1 -1
  23. package/dist/types/plugins/table/nodeviews/types.d.ts +1 -0
  24. package/dist/types/plugins/table/ui/TableFloatingControls/CornerControls/index.d.ts +5 -8
  25. package/dist/types/plugins/table/ui/TableFloatingControls/RowControls/index.d.ts +5 -5
  26. package/dist/types-ts4.0/plugins/table/nodeviews/types.d.ts +1 -0
  27. package/dist/types-ts4.0/plugins/table/ui/TableFloatingControls/CornerControls/index.d.ts +5 -8
  28. package/dist/types-ts4.0/plugins/table/ui/TableFloatingControls/RowControls/index.d.ts +5 -5
  29. package/package.json +7 -2
  30. package/src/__tests__/unit/hover-selection.ts +1 -1
  31. package/src/__tests__/unit/index-with-fake-timers.ts +1 -0
  32. package/src/__tests__/unit/ui/CornerControls.tsx +22 -22
  33. package/src/__tests__/unit/ui/FloatingDeleteButton.tsx +3 -3
  34. package/src/__tests__/unit/ui/FloatingInsertButton.tsx +15 -15
  35. package/src/__tests__/unit/ui/RowControls.tsx +1 -1
  36. package/src/__tests__/unit/ui/TableFloatingControls.tsx +2 -2
  37. package/src/plugins/table/__tests__/unit/commands/insert.ts +2 -2
  38. package/src/plugins/table/__tests__/unit/commands.ts +2 -2
  39. package/src/plugins/table/__tests__/unit/nodeviews/TableComponent.tsx +2 -2
  40. package/src/plugins/table/__tests__/unit/nodeviews/table.ts +1 -0
  41. package/src/plugins/table/__tests__/unit/pm-plugins/sticky-headers/tableRow.tsx +25 -47
  42. package/src/plugins/table/nodeviews/TableComponent.tsx +8 -2
  43. package/src/plugins/table/nodeviews/table.tsx +7 -0
  44. package/src/plugins/table/nodeviews/types.ts +1 -0
  45. package/src/plugins/table/toolbar.ts +0 -1
  46. package/src/plugins/table/ui/FloatingContextualMenu/__tests__/ContextualMenu.tsx +1 -1
  47. package/src/plugins/table/ui/FloatingContextualMenu/__tests__/FloatingContextualMenu.tsx +1 -1
  48. package/src/plugins/table/ui/TableFloatingControls/CornerControls/index.tsx +19 -1
  49. package/src/plugins/table/ui/TableFloatingControls/RowControls/index.tsx +16 -1
  50. package/src/plugins/table/ui/TableFloatingControls/index.tsx +2 -2
@@ -33,9 +33,9 @@ jest.mock('@atlaskit/editor-common/ui', () => ({
33
33
  import { findOverflowScrollParent } from '@atlaskit/editor-common/ui';
34
34
  import { updateStickyState } from '../../../../pm-plugins/sticky-headers/commands';
35
35
  import { TableCssClassName } from '../../../../types';
36
- import { mount } from 'enzyme';
37
36
  import TableComponent from '../../../../nodeviews/TableComponent';
38
37
  import React from 'react';
38
+ import { render, screen } from '@testing-library/react';
39
39
  import {
40
40
  stickyRowOffsetTop,
41
41
  tableScrollbarOffset,
@@ -388,13 +388,13 @@ describe('TableRowNodeView', () => {
388
388
  return scrollContainer;
389
389
  }
390
390
 
391
- function mountTableComponent({
391
+ function renderTableComponent({
392
392
  disableContentDomMock,
393
393
  }: {
394
394
  disableContentDomMock?: true;
395
395
  } = {}) {
396
396
  const getNode = () => editorView.state.doc.firstChild;
397
- return mount(
397
+ return render(
398
398
  <TableComponent
399
399
  view={editorView}
400
400
  eventDispatcher={eventDispatcher}
@@ -428,28 +428,21 @@ describe('TableRowNodeView', () => {
428
428
  });
429
429
 
430
430
  it('sentinel elements are rendered inside table component', () => {
431
- const tableComponent = mountTableComponent();
432
- // rafStub.flush();
433
- const sentinelWrapperTop = tableComponent.find(
434
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_TOP}`,
435
- );
436
- const sentinelWrapperBottom = tableComponent.find(
437
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_BOTTOM}`,
438
- );
439
- expect(sentinelWrapperTop).toHaveLength(1);
440
- expect(sentinelWrapperBottom).toHaveLength(1);
431
+ renderTableComponent();
432
+ const sentinelTop = screen.getByTestId('sticky-sentinel-top');
433
+ const sentinelBottom = screen.getByTestId('sticky-sentinel-bottom');
434
+
435
+ expect(sentinelTop).toBeTruthy();
436
+ expect(sentinelBottom).toBeTruthy();
441
437
  });
442
438
 
443
439
  describe('updates sticky header state', () => {
444
440
  it('top sentinel does nothing if the rootBounds has height 0', () => {
445
- const tableComponent = mountTableComponent();
446
- const sentinelWrapperTop = tableComponent.find(
447
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_TOP}`,
448
- );
449
- const sentinelTop = sentinelWrapperTop.getDOMNode() as HTMLElement;
441
+ renderTableComponent();
442
+ const sentinelTop = screen.getByTestId('sticky-sentinel-top');
450
443
 
451
444
  triggerElementIntersect({
452
- target: sentinelTop,
445
+ target: sentinelTop as HTMLElement,
453
446
  isIntersecting: false,
454
447
  rootBounds: { bottom: 0, top: 0, height: 0 },
455
448
  boundingClientRect: { bottom: 0, top: 0 },
@@ -459,13 +452,10 @@ describe('TableRowNodeView', () => {
459
452
  });
460
453
 
461
454
  it('bottom sentinel does nothing if the rootBounds has height 0', () => {
462
- const tableComponent = mountTableComponent();
463
- const sentinelWrapperBottom = tableComponent.find(
464
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_BOTTOM}`,
465
- );
466
- const sentinelBottom = sentinelWrapperBottom.getDOMNode() as HTMLElement;
455
+ renderTableComponent();
456
+ const sentinelBottom = screen.getByTestId('sticky-sentinel-bottom');
467
457
  triggerElementIntersect({
468
- target: sentinelBottom,
458
+ target: sentinelBottom as HTMLElement,
469
459
  isIntersecting: false,
470
460
  rootBounds: { bottom: 0, top: 0, height: 0 },
471
461
  boundingClientRect: { bottom: 0, top: 0 },
@@ -474,12 +464,9 @@ describe('TableRowNodeView', () => {
474
464
  expect(updateStickyState).not.toHaveBeenCalled();
475
465
  });
476
466
 
477
- it('when top sentinel leaves scroll area', () => {
478
- const tableComponent = mountTableComponent();
479
- const sentinelWrapperTop = tableComponent.find(
480
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_TOP}`,
481
- );
482
- const sentinelTop = sentinelWrapperTop.getDOMNode() as HTMLElement;
467
+ it('updates sticky header when top of sticky header sentinel leaves scroll area', () => {
468
+ renderTableComponent();
469
+ const sentinelTop = screen.getByTestId('sticky-sentinel-top');
483
470
 
484
471
  triggerElementIntersect({
485
472
  target: sentinelTop,
@@ -512,12 +499,9 @@ describe('TableRowNodeView', () => {
512
499
  );
513
500
  });
514
501
 
515
- it('when bottom sentinel enters or leaves scroll area', () => {
516
- const tableComponent = mountTableComponent();
517
- const sentinelWrapperBottom = tableComponent.find(
518
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_BOTTOM}`,
519
- );
520
- const sentinelBottom = sentinelWrapperBottom.getDOMNode() as HTMLElement;
502
+ it('updates sticky header when bottom of sticky header sentinel enters or leaves scroll area', () => {
503
+ renderTableComponent();
504
+ const sentinelBottom = screen.getByTestId('sticky-sentinel-bottom');
521
505
 
522
506
  triggerElementIntersect({
523
507
  target: sentinelBottom,
@@ -560,13 +544,10 @@ describe('TableRowNodeView', () => {
560
544
  (_, contentRectSupported: boolean) => {
561
545
  const { tableWrapper } = getTableElements(tableRowDom);
562
546
  // disabled due to editorView dom being cleared by use of contentDom mocks
563
- const tableComponent = mountTableComponent({
547
+ renderTableComponent({
564
548
  disableContentDomMock: true,
565
549
  });
566
- const sentinelWrapperBottom = tableComponent.find(
567
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_BOTTOM}`,
568
- );
569
- const sentinelBottom = sentinelWrapperBottom.getDOMNode() as HTMLElement;
550
+ const sentinelBottom = screen.getByTestId('sticky-sentinel-bottom');
570
551
  tableWrapper?.appendChild(sentinelBottom);
571
552
  rafStub.flush();
572
553
 
@@ -584,13 +565,10 @@ describe('TableRowNodeView', () => {
584
565
  it('marks sentinels as unobserved when isHeaderRowEnabled is set to false', () => {
585
566
  const { tableWrapper } = getTableElements(tableRowDom);
586
567
  // disabled due to editorView dom being cleared by use of contentDom mocks
587
- const tableComponent = mountTableComponent({
568
+ renderTableComponent({
588
569
  disableContentDomMock: true,
589
570
  });
590
- const sentinelWrapperBottom = tableComponent.find(
591
- `.${TableCssClassName.TABLE_STICKY_SENTINEL_BOTTOM}`,
592
- );
593
- const sentinelBottom = sentinelWrapperBottom.getDOMNode() as HTMLElement;
571
+ const sentinelBottom = screen.getByTestId('sticky-sentinel-bottom');
594
572
  tableWrapper?.appendChild(sentinelBottom);
595
573
  rafStub.flush();
596
574
  expect(sentinelBottom.dataset.isObserved).toBeDefined();
@@ -394,7 +394,10 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
394
394
  data-layout={node.attrs.layout}
395
395
  >
396
396
  {stickyHeadersOptimization && (
397
- <div className={ClassName.TABLE_STICKY_SENTINEL_TOP} />
397
+ <div
398
+ className={ClassName.TABLE_STICKY_SENTINEL_TOP}
399
+ data-testid="sticky-sentinel-top"
400
+ />
398
401
  )}
399
402
  {allowControls &&
400
403
  (!isLoading || initialRenderOptimization) &&
@@ -465,7 +468,10 @@ class TableComponent extends React.Component<ComponentProps, TableState> {
465
468
  </div>
466
469
  )}
467
470
  {stickyHeadersOptimization && (
468
- <div className={ClassName.TABLE_STICKY_SENTINEL_BOTTOM} />
471
+ <div
472
+ className={ClassName.TABLE_STICKY_SENTINEL_BOTTOM}
473
+ data-testid="sticky-sentinel-bottom"
474
+ />
469
475
  )}
470
476
  </div>
471
477
  );
@@ -72,6 +72,10 @@ export default class TableView extends ReactNodeView<Props> {
72
72
  props.portalProviderAPI,
73
73
  props.eventDispatcher,
74
74
  props,
75
+ undefined,
76
+ undefined,
77
+ undefined,
78
+ props.hasIntlContext,
75
79
  );
76
80
  this.getPos = props.getPos;
77
81
  this.tableRenderOptimization = props.tableRenderOptimization;
@@ -233,6 +237,8 @@ export const createTableView = (
233
237
  const { pluginConfig } = getPluginState(view.state);
234
238
  const { allowColumnResizing } = getPluginConfig(pluginConfig);
235
239
  const { tableRenderOptimization } = getEditorFeatureFlags();
240
+ const hasIntlContext = true;
241
+
236
242
  return new TableView({
237
243
  node,
238
244
  view,
@@ -244,5 +250,6 @@ export const createTableView = (
244
250
  tableRenderOptimization,
245
251
  getEditorContainerWidth,
246
252
  getEditorFeatureFlags,
253
+ hasIntlContext,
247
254
  }).init();
248
255
  };
@@ -26,4 +26,5 @@ export interface Props {
26
26
  tableRenderOptimization?: boolean;
27
27
  getEditorContainerWidth: GetEditorContainerWidth;
28
28
  getEditorFeatureFlags: GetEditorFeatureFlags;
29
+ hasIntlContext: boolean;
29
30
  }
@@ -57,7 +57,6 @@ import { findParentDomRefOfType } from 'prosemirror-utils';
57
57
  import { EditorView } from 'prosemirror-view';
58
58
  import { closestElement } from '@atlaskit/editor-common/utils';
59
59
 
60
- // TODO: ED-14403 investigate why these translations don't work
61
60
  export const messages = defineMessages({
62
61
  tableOptions: {
63
62
  id: 'fabric.editor.tableOptions',
@@ -37,7 +37,7 @@ it.skip('TODO: restore unit', () => {});
37
37
  // }));
38
38
  // });
39
39
 
40
- // test('should render contextual menu when no tableCellPosition is passed but exist on editor state ', () => {
40
+ // it('should render contextual menu when no tableCellPosition is passed but exist on editor state ', () => {
41
41
  // const intl = createIntl({ locale: 'en' });
42
42
  // const wrapper = shallow(
43
43
  // <ContextualMenu
@@ -34,7 +34,7 @@ it.skip('TODO: restore unit', () => {});
34
34
  // }));
35
35
  // });
36
36
 
37
- // test('should render floating contextual menu when no tableCellPosition is passed but exist on editor state ', () => {
37
+ // it('should render floating contextual menu when no tableCellPosition is passed but exist on editor state ', () => {
38
38
  // const wrapper = shallow(
39
39
  // <FloatingContextualMenu
40
40
  // editorView={editorView}
@@ -1,4 +1,6 @@
1
1
  import React, { Component } from 'react';
2
+ import type { WrappedComponentProps } from 'react-intl-next';
3
+ import { defineMessages, injectIntl } from 'react-intl-next';
2
4
 
3
5
  import classnames from 'classnames';
4
6
  import { TableMap } from '@atlaskit/editor-tables/table-map';
@@ -12,6 +14,15 @@ import { EditorView } from 'prosemirror-view';
12
14
  import { clearHoverSelection, hoverTable } from '../../../commands';
13
15
  import { TableCssClassName as ClassName } from '../../../types';
14
16
 
17
+ const messages = defineMessages({
18
+ cornerControl: {
19
+ id: 'fabric.editor.cornerControl',
20
+ defaultMessage: 'Highlight table',
21
+ description:
22
+ 'A button on the upper left corner of the table that shows up when the table is in focus. Clicking on it will select the entire table.',
23
+ },
24
+ });
25
+
15
26
  export interface Props {
16
27
  editorView: EditorView;
17
28
  tableRef?: HTMLTableElement;
@@ -23,13 +34,17 @@ export interface Props {
23
34
  stickyTop?: number;
24
35
  }
25
36
 
26
- export default class CornerControls extends Component<Props, any> {
37
+ class CornerControlComponent extends Component<
38
+ Props & WrappedComponentProps,
39
+ any
40
+ > {
27
41
  render() {
28
42
  const {
29
43
  isInDanger,
30
44
  tableRef,
31
45
  isHeaderColumnEnabled,
32
46
  isHeaderRowEnabled,
47
+ intl: { formatMessage },
33
48
  } = this.props;
34
49
  if (!tableRef) {
35
50
  return null;
@@ -50,6 +65,7 @@ export default class CornerControls extends Component<Props, any> {
50
65
  }}
51
66
  >
52
67
  <button
68
+ aria-label={formatMessage(messages.cornerControl)}
53
69
  type="button"
54
70
  className={classnames(ClassName.CONTROLS_CORNER_BUTTON, {
55
71
  danger: isActive && isInDanger,
@@ -103,3 +119,5 @@ export default class CornerControls extends Component<Props, any> {
103
119
  hoverTable()(state, dispatch);
104
120
  };
105
121
  }
122
+
123
+ export const CornerControls = injectIntl(CornerControlComponent);
@@ -1,6 +1,8 @@
1
1
  import React, { Component } from 'react';
2
2
 
3
3
  import { EditorView } from 'prosemirror-view';
4
+ import type { WrappedComponentProps } from 'react-intl-next';
5
+ import { defineMessages, injectIntl } from 'react-intl-next';
4
6
 
5
7
  import { clearHoverSelection } from '../../../commands';
6
8
  import { TableCssClassName as ClassName } from '../../../types';
@@ -12,6 +14,15 @@ import {
12
14
  } from '../../../utils';
13
15
  import { tableControlsSpacing, tableToolbarSize } from '../../consts';
14
16
 
17
+ const messages = defineMessages({
18
+ rowControl: {
19
+ id: 'fabric.editor.rowControl',
20
+ defaultMessage: 'Highlight row',
21
+ description:
22
+ 'A button on the left of each row that shows up when the table is in focus. Clicking on it will select the entire row.',
23
+ },
24
+ });
25
+
15
26
  export interface Props {
16
27
  editorView: EditorView;
17
28
  tableRef: HTMLTableElement;
@@ -24,7 +35,7 @@ export interface Props {
24
35
  stickyTop?: number;
25
36
  }
26
37
 
27
- export default class RowControls extends Component<Props> {
38
+ class RowControlsComponent extends Component<Props & WrappedComponentProps> {
28
39
  render() {
29
40
  const {
30
41
  editorView,
@@ -32,6 +43,7 @@ export default class RowControls extends Component<Props> {
32
43
  hoveredRows,
33
44
  isInDanger,
34
45
  isResizing,
46
+ intl: { formatMessage },
35
47
  } = this.props;
36
48
  if (!tableRef) {
37
49
  return null;
@@ -89,6 +101,7 @@ export default class RowControls extends Component<Props> {
89
101
  }}
90
102
  >
91
103
  <button
104
+ aria-label={formatMessage(messages.rowControl)}
92
105
  type="button"
93
106
  className={`${ClassName.ROW_CONTROLS_BUTTON}
94
107
  ${ClassName.CONTROLS_BUTTON}
@@ -117,3 +130,5 @@ export default class RowControls extends Component<Props> {
117
130
  clearHoverSelection()(state, dispatch);
118
131
  };
119
132
  }
133
+
134
+ export const RowControls = injectIntl(RowControlsComponent);
@@ -11,9 +11,9 @@ import { RowStickyState } from '../../pm-plugins/sticky-headers';
11
11
 
12
12
  import { isSelectionUpdated } from '../../utils';
13
13
 
14
- import CornerControls from './CornerControls';
14
+ import { CornerControls } from './CornerControls';
15
15
  import NumberColumn from './NumberColumn';
16
- import RowControls from './RowControls';
16
+ import { RowControls } from './RowControls';
17
17
  import type { GetEditorFeatureFlags } from '@atlaskit/editor-common/types';
18
18
 
19
19
  export interface Props {