Custom Button Block & Link Picker
Membuat Generic Button Block
File generic-button.js
js
import { RichText, BlockControls } from "@wordpress/block-editor";
import { ToolbarGroup, ToolbarButton } from "@wordpress/components";
wp.blocks.registerBlockType("ourBlockTheme/genericButton", {
title: "Generic Button",
attributes: {
text: { type: "string" },
size: { type: "string", default: "large" },
linkObject: { type: "object", default: { url: "" } }
},
edit: EditComponent,
save: SaveComponent
});RichText untuk Button
Menggunakan RichText dengan tagName="a" dan allowedFormats=[] (tanpa bold/italic):
js
<RichText
allowedFormats={[]}
tagName="a"
className={`btn btn--${props.attributes.size} btn--${colorName}`}
value={props.attributes.text}
onChange={(x) => props.setAttributes({ text: x })}
/>Link Picker dengan LinkControl
Konsep
WordPress menyediakan komponen LinkControl yang memungkinkan pengguna mencari halaman/post atau memasukkan URL manual.
Import yang Diperlukan
js
import { useState } from "@wordpress/element";
import {
RichText,
BlockControls,
__experimentalLinkControl as LinkControl
} from "@wordpress/block-editor";
import { ToolbarGroup, ToolbarButton, Popover } from "@wordpress/components";
import { link } from "@wordpress/icons";Catatan:
@wordpress/iconsperlu diinstall:npm install @wordpress/icons
Attribute linkObject
js
attributes: {
linkObject: {
type: "object",
default: { url: "" }
}
}linkObject menyimpan informasi link lengkap:
| Property | Penjelasan |
|---|---|
url | URL tujuan |
id | ID post/page (jika dipilih dari search) |
title | Judul post/page |
postType | Tipe post (post, page, dll.) |
Implementasi Link Picker
js
function EditComponent(props) {
const [isLinkPickerVisible, setIsLinkPickerVisible] = useState(false);
function handleLinkChange(newLink) {
props.setAttributes({ linkObject: newLink });
}
function buttonHandler() {
setIsLinkPickerVisible((prev) => !prev);
}
return (
<>
<BlockControls>
<ToolbarGroup>
{/* Toolbar buttons untuk size (Large, Medium, Small) */}
<ToolbarButton
onClick={buttonHandler}
icon={link}
/>
</ToolbarGroup>
</BlockControls>
<RichText
allowedFormats={[]}
tagName="a"
className={`btn btn--${props.attributes.size}`}
value={props.attributes.text}
onChange={(x) => props.setAttributes({ text: x })}
/>
{isLinkPickerVisible && (
<Popover
position="middle center"
onFocusOutside={() => setIsLinkPickerVisible(false)}
>
<LinkControl
settings={[]}
value={props.attributes.linkObject}
onChange={handleLinkChange}
/>
</Popover>
)}
</>
);
}Penjelasan Komponen
| Komponen | Fungsi |
|---|---|
useState | State lokal untuk show/hide link picker |
Popover | Popup floating di atas block |
LinkControl | UI pencarian link (search pages/posts atau ketik URL) |
link (icon) | Ikon link dari @wordpress/icons |
Props Popover
| Prop | Fungsi |
|---|---|
position | Posisi popup ("middle center") |
onFocusOutside | Auto-close saat klik di luar popup |
Props LinkControl
| Prop | Fungsi |
|---|---|
settings | Array kosong [] — menonaktifkan opsi tambahan |
value | Object link saat ini (linkObject attribute) |
onChange | Handler perubahan link |
Save Component
js
function SaveComponent(props) {
return (
<a
href={props.attributes.linkObject.url}
className={`btn btn--${props.attributes.size} btn--${colorName}`}
>
<RichText.Content value={props.attributes.text} />
</a>
);
}Cara Menggunakan Link Picker
- Klik ikon link di toolbar block
- Popover muncul dengan search box
- Ketik nama halaman/post → pilih dari hasil pencarian
- Atau ketik URL manual (misal:
/programs) → tekan Enter - Klik Confirm untuk menyimpan
- Klik di luar popover → otomatis tertutup (
onFocusOutside)
Tip: Jika WordPress tidak di-install di root domain, gunakan full URL (termasuk HTTP) alih-alih hanya
/slug.
Kesimpulan
| Fitur | Implementasi |
|---|---|
| Button text | RichText dengan tagName="a", allowedFormats=[] |
| Link picker | LinkControl + Popover + useState |
| Link data | Attribute linkObject (type: object) |
| Toggle picker | ToolbarButton dengan icon link |
| Auto-close | Popover → onFocusOutside |
| Install icons | npm install @wordpress/icons |