From ba6826c51a320488ceb85ff7903994fa63d37a3b Mon Sep 17 00:00:00 2001 From: Brian Ingles Date: Fri, 25 Sep 2020 08:43:12 -0500 Subject: [PATCH] Attempt at virtual scrolling --- src/stories/Editor/Editor.stories.tsx | 25 +++--- src/stories/Editor/EditorVirtualScrolling.tsx | 81 +++++++++++++++++++ 2 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 src/stories/Editor/EditorVirtualScrolling.tsx diff --git a/src/stories/Editor/Editor.stories.tsx b/src/stories/Editor/Editor.stories.tsx index a1a4b62..f325863 100644 --- a/src/stories/Editor/Editor.stories.tsx +++ b/src/stories/Editor/Editor.stories.tsx @@ -7,9 +7,12 @@ import EditorWithSpellcheck, { import EditorWithDecorations, { EditorWithDecorationsProps, } from './EditorWithDecorations' +import EditorVirtualScrolling, { + EditorVirtualScrollingProps, +} from './EditorVirtualScrolling' const meta: Meta = { - title: 'Example/Editor', + title: 'Editor', component: EditorWithDecorations, argTypes: { initialValue: { control: 'object' }, @@ -18,13 +21,17 @@ const meta: Meta = { export default meta -// const Template: Story = (args) => +/** Templates */ + const SpellcheckTemplate: Story = (args) => ( ) const DecorationsTemplate: Story = (args) => ( ) +const VirtualScrollingTemplate: Story = (args) => ( + +) const emptyValue = () => [ { @@ -32,17 +39,17 @@ const emptyValue = () => [ }, ] -// export const Empty = Template.bind({}) -// Empty.args = { -// initialValue: emptyValue(), -// } - export const Decorations = DecorationsTemplate.bind({}) Decorations.args = { initialValue: emptyValue(), } -export const Spellcheck = SpellcheckTemplate.bind({}) -Spellcheck.args = { +export const CustomSpellcheck = SpellcheckTemplate.bind({}) +CustomSpellcheck.args = { + initialValue: emptyValue(), +} + +export const VirtualScrolling = VirtualScrollingTemplate.bind({}) +VirtualScrolling.args = { initialValue: emptyValue(), } diff --git a/src/stories/Editor/EditorVirtualScrolling.tsx b/src/stories/Editor/EditorVirtualScrolling.tsx new file mode 100644 index 0000000..11ccfd5 --- /dev/null +++ b/src/stories/Editor/EditorVirtualScrolling.tsx @@ -0,0 +1,81 @@ +/** @jsx jsx */ +/** @jsxFrag React.Fragment */ +import { css, jsx } from '@emotion/core' + +import React from 'react' +import { createEditor, Node, NodeEntry, Range } from 'slate' +import { Editable, RenderElementProps, Slate, withReact } from 'slate-react' + +const componentCss = css` + [contenteditable='true'] { + border: 1px solid #ccc; + padding: 4px; + } +` + +export interface EditorVirtualScrollingProps { + initialValue: Node[] +} + +const EditorVirtualScrolling: React.FC = ({ + initialValue, +}) => { + const editor = React.useMemo(() => withReact(createEditor()), []) + const [value, setValue] = React.useState(initialValue) + const virtualValue = React.useMemo(() => value.slice(0, 2), [value]) + + const decorate = React.useCallback(([node, path]: NodeEntry) => { + const ranges: Range[] = [] + + if (path.length === 1 && path[0] < 3) { + ranges.push({ + anchor: { path, offset: 0 }, + focus: { path, offset: 2 }, + virtual: true, + }) + } + + return ranges + }, []) + + const renderElement = React.useCallback( + ({ element, attributes, children }: RenderElementProps) => { + return ( +
+ {children} +
+ ) + }, + [] + ) + + return ( +
+ + + +
+ ) +} + +export default EditorVirtualScrolling + +// interface VirtualDocumentProps {} + +// const VirtualDocument: React.FC = React.forwardRef< +// HTMLDivElement, +// VirtualDocumentProps +// >(({ children, ...props }, ref) => { +// console.log(props, children) +// return ( +//
+//
Blah
+// {children} +//
Bleh
+//
+// ) +// })