Add 'placeholder' attribute to taxonomy block and add 'placeholder' a… (#46938)

* Add 'placeholder' attribute to taxonomy block and add 'placeholder' attribute to category field in Simple Product Template

* Only show placeholder when nothing is selected

* Remove suffix from function parameters

* Add changelog for component

* fix unit tests
This commit is contained in:
Nathan Silveira 2024-05-03 15:26:08 -03:00 committed by GitHub
parent 163e579ac6
commit 08508dfecc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 48 additions and 15 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Show 'placeholder' in SelectTree only when nothing is selected

View File

@ -33,7 +33,6 @@ interface SelectTreeProps extends TreeControlProps {
export const SelectTree = function SelectTree( { export const SelectTree = function SelectTree( {
items, items,
treeRef: ref, treeRef: ref,
placeholder,
isLoading, isLoading,
disabled, disabled,
initialInputValue, initialInputValue,
@ -92,6 +91,13 @@ export const SelectTree = function SelectTree( {
} }
}, [ isFocused ] ); }, [ isFocused ] );
let placeholder: string | undefined = '';
if ( Array.isArray( props.selected ) ) {
placeholder = props.selected.length === 0 ? props.placeholder : '';
} else if ( props.selected ) {
placeholder = props.placeholder;
}
const inputProps: React.InputHTMLAttributes< HTMLInputElement > = { const inputProps: React.InputHTMLAttributes< HTMLInputElement > = {
className: 'woocommerce-experimental-select-control__input', className: 'woocommerce-experimental-select-control__input',
id: `${ props.id }-input`, id: `${ props.id }-input`,

View File

@ -32,35 +32,35 @@ describe( 'SelectTree', () => {
} ); } );
it( 'should show the popover only when focused', () => { it( 'should show the popover only when focused', () => {
const { queryByPlaceholderText, queryByText } = render( const { queryByRole, queryByText } = render(
<SelectTree { ...DEFAULT_PROPS } /> <SelectTree { ...DEFAULT_PROPS } />
); );
expect( queryByText( 'Item 1' ) ).not.toBeInTheDocument(); expect( queryByText( 'Item 1' ) ).not.toBeInTheDocument();
queryByPlaceholderText( 'Type here' )?.focus(); queryByRole( 'textbox' )?.focus();
expect( queryByText( 'Item 1' ) ).toBeInTheDocument(); expect( queryByText( 'Item 1' ) ).toBeInTheDocument();
} ); } );
it( 'should show create button when callback is true ', () => { it( 'should show create button when callback is true ', () => {
const { queryByText, queryByPlaceholderText } = render( const { queryByText, queryByRole } = render(
<SelectTree <SelectTree
{ ...DEFAULT_PROPS } { ...DEFAULT_PROPS }
shouldShowCreateButton={ () => true } shouldShowCreateButton={ () => true }
/> />
); );
queryByPlaceholderText( 'Type here' )?.focus(); queryByRole( 'textbox' )?.focus();
expect( queryByText( 'Create new' ) ).toBeInTheDocument(); expect( queryByText( 'Create new' ) ).toBeInTheDocument();
} ); } );
it( 'should not show create button when callback is false or no callback', () => { it( 'should not show create button when callback is false or no callback', () => {
const { queryByText, queryByPlaceholderText } = render( const { queryByText, queryByRole } = render(
<SelectTree { ...DEFAULT_PROPS } /> <SelectTree { ...DEFAULT_PROPS } />
); );
queryByPlaceholderText( 'Type here' )?.focus(); queryByRole( 'textbox' )?.focus();
expect( queryByText( 'Create new' ) ).not.toBeInTheDocument(); expect( queryByText( 'Create new' ) ).not.toBeInTheDocument();
} ); } );
it( 'should show a root item when focused and child when expand button is clicked', () => { it( 'should show a root item when focused and child when expand button is clicked', () => {
const { queryByText, queryByLabelText, queryByPlaceholderText } = const { queryByText, queryByLabelText, queryByRole } =
render( <SelectTree { ...DEFAULT_PROPS } /> ); render( <SelectTree { ...DEFAULT_PROPS } /> );
queryByPlaceholderText( 'Type here' )?.focus(); queryByRole( 'textbox' )?.focus();
expect( queryByText( 'Item 1' ) ).toBeInTheDocument(); expect( queryByText( 'Item 1' ) ).toBeInTheDocument();
expect( queryByText( 'Item 2' ) ).not.toBeInTheDocument(); expect( queryByText( 'Item 2' ) ).not.toBeInTheDocument();
@ -69,10 +69,10 @@ describe( 'SelectTree', () => {
} ); } );
it( 'should show selected items', () => { it( 'should show selected items', () => {
const { queryAllByRole, queryByPlaceholderText } = render( const { queryAllByRole, queryByRole } = render(
<SelectTree { ...DEFAULT_PROPS } selected={ [ mockItems[ 0 ] ] } /> <SelectTree { ...DEFAULT_PROPS } selected={ [ mockItems[ 0 ] ] } />
); );
queryByPlaceholderText( 'Type here' )?.focus(); queryByRole( 'textbox' )?.focus();
expect( queryAllByRole( 'treeitem' )[ 0 ] ).toHaveAttribute( expect( queryAllByRole( 'treeitem' )[ 0 ] ).toHaveAttribute(
'aria-selected', 'aria-selected',
'true' 'true'
@ -80,19 +80,19 @@ describe( 'SelectTree', () => {
} ); } );
it( 'should show Create "<createValue>" button', () => { it( 'should show Create "<createValue>" button', () => {
const { queryByPlaceholderText, queryByText } = render( const { queryByText, queryByRole } = render(
<SelectTree <SelectTree
{ ...DEFAULT_PROPS } { ...DEFAULT_PROPS }
createValue="new item" createValue="new item"
shouldShowCreateButton={ () => true } shouldShowCreateButton={ () => true }
/> />
); );
queryByPlaceholderText( 'Type here' )?.focus(); queryByRole( 'textbox' )?.focus();
expect( queryByText( 'Create "new item"' ) ).toBeInTheDocument(); expect( queryByText( 'Create "new item"' ) ).toBeInTheDocument();
} ); } );
it( 'should call onCreateNew when Create "<createValue>" button is clicked', () => { it( 'should call onCreateNew when Create "<createValue>" button is clicked', () => {
const mockFn = jest.fn(); const mockFn = jest.fn();
const { queryByPlaceholderText, queryByText } = render( const { queryByRole, queryByText } = render(
<SelectTree <SelectTree
{ ...DEFAULT_PROPS } { ...DEFAULT_PROPS }
createValue="new item" createValue="new item"
@ -100,7 +100,7 @@ describe( 'SelectTree', () => {
onCreateNew={ mockFn } onCreateNew={ mockFn }
/> />
); );
queryByPlaceholderText( 'Type here' )?.focus(); queryByRole( 'textbox' )?.focus();
queryByText( 'Create "new item"' )?.click(); queryByText( 'Create "new item"' )?.click();
expect( mockFn ).toBeCalledTimes( 1 ); expect( mockFn ).toBeCalledTimes( 1 );
} ); } );

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add 'placeholder' attribute to taxonomy block

View File

@ -48,6 +48,13 @@ Help text that appears for the name field in the dialog that appears when creati
Label for the parent taxonomy field in the dialog that appears when creating a new taxonomy. Label for the parent taxonomy field in the dialog that appears when creating a new taxonomy.
### placeholder
- **Type:** `String`
- **Required:** `No`
Placeholder for when the input field is empty.
## Usage ## Usage

View File

@ -31,6 +31,10 @@
"parentTaxonomyText": { "parentTaxonomyText": {
"type": "string", "type": "string",
"__experimentalRole": "content" "__experimentalRole": "content"
},
"placeholder": {
"type": "string",
"__experimentalRole": "content"
} }
}, },
"supports": { "supports": {

View File

@ -34,6 +34,7 @@ interface TaxonomyBlockAttributes extends BlockAttributes {
createTitle: string; createTitle: string;
dialogNameHelpText?: string; dialogNameHelpText?: string;
parentTaxonomyText?: string; parentTaxonomyText?: string;
placeholder?: string;
} }
export function Edit( { export function Edit( {
@ -56,6 +57,7 @@ export function Edit( {
dialogNameHelpText, dialogNameHelpText,
parentTaxonomyText, parentTaxonomyText,
disabled, disabled,
placeholder,
} = attributes; } = attributes;
const [ searchValue, setSearchValue ] = useState( '' ); const [ searchValue, setSearchValue ] = useState( '' );
const [ allEntries, setAllEntries ] = useState< Taxonomy[] >( [] ); const [ allEntries, setAllEntries ] = useState< Taxonomy[] >( [] );
@ -114,6 +116,7 @@ export function Edit( {
multiple multiple
createValue={ searchValue } createValue={ searchValue }
onInputChange={ searchDelayed } onInputChange={ searchDelayed }
placeholder={ placeholder }
shouldNotRecursivelySelect shouldNotRecursivelySelect
shouldShowCreateButton={ ( typedValue ) => shouldShowCreateButton={ ( typedValue ) =>
! typedValue || ! typedValue ||

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
New product editor: Add 'placeholder' attribute to category field in Simple Product Template

View File

@ -439,6 +439,7 @@ class SimpleProductTemplate extends AbstractProductFormTemplate implements Produ
'createTitle' => __( 'Create new category', 'woocommerce' ), 'createTitle' => __( 'Create new category', 'woocommerce' ),
'dialogNameHelpText' => __( 'Shown to customers on the product page.', 'woocommerce' ), 'dialogNameHelpText' => __( 'Shown to customers on the product page.', 'woocommerce' ),
'parentTaxonomyText' => __( 'Parent category', 'woocommerce' ), 'parentTaxonomyText' => __( 'Parent category', 'woocommerce' ),
'placeholder' => __( 'Search or create categories…', 'woocommerce' ),
), ),
) )
); );