Last active
July 17, 2023 22:09
-
-
Save leurdo/e92daf168fbe29b02807506dfcadd3f0 to your computer and use it in GitHub Desktop.
Gutenberg Rich Editor button for tooltip
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { registerFormatType, applyFormat, toggleFormat } from '@wordpress/rich-text'; | |
import { useSelect } from '@wordpress/data'; | |
import { BlockControls, MediaUpload, MediaUploadCheck } from '@wordpress/block-editor'; | |
import { Button, TextControl, ToolbarGroup, ToolbarButton, Modal, TextareaControl } from '@wordpress/components'; | |
import { useState } from '@wordpress/element'; | |
import { comment } from '@wordpress/icons'; | |
import { | |
Card, | |
CardHeader, | |
CardBody, | |
CardFooter, | |
__experimentalHeading as Heading, | |
} from '@wordpress/components'; | |
function ImagePopover( { setShowPopover, activeAttributes, onChange, value, popoverAnchor } ) { | |
const getTooltipContent = (link, header, subheading, imageUrl, description, timage) => { | |
let output = ''; | |
if (header) { | |
output += `<div class='line-heading overflow-hidden'> | |
<h3>${header}</h3> | |
</div>`; | |
} | |
if (subheading) { | |
output += `<div class='font-jetbrains'><strong>${subheading}</strong></div>`; | |
} | |
if (description) { | |
output += `<p>${description}</p>`; | |
} | |
if (link) { | |
output += `<a href='${link}' target='_blank'>открыть в новой вкладке -></a>`; | |
} | |
if (imageUrl) { | |
output += `<img class='d-inline-block w-100' src='${imageUrl}' alt='tooltip image'>`; | |
} | |
const newVal = applyFormat( | |
value, | |
{ | |
type: 'engineer/img-link-tooltip', | |
attributes: { | |
'data-bs-title': output, | |
'data-bs-toggle': 'tooltip', | |
'href': 'javascript:void(0);', | |
'data-timage': timage, | |
'data-timageurl': imageUrl, | |
'data-tlink': link, | |
'data-theader': header, | |
'data-tsubheading': subheading, | |
'data-tdescription': description, | |
'data-extra-class': '--big-tooltip' | |
+ (header ? ' heading-tooltip-show' : '' ) | |
+ (imageUrl ? ' img-link-tooltip-show' : '' ) | |
} | |
} | |
); | |
onChange( newVal ); | |
} | |
const onTextChange = (text, activeAttributes, type ) => { | |
const timage = activeAttributes[ 'data-timage' ] ? activeAttributes[ 'data-timage' ] : ''; | |
const timageurl = activeAttributes[ 'data-timageurl' ] ? activeAttributes[ 'data-timageurl' ] : ''; | |
let theader = activeAttributes[ 'data-theader' ] ? activeAttributes[ 'data-theader' ] : ''; | |
let tsubheading = activeAttributes[ 'data-tsubheading' ] ? activeAttributes[ 'data-tsubheading' ] : ''; | |
const tdescription = activeAttributes[ 'data-tdescription' ] ? activeAttributes[ 'data-tdescription' ] : ''; | |
let tlink = activeAttributes[ 'data-tlink' ] ? activeAttributes[ 'data-tlink' ] : ''; | |
switch (type) { | |
case 'link': | |
tlink = text; | |
break; | |
case 'theader': | |
theader = text; | |
break; | |
default: // tsubheading | |
tsubheading = text; | |
break; | |
} | |
getTooltipContent( tlink, theader, tsubheading, timageurl, tdescription, timage ); | |
} | |
const onTextareaChange = ( text, activeAttributes ) => { | |
const timage = activeAttributes[ 'data-timage' ] ? activeAttributes[ 'data-timage' ] : ''; | |
const timageurl = activeAttributes[ 'data-timageurl' ] ? activeAttributes[ 'data-timageurl' ] : ''; | |
const theader = activeAttributes[ 'data-theader' ] ? activeAttributes[ 'data-theader' ] : ''; | |
const tsubheading = activeAttributes[ 'data-tsubheading' ] ? activeAttributes[ 'data-tsubheading' ] : ''; | |
const tdescription = text; | |
const tlink = activeAttributes[ 'data-tlink' ] ? activeAttributes[ 'data-tlink' ] : ''; | |
getTooltipContent( tlink, theader, tsubheading, timageurl, tdescription, timage ); | |
} | |
const onImageRemove = (e) => { | |
e.stopPropagation(); | |
const timage = ''; | |
const timageurl = ''; | |
const theader = activeAttributes[ 'data-theader' ] ? activeAttributes[ 'data-theader' ] : ''; | |
const tsubheading = activeAttributes[ 'data-tsubheading' ] ? activeAttributes[ 'data-tsubheading' ] : ''; | |
const tdescription = activeAttributes[ 'data-tdescription' ] ? activeAttributes[ 'data-tdescription' ] : ''; | |
let tlink = activeAttributes[ 'data-tlink' ] ? activeAttributes[ 'data-tlink' ] : ''; | |
getTooltipContent( tlink, theader, tsubheading, timageurl, tdescription, timage ); | |
} | |
const onImageSelect = ( image ) => { | |
const timage = image.id.toString(); | |
const timageurl = image.url; | |
const theader = activeAttributes[ 'data-theader' ] ? activeAttributes[ 'data-theader' ] : ''; | |
const tsubheading = activeAttributes[ 'data-tsubheading' ] ? activeAttributes[ 'data-tsubheading' ] : ''; | |
const tdescription = activeAttributes[ 'data-tdescription' ] ? activeAttributes[ 'data-tdescription' ] : ''; | |
let tlink = activeAttributes[ 'data-tlink' ] ? activeAttributes[ 'data-tlink' ] : ''; | |
getTooltipContent( tlink, theader, tsubheading, timageurl, tdescription, timage ); | |
} | |
const onToggle = () => { | |
onChange( | |
toggleFormat( value, { | |
type: 'engineer/img-link-tooltip', | |
}) | |
); | |
} | |
return ( | |
<Modal | |
className='img-link-tooltip-popover' | |
__experimentalHideHeader={true} | |
> | |
<Card> | |
<CardHeader> | |
<Heading size={ 24 }>Вы можете добавить заголовок, описание, картинку и ссылку</Heading> | |
<Button variant="secondary" onClick={ () => { | |
setShowPopover(false); | |
} }> | |
Закрыть | |
</Button> | |
</CardHeader> | |
<CardBody> | |
<TextControl | |
label="Заголовок (тултип без картинки)" | |
value={ activeAttributes['data-theader'] ? activeAttributes['data-theader'] : '' } | |
onChange={ (text) => { onTextChange(text, activeAttributes, 'theader' ) } } | |
/> | |
<TextControl | |
label="Подзаголовок (тултип без картинки)" | |
value={ activeAttributes['data-tsubheading'] ? activeAttributes['data-tsubheading'] : '' } | |
onChange={ (text) => { onTextChange(text, activeAttributes, 'tsubheading') } } | |
/> | |
<TextControl | |
label="Ссылка" | |
value={ activeAttributes['data-tlink'] ? activeAttributes['data-tlink'] : '' } | |
onChange={ (text) => { onTextChange(text, activeAttributes, 'link') } } | |
/> | |
<TextareaControl | |
label="Описание (тултип без картинки)" | |
value={ activeAttributes['data-tdescription'] ? activeAttributes['data-tdescription'] : '' } | |
onChange={ (text) => { onTextareaChange(text, activeAttributes) } } | |
/> | |
<MediaUploadCheck> | |
<MediaUpload | |
allowedTypes={ ['image'] } | |
render={ ({ open }) => ( | |
<Button | |
isSecondary={ ! activeAttributes['data-timage'] } | |
className={ activeAttributes['data-timage'] ? 'g-tooltips-image__toggle' : 'g-tooltips-image__preview'} | |
onClick={ open } | |
> | |
{ activeAttributes['data-timage'] && | |
<> | |
<div className="g-tooltips-image__wrapper"> | |
<img className='g-tooltips-image' src={ activeAttributes['data-timageurl'] } alt="" /> | |
<button | |
type="button" | |
className="g-tooltips-image__remove dashicons-before dashicons-no-alt" | |
onClick={ e => onImageRemove(e) } | |
> | |
</button> | |
</div> | |
</> | |
} | |
{ ! activeAttributes['data-timage'] && 'Выберите картинку' } | |
</Button> | |
) } | |
onSelect={ image => onImageSelect(image) } | |
/> | |
</MediaUploadCheck> | |
</CardBody> | |
<CardFooter> | |
<Button variant="primary" onClick={ onToggle }> | |
Удалить тултип | |
</Button> | |
<Button variant="secondary" onClick={ () => setShowPopover(false) }> | |
Закрыть | |
</Button> | |
</CardFooter> | |
</Card> | |
</Modal> | |
) | |
} | |
function ConditionalButton( { isActive, onChange, value, activeAttributes } ) { | |
const [ showPopover, setShowPopover ] = useState( false ); | |
const selectedBlock = useSelect((select) => { | |
return select('core/block-editor').getSelectedBlock(); | |
}, []); | |
if (selectedBlock && selectedBlock.name !== 'core/paragraph') { | |
return null; | |
} | |
const toggleVisible = () => { | |
setShowPopover( (showPopover ) => ! showPopover ); | |
}; | |
return ( | |
<> | |
<BlockControls> | |
<ToolbarGroup> | |
<ToolbarButton | |
icon={ comment } | |
label={ isActive ? 'Редактировать тултип с картинкой' : 'Добавить тултип с картинкой' } | |
onClick={ toggleVisible } | |
isPressed={ isActive } | |
/> | |
</ToolbarGroup> | |
</BlockControls> | |
{ showPopover && ( | |
<ImagePopover | |
setShowPopover={setShowPopover} | |
activeAttributes={activeAttributes} | |
onChange={onChange} | |
value={value} | |
/> | |
) } | |
</> | |
); | |
} | |
registerFormatType( 'myproject/img-link-tooltip', { | |
title: 'Тултип', | |
tagName: 'a', | |
className: 'text-tooltip', | |
edit: (props) => ConditionalButton(props), | |
attributes: { | |
'data-bs-title': 'data-bs-title', | |
'data-bs-toggle': 'data-bs-toggle', | |
'href': 'href', | |
'data-timage': 'data-timage', | |
'data-timageurl': 'data-timageurl', | |
'data-theader': 'data-theader', | |
'data-tsubheading': 'data-tsubheading', | |
'data-tdescription': 'data-tdescription', | |
'data-tlink': 'data-tlink', | |
'data-extra-class': 'data-extra-class', | |
}, | |
} ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment