import { NodeViewContent, NodeViewWrapper } from '@tiptap/react' import React, { useState, useRef, useEffect } from 'react' import Picker from '@emoji-mart/react' import { ArrowRight, ChevronDown, Link, AlignLeft, AlignCenter, AlignRight, Palette } from 'lucide-react' import { twMerge } from 'tailwind-merge' import { useEditorProvider } from '@components/Contexts/Editor/EditorContext' const ButtonsExtension: React.FC = (props: any) => { const [emoji, setEmoji] = useState(props.node.attrs.emoji) const [link, setLink] = useState(props.node.attrs.link) const [alignment, setAlignment] = useState(props.node.attrs.alignment) const [showEmojiPicker, setShowEmojiPicker] = useState(false) const [showLinkInput, setShowLinkInput] = useState(false) const [color, setColor] = useState(props.node.attrs.color || 'blue') const [showColorPicker, setShowColorPicker] = useState(false) const pickerRef = useRef(null) const linkInputRef = useRef(null) const colorPickerRef = useRef(null) const editorState = useEditorProvider() as any const isEditable = editorState.isEditable useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (pickerRef.current && !pickerRef.current.contains(event.target as Node)) { setShowEmojiPicker(false) } if (linkInputRef.current && !linkInputRef.current.contains(event.target as Node)) { setShowLinkInput(false) } if (colorPickerRef.current && !colorPickerRef.current.contains(event.target as Node)) { setShowColorPicker(false) } } document.addEventListener('mousedown', handleClickOutside) return () => { document.removeEventListener('mousedown', handleClickOutside) } }, []) const handleEmojiSelect = (emoji: any) => { setEmoji(emoji.native) setShowEmojiPicker(false) props.updateAttributes({ emoji: emoji.native, }) } const handleLinkChange = (e: React.ChangeEvent) => { setLink(e.target.value) props.updateAttributes({ link: e.target.value, }) } const handleAlignmentChange = (newAlignment: 'left' | 'center' | 'right') => { setAlignment(newAlignment) props.updateAttributes({ alignment: newAlignment, }) } const getAlignmentClass = () => { switch (alignment) { case 'left': return 'text-left'; case 'center': return 'text-center'; case 'right': return 'text-right'; default: return 'text-left'; } } const handleColorSelect = (selectedColor: string) => { setColor(selectedColor) setShowColorPicker(false) props.updateAttributes({ color: selectedColor, }) } const getButtonColor = (color: string) => { switch (color) { case 'sky': return 'bg-sky-500 hover:bg-sky-600'; case 'green': return 'bg-green-500 hover:bg-green-600'; case 'yellow': return 'bg-yellow-500 hover:bg-yellow-600'; case 'red': return 'bg-red-500 hover:bg-red-600'; case 'purple': return 'bg-purple-500 hover:bg-purple-600'; case 'teal': return 'bg-teal-500 hover:bg-teal-600'; case 'amber': return 'bg-amber-500 hover:bg-amber-600'; case 'indigo': return 'bg-indigo-500 hover:bg-indigo-600'; case 'neutral': return 'bg-neutral-500 hover:bg-neutral-600'; default: return 'bg-blue-500 hover:bg-blue-600'; } } const colors = ['sky', 'green', 'yellow', 'red', 'purple', 'teal', 'amber', 'indigo', 'neutral', 'blue'] return (
{isEditable && (
)}
{isEditable && showEmojiPicker && (
)} {isEditable && showLinkInput && ( )} {isEditable && showColorPicker && (
{colors.map((c) => (
)}
) } export default ButtonsExtension