Reusable React product selector component for WordPress projects (Gutenberg blocks).
This package provides a searchable WooCommerce product selector built on top of ComboboxControl, with optional support for fetching product information such as price, title, or metadata.
It is designed to be framework-agnostic but optimized for WordPress environments.
npm install @ziorweb-dev/product-selectoror
yarn add @ziorweb-dev/product-selector- Search WooCommerce products
- Async REST API loading
- Debounced search
- Custom fetchers supported
- Emits product information
- Error handling support
- Small bundle size
- Gutenberg compatible
- TypeScript support
import { ProductSelector } from '@ziorweb-dev/product-selector';
const EMPTY_PRODUCT = { id: '', label: '' };
<ProductSelector
value={product ?? EMPTY_PRODUCT}
onChange={(nextProduct) => {
setProduct(nextProduct);
}}
/>The selector can automatically fetch product information and notify the consumer.
Example for updating a block with a product price.
<ProductSelector
value={product ?? { id: '', label: '' }}
onChange={(product) => {
setAttributes({ product });
}}
onProductInformationChange={(info) => {
setAttributes({
content: info?.price_html ?? '',
});
}}
/>Example product information response:
{
id: 123,
name: "Product Name",
price_html: "<span class='woocommerce-Price-amount'>$29.00</span>"
}If the product is cleared or the request fails, the callback may receive:
nullYou can handle API failures using onProductInformationError.
<ProductSelector
value={product}
onProductInformationError={(error) => {
console.error('Product fetch failed', error);
}}
/>This is triggered when the product information request fails.
The component allows overriding the default fetch logic.
<ProductSelector
value={product}
fetchOptions={async (search) => {
const res = await fetch(`/api/products?search=${search}`);
return res.json();
}}
/>Expected response format:
{
products: [
{ id: 1, name: "Product A" },
{ id: 2, name: "Product B" }
]
}<ProductSelector
value={product}
fetchProductInformation={async (productId) => {
const res = await fetch(`/api/products/${productId}`);
return res.json();
}}
/>Expected response:
{
id: 1,
name: "Product A",
price_html: "<span>$29</span>"
}Example inside a block Edit component.
<ProductSelector
value={attributes.product}
onChange={(product) => {
setAttributes({ product });
}}
onProductInformationChange={(info) => {
setAttributes({
content: info?.price_html ?? '',
});
}}
onProductInformationError={() => {
setAttributes({ content: '' });
}}
/>type ProductValue = {
id: string
label: string
}type ProductInformation = {
id?: string | number
name?: string
price_html?: string
[key: string]: unknown
}| Prop | Type | Description |
|---|---|---|
value |
ProductValue |
Currently selected product |
onChange |
(product) => void |
Triggered when product changes |
onProductInformationChange |
(info) => void |
Triggered when product information is loaded |
onProductInformationError |
(error) => void |
Triggered when product information fetch fails |
fetchOptions |
function |
Custom function for fetching product search results |
fetchProductInformation |
function |
Custom function for fetching product details |
By default the component expects a REST API endpoint similar to:
/wp-json/your-namespace/products/lists
Example response:
{
"products": [
{ "id": 123, "name": "Example Product" }
]
}