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

Refactor/toc #3586

Merged
merged 3 commits into from
Sep 28, 2024
Merged
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
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