diff --git a/.markdownlint.json b/.markdownlint.json index 57085409db7..5e29a079a84 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -4,6 +4,7 @@ "MD007": { "indent": 4 }, "MD013": { "line_length": 9999 }, "MD024": { "allow_different_nesting": true }, + "MD033": { "allowed_elements": ["video"] }, "no-hard-tabs": false, "whitespace": false } diff --git a/packages/js/product-editor/changelog/doc-more-reusable-blocks b/packages/js/product-editor/changelog/doc-more-reusable-blocks new file mode 100644 index 00000000000..5ac79cfaf04 --- /dev/null +++ b/packages/js/product-editor/changelog/doc-more-reusable-blocks @@ -0,0 +1,5 @@ +Significance: patch +Type: dev +Comment: Add reusable blocks documentation + + diff --git a/packages/js/product-editor/src/blocks/checkbox/README.md b/packages/js/product-editor/src/blocks/checkbox/README.md index ddbad959b38..367e344371d 100644 --- a/packages/js/product-editor/src/blocks/checkbox/README.md +++ b/packages/js/product-editor/src/blocks/checkbox/README.md @@ -36,7 +36,7 @@ Property in which the checkbox value is stored. Tooltip text that is shown when hovering the icon at the side of the label. -## Example +## Usage Here's an example on the code that is used for the 'sold_individually' field in the Inventory section: diff --git a/packages/js/product-editor/src/blocks/collapsible/README.md b/packages/js/product-editor/src/blocks/collapsible/README.md new file mode 100644 index 00000000000..c1e5ff276fc --- /dev/null +++ b/packages/js/product-editor/src/blocks/collapsible/README.md @@ -0,0 +1,51 @@ +# woocommerce/product-collapsible + +Container with collapsible inner blocks. + +![Collapsible](https://woocommerce.files.wordpress.com/2023/09/woocommerceproduct-collapsible.png) + +## Attributes + +### toggleText + +- **Type**: `string` +- **Required**: ` Yes` + +The text to display on the toggle button. + +### initialCollapsed + +- **Type**: `boolean` +- **Required**: ` Yes` + +Controls if the content is collapsed by default. + +### persistRender + +- **Type**: `boolean` +- **Required**: ` Yes` + +Controls if content is rendered to the DOM even when collapsed. + +## Usage + +Here's the code that was used to create the example in the screenshot above: + +```php +$product_inventory_advanced = $product_inventory_section->add_block( + [ + 'id' => 'product-inventory-advanced', + 'blockName' => 'woocommerce/product-collapsible', + 'attributes' => [ + 'toggleText' => __( 'Advanced', 'woocommerce' ), + 'initialCollapsed' => true, + 'persistRender' => true, + ], + ] +); +$product_inventory_advanced->add_block( + [ + // add block information here + ] +) +``` diff --git a/packages/js/product-editor/src/blocks/conditional/README.md b/packages/js/product-editor/src/blocks/conditional/README.md new file mode 100644 index 00000000000..c1b778b55d5 --- /dev/null +++ b/packages/js/product-editor/src/blocks/conditional/README.md @@ -0,0 +1,45 @@ +# woocommerce/conditional + +Container to only conditionally render inner blocks. + + + +## Attributes + +### mustMatch + +- **Type**: `Record< string, Array< string > >` +- **Required**: `Yes` + +A list of requirements that must be met for the inner blocks to be rendered. The keys should reference properties from the product, and the values are possible values for that property so that the inner blocks are rendered. + +## Usage + +Here's the code that was used to create the example in the video above: + +```php +$wrapper = $product_summary_field->get_parent()->add_block( + [ + 'id' => 'example-conditional-wrapper', + 'blockName' => 'woocommerce/conditional', + 'order' => $product_summary_field->get_order() + 5, + 'attributes' => [ + 'mustMatch' => [ + 'name' => [ 'Car', 'Bike' ] + ], + ], + ] +); +$wrapper->add_block( + [ + 'id' => 'example-pricing-field', + 'blockName' => 'woocommerce/product-pricing-field', + 'order' => $product_summary_field->get_order() + 5, + 'attributes' => [ + 'label' => __( 'Example price field', 'woocommerce'), + 'property' => 'custom_price', + 'help' => 'This is a help text', + ], + ] +); +``` diff --git a/packages/js/product-editor/src/blocks/pricing/README.md b/packages/js/product-editor/src/blocks/pricing/README.md new file mode 100644 index 00000000000..4cc92be24cf --- /dev/null +++ b/packages/js/product-editor/src/blocks/pricing/README.md @@ -0,0 +1,64 @@ +# woocommerce/product-pricing-field + +A product price block with currency display. + +![Product pricing field](https://woocommerce.files.wordpress.com/2023/09/woocommerceproduct-pricing-field.png) + +## Attributes + +### property + +- **Type:** `String` +- **Required:** `Yes` + +Property in which the price value is stored. + +### label + +- **Type:** `String` +- **Required:** `Yes` + +Label that appears on top of the price field. + +### help + +- **Type:** `String` +- **Required:** `No` + +Help text that appears below the price field. + +## Usage + +Here's the code that adds the field from the screenshot after the Summary field: + +```php +get_parent()->add_block( + [ + 'id' => 'example-pricing-field', + 'blockName' => 'woocommerce/product-pricing-field', + 'order' => $product_summary_field->get_order() + 5, + 'attributes' => [ + 'label' => __( 'Example price field', 'woocommerce'), + 'property' => 'custom_price', + 'help' => 'This is a help text', + ], + ] + ); + } +} + +if ( ! function_exists( 'example_hook_up_block_template_modifications_pricing' ) ) { + function example_hook_up_block_template_modifications_pricing() { + add_action( + 'woocommerce_block_template_area_product-form_after_add_block_product-summary', + 'add_pricing_field' + ); + } +} + +add_action( 'init', 'example_hook_up_block_template_modifications_pricing', 0 ); +``` diff --git a/packages/js/product-editor/src/blocks/pricing/block.json b/packages/js/product-editor/src/blocks/pricing/block.json index 0b0bece7105..97901c45546 100644 --- a/packages/js/product-editor/src/blocks/pricing/block.json +++ b/packages/js/product-editor/src/blocks/pricing/block.json @@ -8,7 +8,7 @@ "keywords": [ "products", "price" ], "textdomain": "default", "attributes": { - "name": { + "property": { "type": "string", "__experimentalRole": "content" }, diff --git a/packages/js/product-editor/src/blocks/pricing/edit.tsx b/packages/js/product-editor/src/blocks/pricing/edit.tsx index b698159ea94..9784aa2e05e 100644 --- a/packages/js/product-editor/src/blocks/pricing/edit.tsx +++ b/packages/js/product-editor/src/blocks/pricing/edit.tsx @@ -26,11 +26,11 @@ export function Edit( { attributes, }: ProductEditorBlockEditProps< PricingBlockAttributes > ) { const blockProps = useWooBlockProps( attributes ); - const { name, label, help } = attributes; + const { property, label, help } = attributes; const [ price, setPrice ] = useEntityProp< string >( 'postType', 'product', - name + property ); const inputProps = useCurrencyInputProps( { value: price, @@ -61,7 +61,7 @@ export function Edit( { diff --git a/packages/js/product-editor/src/blocks/pricing/types.ts b/packages/js/product-editor/src/blocks/pricing/types.ts index ae5ec68b128..46f4de43562 100644 --- a/packages/js/product-editor/src/blocks/pricing/types.ts +++ b/packages/js/product-editor/src/blocks/pricing/types.ts @@ -4,7 +4,7 @@ import { BlockAttributes } from '@wordpress/blocks'; export interface PricingBlockAttributes extends BlockAttributes { - name: string; + property: string; label: string; help?: string; } diff --git a/packages/js/product-editor/src/blocks/radio/README.md b/packages/js/product-editor/src/blocks/radio/README.md new file mode 100644 index 00000000000..4bb31e8c26e --- /dev/null +++ b/packages/js/product-editor/src/blocks/radio/README.md @@ -0,0 +1,60 @@ +# woocommerce/product-radio-field block + +Radio button field for the product editor. + +![Product radio field](https://woocommerce.files.wordpress.com/2023/09/woocommerceproduct-radio-field.png) + +## Attributes + +### title + +- **Type:** `String` +- **Required:** `Yes` + +### description + +- **Type:** `String` +- **Required:** `No` + + +### property + +- **Type:** `String` +- **Required:** `Yes` + +### options + +- **Type:** `Array` +- **Required:** `Yes` + +## Usage + +Here's an example of the usage on the "Charge sales tax on" field in the Pricing section: + +```php +$product_pricing_section->add_block( + [ + 'id' => 'product-sale-tax', + 'blockName' => 'woocommerce/product-radio-field', + 'order' => 30, + 'attributes' => [ + 'title' => __( 'Charge sales tax on', 'woocommerce' ), + 'property' => 'tax_status', + 'options' => [ + [ + 'label' => __( 'Product and shipping', 'woocommerce' ), + 'value' => 'taxable', + ], + [ + 'label' => __( 'Only shipping', 'woocommerce' ), + 'value' => 'shipping', + ], + [ + 'label' => __( "Don't charge tax", 'woocommerce' ), + 'value' => 'none', + ], + ], + ], + ] +); +``` diff --git a/packages/js/product-editor/src/blocks/taxonomy/README.md b/packages/js/product-editor/src/blocks/taxonomy/README.md index 60f9c97e595..7b19e17a2b1 100644 --- a/packages/js/product-editor/src/blocks/taxonomy/README.md +++ b/packages/js/product-editor/src/blocks/taxonomy/README.md @@ -2,6 +2,55 @@ This is a block that displays a taxonomy field, allowing searching, selection, and creation of new items, to be used in a product context. +![Taxonomy block](https://woocommerce.files.wordpress.com/2023/09/woocommerceproduct-taxonomy-field.png) + +## Attributes + +### slug + +- **Type:** `String` +- **Required:** `Yes` + +The taxonomy slug. + +### property + +- **Type:** `String` +- **Required:** `Yes` + +Property name in which the taxonomy value is stored in the product. + +### label + +- **Type:** `String` +- **Required:** `No` + +Label that appears on top of the field. + +### createTitle + +- **Type:** `String` +- **Required:** `No` + +Title of the dialog that appears when creating a new taxonomy. + +### dialogNameHelpText + +- **Type:** `String` +- **Required:** `No` + +Help text that appears for the name field in the dialog that appears when creating a new taxonomy. + +### parentTaxonomyText + +- **Type:** `String` +- **Required:** `No` + +Label for the parent taxonomy field in the dialog that appears when creating a new taxonomy. + + +## Usage + Please note that to use this block you need to have the custom taxonomy registered in the backend, attached to the products post type and added to the REST API. Here's a snippet that shows how to add an already registered taxonomy to the REST API: ```php @@ -49,3 +98,23 @@ function YOUR_PREFIX_rest_api_add_custom1_to_product( $product, $request, $creat add_filter( 'woocommerce_rest_insert_product_object', 'YOUR_PREFIX_rest_api_add_custom1_to_product', 10, 3 ); ``` + +Here's a snippet that shows how it is used for the Categories field: + +```php +$product_catalog_section->add_block( + [ + 'id' => 'product-categories', + 'blockName' => 'woocommerce/product-taxonomy-field', + 'order' => 10, + 'attributes' => [ + 'slug' => 'product_cat', + 'property' => 'categories', + 'label' => __( 'Categories', 'woocommerce' ), + 'createTitle' => __( 'Create new category', 'woocommerce' ), + 'dialogNameHelpText' => __( 'Shown to customers on the product page.', 'woocommerce' ), + 'parentTaxonomyText' => __( 'Parent category', 'woocommerce' ), + ], + ] +); +```