| 1 |
import { Button, Popover } from '@wordpress/components'; |
| 2 |
import { useDispatch, useSelect } from '@wordpress/data'; |
| 3 |
import { useRef, useState } from '@wordpress/element'; |
| 4 |
import { __, sprintf } from '@wordpress/i18n'; |
| 5 |
|
| 6 |
const LEVELS = [1, 2, 3, 4, 5, 6]; |
| 7 |
|
| 8 |
// Gutenberg ships the heading-level picker inside `.block-editor-block-switcher`, |
| 9 |
// which our floating bar hides (transform options aren't in scope for QE). |
| 10 |
// Restore just the level picker as a standalone button, matching the |
| 11 |
// ColorButton shape so the bar feels uniform. |
| 12 |
export function HeadingLevelButton() { |
| 13 |
const [open, setOpen] = useState(false); |
| 14 |
const wrapRef = useRef(null); |
| 15 |
|
| 16 |
const selected = useSelect((select) => { |
| 17 |
const editor = select('core/block-editor'); |
| 18 |
const clientId = editor.getSelectedBlockClientId(); |
| 19 |
if (!clientId) return null; |
| 20 |
const block = editor.getBlock(clientId); |
| 21 |
if (!block || block.name !== 'core/heading') return null; |
| 22 |
return { clientId, level: Number(block.attributes?.level) || 2 }; |
| 23 |
}, []); |
| 24 |
|
| 25 |
const dispatch = useDispatch('core/block-editor'); |
| 26 |
|
| 27 |
if (!selected) return null; |
| 28 |
|
| 29 |
const setLevel = (level) => { |
| 30 |
dispatch?.updateBlockAttributes?.(selected.clientId, { level }); |
| 31 |
setOpen(false); |
| 32 |
}; |
| 33 |
|
| 34 |
return ( |
| 35 |
<div className="relative inline-flex items-center" ref={wrapRef}> |
| 36 |
<Button |
| 37 |
className="extendify-quick-edit-heading-level-button" |
| 38 |
label={__('Heading level', 'extendify-local')} |
| 39 |
aria-expanded={open} |
| 40 |
onMouseDown={(ev) => ev.preventDefault()} |
| 41 |
onClick={() => setOpen((v) => !v)} |
| 42 |
> |
| 43 |
<span aria-hidden="true">{`H${selected.level}`}</span> |
| 44 |
</Button> |
| 45 |
{open ? ( |
| 46 |
<Popover |
| 47 |
placement="bottom-start" |
| 48 |
onClose={() => setOpen(false)} |
| 49 |
focusOnMount="firstElement" |
| 50 |
className="extendify-quick-edit extendify-quick-edit-heading-level-popover" |
| 51 |
anchor={wrapRef.current} |
| 52 |
> |
| 53 |
<div |
| 54 |
className="extendify-quick-edit-heading-level-popover-inner" |
| 55 |
role="listbox" |
| 56 |
aria-label={__('Heading level', 'extendify-local')} |
| 57 |
> |
| 58 |
{LEVELS.map((n) => ( |
| 59 |
<Button |
| 60 |
key={n} |
| 61 |
role="option" |
| 62 |
aria-selected={selected.level === n} |
| 63 |
className="extendify-quick-edit-heading-level-option" |
| 64 |
variant={selected.level === n ? 'primary' : 'tertiary'} |
| 65 |
onClick={() => setLevel(n)} |
| 66 |
onMouseDown={(ev) => ev.preventDefault()} |
| 67 |
label={sprintf( |
| 68 |
// translators: %d is the heading level number 1-6. |
| 69 |
__('Heading %d', 'extendify-local'), |
| 70 |
n, |
| 71 |
)} |
| 72 |
> |
| 73 |
{`H${n}`} |
| 74 |
</Button> |
| 75 |
))} |
| 76 |
</div> |
| 77 |
</Popover> |
| 78 |
) : null} |
| 79 |
</div> |
| 80 |
); |
| 81 |
} |
| 82 |
|