PluginProbe
Extendify / 3.1.5
Extendify v3.1.5
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / src / QuickEdit / components / toolbar / ColorButton.jsx

ColorButton.jsx in Extendify 3.1.5, at src/QuickEdit/components/toolbar/ColorButton.jsx

88 lines 2.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { Button, ColorPalette, Popover } from '@wordpress/components';
2 import { useDispatch, useSelect } from '@wordpress/data';
3 import { useRef, useState } from '@wordpress/element';
4 import { __ } from '@wordpress/i18n';
5 import {
6 applyColorFormat,
7 captureDomRichTextSelection,
8 } from '../../lib/rich-text-color';
9
10 export function ColorButton({ kind, label, iconClassName }) {
11 const [open, setOpen] = useState(false);
12 const wrapRef = useRef(null);
13 const frozenSel = useRef(null);
14
15 const sel = useSelect((select) => {
16 const editor = select('core/block-editor');
17 const start = editor.getSelectionStart();
18 const end = editor.getSelectionEnd();
19 if (!start || !start.clientId) return null;
20 const block = editor.getBlock(start.clientId);
21 if (!block) return null;
22 const settings = editor.getSettings() || {};
23 return { start, end, block, palette: settings.colors || [] };
24 }, []);
25
26 // React-context registry dispatch; the outer wp.data.dispatch can't see this block.
27 const dispatch = useDispatch('core/block-editor');
28
29 return (
30 <div className="relative inline-flex items-center" ref={wrapRef}>
31 <Button
32 className="extendify-quick-edit-color-button"
33 label={label}
34 aria-expanded={open}
35 onMouseDown={(ev) => {
36 // Capture selection before focus moves to the popover and discards it.
37 ev.preventDefault();
38 frozenSel.current = {
39 sel,
40 dom: captureDomRichTextSelection(),
41 };
42 }}
43 onClick={() => setOpen((v) => !v)}
44 icon={
45 <span
46 className={`relative inline-flex h-[20px] w-[20px] items-center justify-center text-[15px] font-semibold leading-none text-gray-900 font-qe ${iconClassName}`}
47 aria-hidden="true"
48 />
49 }
50 />
51 {open ? (
52 <Popover
53 placement="bottom-start"
54 onClose={() => setOpen(false)}
55 focusOnMount="firstElement"
56 className="extendify-quick-edit extendify-quick-edit-color-popover"
57 anchor={wrapRef.current}
58 >
59 <div className="extendify-quick-edit-color-popover-inner">
60 <ColorPalette
61 colors={sel?.palette || []}
62 onChange={(c) => {
63 applyColorFormat(frozenSel.current, kind, c, dispatch);
64 setOpen(false);
65 }}
66 clearable
67 disableCustomColors={false}
68 enableAlpha={false}
69 />
70 <Button
71 variant="tertiary"
72 className="extendify-quick-edit-color-clear"
73 onClick={() => {
74 applyColorFormat(frozenSel.current, kind, null, dispatch);
75 setOpen(false);
76 }}
77 >
78 {kind === 'text'
79 ? __('Clear text color', 'extendify-local')
80 : __('Clear highlight', 'extendify-local')}
81 </Button>
82 </div>
83 </Popover>
84 ) : null}
85 </div>
86 );
87 }
88