Skip to content

Commit

Permalink
implement resize
Browse files Browse the repository at this point in the history
  • Loading branch information
dimaanj committed Nov 9, 2023
1 parent 0561f52 commit 8147846
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 29 deletions.
4 changes: 2 additions & 2 deletions apps/www/src/registry/default/plate-ui/table-cell-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ const TableCellElement = React.forwardRef<
rowSize,
borders,
isSelectingCell,
colSpan,
} = useTableCellElementState();
const { props: cellProps } = useTableCellElement({ element: props.element });
const resizableState = useTableCellElementResizableState({
colIndex,
rowIndex,
colSpan,
});



const { rightProps, bottomProps, leftProps, hiddenLeft } =
useTableCellElementResizable(resizableState);

Expand Down
2 changes: 1 addition & 1 deletion packages/plate-utils/src/components/PortalBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ export const PortalBody: ({
element || typeof window !== 'undefined' ? document.body : undefined;
if (!container) return (<>{children}</>) as any;

return ReactDOM.createPortal(children as any, element || document.body);
return ReactDOM.createPortal(children, element || document.body);
};
9 changes: 8 additions & 1 deletion packages/resizable/src/components/ResizeHandle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const ResizeHandleProvider = ({

export type ResizeHandleOptions = {
direction?: ResizeDirection;
initialSize?: number;
onResize?: (event: ResizeEvent) => void;
onMouseDown?: MouseEventHandler;
onTouchStart?: TouchEventHandler;
Expand All @@ -60,6 +61,7 @@ export type ResizeHandleOptions = {

export const useResizeHandleState = ({
direction = 'left',
initialSize: _initialSize,
onResize,
onMouseDown,
onTouchStart,
Expand Down Expand Up @@ -88,7 +90,12 @@ export const useResizeHandleState = ({

const currentPosition = isHorizontal ? clientX : clientY;
const delta = currentPosition - initialPosition;
onResize?.({ initialSize, delta, finished, direction });
onResize?.({
initialSize: _initialSize || initialSize,
delta,
finished,
direction,
});
};

const handleMouseMove = (event: MouseEvent | TouchEvent) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { TableCellElementState } from './useTableCellElementState';

export type TableCellElementResizableOptions = Pick<
TableCellElementState,
'colIndex' | 'rowIndex'
'colIndex' | 'rowIndex' | 'colSpan'
> & {
/**
* Resize by step instead of by pixel.
Expand All @@ -50,6 +50,7 @@ export const useTableCellElementResizableState = ({
step,
stepX = step,
stepY = step,
colSpan,
}: TableCellElementResizableOptions) => {
const editor = useEditorRef();
const { disableMarginLeft } = getPluginOptions<TablePlugin>(
Expand All @@ -63,6 +64,7 @@ export const useTableCellElementResizableState = ({
rowIndex,
stepX,
stepY,
colSpan,
};
};

Expand All @@ -72,6 +74,7 @@ export const useTableCellElementResizable = ({
rowIndex,
stepX,
stepY,
colSpan,
}: ReturnType<typeof useTableCellElementResizableState>): {
rightProps: ComponentPropsWithoutRef<typeof ResizeHandle>;
bottomProps: ComponentPropsWithoutRef<typeof ResizeHandle>;
Expand All @@ -86,6 +89,12 @@ export const useTableCellElementResizable = ({
ELEMENT_TABLE
);

// MERGE: override width for horizontally merged cell
let initialWidth: number | undefined;
if (colSpan > 1) {
initialWidth = tableElement.colSizes?.[colIndex];
}

const [hoveredColIndex, setHoveredColIndex] =
useTableStore().use.hoveredColIndex();

Expand Down Expand Up @@ -246,6 +255,7 @@ export const useTableCellElementResizable = ({
rightProps: {
options: {
direction: 'right',
initialSize: initialWidth,
onResize: handleResizeRight,
...getHandleHoverProps(colIndex),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,25 @@ export type TableCellElementState = {
rowSize: number | undefined;
borders: BorderStylesDefault;
isSelectingCell: boolean;
colSpan: number;
};

/**
* Returns the colspan attribute of the table cell element.
* @default 1 if undefined.
*/
export const getColSpan = (cellElem: TTableCellElement) => {
const attrColSpan = Number(cellElem.attributes?.colspan);
return cellElem.colSpan || attrColSpan || 1;
};

/**
* Returns the rowspan attribute of the table cell element.
* @default 1 if undefined
*/
export const getRowSpan = (cellElem: TTableCellElement) => {
const attrRowSpan = Number(cellElem.attributes?.rowspan);
return cellElem.rowSpan || attrRowSpan || 1;
};

export const useTableCellElementState = ({
Expand All @@ -39,20 +58,32 @@ export const useTableCellElementState = ({
const editor = useEditorRef();
const cellElement = useElement<TTableCellElement>();

const colIndex = getTableColumnIndex(editor, cellElement);
const rowIndex = getTableRowIndex(editor, cellElement);
const colSpan = getColSpan(cellElement);
const rowSpan = getRowSpan(cellElement);

const defaultColIndex = getTableColumnIndex(editor, cellElement);
const defaultRowIndex = getTableRowIndex(editor, cellElement);

const readOnly = useReadOnly();

const isCellSelected = useIsCellSelected(cellElement);
const hoveredColIndex = useTableStore().get.hoveredColIndex();
const selectedCells = useTableStore().get.selectedCells();
const cellAttributes = useTableStore().get.cellAttributes();

const tableElement = useElement<TTableElement>(ELEMENT_TABLE);
const rowElement = useElement<TTableRowElement>(ELEMENT_TR);

const x = cellAttributes.get(cellElement);
const colIndex = x?.col ?? defaultColIndex;
const rowIndex = x?.row ?? defaultRowIndex;

const endingRowIndex = rowIndex + rowSpan - 1;
const endingColIndex = colIndex + colSpan - 1;

const rowSizeOverrides = useTableStore().get.rowSizeOverrides();
const rowSize =
rowSizeOverrides.get(rowIndex) ?? rowElement?.size ?? undefined;
rowSizeOverrides.get(endingRowIndex) ?? rowElement?.size ?? undefined;

const isFirstCell = colIndex === 0;
const isFirstRow = tableElement.children?.[0] === rowElement;
Expand All @@ -63,15 +94,16 @@ export const useTableCellElementState = ({
});

return {
colIndex,
rowIndex,
colIndex: endingColIndex,
rowIndex: endingRowIndex,
readOnly: !ignoreReadOnly && readOnly,
selected: isCellSelected,
hovered: hoveredColIndex === colIndex,
hovered: hoveredColIndex === endingColIndex,
hoveredLeft: isFirstCell && hoveredColIndex === -1,
rowSize,
borders,
isSelectingCell: !!selectedCells,
colSpan,
};
};

Expand Down
46 changes: 28 additions & 18 deletions packages/table/src/components/TableElement/useTableElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import {
import { Path } from 'slate';

import { ELEMENT_TABLE } from '../../createTablePlugin';
import { useTableStore } from '../../stores/tableStore';
import {
TableStoreCellAttributes,
useTableStore,
} from '../../stores/tableStore';
import {
TablePlugin,
TTableCellElement,
Expand Down Expand Up @@ -47,11 +50,13 @@ export const useTableElementState = ({
const element = useElement<TTableElement>();
const selectedCells = useTableStore().get.selectedCells();
const marginLeftOverride = useTableStore().get.marginLeftOverride();
const setCellAttributes = useTableStore().set.cellAttributes();

// initial calc, than it will be calculated when each individual cell updated
useEffect(() => {
calculateCellIndexes(editor, element);
}, [editor, element]);
const newAttributes = new WeakMap() as TableStoreCellAttributes;
calculateCellIndexes(editor, element, newAttributes);
setCellAttributes(newAttributes);
}, [editor, element, setCellAttributes]);

const marginLeft = disableMarginLeft
? 0
Expand Down Expand Up @@ -98,13 +103,13 @@ export const useTableElement = () => {
};
};

const cellAttributes = new WeakMap<
TTableCellElement,
{ row: number; col: number }
>();
// const cellAttributes = new WeakMap<
// TTableCellElement,
// { row: number; col: number }
// >();

function getCellIndices(
editor: PlateEditor,
cellAttributes: TableStoreCellAttributes,
tableEl: TTableElement,
tablePath: Path,
cellPath: Path
Expand Down Expand Up @@ -161,7 +166,8 @@ function getCellIndices(

const calculateCellIndexes = (
editor: PlateEditor,
tableNode: TTableElement
tableNode: TTableElement,
cellAttributes: TableStoreCellAttributes
) => {
// (Place the `getCellIndices()` function from the previous response here)

Expand All @@ -180,19 +186,23 @@ const calculateCellIndexes = (
const cell = row.children[c] as TTableCellElement;

// Get cell indices and store them in the row's array
// const cellPath = findNodePath(editor, cell)!; // TODO: use concat instead of findNodePath
const cellPath = [r, c];
console.log(
'searching for',
cell.children.map((m) => {
return (m as any).children[0].text;
}),
// console.log(
// 'searching for',
// cell.children.map((m) => {
// return (m as any).children[0].text;
// }),
// tableNode,
// tablePath,
// cellPath
// );

const indices = getCellIndices(
cellAttributes,
tableNode,
tablePath,
cellPath
);

const indices = getCellIndices(editor, tableNode, tablePath, cellPath);
if (indices) {
cellAttributes.set(cell, indices);
}
Expand Down
7 changes: 7 additions & 0 deletions packages/table/src/stores/tableStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ import { useCallback } from 'react';
import { createAtomStore, TElement } from '@udecode/plate-common';

import { ELEMENT_TABLE } from '../createTablePlugin';
import { TTableCellElement } from '../types';

export type TableStoreSizeOverrides = Map<number, number>;

export type TableStoreCellAttributes = Map<
TTableCellElement,
{ row: number; col: number }
>;

export const { tableStore, useTableStore } = createAtomStore(
{
colSizeOverrides: new Map() as TableStoreSizeOverrides,
rowSizeOverrides: new Map() as TableStoreSizeOverrides,
cellAttributes: new WeakMap() as TableStoreCellAttributes,
marginLeftOverride: null as number | null,
hoveredColIndex: null as number | null,
selectedCells: null as TElement[] | null,
Expand Down
4 changes: 4 additions & 0 deletions packages/table/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ export interface TTableCellElement extends TElement {
*/
right?: BorderStyle;
};
attributes: {
colspan?: string;
rowspan?: string;
}
}

export type BorderDirection = 'top' | 'left' | 'bottom' | 'right';
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ const TableCellElement = React.forwardRef<
rowSize,
borders,
isSelectingCell,
colSpan,
} = useTableCellElementState();
const { props: cellProps } = useTableCellElement({ element: props.element });
const resizableState = useTableCellElementResizableState({
colIndex,
rowIndex,
colSpan,
});
const { rightProps, bottomProps, leftProps, hiddenLeft } =
useTableCellElementResizable(resizableState);
Expand Down

0 comments on commit 8147846

Please sign in to comment.