Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize hooks a little #4

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions packages/leyden-react/src/hooks/useAreCoordinatesSelected.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Coordinates, LeydenEditor } from 'leyden';
import { useEffect, useState } from 'react';

import { useLeydenStatic } from './useLeydenStatic';

export const useAreCoordinatesSelected = (coords: Coordinates|null): boolean => {
const editor = useLeydenStatic();
const currentSelectedCoords = LeydenEditor.selectedCoords(editor);
const [coordinatesSelected, setCoordinatesSelected] = useState(
(coords && currentSelectedCoords) ?
Coordinates.equals(currentSelectedCoords, coords) :
false
);

useEffect(() => {
const unsubscribe = LeydenEditor.subscribeToSelectedCoordinatesByCoordinates(
editor,
setCoordinatesSelected,
{
at: coords
},
);
return () => {
unsubscribe();
};
}, []);

return coordinatesSelected;
};
15 changes: 2 additions & 13 deletions packages/leyden-react/src/hooks/useCellIsSelected.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
import { Coordinates } from 'leyden';
import { useMemo } from 'react';
import { Descendant } from 'slate';

import { useCoordinates } from './useCoordinates';
import { useSelectedCoordinates } from './useSelectedCoordinates';
import { useAreCoordinatesSelected } from './useAreCoordinatesSelected';

export const useCellIsSelected = (node: Descendant): boolean => {
const ownCoords = useCoordinates(node);
const selectedCoords = useSelectedCoordinates();

const cellSelected = useMemo(() => {
return (
ownCoords !== null
&& selectedCoords !== null
&& Coordinates.equals(ownCoords, selectedCoords)
);
}, [ownCoords, selectedCoords]);

return cellSelected;
return useAreCoordinatesSelected(ownCoords);
};
16 changes: 7 additions & 9 deletions packages/leyden-react/src/hooks/useCoordinates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ export const useCoordinates = (node: Descendant): Coordinates|null => {
return;
}
// If not wrapped in `setTimeout`, this runs before the cell paths are updated
// and coordinate movement is never detected.
setTimeout(() => {
const newCoords = ReactEditor.cellCoords(editor, node);
if ((newCoords === null || !Coordinates.equals(coordinates, newCoords))
&& !canceled
) {
setCoordinates(newCoords);
}
});
// and coordinate movement is never detected.
const newCoords = ReactEditor.cellCoords(editor, node);
if ((newCoords === null || !Coordinates.equals(coordinates, newCoords))
&& !canceled
) {
setCoordinates(newCoords);
}
});
return () => {
canceled = true;
Expand Down
42 changes: 37 additions & 5 deletions packages/leyden/src/interfaces/LeydenEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import { Coordinates } from './Coordinates';
import { Table } from './Table';
import { ValidationFunc, Validator } from './Validator';
import {
CellSubscriber,
OperationSubscriber,
SelectedCoordinatesSubscriber,
Unsubscriber,
CellSubscriber, CoordinateSelectedSubscriber, OperationSubscriber, SelectedCoordinatesSubscriber, Unsubscriber,
} from '../utils/types';
import { OPERATION_SUBSCRIBERS } from '../utils/weakMaps';

Expand Down Expand Up @@ -79,6 +76,13 @@ export interface LeydenEditorInterface {
editor: Editor,
subscriber: SelectedCoordinatesSubscriber
) => Unsubscriber;
subscribeToSelectedCoordinatesByCoordinates: (
editor: Editor,
subscriber: CoordinateSelectedSubscriber,
options: {
at: Coordinates | null,
}
) => Unsubscriber;
table: (editor: Editor) => Table;
tablePath: () => Path;
}
Expand Down Expand Up @@ -148,7 +152,7 @@ export const LeydenEditor: LeydenEditorInterface = {
},

/**
* Get the path to the nth cell in an editor.
* Get the path to the nth cell in an editor.
*/

nthCellPath(n: number): CellPath {
Expand Down Expand Up @@ -333,6 +337,34 @@ export const LeydenEditor: LeydenEditorInterface = {
});
},

/**
* Subscribe to the selected status of a cell at the specified coordinates.
*/

subscribeToSelectedCoordinatesByCoordinates(
editor: Editor,
subscriber: CoordinateSelectedSubscriber,
options: {
at: Coordinates | null,
}
): Unsubscriber {
const { at } = options;
if (!at) {
return () => subscriber(false);
}
const cellPath = LeydenEditor.cellPath(editor, { at });
return LeydenEditor.subscribeToOperations(editor, op => {
if (Operation.isSelectionOperation(op) &&
op.newProperties?.focus?.path &&
Path.equals(op.newProperties?.focus?.path.slice(0, 2), cellPath)
) {
subscriber(true);
} else if (Operation.isSelectionOperation(op)) {
subscriber(false);
}
});
},

/**
* Get an editor's table.
*/
Expand Down
12 changes: 9 additions & 3 deletions packages/leyden/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,27 @@ export type CellSubscriber<T extends CellType> = (cell: Cell<T>) => void;
export type SelectedCoordinatesSubscriber = (coords: Coordinates|null) => void;

/**
* A function which will end a subscription
* A function fired when the current cell's coordinates become selected.
*/

export type CoordinateSelectedSubscriber = (selected: boolean) => void;

/**
* A function which will end a subscription
*/

export type Unsubscriber = () => void;

/**
* An option representing a leyden editor passed during editor initialization
* An option representing a leyden editor passed during editor initialization
*/

export interface EditorOption<T extends Editor> {
editor: T,
}

/**
* An option representing a validator set passed during editor initialization
* An option representing a validator set passed during editor initialization
*/

export interface ValidatorsOption {
Expand Down
13 changes: 8 additions & 5 deletions packages/leyden/src/withLeyden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,16 @@ export const withLeyden = <T extends Editor>({ editor, ...rest }: WithLeydenOpti
}
}
apply(op);

// Notify subscribers of operations after application
const opSubscribers = OPERATION_SUBSCRIBERS.get(e);
if (opSubscribers !== undefined) {
for (const opSubscriber of opSubscribers) {
opSubscriber(op);
setTimeout(() => {
const opSubscribers = OPERATION_SUBSCRIBERS.get(e);
if (opSubscribers !== undefined) {
for (const opSubscriber of opSubscribers) {
opSubscriber(op);
}
}
}
});
};

e.getValidationFunc = validator => (
Expand Down