Skip to content

Commit

Permalink
Handle taxes not being enabled and customized tax classes (#45531)
Browse files Browse the repository at this point in the history
* Create and register the woocommerce/product-select-field block

* Replace the tax class radio group block by woocommerce/product-select-field block

* Hide tax fields when taxes are disabled

* Hide tax fields when taxes are disabled in product variations

* Add changelog files

* Fix linter errors
  • Loading branch information
mdperez86 committed Mar 18, 2024
1 parent ee044a7 commit dea68ee
Show file tree
Hide file tree
Showing 13 changed files with 403 additions and 119 deletions.
4 changes: 4 additions & 0 deletions packages/js/product-editor/changelog/add-43232
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Create woocommerce/product-select-field block
98 changes: 98 additions & 0 deletions packages/js/product-editor/src/blocks/generic/select/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# woocommerce/product-select-field

A reusable select field for the product editor.

## Attributes

### label

- **Type:** `String`
- **Required:** `Yes`

Label that appears on top of the field.

### property

- **Type:** `String`
- **Required:** `Yes`

Property in which the value is stored.

### help

- **Type:** `String`
- **Required:** `No`

Help text that appears below the field.

### multiple

- **Type:** `Boolean`
- **Required:** `No`

Indicates where the select is of multiple choices or not.

### placeholder

- **Type:** `String`
- **Required:** `No`

Placeholder text that appears in the field when it's empty.

### disabled

- **Type:** `Boolean`
- **Required:** `No`

Indicates and enforces that the field is disabled.

### options

- **Type:** `Array`
- **Items:** `Object`
- `value`
- **Type:** `String`
- **Required:** `Yes`
- `label`
- **Type:** `String`
- **Required:** `Yes`
- `disabled`
- **Type:** `Boolean`
- **Required:** `No`
- **Required:** `No`

Refers to the options of the select field.

## Usage

Here's a snippet that adds tax classes as options to the
single selection field:

```php
$section->add_block(
array(
'id' => 'unique-block-id',
'blockName' => 'woocommerce/product-select-field',
'order' => 13,
'attributes' => array(
'label' => 'Tax class',
'property' => 'tax_class',
'help' => 'Apply a tax rate if this product qualifies for tax reduction or exemption.',
'options' => array(
array(
'value' => 'Standard rate',
'label' => '',
),
array(
'value' => 'Reduced rate',
'label' => 'reduced-rate',
),
array(
'value' => 'Zero rate',
'label' => 'zero-rate',
),
),
),
)
);
```
61 changes: 61 additions & 0 deletions packages/js/product-editor/src/blocks/generic/select/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "woocommerce/product-select-field",
"title": "Product select field",
"category": "woocommerce",
"description": "A select field for use in the product editor.",
"keywords": [ "products", "select" ],
"textdomain": "default",
"attributes": {
"label": {
"type": "string",
"__experimentalRole": "content"
},
"property": {
"type": "string"
},
"placeholder": {
"type": "string"
},
"help": {
"type": "string"
},
"disabled": {
"type": "boolean"
},
"multiple": {
"type": "boolean",
"default": false
},
"options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"value": {
"type": "string"
},
"disabled": {
"type": "boolean",
"default": false
}
}
},
"default": []
}
},
"supports": {
"align": false,
"html": false,
"multiple": true,
"reusable": false,
"inserter": false,
"lock": false,
"__experimentalToolbar": false
},
"usesContext": [ "postType" ]
}
53 changes: 53 additions & 0 deletions packages/js/product-editor/src/blocks/generic/select/edit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* External dependencies
*/
import { useWooBlockProps } from '@woocommerce/block-templates';
import { SelectControl } from '@wordpress/components';
import { createElement } from '@wordpress/element';

/**
* Internal dependencies
*/
import useProductEntityProp from '../../../hooks/use-product-entity-prop';
import { sanitizeHTML } from '../../../utils/sanitize-html';
import type { ProductEditorBlockEditProps } from '../../../types';
import type { SelectBlockAttributes } from './types';

