Skip to content

Commit

Permalink
Merge pull request #5 from topthithu/dev
Browse files Browse the repository at this point in the history
v0.0.1
  • Loading branch information
imfelixng authored Apr 3, 2022
2 parents ce4e837 + 6b2e9f0 commit 5a13fef
Show file tree
Hide file tree
Showing 39 changed files with 4,588 additions and 554 deletions.
14 changes: 14 additions & 0 deletions dts.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const postcss = require('rollup-plugin-postcss');

module.exports = {
rollup(config, options) {
config.plugins.push(
postcss({
inject: true,
modules: true,
extract: !!options.writeMeta,
})
);
return config;
},
};
16 changes: 11 additions & 5 deletions example/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import 'react-app-polyfill/ie11';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Thing } from '../.';
import { Box, ChakraProvider } from '@chakra-ui/react';

import { WebEditor } from '../.';

const App = () => {
return (
<div>
<Thing />
</div>
<ChakraProvider>
<Box m={20}>
<WebEditor />
</Box>
<Box m={20}>
<WebEditor hasToolbar={false} />
</Box>
</ChakraProvider>
);
};

Expand Down
714 changes: 714 additions & 0 deletions example/yarn.lock

Large diffs are not rendered by default.

45 changes: 34 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,48 @@
}
],
"devDependencies": {
"@babel/core": "^7.16.7",
"@size-limit/preset-small-lib": "^7.0.5",
"@storybook/addon-essentials": "^6.4.13",
"@babel/core": "^7.17.0",
"@chakra-ui/react": "^1.8.1",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@size-limit/preset-small-lib": "^7.0.8",
"@storybook/addon-essentials": "^6.4.18",
"@storybook/addon-info": "^5.3.21",
"@storybook/addon-links": "^6.4.13",
"@storybook/addons": "^6.4.13",
"@storybook/react": "^6.4.13",
"@storybook/addon-links": "^6.4.18",
"@storybook/addons": "^6.4.18",
"@storybook/react": "^6.4.18",
"@tiptap/extension-underline": "^2.0.0-beta.23",
"@tsconfig/create-react-app": "^1.0.2",
"@tsconfig/recommended": "^1.0.1",
"@types/react": "^17.0.38",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.11",
"babel-loader": "^8.2.3",
"dts-cli": "^1.1.6",
"dts-cli": "^1.2.0",
"framer-motion": "^6",
"husky": "^7.0.4",
"node-sass": "npm:sass",
"postcss": "^8.4.6",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.3.1",
"react-is": "^17.0.2",
"size-limit": "^7.0.5",
"rollup-plugin-postcss": "^4.0.2",
"sass": "^1.49.7",
"size-limit": "^7.0.8",
"tslib": "^2.3.1",
"typescript": "^4.5.4"
"typescript": "^4.5.5"
},
"dependencies": {
"@tiptap/extension-code-block-lowlight": "^2.0.0-beta.68",
"@tiptap/extension-highlight": "^2.0.0-beta.33",
"@tiptap/extension-placeholder": "^2.0.0-beta.48",
"@tiptap/extension-subscript": "^2.0.0-beta.10",
"@tiptap/extension-superscript": "^2.0.0-beta.10",
"@tiptap/extension-task-item": "^2.0.0-beta.31",
"@tiptap/extension-task-list": "^2.0.0-beta.26",
"@tiptap/extension-text-align": "^2.0.0-beta.29",
"@tiptap/react": "^2.0.0-beta.107",
"@tiptap/starter-kit": "^2.0.0-beta.181",
"@tiptap/suggestion": "^2.0.0-beta.90"
}
}
}
112 changes: 112 additions & 0 deletions src/editor/extensions/command-menu.ext/command-list.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Box, Center, HStack, Icon, Square, Text } from '@chakra-ui/react';
import { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { HiOutlineArchive } from 'react-icons/hi';
import styles from './index.module.scss';

const CommandList = forwardRef<any, any>((props, ref) => {
const [selectedIndex, setSelectedIndex] = useState(0);

const selectItem = (index: number) => {
const item = props.items[index];

if (item) {
props.command({ id: item });
}
};

const upHandler = () => {
setSelectedIndex(
(selectedIndex + props.items.length - 1) % props.items.length
);
};

const downHandler = () => {
setSelectedIndex((selectedIndex + 1) % props.items.length);
};

const enterHandler = () => {
selectItem(selectedIndex);
};

useEffect(() => setSelectedIndex(0), [props.items]);

useEffect(() => {
const commandElm = document.querySelector(
`#command-suggestion__item-${selectedIndex}`
);
commandElm?.scrollIntoView();
}, [selectedIndex]);

useImperativeHandle(ref, () => ({
onKeyDown: ({ event }: any) => {
if (event.key === 'ArrowUp') {
upHandler();
return true;
}

if (event.key === 'ArrowDown') {
downHandler();
return true;
}

if (event.key === 'Enter') {
enterHandler();
return true;
}

return false;
},
}));

return (
<Box
shadow="base"
rounded="base"
borderWidth={1}
bg="white"
w="300px"
maxH="300px"
overflow="auto"
className={styles['command-list-container']}
>
{props.items.length ? (
props.items.map((item: any, index: number) => (
<HStack
id={`command-suggestion__item-${index}`}
key={index}
onClick={() => selectItem(index)}
bg={index === selectedIndex ? 'gray.100' : 'inherit'}
_hover={{
bg: 'gray.50',
cursor: 'pointer',
}}
align="center"
px={4}
py={2}
>
<Square p={2} borderWidth={1} rounded="base" bg="white">
<Icon as={item.icon} boxSize={6} color="gray.600" />
</Square>
<Box flex={1}>
<Text>{item.title}</Text>
{item.desc && (
<Text color="gray.400" fontSize="sm">
{item.desc}
</Text>
)}
</Box>
</HStack>
))
) : (
<Center flexDir="column" px={4} py={2}>
<Icon as={HiOutlineArchive} boxSize={6} color="gray.500" />
<Text fontSize="sm" color="gray.400">
No results
</Text>
</Center>
)}
</Box>
);
});

export default CommandList;
157 changes: 157 additions & 0 deletions src/editor/extensions/command-menu.ext/command-suggestion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import tippy from 'tippy.js';
import { ReactRenderer } from '@tiptap/react';
import {
MdFormatQuote,
MdLooks3,
MdLooks4,
MdLooks5,
MdLooks6,
MdLooksOne,
MdLooksTwo,
} from 'react-icons/md';

import CommandList from './command-list';

export const CommandSuggestion = {
items: ({ query }: { query: string }) => {
return [
{
title: 'H1',
desc: 'Heading 1',
icon: MdLooksOne,
command: ({ editor, range }: any) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', { level: 1 })
.run();
},
},
{
title: 'H2',
desc: 'Heading 2',
icon: MdLooksTwo,
command: ({ editor, range }: any) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', { level: 2 })
.run();
},
},
{
title: 'H3',
desc: 'Heading 3',
icon: MdLooks3,
command: ({ editor, range }: any) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', { level: 3 })
.run();
},
},
{
title: 'H4',
desc: 'Heading 4',
icon: MdLooks4,
command: ({ editor, range }: any) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', { level: 4 })
.run();
},
},
{
title: 'H5',
desc: 'Heading 5',
icon: MdLooks5,
command: ({ editor, range }: any) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', { level: 5 })
.run();
},
},
{
title: 'H6',
desc: 'Heading 6',
icon: MdLooks6,
command: ({ editor, range }: any) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', { level: 6 })
.run();
},
},
{
title: 'Quote',
desc: 'Capture a quote',
icon: MdFormatQuote,
command: ({ editor, range }: any) => {
editor.chain().focus().deleteRange(range).toggleBlockquote().run();
},
},
]
.filter((item) =>
item.title.toLowerCase().startsWith(query.toLowerCase())
)
.slice(0, 10);
},

render: () => {
let component: any;
let popup: any;

return {
onStart: (props: any) => {
component = new ReactRenderer(CommandList, {
props,
editor: props.editor,
});

popup = tippy('body', {
getReferenceClientRect: props.clientRect,
appendTo: () => document.body,
content: component.element,
showOnCreate: true,
interactive: true,
trigger: 'manual',
placement: 'bottom-start',
});
},

onUpdate(props: any) {
component.updateProps(props);

popup[0].setProps({
getReferenceClientRect: props.clientRect,
});
},

onKeyDown(props: any) {
if (props.event.key === 'Escape') {
popup[0].hide();

return true;
}

return component.ref?.onKeyDown(props);
},

onExit() {
popup[0].destroy();
component.destroy();
},
};
},
};
21 changes: 21 additions & 0 deletions src/editor/extensions/command-menu.ext/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.command-list-container {

&::-webkit-scrollbar {
background-color: #fff;
width: 16px;
padding: 0px;
}

&::-webkit-scrollbar-track {
background-color: #fff;
}

&::-webkit-scrollbar-thumb {
background-color: #babac0;
border: 4px solid #fff;
}

&::-webkit-scrollbar-button {
display: none;
}
}
Loading

0 comments on commit 5a13fef

Please sign in to comment.