Skip to content

Commit

Permalink
feat: add extension twitter
Browse files Browse the repository at this point in the history
  • Loading branch information
hunghg255 committed Nov 6, 2024
1 parent 33c672c commit 8eda263
Show file tree
Hide file tree
Showing 27 changed files with 485 additions and 4 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ export function getLocaleConfig(lang: string) {
text: 'Mermaid',
link: '/extensions/Mermaid/index.md',
},
{
text: 'Twitter',
link: '/extensions/Twitter/index.md',
},
],
},
]
Expand Down
4 changes: 2 additions & 2 deletions docs/extensions/Mermaid/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
description: Mermaid

next:
text: Mermaid
link: /extensions/Mermaid/index.md
text: Twitter
link: /extensions/Twitter/index.md
---

# Mermaid
Expand Down
21 changes: 21 additions & 0 deletions docs/extensions/Twitter/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
description: Twitter
---

# Twitter

Twitter is a node extension that allows you to add an Twitter to your editor.

- [react-tweet](https://www.npmjs.com/package/react-tweet)

## Usage

```tsx
import { Twitter } from 'reactjs-tiptap-editor'; // [!code ++]

const extensions = [
...,
// Import Extensions Here
Twitter
];
```
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"re-resizable": "^6.10.0",
"react-colorful": "^5.6.1",
"react-image-crop": "^11.0.7",
"react-tweet": "^3.2.1",
"react-visibility-sensor": "^5.1.1",
"scroll-into-view-if-needed": "^3.1.0",
"shiki": "^1.22.1",
Expand Down
4 changes: 3 additions & 1 deletion playground/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import RichTextEditor, {
TaskList,
TextAlign,
TextDirection,
Twitter,
Underline,
Video,
locale,
Expand Down Expand Up @@ -173,9 +174,10 @@ const extensions = [
})
},
}),
Twitter,
]

const DEFAULT = ``
const DEFAULT = `<div data-twitter="" src="https://x.com/cryptocevo/status/1854058823394160878"></div><p dir="auto"></p>`