export function Edit( {
attributes,
context: { postType },
}: ProductEditorBlockEditProps< SelectBlockAttributes > ) {
const blockProps = useWooBlockProps( attributes );

const { property, label, placeholder, help, disabled, options, multiple } =
attributes;

const [ value, setValue ] = useProductEntityProp< string | string[] >(
property,
{
postType,
fallbackValue: '',
}
);

function renderHelp() {
if ( help ) {
return <span dangerouslySetInnerHTML={ sanitizeHTML( help ) } />;
}
}

return (
<div { ...blockProps }>
<SelectControl
value={ value }
disabled={ disabled }
label={ label }
onChange={ setValue }
help={ renderHelp() }
placeholder={ placeholder }
options={ options }
multiple={ multiple as never }
/>
</div>
);
}
33 changes: 33 additions & 0 deletions packages/js/product-editor/src/blocks/generic/select/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { registerProductEditorBlockType } from '../../../utils';

/**
* Internal dependencies
*/
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { SelectBlockAttributes } from './types';

const { name, ...metadata } =
blockConfiguration as BlockConfiguration< SelectBlockAttributes >;

export { metadata, name };

export const settings = {
example: {},
edit: Edit,
};

export const init = () =>
registerProductEditorBlockType( {
name,
metadata: metadata as never,
settings: settings as never,
} );
15 changes: 15 additions & 0 deletions packages/js/product-editor/src/blocks/generic/select/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* External dependencies
*/
import type { BlockAttributes } from '@wordpress/blocks';
import { SelectControl } from '@wordpress/components';

export interface SelectBlockAttributes extends BlockAttributes {
property: string;
label: string;
help?: string;
placeholder?: string;
disabled?: boolean;
multiple?: boolean;
options?: SelectControl.Option[];
}
1 change: 1 addition & 0 deletions packages/js/product-editor/src/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ export { init as initText } from './generic/text';
export { init as initNumber } from './generic/number';
export { init as initLinkedProductList } from './generic/linked-product-list';
export { init as initTextArea } from './generic/text-area';
export { init as initSelect } from './generic/select';
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@
*/
import classNames from 'classnames';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Link } from '@woocommerce/components';
import { Product } from '@woocommerce/data';
import { getNewPath } from '@woocommerce/navigation';
import { recordEvent } from '@woocommerce/tracks';
import { useInstanceId } from '@wordpress/compose';
import { useEntityProp } from '@wordpress/core-data';
import {
createElement,
createInterpolateElement,
useEffect,
} from '@wordpress/element';
import { createElement, useEffect } from '@wordpress/element';
import { sprintf, __ } from '@wordpress/i18n';
import {
BaseControl,
Expand All @@ -24,11 +17,12 @@ import {
/**
* Internal dependencies
*/
import { Label } from '../../../components/label/label';
import { useValidation } from '../../../contexts/validation-context';
import { useCurrencyInputProps } from '../../../hooks/use-currency-input-props';
import { SalePriceBlockAttributes } from './types';
import { ProductEditorBlockEditProps } from '../../../types';
import { Label } from '../../../components/label/label';
import { sanitizeHTML } from '../../../utils/sanitize-html';
import type { ProductEditorBlockEditProps } from '../../../types';
import type { SalePriceBlockAttributes } from './types';

export function Edit( {
attributes,
Expand All @@ -52,18 +46,11 @@ export function Edit( {
onChange: setRegularPrice,
} );

const interpolatedHelp = help
? createInterpolateElement( help, {
PricingTab: (
<Link
href={ getNewPath( { tab: 'pricing' } ) }
onClick={ () => {
recordEvent( 'product_pricing_help_click' );
} }
/>
),
} )
: null;
function renderHelp() {
if ( help ) {
return <span dangerouslySetInnerHTML={ sanitizeHTML( help ) } />;
}
}

const regularPriceId = useInstanceId(
BaseControl,
Expand Down Expand Up @@ -115,7 +102,7 @@ export function Edit( {
help={
regularPriceValidationError
? regularPriceValidationError
: interpolatedHelp
: renderHelp()
}
className={ classNames( {
'has-error': regularPriceValidationError,
Expand Down
4 changes: 4 additions & 0 deletions plugins/woocommerce/changelog/add-43232
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Hide tax fields when taxes are disabled in product and variations
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class BlockRegistry {
'woocommerce/product-text-area-field',
'woocommerce/product-number-field',
'woocommerce/product-linked-list-field',
'woocommerce/product-select-field',
);

/**
Expand Down
Loading

0 comments on commit dea68ee

Please sign in to comment.