From 8bfd1cdb8824dbd95930ffa50286dd53110b46d0 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Thu, 21 Jul 2022 17:33:50 +0530
Subject: [PATCH 01/16] Add renderSuggestion prop to SuggestionsList component

---
 .../src/form-token-field/suggestions-list.tsx | 33 ++++++++++++-------
 .../components/src/form-token-field/types.ts  |  7 +++-
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/packages/components/src/form-token-field/suggestions-list.tsx b/packages/components/src/form-token-field/suggestions-list.tsx
index 3828feef5dfab2..959367da8021b6 100644
--- a/packages/components/src/form-token-field/suggestions-list.tsx
+++ b/packages/components/src/form-token-field/suggestions-list.tsx
@@ -4,7 +4,7 @@
 import { map } from 'lodash';
 import scrollView from 'dom-scroll-into-view';
 import classnames from 'classnames';
-import type { MouseEventHandler } from 'react';
+import type { MouseEventHandler, ReactNode } from 'react';
 
 /**
  * WordPress dependencies
@@ -31,6 +31,7 @@ export function SuggestionsList< T extends string | { value: string } >( {
 	suggestions = [],
 	displayTransform,
 	instanceId,
+	renderSuggestion,
 }: SuggestionsListProps< T > ) {
 	const [ scrollingIntoView, setScrollingIntoView ] = useState( false );
 
@@ -122,6 +123,24 @@ export function SuggestionsList< T extends string | { value: string } >( {
 					}
 				);
 
+				let output: ReactNode;
+
+				if ( typeof renderSuggestion === 'function' ) {
+					output = renderSuggestion( suggestion );
+				} else if ( matchText ) {
+					output = (
+						<span aria-label={ displayTransform( suggestion ) }>
+							{ matchText.suggestionBeforeMatch }
+							<strong className="components-form-token-field__suggestion-match">
+								{ matchText.suggestionMatch }
+							</strong>
+							{ matchText.suggestionAfterMatch }
+						</span>
+					);
+				} else {
+					output = displayTransform( suggestion );
+				}
+
 				/* eslint-disable jsx-a11y/click-events-have-key-events */
 				return (
 					<li
@@ -139,17 +158,7 @@ export function SuggestionsList< T extends string | { value: string } >( {
 						onMouseEnter={ handleHover( suggestion ) }
 						aria-selected={ index === selectedIndex }
 					>
-						{ matchText ? (
-							<span aria-label={ displayTransform( suggestion ) }>
-								{ matchText.suggestionBeforeMatch }
-								<strong className="components-form-token-field__suggestion-match">
-									{ matchText.suggestionMatch }
-								</strong>
-								{ matchText.suggestionAfterMatch }
-							</span>
-						) : (
-							displayTransform( suggestion )
-						) }
+						{ output }
 					</li>
 				);
 				/* eslint-enable jsx-a11y/click-events-have-key-events */
diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts
index f7e0a11e0e4140..996ba9fc31743a 100644
--- a/packages/components/src/form-token-field/types.ts
+++ b/packages/components/src/form-token-field/types.ts
@@ -1,7 +1,11 @@
 /**
  * External dependencies
  */
-import type { ComponentPropsWithRef, MouseEventHandler } from 'react';
+import type {
+	ComponentPropsWithRef,
+	MouseEventHandler,
+	ReactNode,
+} from 'react';
 
 type Messages = {
 	/**
@@ -165,6 +169,7 @@ export interface SuggestionsListProps< T = string | { value: string } > {
 	suggestions: T[];
 	displayTransform: ( value: T ) => string;
 	instanceId: string | number;
+	renderSuggestion?: ( suggestion: T ) => ReactNode;
 }
 
 export interface TokenProps extends TokenItem {

From 3f236c0b4ccd082102f4c613dc320a838629c581 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Thu, 21 Jul 2022 17:34:50 +0530
Subject: [PATCH 02/16] Add renderOption prop to ComboboxControl component

---
 packages/components/src/combobox-control/index.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/packages/components/src/combobox-control/index.js b/packages/components/src/combobox-control/index.js
index 2440296865c746..4d35c121f47d15 100644
--- a/packages/components/src/combobox-control/index.js
+++ b/packages/components/src/combobox-control/index.js
@@ -58,6 +58,7 @@ function ComboboxControl( {
 	messages = {
 		selected: __( 'Item selected.' ),
 	},
+	renderOption,
 } ) {
 	const currentOption = options.find( ( option ) => option.value === value );
 	const currentLabel = currentOption?.label ?? '';
@@ -279,6 +280,7 @@ function ComboboxControl( {
 							onHover={ setSelectedSuggestion }
 							onSelect={ onSuggestionSelected }
 							scrollIntoView
+							renderSuggestion={ renderOption }
 						/>
 					) }
 				</div>

From 97195ecb5934dbe126835f2f516a41012b6da3fd Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Thu, 21 Jul 2022 17:35:39 +0530
Subject: [PATCH 03/16] Add story to ComboboxControl component

---
 .../src/combobox-control/stories/index.js     | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/packages/components/src/combobox-control/stories/index.js b/packages/components/src/combobox-control/stories/index.js
index 3ba34f74dc8a95..ba4efdc687b546 100644
--- a/packages/components/src/combobox-control/stories/index.js
+++ b/packages/components/src/combobox-control/stories/index.js
@@ -287,3 +287,69 @@ _default.args = {
 	__next36pxDefaultSize: false,
 	allowReset: false,
 };
+
+const authors = [
+	{
+		name: 'Hermann P. Schnitzel',
+		age: 45,
+		country: 'Germany',
+	},
+	{
+		name: 'Shequondolisa Bivouac',
+		age: 43,
+		country: 'France',
+	},
+	{
+		name: 'Bodrum Salvador',
+		age: 42,
+		country: 'Spain',
+	},
+	{
+		name: 'Parsley Montana',
+		age: 48,
+		country: 'Germany',
+	},
+	{
+		name: 'Cabbage New York',
+		age: 44,
+		country: 'France',
+	},
+	{
+		name: 'Jake Weary',
+		age: 41,
+		country: 'United Kingdom',
+	},
+];
+
+const authorOptions = authors.map( ( { name, ...details } ) => ( {
+	value: name,
+	label: name,
+	...details,
+} ) );
+
+export const WithRenderOption = ( args ) => {
+	const [ value, setValue ] = useState( '' );
+
+	return (
+		<>
+			<ComboboxControl
+				{ ...args }
+				value={ value }
+				onChange={ setValue }
+				label="Select an author"
+				options={ authorOptions }
+				renderOption={ ( { label, age, country } ) => (
+					<div>
+						<div style={ { marginBottom: '0.2rem' } }>
+							{ label }
+						</div>
+						<small>
+							Age: { age }, Country: { country }
+						</small>
+					</div>
+				) }
+			/>
+			<p>Selected author: { value }</p>
+		</>
+	);
+};

From c1d08eb6d41343f6965bf40eadb582da25496646 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Mon, 25 Jul 2022 11:31:26 +0530
Subject: [PATCH 04/16] Improve renderSuggestion and renderOption signature

---
 .../components/src/combobox-control/index.js  |  4 +++-
 .../src/combobox-control/stories/index.js     | 21 +++++++++++--------
 .../src/form-token-field/suggestions-list.tsx |  2 +-
 .../components/src/form-token-field/types.ts  |  2 +-
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/packages/components/src/combobox-control/index.js b/packages/components/src/combobox-control/index.js
index 4d35c121f47d15..bb2546f6e658bb 100644
--- a/packages/components/src/combobox-control/index.js
+++ b/packages/components/src/combobox-control/index.js
@@ -280,7 +280,9 @@ function ComboboxControl( {
 							onHover={ setSelectedSuggestion }
 							onSelect={ onSuggestionSelected }
 							scrollIntoView
-							renderSuggestion={ renderOption }
+							renderSuggestion={ ( { suggestion } ) =>
+								renderOption( { option: suggestion } )
+							}
 						/>
 					) }
 				</div>
diff --git a/packages/components/src/combobox-control/stories/index.js b/packages/components/src/combobox-control/stories/index.js
index ba4efdc687b546..583cadf9783467 100644
--- a/packages/components/src/combobox-control/stories/index.js
+++ b/packages/components/src/combobox-control/stories/index.js
@@ -338,16 +338,19 @@ export const WithRenderOption = ( args ) => {
 				onChange={ setValue }
 				label="Select an author"
 				options={ authorOptions }
-				renderOption={ ( { label, age, country } ) => (
-					<div>
-						<div style={ { marginBottom: '0.2rem' } }>
-							{ label }
+				renderOption={ ( { option } ) => {
+					const { label, age, country } = option;
+					return (
+						<div>
+							<div style={ { marginBottom: '0.2rem' } }>
+								{ label }
+							</div>
+							<small>
+								Age: { age }, Country: { country }
+							</small>
 						</div>
-						<small>
-							Age: { age }, Country: { country }
-						</small>
-					</div>
-				) }
+					);
+				} }
 			/>
 			<p>Selected author: { value }</p>
 		</>
diff --git a/packages/components/src/form-token-field/suggestions-list.tsx b/packages/components/src/form-token-field/suggestions-list.tsx
index 959367da8021b6..34f5203d63595b 100644
--- a/packages/components/src/form-token-field/suggestions-list.tsx
+++ b/packages/components/src/form-token-field/suggestions-list.tsx
@@ -126,7 +126,7 @@ export function SuggestionsList< T extends string | { value: string } >( {
 				let output: ReactNode;
 
 				if ( typeof renderSuggestion === 'function' ) {
-					output = renderSuggestion( suggestion );
+					output = renderSuggestion( { suggestion } );
 				} else if ( matchText ) {
 					output = (
 						<span aria-label={ displayTransform( suggestion ) }>
diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts
index 996ba9fc31743a..862927c30c5cc5 100644
--- a/packages/components/src/form-token-field/types.ts
+++ b/packages/components/src/form-token-field/types.ts
@@ -169,7 +169,7 @@ export interface SuggestionsListProps< T = string | { value: string } > {
 	suggestions: T[];
 	displayTransform: ( value: T ) => string;
 	instanceId: string | number;
-	renderSuggestion?: ( suggestion: T ) => ReactNode;
+	renderSuggestion?: ( props: { suggestion: T } ) => ReactNode;
 }
 
 export interface TokenProps extends TokenItem {

From 458371c4d23efb04c3742d053205615402ca85d7 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Mon, 25 Jul 2022 11:33:58 +0530
Subject: [PATCH 05/16] Add renderSuggestion prop to FormTokenField

---
 packages/components/src/form-token-field/index.tsx | 2 ++
 packages/components/src/form-token-field/types.ts  | 6 +++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/packages/components/src/form-token-field/index.tsx b/packages/components/src/form-token-field/index.tsx
index eb96daa8fd6f24..cbd9c9d120c5bd 100644
--- a/packages/components/src/form-token-field/index.tsx
+++ b/packages/components/src/form-token-field/index.tsx
@@ -72,6 +72,7 @@ export function FormTokenField( props: FormTokenFieldProps ) {
 			remove: __( 'Remove item' ),
 			__experimentalInvalid: __( 'Invalid item' ),
 		},
+		renderSuggestion,
 		__experimentalExpandOnFocus = false,
 		__experimentalValidateInput = () => true,
 		__experimentalShowHowTo = true,
@@ -692,6 +693,7 @@ export function FormTokenField( props: FormTokenFieldProps ) {
 						scrollIntoView={ selectedSuggestionScroll }
 						onHover={ onSuggestionHovered }
 						onSelect={ onSuggestionSelected }
+						renderSuggestion={ renderSuggestion }
 					/>
 				) }
 			</div>
diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts
index 862927c30c5cc5..b2319eb5eb125b 100644
--- a/packages/components/src/form-token-field/types.ts
+++ b/packages/components/src/form-token-field/types.ts
@@ -158,6 +158,10 @@ export interface FormTokenFieldProps
 	 * @default false
 	 */
 	__next36pxDefaultSize?: boolean;
+	/**
+	 * Custom renderer for the token suggestions.
+	 */
+	renderSuggestion?: ( args: { suggestion: string } ) => ReactNode;
 }
 
 export interface SuggestionsListProps< T = string | { value: string } > {
@@ -169,7 +173,7 @@ export interface SuggestionsListProps< T = string | { value: string } > {
 	suggestions: T[];
 	displayTransform: ( value: T ) => string;
 	instanceId: string | number;
-	renderSuggestion?: ( props: { suggestion: T } ) => ReactNode;
+	renderSuggestion?: ( args: { suggestion: T } ) => ReactNode;
 }
 
 export interface TokenProps extends TokenItem {

From cc5d7dadf33e64501dddec7e77fd4a54785f7d3c Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Mon, 25 Jul 2022 11:42:43 +0530
Subject: [PATCH 06/16] Add props to README

---
 packages/components/src/combobox-control/README.md | 7 +++++++
 packages/components/src/form-token-field/README.md | 3 ++-
 packages/components/src/form-token-field/types.ts  | 2 +-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/packages/components/src/combobox-control/README.md b/packages/components/src/combobox-control/README.md
index e0d5a71ab14152..c4ec026271a295 100644
--- a/packages/components/src/combobox-control/README.md
+++ b/packages/components/src/combobox-control/README.md
@@ -116,6 +116,13 @@ The current value of the input.
 -   Type: `mixed`
 -   Required: Yes
 
+#### renderOption
+
+Custom renderer for options in suggestion list.
+
+-   Type: `Function` - `( args: { option: object } ) => ReactNode`
+-   Required: No
+
 ## Related components
 
 -   Like this component, but without a search input, the `CustomSelectControl` component.
diff --git a/packages/components/src/form-token-field/README.md b/packages/components/src/form-token-field/README.md
index e24f2f2ed7d8c4..8ddde047221d1c 100644
--- a/packages/components/src/form-token-field/README.md
+++ b/packages/components/src/form-token-field/README.md
@@ -56,6 +56,7 @@ The `value` property is handled in a manner similar to controlled form component
     -   `removed` - The user removed an existing token.
     -   `remove` - The user focused the button to remove the token.
     -   `__experimentalInvalid` - The user tried to add a token that didn't pass the validation.
+-   `renderSuggestion` - Custom renderer for suggestions.
 -   `__experimentalExpandOnFocus` - If true, the suggestions list will be always expanded when the input field has the focus.
 -   `__experimentalShowHowTo` - If false, the text on how to use the select (ie: _Separate with commas or the Enter key._) will be hidden.
 -   `__experimentalValidateInput` - If passed, all introduced values will be validated before being added as tokens.
@@ -78,7 +79,7 @@ const continents = [
 const MyFormTokenField = () => {
 	const [ selectedContinents, setSelectedContinents ] = useState( [] );
 
-	return(
+	return (
 		<FormTokenField
 			value={ selectedContinents }
 			suggestions={ continents }
diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts
index b2319eb5eb125b..68301762f9db4f 100644
--- a/packages/components/src/form-token-field/types.ts
+++ b/packages/components/src/form-token-field/types.ts
@@ -159,7 +159,7 @@ export interface FormTokenFieldProps
 	 */
 	__next36pxDefaultSize?: boolean;
 	/**
-	 * Custom renderer for the token suggestions.
+	 * Custom renderer for suggestions.
 	 */
 	renderSuggestion?: ( args: { suggestion: string } ) => ReactNode;
 }

From 3229289cd992840e808fe24e0d9b430bcdd8f492 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Mon, 25 Jul 2022 11:46:01 +0530
Subject: [PATCH 07/16] Update changelog

---
 packages/components/CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md
index 5f8a7d95afd863..91c7a1f4a407c5 100644
--- a/packages/components/CHANGELOG.md
+++ b/packages/components/CHANGELOG.md
@@ -23,6 +23,7 @@
 -   `BorderControl`: Render dropdown as prefix within its `UnitControl` ([#42212](https://github.com/WordPress/gutenberg/pull/42212/))
 -   `UnitControl`: Update prop types to allow ReactNode as prefix ([#42212](https://github.com/WordPress/gutenberg/pull/42212/))
 -   `ToolsPanel`: Updated README with panel layout information and more expansive usage example ([#42615](https://github.com/WordPress/gutenberg/pull/42615)).
+-   `ComboboxControl`, `FormTokenField`: Add custom render callback for options in suggestions list ([#42597](https://github.com/WordPress/gutenberg/pull/42597/)).
 
 ### Internal
 

From b602ccede0ca22d5c574e3fbfe19253f44fd9a67 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Mon, 25 Jul 2022 12:24:08 +0530
Subject: [PATCH 08/16] Fix fatal error

---
 packages/components/src/combobox-control/index.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/components/src/combobox-control/index.js b/packages/components/src/combobox-control/index.js
index bb2546f6e658bb..6b7addb6304c3d 100644
--- a/packages/components/src/combobox-control/index.js
+++ b/packages/components/src/combobox-control/index.js
@@ -281,7 +281,7 @@ function ComboboxControl( {
 							onSelect={ onSuggestionSelected }
 							scrollIntoView
 							renderSuggestion={ ( { suggestion } ) =>
-								renderOption( { option: suggestion } )
+								renderOption?.( { option: suggestion } )
 							}
 						/>
 					) }

From 901b40cbd3c67a55184be879070e8ef9318983ca Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Wed, 27 Jul 2022 10:16:35 +0530
Subject: [PATCH 09/16] Fix backward compatibility

---
 packages/components/src/combobox-control/index.js | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/packages/components/src/combobox-control/index.js b/packages/components/src/combobox-control/index.js
index 6b7addb6304c3d..b8ee8dd5d6d507 100644
--- a/packages/components/src/combobox-control/index.js
+++ b/packages/components/src/combobox-control/index.js
@@ -280,8 +280,14 @@ function ComboboxControl( {
 							onHover={ setSelectedSuggestion }
 							onSelect={ onSuggestionSelected }
 							scrollIntoView
-							renderSuggestion={ ( { suggestion } ) =>
-								renderOption?.( { option: suggestion } )
+							renderSuggestion={
+								typeof renderOption === 'function'
+									? ( { suggestion } ) => {
+											renderOption( {
+												option: suggestion,
+											} );
+									  }
+									: null
 							}
 						/>
 					) }

From 26e3ce440a3fc94c73a17ef4ea7ce2077cc8bc6a Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Wed, 27 Jul 2022 21:01:08 +0530
Subject: [PATCH 10/16] Update
 packages/components/src/combobox-control/index.js

Co-authored-by: Renzo Canepa <rcanepag@gmail.com>
---
 packages/components/src/combobox-control/index.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/components/src/combobox-control/index.js b/packages/components/src/combobox-control/index.js
index b8ee8dd5d6d507..7316f85b0d7955 100644
--- a/packages/components/src/combobox-control/index.js
+++ b/packages/components/src/combobox-control/index.js
@@ -283,7 +283,7 @@ function ComboboxControl( {
 							renderSuggestion={
 								typeof renderOption === 'function'
 									? ( { suggestion } ) => {
-											renderOption( {
+											return renderOption( {
 												option: suggestion,
 											} );
 									  }

From b9ffdfed76bd0cd1f62a31a3b40325cae9dc5968 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Wed, 3 Aug 2022 10:37:35 +0530
Subject: [PATCH 11/16] Add __experimental prefix to render callbacks

---
 packages/components/src/combobox-control/index.js    | 12 +++---------
 .../components/src/combobox-control/stories/index.js |  8 ++++++--
 packages/components/src/form-token-field/index.tsx   |  4 ++--
 .../src/form-token-field/suggestions-list.tsx        |  6 +++---
 packages/components/src/form-token-field/types.ts    |  4 ++--
 5 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/packages/components/src/combobox-control/index.js b/packages/components/src/combobox-control/index.js
index 7316f85b0d7955..f982735387aee0 100644
--- a/packages/components/src/combobox-control/index.js
+++ b/packages/components/src/combobox-control/index.js
@@ -58,7 +58,7 @@ function ComboboxControl( {
 	messages = {
 		selected: __( 'Item selected.' ),
 	},
-	renderOption,
+	__experimentalRenderItem,
 } ) {
 	const currentOption = options.find( ( option ) => option.value === value );
 	const currentLabel = currentOption?.label ?? '';
@@ -280,14 +280,8 @@ function ComboboxControl( {
 							onHover={ setSelectedSuggestion }
 							onSelect={ onSuggestionSelected }
 							scrollIntoView
-							renderSuggestion={
-								typeof renderOption === 'function'
-									? ( { suggestion } ) => {
-											return renderOption( {
-												option: suggestion,
-											} );
-									  }
-									: null
+							__experimentalRenderItem={
+								__experimentalRenderItem
 							}
 						/>
 					) }
diff --git a/packages/components/src/combobox-control/stories/index.js b/packages/components/src/combobox-control/stories/index.js
index 583cadf9783467..b713456e981286 100644
--- a/packages/components/src/combobox-control/stories/index.js
+++ b/packages/components/src/combobox-control/stories/index.js
@@ -338,8 +338,8 @@ export const WithRenderOption = ( args ) => {
 				onChange={ setValue }
 				label="Select an author"
 				options={ authorOptions }
-				renderOption={ ( { option } ) => {
-					const { label, age, country } = option;
+				__experimentalRenderItem={ ( { item } ) => {
+					const { label, age, country } = item;
 					return (
 						<div>
 							<div style={ { marginBottom: '0.2rem' } }>
@@ -356,3 +356,7 @@ export const WithRenderOption = ( args ) => {
 		</>
 	);
 };
+
+WithRenderOption.args = {
+	allowReset: false,
+};
diff --git a/packages/components/src/form-token-field/index.tsx b/packages/components/src/form-token-field/index.tsx
index cbd9c9d120c5bd..2dde11ba9627be 100644
--- a/packages/components/src/form-token-field/index.tsx
+++ b/packages/components/src/form-token-field/index.tsx
@@ -72,7 +72,7 @@ export function FormTokenField( props: FormTokenFieldProps ) {
 			remove: __( 'Remove item' ),
 			__experimentalInvalid: __( 'Invalid item' ),
 		},
-		renderSuggestion,
+		__experimentalRenderItem,
 		__experimentalExpandOnFocus = false,
 		__experimentalValidateInput = () => true,
 		__experimentalShowHowTo = true,
@@ -693,7 +693,7 @@ export function FormTokenField( props: FormTokenFieldProps ) {
 						scrollIntoView={ selectedSuggestionScroll }
 						onHover={ onSuggestionHovered }
 						onSelect={ onSuggestionSelected }
-						renderSuggestion={ renderSuggestion }
+						__experimentalRenderItem={ __experimentalRenderItem }
 					/>
 				) }
 			</div>
diff --git a/packages/components/src/form-token-field/suggestions-list.tsx b/packages/components/src/form-token-field/suggestions-list.tsx
index 34f5203d63595b..cb3f8299c935f7 100644
--- a/packages/components/src/form-token-field/suggestions-list.tsx
+++ b/packages/components/src/form-token-field/suggestions-list.tsx
@@ -31,7 +31,7 @@ export function SuggestionsList< T extends string | { value: string } >( {
 	suggestions = [],
 	displayTransform,
 	instanceId,
-	renderSuggestion,
+	__experimentalRenderItem,
 }: SuggestionsListProps< T > ) {
 	const [ scrollingIntoView, setScrollingIntoView ] = useState( false );
 
@@ -125,8 +125,8 @@ export function SuggestionsList< T extends string | { value: string } >( {
 
 				let output: ReactNode;
 
-				if ( typeof renderSuggestion === 'function' ) {
-					output = renderSuggestion( { suggestion } );
+				if ( typeof __experimentalRenderItem === 'function' ) {
+					output = __experimentalRenderItem( { item: suggestion } );
 				} else if ( matchText ) {
 					output = (
 						<span aria-label={ displayTransform( suggestion ) }>
diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts
index 68301762f9db4f..269d7670feaec0 100644
--- a/packages/components/src/form-token-field/types.ts
+++ b/packages/components/src/form-token-field/types.ts
@@ -161,7 +161,7 @@ export interface FormTokenFieldProps
 	/**
 	 * Custom renderer for suggestions.
 	 */
-	renderSuggestion?: ( args: { suggestion: string } ) => ReactNode;
+	__experimentalRenderItem?: ( args: { item: string } ) => ReactNode;
 }
 
 export interface SuggestionsListProps< T = string | { value: string } > {
@@ -173,7 +173,7 @@ export interface SuggestionsListProps< T = string | { value: string } > {
 	suggestions: T[];
 	displayTransform: ( value: T ) => string;
 	instanceId: string | number;
-	renderSuggestion?: ( args: { suggestion: T } ) => ReactNode;
+	__experimentalRenderItem?: ( args: { item: T } ) => ReactNode;
 }
 
 export interface TokenProps extends TokenItem {

From f60149135814e94c13dcfe609cc3c25fba42eb2b Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Wed, 3 Aug 2022 17:38:51 +0530
Subject: [PATCH 12/16] Update
 packages/components/src/form-token-field/types.ts

Co-authored-by: Lena Morita <lena@jaguchi.com>
---
 packages/components/src/form-token-field/types.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts
index 269d7670feaec0..a979aab45dd2c9 100644
--- a/packages/components/src/form-token-field/types.ts
+++ b/packages/components/src/form-token-field/types.ts
@@ -164,7 +164,9 @@ export interface FormTokenFieldProps
 	__experimentalRenderItem?: ( args: { item: string } ) => ReactNode;
 }
 
-export interface SuggestionsListProps< T = string | { value: string } > {
+export interface SuggestionsListProps<
+	T = string | ( Record< string, unknown > & { value: string } )
+> {
 	selectedIndex: number;
 	scrollIntoView: boolean;
 	match: T;

From 444c735a70ae67d77a7adb8cbe6b66d2ccfe9740 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Wed, 3 Aug 2022 17:48:24 +0530
Subject: [PATCH 13/16] Improve and clean up story

---
 .../src/combobox-control/stories/index.js     | 95 +++++++------------
 1 file changed, 33 insertions(+), 62 deletions(-)

diff --git a/packages/components/src/combobox-control/stories/index.js b/packages/components/src/combobox-control/stories/index.js
index b713456e981286..3c6974e954afa6 100644
--- a/packages/components/src/combobox-control/stories/index.js
+++ b/packages/components/src/combobox-control/stories/index.js
@@ -266,7 +266,7 @@ const mapCountryOption = ( country ) => ( {
 
 const countryOptions = countries.map( mapCountryOption );
 
-function CountryCodeComboboxControl( args ) {
+function Template( args ) {
 	const [ value, setValue ] = useState( null );
 
 	return (
@@ -275,88 +275,59 @@ function CountryCodeComboboxControl( args ) {
 				{ ...args }
 				value={ value }
 				onChange={ setValue }
-				label="Select a country"
-				options={ countryOptions }
 			/>
 			<p>Value: { value }</p>
 		</>
 	);
 }
-export const _default = CountryCodeComboboxControl.bind( {} );
-_default.args = {
+export const Default = Template.bind( {} );
+Default.args = {
 	__next36pxDefaultSize: false,
 	allowReset: false,
+	label: 'Select a country',
+	options: countryOptions,
 };
 
-const authors = [
+const authorOptions = [
 	{
-		name: 'Hermann P. Schnitzel',
-		age: 45,
-		country: 'Germany',
-	},
-	{
-		name: 'Shequondolisa Bivouac',
-		age: 43,
-		country: 'France',
-	},
-	{
-		name: 'Bodrum Salvador',
-		age: 42,
-		country: 'Spain',
-	},
-	{
-		name: 'Parsley Montana',
+		value: 'parsley',
+		label: 'Parsley Montana',
 		age: 48,
 		country: 'Germany',
 	},
 	{
-		name: 'Cabbage New York',
+		value: 'cabbage',
+		label: 'Cabbage New York',
 		age: 44,
 		country: 'France',
 	},
 	{
-		name: 'Jake Weary',
+		value: 'jake',
+		label: 'Jake Weary',
 		age: 41,
 		country: 'United Kingdom',
 	},
 ];
 
-const authorOptions = authors.map( ( { name, ...details } ) => ( {
-	value: name,
-	label: name,
-	...details,
-} ) );
-
-export const WithRenderOption = ( args ) => {
-	const [ value, setValue ] = useState( '' );
-
-	return (
-		<>
-			<ComboboxControl
-				{ ...args }
-				value={ value }
-				onChange={ setValue }
-				label="Select an author"
-				options={ authorOptions }
-				__experimentalRenderItem={ ( { item } ) => {
-					const { label, age, country } = item;
-					return (
-						<div>
-							<div style={ { marginBottom: '0.2rem' } }>
-								{ label }
-							</div>
-							<small>
-								Age: { age }, Country: { country }
-							</small>
-						</div>
-					);
-				} }
-			/>
-			<p>Selected author: { value }</p>
-		</>
-	);
-};
-
-WithRenderOption.args = {
-	allowReset: false,
+/**
+ * The rendered output of each suggestion can be customized by passing a
+ * render function to the `__experimentalRenderItem` prop. (This is still an experimental feature
+ * and is subject to change.)
+ */
+export const WithCustomRenderItem = Template.bind( {} );
+WithCustomRenderItem.args = {
+	...Default.args,
+	label: 'Select an author',
+	options: authorOptions,
+	__experimentalRenderItem: ( { item } ) => {
+		const { label, age, country } = item;
+		return (
+			<div>
+				<div style={ { marginBottom: '0.2rem' } }>{ label }</div>
+				<small>
+					Age: { age }, Country: { country }
+				</small>
+			</div>
+		);
+	},
 };

From 763dafff4855922d0382dd06ff6f0b6c5c53cd4a Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Wed, 3 Aug 2022 17:48:43 +0530
Subject: [PATCH 14/16] Update docs

---
 packages/components/src/combobox-control/README.md | 2 +-
 packages/components/src/form-token-field/README.md | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/components/src/combobox-control/README.md b/packages/components/src/combobox-control/README.md
index c4ec026271a295..68dc4012e407a8 100644
--- a/packages/components/src/combobox-control/README.md
+++ b/packages/components/src/combobox-control/README.md
@@ -116,7 +116,7 @@ The current value of the input.
 -   Type: `mixed`
 -   Required: Yes
 
-#### renderOption
+#### \_\_experimentalRenderItem
 
 Custom renderer for options in suggestion list.
 
diff --git a/packages/components/src/form-token-field/README.md b/packages/components/src/form-token-field/README.md
index 8ddde047221d1c..9c6ec50e3d14c6 100644
--- a/packages/components/src/form-token-field/README.md
+++ b/packages/components/src/form-token-field/README.md
@@ -56,7 +56,7 @@ The `value` property is handled in a manner similar to controlled form component
     -   `removed` - The user removed an existing token.
     -   `remove` - The user focused the button to remove the token.
     -   `__experimentalInvalid` - The user tried to add a token that didn't pass the validation.
--   `renderSuggestion` - Custom renderer for suggestions.
+-   `__experimentalRenderItem` - Custom renderer for suggestions.
 -   `__experimentalExpandOnFocus` - If true, the suggestions list will be always expanded when the input field has the focus.
 -   `__experimentalShowHowTo` - If false, the text on how to use the select (ie: _Separate with commas or the Enter key._) will be hidden.
 -   `__experimentalValidateInput` - If passed, all introduced values will be validated before being added as tokens.

From 21746dccbbf1a35ba293a5f10657306a1c4a823b Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Wed, 3 Aug 2022 17:51:46 +0530
Subject: [PATCH 15/16] Update form-token-field story

---
 .../src/form-token-field/stories/index.tsx         | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/packages/components/src/form-token-field/stories/index.tsx b/packages/components/src/form-token-field/stories/index.tsx
index 0d7fcad6564be0..54a4467a791eb5 100644
--- a/packages/components/src/form-token-field/stories/index.tsx
+++ b/packages/components/src/form-token-field/stories/index.tsx
@@ -101,3 +101,17 @@ Async.args = {
 	label: 'Type a continent',
 	suggestions: continents,
 };
+
+/**
+ * The rendered output of each suggestion can be customized by passing a
+ * render function to the `__experimentalRenderItem` prop. (This is still an experimental feature
+ * and is subject to change.)
+ */
+export const WithCustomRenderItem: ComponentStory< typeof FormTokenField > =
+	DefaultTemplate.bind( {} );
+WithCustomRenderItem.args = {
+	...Default.args,
+	__experimentalRenderItem: ( { item } ) => (
+		<div>{ `${ item } — a nice place to visit` }</div>
+	),
+};

From 49ebc8730ae59f72a3c5cf36573cf766abc34e41 Mon Sep 17 00:00:00 2001
From: Manzoor Wani <manzoorwani.jk@gmail.com>
Date: Tue, 9 Aug 2022 20:21:49 +0530
Subject: [PATCH 16/16] Improve docs

---
 packages/components/src/combobox-control/README.md | 6 +++---
 packages/components/src/form-token-field/README.md | 2 +-
 packages/components/src/form-token-field/types.ts  | 3 +++
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/packages/components/src/combobox-control/README.md b/packages/components/src/combobox-control/README.md
index 68dc4012e407a8..f6e81d2cff3513 100644
--- a/packages/components/src/combobox-control/README.md
+++ b/packages/components/src/combobox-control/README.md
@@ -116,11 +116,11 @@ The current value of the input.
 -   Type: `mixed`
 -   Required: Yes
 
-#### \_\_experimentalRenderItem
+#### __experimentalRenderItem
 
-Custom renderer for options in suggestion list.
+Custom renderer invoked for each option in the suggestion list. The render prop receives as its argument an object containing, under the `item` key, the single option's data (directly from the array of data passed to the `options` prop).
 
--   Type: `Function` - `( args: { option: object } ) => ReactNode`
+-   Type: `Function` - `( args: { item: object } ) => ReactNode`
 -   Required: No
 
 ## Related components
diff --git a/packages/components/src/form-token-field/README.md b/packages/components/src/form-token-field/README.md
index 9c6ec50e3d14c6..2df2ad3c501759 100644
--- a/packages/components/src/form-token-field/README.md
+++ b/packages/components/src/form-token-field/README.md
@@ -56,7 +56,7 @@ The `value` property is handled in a manner similar to controlled form component
     -   `removed` - The user removed an existing token.
     -   `remove` - The user focused the button to remove the token.
     -   `__experimentalInvalid` - The user tried to add a token that didn't pass the validation.
--   `__experimentalRenderItem` - Custom renderer for suggestions.
+-   `__experimentalRenderItem` - Custom renderer invoked for each option in the suggestion list. The render prop receives as its argument an object containing, under the `item` key, the single option's data (directly from the array of data passed to the `options` prop).
 -   `__experimentalExpandOnFocus` - If true, the suggestions list will be always expanded when the input field has the focus.
 -   `__experimentalShowHowTo` - If false, the text on how to use the select (ie: _Separate with commas or the Enter key._) will be hidden.
 -   `__experimentalValidateInput` - If passed, all introduced values will be validated before being added as tokens.
diff --git a/packages/components/src/form-token-field/types.ts b/packages/components/src/form-token-field/types.ts
index a979aab45dd2c9..8a032700b411a1 100644
--- a/packages/components/src/form-token-field/types.ts
+++ b/packages/components/src/form-token-field/types.ts
@@ -164,6 +164,9 @@ export interface FormTokenFieldProps
 	__experimentalRenderItem?: ( args: { item: string } ) => ReactNode;
 }
 
+/**
+ * `T` can be either a `string` or an object which must have a `value` prop as a string.
+ */
 export interface SuggestionsListProps<
 	T = string | ( Record< string, unknown > & { value: string } )
 > {