function debounce(func: any, wait: number) {
let timeout: NodeJS.Timeout
Expand Down
40 changes: 40 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/components/BubbleMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { BubbleMenuExcalidraw } from '@/components/menus/components/BubbleMenuEx
import { BubbleMenuIframe } from '@/components/menus/components/BubbleMenuIframe'
import { ImageGif } from '@/extensions'
import { BubbleMenuMermaid } from '@/components/menus/components/BubbleMenuMermaid'
import { BubbleMenuTwitter } from '@/components/menus/components/BubbleMenuTwitter'

export interface BubbleMenuComponentProps {
editor: Editor
Expand Down Expand Up @@ -36,6 +37,7 @@ export function BubbleMenu({ editor, disabled, bubbleMenu }: BubbleMenuComponent
extensionsNames.includes('excalidraw') && !bubbleMenu?.excalidrawConfig?.hidden ? <BubbleMenuExcalidraw key="excalidraw" editor={editor} disabled={disabled} /> : null,
extensionsNames.includes('mermaid') && !bubbleMenu?.mermaidConfig?.hidden ? <BubbleMenuMermaid key="mermaid" editor={editor} disabled={disabled} /> : null,
extensionsNames.includes('iframe') && !bubbleMenu?.iframeConfig?.hidden ? <BubbleMenuIframe key="iframe" editor={editor} disabled={disabled} /> : null,
extensionsNames.includes('twitter') && !bubbleMenu?.twitterConfig?.hidden ? <BubbleMenuTwitter key="iframe" editor={editor} disabled={disabled} /> : null,
!bubbleMenu?.floatingMenuConfig?.hidden ? <ContentMenu key="content" editor={editor} disabled={disabled} /> : null,
!bubbleMenu?.textConfig?.hidden ? <BubbleMenuText key="text" editor={editor} disabled={disabled} /> : null,
]
Expand Down
1 change: 1 addition & 0 deletions src/components/SizeSetter/SizeSetter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const SizeSetter: React.FC<IProps> = ({ width, maxWidth, height, onOk, ch

function handleSubmit(event: any) {
event.preventDefault()
event.stopPropagation()
onOk(form)
}

Expand Down
5 changes: 5 additions & 0 deletions src/components/icons/Twitter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function Twitter() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" d="m3 21l7.548-7.548M21 3l-7.548 7.548m0 0L8 3H3l7.548 10.452m2.904-2.904L21 21h-5l-5.452-7.548" color="currentColor"></path></svg>
)
}
2 changes: 2 additions & 0 deletions src/components/icons/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import { LeftToRight } from '@/components/icons/LeftToRight'
import { RightToLeft } from '@/components/icons/RightToLeft'
import { GifIcon } from '@/components/icons/GIfIcon'
import { Mermaid } from '@/components/icons/Mermaid'
import { Twitter } from '@/components/icons/Twitter'

export const icons = {
Bold,
Expand Down Expand Up @@ -199,4 +200,5 @@ export const icons = {
ChevronUp,
Crop: CropIcon,
Mermaid,
Twitter,
} as any
97 changes: 97 additions & 0 deletions src/components/menus/components/BubbleMenuTwitter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* eslint-disable react/no-useless-fragment */
import { useCallback, useMemo, useState } from 'react'

import type { Editor } from '@tiptap/react'
import { BubbleMenu } from '@tiptap/react'

import { Twitter } from '@/extensions'
import { ActionButton } from '@/components/ActionButton'
import { useLocale } from '@/locales'
import FormEditLinkTwitter from '@/extensions/Twitter/components/FormEditLinkTwitter'
import { deleteNode } from '@/utils/delete-node'

export interface BubbleMenuTwitterProps {
editor: Editor
disabled?: boolean
}

function BubbleMenuTwitter({ editor, disabled }: BubbleMenuTwitterProps) {
const [showEdit, setShowEdit] = useState(false)
const { t } = useLocale()

const srcInit = useMemo(() => {
const { src } = editor.getAttributes(Twitter.name)
return src as string
}, [editor])

const shouldShow = useCallback(({ editor }: { editor: Editor }) => {
const isActive = editor.isActive(Twitter.name)
return isActive
}, [])

const onSetLink = (src: string) => {
editor.commands.updateTweet({ src })
setShowEdit(false)
}

const deleteMe = useCallback(() => deleteNode(Twitter.name, editor), [editor])

return (
<>
<BubbleMenu
editor={editor}
shouldShow={shouldShow}
tippyOptions={{
popperOptions: {
modifiers: [{ name: 'flip', enabled: false }],
},
placement: 'bottom-start',
offset: [-2, 16],
zIndex: 9999,
onHidden: () => {
setShowEdit(false)
},
}}
>
{disabled
? (
<></>
)
: (
<>
{showEdit
? (
<FormEditLinkTwitter
onSetLink={onSetLink}
editor={editor}
srcInit={srcInit}
/>
)
: (
<div className="richtext-flex richtext-items-center richtext-gap-2 richtext-p-2 richtext-bg-white !richtext-border richtext-rounded-lg richtext-shadow-sm dark:richtext-bg-black richtext-border-neutral-200 dark:richtext-border-neutral-800">
<div className="richtext-flex richtext-flex-nowrap">
<ActionButton
icon="Pencil"
tooltip={t('editor.link.edit.tooltip')}
action={() => {
setShowEdit(true)
}}
tooltipOptions={{ sideOffset: 15 }}
/>
<ActionButton
icon="Trash"
tooltip={t('editor.delete')}
action={deleteMe}
tooltipOptions={{ sideOffset: 15 }}
/>
</div>
</div>
)}
</>
)}
</BubbleMenu>
</>
)
}

export { BubbleMenuTwitter }
1 change: 1 addition & 0 deletions src/extensions/Image/components/ActionImageButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function ActionImageButton(props: any) {
}
function handleLink(e: any) {
e.preventDefault()
e.stopPropagation()

props.editor.chain().focus().setImageInline({ src: link, inline: imageInline }).run()
actionDialogImage.setOpen(false)
Expand Down
1 change: 1 addition & 0 deletions src/extensions/Link/components/LinkEditBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function LinkEditBlock(props: IPropsLinkEditBlock) {

function handleSubmit(event: any) {
event.preventDefault()
event.stopPropagation()
props?.onSetLink(form.link, form.text, openInNewTab)
}

Expand Down
Loading

0 comments on commit 8eda263

Please sign in to comment.