Skip to content

ZIORWebDev/product-selector

Repository files navigation

Product Selector

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.


Installation

npm install @ziorweb-dev/product-selector

or

yarn add @ziorweb-dev/product-selector

Features

  • 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

Basic Usage

import { ProductSelector } from '@ziorweb-dev/product-selector';

const EMPTY_PRODUCT = { id: '', label: '' };

<ProductSelector
	value={product ?? EMPTY_PRODUCT}
	onChange={(nextProduct) => {
		setProduct(nextProduct);
	}}
/>

Getting Product Information

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:

null

Error Handling

You 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.


Custom Fetchers

The component allows overriding the default fetch logic.

Custom product search

<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" }
	]
}

Custom product information fetch

<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>"
}

Gutenberg Example

Example inside a block Edit component.

<ProductSelector
	value={attributes.product}

	onChange={(product) => {
		setAttributes({ product });
	}}

	onProductInformationChange={(info) => {
		setAttributes({
			content: info?.price_html ?? '',
		});
	}}

	onProductInformationError={() => {
		setAttributes({ content: '' });
	}}
/>

Types

ProductValue

type ProductValue = {
	id: string
	label: string
}

ProductInformation

type ProductInformation = {
	id?: string | number
	name?: string
	price_html?: string
	[key: string]: unknown
}

Component API

ProductSelector Props

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

Default WordPress Behavior

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" }
  ]
}

About

Reusable React product selector component for WordPress projects (Gutenberg blocks).

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors