Skip to content

Commit

Permalink
Fix selection on focus (#1435)
Browse files Browse the repository at this point in the history
* fix

* Create stupid-readers-fetch.md

* Create popular-months-obey.md

* fix

* fix
  • Loading branch information
zbeyens authored Mar 13, 2022
1 parent 06ec998 commit 289c8e7
Show file tree
Hide file tree
Showing 40 changed files with 215 additions and 128 deletions.
9 changes: 9 additions & 0 deletions .changeset/popular-months-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@udecode/plate-ui-alignment": minor
"@udecode/plate-ui-code-block": minor
"@udecode/plate-ui-font": minor
"@udecode/plate-ui-image": minor
"@udecode/plate-ui-line-height": minor
---

new prop: editor `id`
11 changes: 11 additions & 0 deletions .changeset/stupid-readers-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@udecode/plate-core": minor
---

Fix a critical issue when using multiple editors #1352
- `withHOC`: 3rd parameter can be used to add props to HOC.
- `usePlateId` now just gets plate id atom value and no longer gets event editor id as fallback.
- `useEventEditorId`: Get last event editor id: focus, blur or last.
- `useEventPlateId`: Get provider plate id or event editor id.
- `PlateEventProvider`: `PlateProvider` where id is the event editor id (used for toolbar buttons).
- `withPlateEventProvider`
3 changes: 1 addition & 2 deletions docs/docs/guides/multiple-editors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ Let's render 3 editors with common heading and balloon toolbars.
<BasicMarkToolbarButtons />
</HeadingToolbar>


<div className="flex">
<MultipleEditor
id="multiple-editors-basic"
Expand All @@ -49,7 +48,7 @@ Let's render 3 editors with common heading and balloon toolbars.
<MultipleEditor
id="multiple-editors-image"
plugins={PLUGINS.image}
initialValue={VALUES.images}
initialValue={VALUES.image}
/>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/common/hoc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

export * from './createNodeHOC';
export * from './createNodesHOC';
export * from './withHOC';
export * from './withProps';
export * from './withProviders';
export * from './withHOC';
5 changes: 3 additions & 2 deletions packages/core/src/common/hoc/withHOC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import React, { FunctionComponent } from 'react';

export const withHOC = <T,>(
HOC: FunctionComponent<any>,
Component: FunctionComponent<T>
Component: FunctionComponent<T>,
hocProps?: any
): FunctionComponent<T> => (props: T) => (
<HOC>
<HOC {...hocProps}>
<Component {...props} />
</HOC>
);
19 changes: 19 additions & 0 deletions packages/core/src/components/PlateEventProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { FC } from 'react';
import { withHOC } from '../common/hoc/withHOC';
import { useEventPlateId } from '../stores/event-editor/selectors/useEventPlateId';
import { PlateProvider } from './PlateProvider';

export const PlateEventProvider = ({
id,
children,
}: {
id?: string;
children: any;
}) => {
id = useEventPlateId(id);

return <PlateProvider id={id}>{children}</PlateProvider>;
};

export const withPlateEventProvider = <T,>(Component: FC<T>, hocProps?: T) =>
withHOC<T>(PlateEventProvider, Component, hocProps);
16 changes: 6 additions & 10 deletions packages/core/src/components/PlateProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
import React, { FC } from 'react';
import { castArray } from 'lodash';
import { withHOC } from '../common/hoc/withHOC';
import { usePlatesStoreEffect } from '../hooks/usePlatesStoreEffect';
import { usePlatesSelectors } from '../stores/plate/platesStore';

export const PlateProvider = ({
id: _ids = 'main',
id = 'main',
children,
}: {
id?: string | string[];
id?: string;
children: any;
}) => {
const ids = castArray<string>(_ids) ?? ['main'];
const id = ids[0];
const hasId = usePlatesSelectors.has(id);

const hasId = usePlatesSelectors.has(ids);

usePlatesStoreEffect(_ids);
usePlatesStoreEffect(id);

if (!hasId) return null;

return <React.Fragment key={id}>{children}</React.Fragment>;
};

export const withPlateProvider = <T,>(Component: FC<T>) =>
withHOC<T>(PlateProvider, Component);
export const withPlateProvider = <T,>(Component: FC<T>, hocProps?: T) =>
withHOC<T>(PlateProvider, Component, hocProps);
3 changes: 2 additions & 1 deletion packages/core/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

export * from './DefaultLeaf';
export * from './EditablePlugins';
export * from './PlateProvider';
export * from './EditorRefEffect';
export * from './EditorStateEffect';
export * from './Plate';
export * from './PlateEventProvider';
export * from './PlateProvider';
export * from './PlateTest';
2 changes: 1 addition & 1 deletion packages/core/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

export * from './useEditorRef';
export * from './useEditorState';
export * from './usePlate/index';
export * from './usePlatesStoreEffect';
export * from './usePlate/index';
1 change: 1 addition & 0 deletions packages/core/src/hooks/usePlate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
export * from './useEditableProps';
export * from './usePlate';
export * from './usePlateEffects';
export * from './usePlateStoreEffects';
export * from './useSlateProps';
26 changes: 4 additions & 22 deletions packages/core/src/hooks/usePlatesStoreEffect.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
import { useEffect } from 'react';
import { castArray } from 'lodash';
import { PlateProps } from '../components/Plate';
import { platesActions, platesSelectors } from '../stores/plate/platesStore';
import { usePlateId } from '../stores/plate/selectors/getPlateId';

/**
* On mount: create plate store and set it to the plates store.
* If id is not defined, event id is used.
*/
export const usePlatesStoreEffect = (
_ids?: string | string[],
props?: PlateProps
) => {
const __ids = castArray<string>(_ids);
const id = usePlateId(__ids[0]);

export const usePlatesStoreEffect = (id?: string, props?: PlateProps) => {
useEffect(() => {
// Set multiple plate stores
if (Array.isArray(_ids)) {
const ids = castArray<string>(_ids);

ids.forEach((_id) => {
if (!platesSelectors.has(_id)) {
platesActions.set(_id, props);
}
});
} else if (!platesSelectors.has(id)) {
platesActions.set(id, props);
if (!platesSelectors.has(id)) {
platesActions.set(id!, props);
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [_ids, id]);
}, [id]);
};
1 change: 1 addition & 0 deletions packages/core/src/stores/event-editor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
*/

export * from './event-editor.store';
export * from './selectors/index';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { eventEditorSelectors } from '../event-editor.store';

export const getEventEditorId = (id?: string) => {
if (id) return id;

const focus = eventEditorSelectors.focus();
if (focus) return focus;

const blur = eventEditorSelectors.blur();
if (blur) return blur;

return eventEditorSelectors.last() ?? 'main';
};
7 changes: 7 additions & 0 deletions packages/core/src/stores/event-editor/selectors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @file Automatically generated by barrelsby.
*/

export * from './getEventEditorId';
export * from './useEventEditorId';
export * from './useEventPlateId';
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useEventEditorSelectors } from '../event-editor.store';

/**
* Get last event editor id: focus, blur or last.
*/
export const useEventEditorId = () => {
const focus = useEventEditorSelectors.focus();
const blur = useEventEditorSelectors.blur();
const last = useEventEditorSelectors.last();

if (focus) return focus;
if (blur) return blur;
return last;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { usePlateId } from '../../plate/selectors/usePlateId';
import { useEventEditorId } from './useEventEditorId';

export const useEventPlateId = (id?: string) => {
const plateId = usePlateId();
const eventEditorId = useEventEditorId();

return id ?? plateId ?? eventEditorId ?? 'main';
};
2 changes: 1 addition & 1 deletion packages/core/src/stores/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
* @file Automatically generated by barrelsby.
*/

export * from './plateIdAtom';
export * from './event-editor/index';
export * from './plate/index';
export { plateIdAtom } from './plateIdAtom';
40 changes: 0 additions & 40 deletions packages/core/src/stores/plate/selectors/getPlateId.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/core/src/stores/plate/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* @file Automatically generated by barrelsby.
*/

export * from './getPlateId';
export * from './usePlateEditorRef';
export * from './usePlateEditorState';
export * from './usePlateId';
export * from './usePlatePlugins';
export * from './usePlateSelection';
11 changes: 11 additions & 0 deletions packages/core/src/stores/plate/selectors/usePlateId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useAtom } from 'jotai';
import { plateIdAtom } from '../../plateIdAtom';

/**
* Get plate editor id provided by PlateProvider.
*/
export const usePlateId = () => {
const [plateId] = useAtom(plateIdAtom);

return plateId;
};
8 changes: 5 additions & 3 deletions packages/core/src/stores/plate/usePlateStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PlateStoreApi } from '../../types/PlateStore';
import { getPlateId, usePlateId } from './selectors/getPlateId';
import { getEventEditorId } from '../event-editor/selectors/getEventEditorId';
import { usePlateId } from './selectors/usePlateId';
import { createPlateStore } from './createPlateStore';
import { platesStore } from './platesStore';

Expand All @@ -8,15 +9,16 @@ const loadingStore = createPlateStore({
});

export const getPlateStore = (id?: string): PlateStoreApi => {
id = getPlateId(id);
id = getEventEditorId(id);

const store = platesStore.get.get(id);

return store || loadingStore;
};

export const usePlateStore = (id?: string): PlateStoreApi => {
id = usePlateId(id);
const plateId = usePlateId();
id = id ?? plateId ?? 'main';

const store = platesStore.use.get(id);

Expand Down
4 changes: 4 additions & 0 deletions packages/nodes/mention/src/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* @file Automatically generated by barrelsby.
*/

export * from './KeyboardEventHandler';
export * from './mentionOnKeyDownHandler';
export * from './moveSelectionByOffset';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @jsx jsx */

import { jsx } from '@udecode/plate-test-utils';
import { createEditorWithMentions } from '../testing/createEditorWithMentions';
import { createEditorWithMentions } from '../__tests__/createEditorWithMentions';
import { mentionOnKeyDownHandler } from './mentionOnKeyDownHandler';

jsx;
Expand Down
2 changes: 1 addition & 1 deletion packages/nodes/mention/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

export * from './createMentionPlugin';
export * from './getMentionOnSelectItem';
export * from './handlers';
export * from './types';
export * from './withMention';
export * from './handlers/index';
export * from './queries/index';
export * from './transforms/index';
2 changes: 1 addition & 1 deletion packages/nodes/mention/src/withMention.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { PlateEditor } from '@udecode/plate-core';
import { jsx } from '@udecode/plate-test-utils';
import { Range, Transforms } from 'slate';
import { createEditorWithMentions } from './testing/createEditorWithMentions';
import { createEditorWithMentions } from './__tests__/createEditorWithMentions';
import { getMentionOnSelectItem } from './getMentionOnSelectItem';
import { withMention } from './withMention';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import {
getPreventDefaultHandler,
isCollapsed,
someNode,
useEventPlateId,
usePlateEditorState,
withPlateProvider,
withPlateEventProvider,
} from '@udecode/plate-core';
import { ToolbarButton, ToolbarButtonProps } from '@udecode/plate-ui-toolbar';

Expand All @@ -14,9 +15,10 @@ export interface AlignToolbarButtonProps extends ToolbarButtonProps {
pluginKey?: string;
}

export const AlignToolbarButton = withPlateProvider(
({ value, pluginKey = KEY_ALIGN, ...props }: AlignToolbarButtonProps) => {
const editor = usePlateEditorState()!;
export const AlignToolbarButton = withPlateEventProvider(
({ id, value, pluginKey = KEY_ALIGN, ...props }: AlignToolbarButtonProps) => {
id = useEventPlateId(id);
const editor = usePlateEditorState(id)!;

return (
<ToolbarButton
Expand Down
Loading

1 comment on commit 289c8e7

@vercel
Copy link

@vercel vercel bot commented on 289c8e7 Mar 13, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.