Move Lexical styles to tailwind

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak
2023-03-28 17:42:16 +02:00
parent 6b2109735d
commit 4ccfab3e5e
4 changed files with 91 additions and 419 deletions

View File

@ -157,11 +157,15 @@ const FloatingLinkEditor = ({
}, [isEditMode]);
return (
<div ref={editorRef} className='link-editor'>
<div className='link-input'>
<div
ref={editorRef}
className='absolute top-0 left-0 z-10 w-full max-w-sm rounded-lg bg-white opacity-0 shadow-md transition-opacity will-change-transform'
>
<div className='relative my-2 mx-3 box-border block rounded-2xl border-0 bg-gray-100 py-2 px-3 text-sm text-gray-800 outline-0 dark:bg-gray-800 dark:text-gray-100'>
{isEditMode ? (
<>
<input
className='-my-2 -mx-3 w-full border-0 bg-transparent py-2 px-3 text-sm text-gray-900 outline-0'
ref={inputRef}
value={linkUrl}
onChange={(event) => {
@ -188,7 +192,7 @@ const FloatingLinkEditor = ({
}}
/>
<div
className='link-edit'
className='absolute inset-y-0 right-0 flex w-9 cursor-pointer items-center justify-center'
role='button'
tabIndex={0}
onMouseDown={(event) => event.preventDefault()}
@ -201,11 +205,11 @@ const FloatingLinkEditor = ({
</>
) : (
<>
<a href={linkUrl} target='_blank' rel='noopener noreferrer'>
<a className='mr-8 block overflow-hidden text-ellipsis whitespace-nowrap text-primary-600 no-underline hover:underline dark:text-accent-blue' href={linkUrl} target='_blank' rel='noopener noreferrer'>
{linkUrl}
</a>
<div
className='link-edit'
className='absolute inset-y-0 right-0 flex w-9 cursor-pointer items-center justify-center'
role='button'
tabIndex={0}
onMouseDown={(event) => event.preventDefault()}

View File

@ -80,6 +80,24 @@ const blockTypeToBlockName = {
quote: 'Quote',
};
interface IToolbarButton extends React.HTMLAttributes<HTMLButtonElement> {
active?: boolean
icon: string
}
const ToolbarButton: React.FC<IToolbarButton> = ({ active, icon, ...props }) => (
<button
className={clsx(
'flex cursor-pointer rounded-lg border-0 bg-none p-1 align-middle hover:bg-gray-100 disabled:cursor-not-allowed disabled:hover:bg-none hover:dark:bg-primary-700',
{ 'bg-gray-100/30 dark:bg-gray-800/30': active },
)}
type='button'
{...props}
>
<Icon className='h-5 w-5' src={icon} />
</button>
);
const BlockTypeDropdown = ({ editor, anchorElem, blockType, icon }: {
editor: LexicalEditor
anchorElem: HTMLElement
@ -172,70 +190,56 @@ const BlockTypeDropdown = ({ editor, anchorElem, blockType, icon }: {
<>
<button
onClick={() => setShowDropDown(!showDropDown)}
className='popup-item spaced relative'
className='relative flex cursor-pointer rounded-lg border-0 bg-none p-1 align-middle hover:bg-gray-100 disabled:cursor-not-allowed disabled:hover:bg-none hover:dark:bg-primary-700'
aria-label=''
type='button'
>
<Icon src={icon} />
<Icon src={require('@tabler/icons/chevron-down.svg')} className='-bottom-2 h-4 w-4' />
{showDropDown && (
<div className='floating-text-format-popup' style={{ opacity: 1, top: 36 }}>
<button
<div
className='absolute top-9 left-0 z-10 flex h-[38px] gap-0.5 rounded-lg bg-white p-1 shadow-lg transition-[opacity] dark:bg-gray-900'
>
<ToolbarButton
onClick={formatParagraph}
className={clsx('popup-item spaced', blockType === 'paragraph' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.paragraph} />
</button>
<button
active={blockType === 'paragraph'}
icon={blockTypeToIcon.paragraph}
/>
<ToolbarButton
onClick={() => formatHeading('h1')}
className={clsx('popup-item spaced', blockType === 'h1' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.h1} />
</button>
<button
active={blockType === 'h1'}
icon={blockTypeToIcon.h1}
/>
<ToolbarButton
onClick={() => formatHeading('h2')}
className={clsx('popup-item spaced', blockType === 'h2' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.h2} />
</button>
<button
active={blockType === 'h2'}
icon={blockTypeToIcon.h2}
/>
<ToolbarButton
onClick={() => formatHeading('h3')}
className={clsx('popup-item spaced', blockType === 'h3' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.h3} />
</button>
<button
active={blockType === 'h3'}
icon={blockTypeToIcon.h3}
/>
<ToolbarButton
onClick={formatBulletList}
className={clsx('popup-item spaced', blockType === 'bullet' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.bullet} />
</button>
<button
active={blockType === 'bullet'}
icon={blockTypeToIcon.bullet}
/>
<ToolbarButton
onClick={formatNumberedList}
className={clsx('popup-item spaced', blockType === 'number' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.number} />
</button>
<button
active={blockType === 'number'}
icon={blockTypeToIcon.number}
/>
<ToolbarButton
onClick={formatQuote}
className={clsx('popup-item spaced', blockType === 'quote' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.quote} />
</button>
<button
active={blockType === 'quote'}
icon={blockTypeToIcon.quote}
/>
<ToolbarButton
onClick={formatCode}
className={clsx('popup-item spaced', blockType === 'code' && 'active')}
type='button'
>
<Icon src={blockTypeToIcon.code} />
</button>
active={blockType === 'code'}
icon={blockTypeToIcon.code}
/>
</div>
)}
</button>
@ -344,7 +348,10 @@ const TextFormatFloatingToolbar = ({
}, [editor, updateTextFormatFloatingToolbar]);
return (
<div ref={popupCharStylesEditorRef} className='floating-text-format-popup'>
<div
ref={popupCharStylesEditorRef}
className='absolute top-0 left-0 z-10 flex h-[38px] gap-0.5 rounded-lg bg-white p-1 opacity-0 shadow-lg transition-[opacity] dark:bg-gray-900'
>
{editor.isEditable() && (
<>
<BlockTypeDropdown
@ -353,64 +360,52 @@ const TextFormatFloatingToolbar = ({
blockType={blockType}
icon={blockTypeToIcon[blockType]}
/>
<button
<ToolbarButton
onClick={() => {
editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold');
}}
className={'popup-item spaced ' + (isBold ? 'active' : '')}
active={isBold}
aria-label='Format text as bold'
type='button'
>
<Icon src={require('@tabler/icons/bold.svg')} />
</button>
<button
icon={require('@tabler/icons/bold.svg')}
/>
<ToolbarButton
onClick={() => {
editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'italic');
}}
className={'popup-item spaced ' + (isItalic ? 'active' : '')}
active={isItalic}
aria-label='Format text as italics'
type='button'
>
<Icon src={require('@tabler/icons/italic.svg')} />
</button>
<button
icon={require('@tabler/icons/italic.svg')}
/>
<ToolbarButton
onClick={() => {
editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'underline');
}}
className={'popup-item spaced ' + (isUnderline ? 'active' : '')}
active={isUnderline}
aria-label='Format text to underlined'
type='button'
>
<Icon src={require('@tabler/icons/underline.svg')} />
</button>
<button
icon={require('@tabler/icons/underline.svg')}
/>
<ToolbarButton
onClick={() => {
editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough');
}}
className={'popup-item spaced ' + (isStrikethrough ? 'active' : '')}
active={isStrikethrough}
aria-label='Format text with a strikethrough'
type='button'
>
<Icon src={require('@tabler/icons/strikethrough.svg')} />
</button>
<button
icon={require('@tabler/icons/strikethrough.svg')}
/>
<ToolbarButton
onClick={() => {
editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'code');
}}
className={'popup-item spaced ' + (isCode ? 'active' : '')}
active={isCode}
aria-label='Insert code block'
type='button'
>
<Icon src={require('@tabler/icons/code.svg')} />
</button>
<button
icon={require('@tabler/icons/code.svg')}
/>
<ToolbarButton
onClick={insertLink}
className={'popup-item spaced ' + (isLink ? 'active' : '')}
active={isLink}
aria-label='Insert link'
type='button'
>
<Icon src={require('@tabler/icons/link.svg')} />
</button>
icon={require('@tabler/icons/link.svg')}
/>
</>
)}
</div>