Skip to content

Commit

Permalink
feat(tables): add a new positioner for cell selections (#1924)
Browse files Browse the repository at this point in the history
  • Loading branch information
whawker committed Oct 27, 2022
1 parent ab5fcb0 commit 0d2237a
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/shaggy-shrimps-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@remirror/extension-tables': patch
---

Add a new table positioner for cell selections
1 change: 1 addition & 0 deletions packages/remirror__extension-tables/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export {
activeCellRowPositioner,
allColumnsStartPositioner,
allRowsStartPositioner,
cellSelectionPositioner,
selectedColumnPositioner,
selectedRowPositioner,
tablePositioner,
Expand Down
58 changes: 57 additions & 1 deletion packages/remirror__extension-tables/src/table-positioners.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
FindProsemirrorNodeResult,
isElementDomNode,
mergeDOMRects,
NodeWithPosition,
ProsemirrorNode,
Selection,
Expand All @@ -11,7 +12,7 @@ import {
isPositionVisible,
Positioner,
} from '@remirror/extension-positioner';
import { isCellSelection, TableMap } from '@remirror/pm/tables';
import { CellSelection, isCellSelection, TableMap } from '@remirror/pm/tables';

import { findCellClosestToPos, findTable } from './table-utils';

Expand Down Expand Up @@ -472,3 +473,58 @@ export const selectedRowPositioner = activeCellRowPositioner.clone(({ getActive
return [data];
},
}));

/**
* Creates a positioner for the current cell selection in a table
*
* It spans the full width and height of the selected cells
*/
export const cellSelectionPositioner = Positioner.create<CellSelection>({
hasChanged: hasStateChanged,

getActive(props) {
const { selection } = props.state;

if (!isCellSelection(selection)) {
return Positioner.EMPTY;
}

return [selection];
},

getPosition(props) {
const { view, data: selection } = props;

const { $headCell, $anchorCell } = selection;

const headNode = view.nodeDOM($headCell.pos);
const anchorNode = view.nodeDOM($anchorCell.pos);

if (!isElementDomNode(headNode) || !isElementDomNode(anchorNode)) {
return defaultAbsolutePosition;
}

const rect = mergeDOMRects(
headNode.getBoundingClientRect(),
anchorNode.getBoundingClientRect(),
);

const editorRect = view.dom.getBoundingClientRect();

const height = rect.height;
const width = rect.width;

// The top and left relative to the parent `editorRect`.
const left = view.dom.scrollLeft + rect.left - editorRect.left - 1;
const top = view.dom.scrollTop + rect.top - editorRect.top - 1;

return {
x: left,
y: top,
width,
height,
rect,
visible: isPositionVisible(rect, view.dom),
};
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ActiveCellRow,
AllColumnsStart,
AllRowsStart,
CellSelection,
SelectedColumn,
SelectedRow,
Table,
Expand All @@ -26,6 +27,7 @@ export { EmptyBlock };
export { EmptyBlockStart };
export { EmptyBlockEnd };
export { Table };
export { CellSelection };
export { ActiveCell };
export { ActiveCellColumn };
export { ActiveCellRow };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
activeCellRowPositioner,
allColumnsStartPositioner,
allRowsStartPositioner,
cellSelectionPositioner,
selectedColumnPositioner,
selectedRowPositioner,
TableExtension,
Expand Down Expand Up @@ -202,4 +203,11 @@ AllRowsStart.args = {
multi: true,
};

export const CellSelection: Story = Template.bind({});
CellSelection.args = {
positioner: cellSelectionPositioner,
placement: 'bottom',
label: 'Creates a rect which wraps the selected cells.',
};

export default Table;

1 comment on commit 0d2237a

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Published on https://remirror.io as production
🚀 Deployed on https://635af57ac544fc06162311e9--remirror.netlify.app

Please sign in to comment.