Skip to content

Commit

Permalink
Merge pull request #3586 from udecode/refactor/toc
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfeng33 authored Sep 28, 2024
2 parents 98163e1 + 8cffd67 commit a0de445
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/giant-deers-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@udecode/plate-heading': patch
---

Remove useless props move config from `useTocElementState` to TocPlugin `options`
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { CodeBlockPlugin } from '@udecode/plate-code-block/react';
import { insertEmptyElement } from '@udecode/plate-common';
import { ParagraphPlugin, focusEditor } from '@udecode/plate-common/react';
import { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';
import { HEADING_KEYS } from '@udecode/plate-heading';
import { HEADING_KEYS, insertToc } from '@udecode/plate-heading';
import { TocPlugin } from '@udecode/plate-heading/react';
import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
import { toggleIndentList } from '@udecode/plate-indent-list';
import { IndentListPlugin } from '@udecode/plate-indent-list/react';
Expand Down Expand Up @@ -117,6 +118,12 @@ const items = [
label: 'Columns',
value: ColumnPlugin.key,
},
{
description: 'Table of Contents',
icon: Icons.h3,
label: 'Table of Contents',
value: TocPlugin.key,
},
],
label: 'Basic blocks',
},
Expand Down Expand Up @@ -241,6 +248,11 @@ export function PlaygroundInsertDropdownMenu(props: DropdownMenuProps) {

break;
}
case TocPlugin.key: {
insertToc(editor);

break;
}
default: {
insertEmptyElement(editor, type, {
nextBlock: true,
Expand Down
3 changes: 3 additions & 0 deletions apps/www/src/lib/plate/create-plate-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { EmojiInputPlugin } from '@udecode/plate-emoji/react';
import { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';
import { FindReplacePlugin } from '@udecode/plate-find-replace';
import { HEADING_KEYS } from '@udecode/plate-heading';
import { TocPlugin } from '@udecode/plate-heading/react';
import { HighlightPlugin } from '@udecode/plate-highlight/react';
import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
import { KbdPlugin } from '@udecode/plate-kbd/react';
Expand Down Expand Up @@ -84,6 +85,7 @@ import {
} from '@/registry/default/plate-ui/table-cell-element';
import { TableElement } from '@/registry/default/plate-ui/table-element';
import { TableRowElement } from '@/registry/default/plate-ui/table-row-element';
import { TocElement } from '@/registry/default/plate-ui/toc-element';
import { TodoListElement } from '@/registry/default/plate-ui/todo-list-element';
import { ToggleElement } from '@/registry/default/plate-ui/toggle-element';
import { withDraggables } from '@/registry/default/plate-ui/with-draggables';
Expand Down Expand Up @@ -133,6 +135,7 @@ export const createPlateUI = ({
[TableCellPlugin.key]: TableCellElement,
[TablePlugin.key]: TableElement,
[TableRowPlugin.key]: TableRowElement,
[TocPlugin.key]: TocElement,
[TodoListPlugin.key]: TodoListElement,
[TogglePlugin.key]: ToggleElement,
[UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),
Expand Down
9 changes: 8 additions & 1 deletion apps/www/src/registry/default/example/playground-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
FontSizePlugin,
} from '@udecode/plate-font/react';
import { HEADING_KEYS } from '@udecode/plate-heading';
import { HeadingPlugin } from '@udecode/plate-heading/react';
import { HeadingPlugin, TocPlugin } from '@udecode/plate-heading/react';
import { HighlightPlugin } from '@udecode/plate-highlight/react';
import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
import { IndentPlugin } from '@udecode/plate-indent/react';
Expand Down Expand Up @@ -120,6 +120,13 @@ export const usePlaygroundEditor = (id: any = '', scrollSelector?: string) => {
plugins: [
// Nodes
HeadingPlugin,
TocPlugin.configure({
options: {
isScroll: true,
scrollContainerSelector: `#${scrollSelector}`,
topOffset: 80,
},
}),
BlockquotePlugin,
CodeBlockPlugin.configure({
options: {
Expand Down
56 changes: 56 additions & 0 deletions apps/www/src/registry/default/plate-ui/toc-element.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { cn } from '@udecode/cn';
import { PlateElement } from '@udecode/plate-common/react';
import {
useTocElement,
useTocElementState,
} from '@udecode/plate-heading/react';
import { withRef } from '@udecode/react-utils';
import { cva } from 'class-variance-authority';

import { Button } from './button';

const headingItemVariants = cva(
'block h-auto w-full cursor-pointer truncate rounded-none px-0.5 py-1.5 text-left font-medium text-muted-foreground underline decoration-[0.5px] underline-offset-4 hover:bg-accent hover:text-muted-foreground',
{
variants: {
depth: {
1: 'pl-0.5',
2: 'pl-[26px]',
3: 'pl-[50px]',
},
},
}
);

export const TocElement = withRef<typeof PlateElement>(
({ children, className, ...props }, ref) => {
const state = useTocElementState();

const { props: btnProps } = useTocElement(state);

const { headingList } = state;

return (
<PlateElement
ref={ref}
className={cn('relative mb-1 p-0', className)}
{...props}
>
<nav contentEditable={false}>
{headingList.map((item) => (
<Button
key={item.id}
variant="ghost"
className={cn(headingItemVariants({ depth: item.depth as any }))}
onClick={(e) => btnProps.onClick(e, item, 'smooth')}
aria-current
>
{item.title}
</Button>
))}
</nav>
{children}
</PlateElement>
);
}
);
8 changes: 8 additions & 0 deletions packages/heading/src/lib/BaseTocPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ import type { Heading } from './types';
export type TocConfig = PluginConfig<
'toc',
{
isScroll: boolean;
topOffset: number;
queryHeading?: (editor: SlateEditor) => Heading[];
scrollContainerSelector?: string;
}
>;

export const BaseTocPlugin = createTSlatePlugin<TocConfig>({
key: 'toc',
node: { isElement: true, isVoid: true },
options: {
isScroll: true,
scrollContainerSelector: '#scroll_container',
topOffset: 80,
},
});
3 changes: 0 additions & 3 deletions packages/heading/src/react/hooks/useTocController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,18 @@ import { useTocObserver } from './useTocObserver';
interface UseTocController {
activeId: string;
isObserve: boolean;
showHeader: boolean;
tocRef: React.RefObject<HTMLElement>;
}

export const useTocController = ({
activeId,
isObserve,
showHeader,
tocRef,
}: UseTocController) => {
const [activeTocId, setActiveTocId] = React.useState('');
const { offset, visible } = useTocObserver({
activeId: activeTocId,
isObserve,
showHeader,
tocRef,
});

Expand Down
18 changes: 5 additions & 13 deletions packages/heading/src/react/hooks/useTocElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,19 @@ import React, { useEffect } from 'react';
import { getNode } from '@udecode/plate-common';
import {
toDOMNode,
useEditorRef,
useEditorPlugin,
useEditorSelector,
} from '@udecode/plate-common/react';

import type { Heading } from '../../lib/types';

import { getHeadingList } from '../../internal/getHeadingList';
import { TocPlugin } from '../TocPlugin';
import { heightToTop } from '../utils';

export type useTocElementStateProps = {
isScroll: boolean;
topOffset: number;
scrollContainerSelector?: string;
};

export const useTocElementState = ({
isScroll,
scrollContainerSelector,
topOffset,
}: useTocElementStateProps) => {
const editor = useEditorRef();
export const useTocElementState = () => {
const { editor, getOptions } = useEditorPlugin(TocPlugin);
const { isScroll, scrollContainerSelector, topOffset } = getOptions();

const headingList = useEditorSelector(getHeadingList, []);

Expand Down
1 change: 0 additions & 1 deletion packages/heading/src/react/hooks/useTocObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from 'react';
interface UseTocObserver {
activeId: string;
isObserve: boolean;
showHeader: boolean;
tocRef: React.RefObject<HTMLElement>;
}

Expand Down
24 changes: 13 additions & 11 deletions packages/heading/src/react/hooks/useTocSideBarState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import { getNode } from '@udecode/plate-common';
import {
toDOMNode,
useEditorRef,
useEditorPlugin,
useEditorSelector,
} from '@udecode/plate-common/react';

Expand All @@ -12,19 +12,25 @@ import type { TocSideBarProps } from '../types';

import { useContentController, useTocController } from '.';
import { getHeadingList } from '../../internal/getHeadingList';
import { TocPlugin } from '../TocPlugin';
import { checkIn } from '../utils';

export const useTocSideBarState = ({
containerRef,
open = true,
rootMargin = '0px 0px 0px 0px',
showHeader = true,
style,
topOffset = 0,
onOpenChange,
}: TocSideBarProps) => {
const editor = useEditorRef();
const { editor, getOptions } = useEditorPlugin(TocPlugin);
const { scrollContainerSelector } = getOptions();
const headingList = useEditorSelector(getHeadingList, []);
const scrollContainerRef = React.useRef<HTMLDivElement | null>(null);

React.useEffect(() => {
scrollContainerRef.current = document.querySelector(
scrollContainerSelector ?? '#scroll_container'
)!;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const tocRef = React.useRef<HTMLElement>(null);

Expand All @@ -33,7 +39,7 @@ export const useTocSideBarState = ({
const [isObserve, setIsObserve] = React.useState(open);

const { activeContentId, onContentScroll } = useContentController({
containerRef,
containerRef: scrollContainerRef,
isObserve,
rootMargin,
topOffset,
Expand All @@ -42,7 +48,6 @@ export const useTocSideBarState = ({
useTocController({
activeId: activeContentId,
isObserve,
showHeader,
tocRef,
});

Expand All @@ -54,11 +59,8 @@ export const useTocSideBarState = ({
open,
setIsObserve,
setMouseInToc,
showHeader,
style,
tocRef,
onContentScroll,
onOpenChange,
};
};

Expand Down
5 changes: 0 additions & 5 deletions packages/heading/src/react/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
export interface TocSideBarProps {
containerRef: React.RefObject<HTMLDivElement>;
className?: string;
onOpenChange?: (open: boolean) => void;
open?: boolean;
rootMargin?: string;
showHeader?: boolean;
style?: React.CSSProperties;
topOffset?: number;
}

Expand Down
14 changes: 7 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6215,14 +6215,14 @@ __metadata:
languageName: unknown
linkType: soft

"@udecode/plate-docx@npm:38.0.8, @udecode/plate-docx@workspace:^, @udecode/plate-docx@workspace:packages/docx":
"@udecode/plate-docx@npm:38.0.10, @udecode/plate-docx@workspace:^, @udecode/plate-docx@workspace:packages/docx":
version: 0.0.0-use.local
resolution: "@udecode/plate-docx@workspace:packages/docx"
dependencies:
"@udecode/plate-common": "workspace:^"
"@udecode/plate-heading": "npm:38.0.1"
"@udecode/plate-indent": "npm:38.0.1"
"@udecode/plate-indent-list": "npm:38.0.1"
"@udecode/plate-indent-list": "npm:38.0.10"
"@udecode/plate-media": "npm:38.0.6"
"@udecode/plate-table": "npm:38.0.8"
validator: "npm:^13.12.0"
Expand Down Expand Up @@ -6389,7 +6389,7 @@ __metadata:
languageName: unknown
linkType: soft

"@udecode/plate-indent-list@npm:38.0.1, @udecode/plate-indent-list@workspace:^, @udecode/plate-indent-list@workspace:packages/indent-list":
"@udecode/plate-indent-list@npm:38.0.10, @udecode/plate-indent-list@workspace:^, @udecode/plate-indent-list@workspace:packages/indent-list":
version: 0.0.0-use.local
resolution: "@udecode/plate-indent-list@workspace:packages/indent-list"
dependencies:
Expand Down Expand Up @@ -6695,7 +6695,7 @@ __metadata:
languageName: unknown
linkType: soft

"@udecode/plate-selection@npm:38.0.9, @udecode/plate-selection@workspace:^, @udecode/plate-selection@workspace:packages/selection":
"@udecode/plate-selection@npm:38.0.11, @udecode/plate-selection@workspace:^, @udecode/plate-selection@workspace:packages/selection":
version: 0.0.0-use.local
resolution: "@udecode/plate-selection@workspace:packages/selection"
dependencies:
Expand Down Expand Up @@ -6913,7 +6913,7 @@ __metadata:
"@udecode/plate-common": "npm:38.0.6"
"@udecode/plate-csv": "npm:38.0.8"
"@udecode/plate-diff": "npm:38.0.0"
"@udecode/plate-docx": "npm:38.0.8"
"@udecode/plate-docx": "npm:38.0.10"
"@udecode/plate-find-replace": "npm:38.0.0"
"@udecode/plate-floating": "npm:38.0.1"
"@udecode/plate-font": "npm:38.0.1"
Expand All @@ -6922,7 +6922,7 @@ __metadata:
"@udecode/plate-horizontal-rule": "npm:38.0.1"
"@udecode/plate-html": "npm:38.0.1"
"@udecode/plate-indent": "npm:38.0.1"
"@udecode/plate-indent-list": "npm:38.0.1"
"@udecode/plate-indent-list": "npm:38.0.10"
"@udecode/plate-kbd": "npm:38.0.1"
"@udecode/plate-layout": "npm:38.0.1"
"@udecode/plate-line-height": "npm:38.0.1"
Expand All @@ -6936,7 +6936,7 @@ __metadata:
"@udecode/plate-reset-node": "npm:38.0.1"
"@udecode/plate-resizable": "npm:38.0.0"
"@udecode/plate-select": "npm:38.0.1"
"@udecode/plate-selection": "npm:38.0.9"
"@udecode/plate-selection": "npm:38.0.11"
"@udecode/plate-slash-command": "npm:38.0.1"
"@udecode/plate-suggestion": "npm:38.0.1"
"@udecode/plate-tabbable": "npm:38.0.1"
Expand Down

0 comments on commit a0de445

Please sign in to comment.