HEX
Server: LiteSpeed
System: Linux eko108.isimtescil.net 4.18.0-477.21.1.lve.1.el8.x86_64 #1 SMP Tue Sep 5 23:08:35 UTC 2023 x86_64
User: uyarreklamcomtr (11202)
PHP: 7.4.33
Disabled: opcache_get_status
Upload Files
File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/editor-components.tar
block-title/editor.scss000064400000000557151550716220011153 0ustar00// Ensure textarea bg color is transparent for block titles.
// Some themes (e.g. Twenty Twenty) set a non-white background for the editor, and Gutenberg sets white background for text inputs, creating this issue.
// https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/1204
.wc-block-editor-components-title {
	background-color: transparent;
}
block-title/index.tsx000064400000002034151550716220010627 0ustar00/**
 * External dependencies
 */
import { PlainText } from '@wordpress/block-editor';
import { withInstanceId } from '@wordpress/compose';
import { __ } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import './editor.scss';
interface BlockTitleProps {
	className: string;
	headingLevel: number;
	onChange: ( value: string ) => void;
	heading: string;
	instanceId: number;
}
const BlockTitle = ( {
	className,
	headingLevel,
	onChange,
	heading,
	instanceId,
}: BlockTitleProps ) => {
	const TagName = `h${ headingLevel }` as keyof JSX.IntrinsicElements;
	return (
		<TagName className={ className }>
			<label
				className="screen-reader-text"
				htmlFor={ `block-title-${ instanceId }` }
			>
				{ __( 'Block title', 'woo-gutenberg-products-block' ) }
			</label>
			<PlainText
				id={ `block-title-${ instanceId }` }
				className="wc-block-editor-components-title"
				value={ heading }
				onChange={ onChange }
				style={ { backgroundColor: 'transparent' } }
			/>
		</TagName>
	);
};

export default withInstanceId( BlockTitle );
color-panel/index.tsx000064400000010507151550716220010635 0ustar00/* eslint-disable @typescript-eslint/ban-ts-comment */
/**
 * External dependencies
 */
import { useMemo } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import {
	store as blockEditorStore,
	getColorClassName,
	InspectorControls,
	useBlockEditContext,
	// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
	__experimentalColorGradientSettingsDropdown as ColorGradientSettingsDropdown,
	// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
	__experimentalUseMultipleOriginColorsAndGradients as useMultipleOriginColorsAndGradients,
} from '@wordpress/block-editor';

/**
 * Internal dependencies
 */
import {
	ColorSetting,
	ColorAttributes,
	ColorPaletteOption,
	GradientPaletteOption,
	ColorGradientOptionsItems,
	CustomColorsMap,
} from './types';

const flattenColors = (
	colorGradientOptions: ColorGradientOptionsItems
): ColorPaletteOption[] & GradientPaletteOption[] => {
	const flattenedColors: ColorPaletteOption[] & GradientPaletteOption[] = [];
	if ( colorGradientOptions.colors ) {
		colorGradientOptions.colors.forEach( ( colorItem ) => {
			flattenedColors.push( ...colorItem.colors );
		} );
	}
	if ( colorGradientOptions.gradients ) {
		colorGradientOptions.gradients.forEach( ( gradientItem ) => {
			flattenedColors.push( ...gradientItem.gradients );
		} );
	}
	return flattenedColors;
};

const getColorObject = (
	colors: ColorPaletteOption[] & GradientPaletteOption[],
	colorValue: string | undefined,
	context: string
) => {
	if ( ! colorValue ) {
		return;
	}
	const colorObject =
		( colors?.find( ( color ) => {
			return color.color === colorValue || color.slug === colorValue;
		} ) as {
			color: string;
			slug?: string | undefined;
			class?: string | undefined;
		} ) || {};
	if ( ! colorObject?.color ) {
		colorObject.color = colorValue;
	}
	colorObject.class = getColorClassName( context, colorObject?.slug );
	return colorObject;
};

const createSetColor = (
	colorName: string,
	context: string,
	colors: ColorPaletteOption[] & GradientPaletteOption[],
	setAttributes: ( attributes: Record< string, unknown > ) => void
): ( ( colorValue?: string ) => void ) => {
	return ( colorValue?: string ) => {
		const colorObject = getColorObject( colors, colorValue, context ) || {};
		setAttributes( {
			[ colorName ]: colorObject,
		} );
	};
};

const createSettings = (
	colorTypes: CustomColorsMap,
	colors: ColorPaletteOption[] & GradientPaletteOption[],
	attributes: ColorAttributes | undefined,
	setAttributes: ( attributes: Record< string, unknown > ) => void
) => {
	return Object.entries( colorTypes ).reduce(
		( settingsAccumulator, [ colorAttributeName, colorAttribute ] ) => {
			const colorSetter = createSetColor(
				colorAttributeName,
				colorAttribute.context,
				colors,
				setAttributes
			);
			const colorSetting = {
				colorValue:
					attributes?.[ colorAttributeName ]?.color ?? undefined,
				label: colorAttribute.label,
				onColorChange: colorSetter,
				resetAllFilter: () => colorSetter(),
			};
			settingsAccumulator.push( colorSetting );
			return settingsAccumulator;
		},
		[] as ColorSetting[]
	);
};

export const ColorPanel = ( {
	colorTypes,
}: {
	colorTypes: CustomColorsMap;
} ) => {
	const colorGradientOptions = useMultipleOriginColorsAndGradients();
	const flattenedColors = flattenColors( colorGradientOptions );
	const { clientId } = useBlockEditContext();
	const attributes = useSelect(
		( select ) => {
			// @ts-ignore @wordpress/block-editor/store types not provided
			const { getBlockAttributes } = select( blockEditorStore );
			return getBlockAttributes( clientId ) || {};
		},
		[ clientId ]
	);
	// @ts-ignore @wordpress/block-editor/store types not provided
	const { updateBlockAttributes } = useDispatch( blockEditorStore );
	const settings = useMemo( () => {
		return createSettings(
			colorTypes,
			flattenedColors,
			attributes,
			( newAttributes ) =>
				updateBlockAttributes( clientId, newAttributes )
		);
	}, [
		colorTypes,
		flattenedColors,
		updateBlockAttributes,
		attributes,
		clientId,
	] );
	return (
		colorGradientOptions.hasColorsOrGradients && (
			// @ts-ignore The dev package version doesn't have types for group.
			<InspectorControls group="color">
				<ColorGradientSettingsDropdown
					__experimentalIsRenderedInSidebar
					settings={ settings }
					panelId={ clientId }
					{ ...colorGradientOptions }
				/>
			</InspectorControls>
		)
	);
};
color-panel/types.ts000064400000001543151550716220010502 0ustar00export interface ColorSetting {
	colorValue: string | undefined;
	onColorChange: ( value: string ) => void;
	label: string;
	resetAllFilter: () => void;
}

export interface ColorAttributes {
	[ key: string ]: {
		[ key: string ]: string;
	};
}

export interface CustomColorsMap {
	[ key: string ]: {
		label: string;
		context: string;
	};
}

export interface ColorPaletteOption {
	name: string;
	slug: string | undefined;
	color: string;
}

export interface GradientPaletteOption {
	name: string;
	gradient: string;
	slug: string;
}

interface ColorGradientOptionsColorItem {
	name: string;
	colors: ColorPaletteOption[];
}

interface ColorGradientOptionsGradientItem {
	name: string;
	gradients: GradientPaletteOption[];
}

export interface ColorGradientOptionsItems {
	colors: [ ColorGradientOptionsColorItem ];
	gradients: [ ColorGradientOptionsGradientItem ];
}
default-notice/editor.scss000064400000000415151550716220011636 0ustar00.wc-default-page-notice.is-dismissible {
	margin: 0;
	padding-right: 16px;
	.components-notice__dismiss {
		min-width: 24px;
	}
	.components-notice__content {
		margin: 4px 0;
	}
	svg {
		width: 16px;
		height: 16px;
	}
}

.wc-blocks-legacy-page-notice {
	margin: 0;
}
default-notice/index.tsx000064400000010130151550716220011315 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { store as editorStore } from '@wordpress/editor';
import triggerFetch from '@wordpress/api-fetch';
import { store as coreStore } from '@wordpress/core-data';
import { Notice, Button } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { CHECKOUT_PAGE_ID, CART_PAGE_ID } from '@woocommerce/block-settings';
import { useCallback, useState } from '@wordpress/element';
/**
 * Internal dependencies
 */
import './editor.scss';

export function DefaultNotice( { block }: { block: string } ) {
	// To avoid having the same logic twice, we're going to handle both pages here.
	const ORIGINAL_PAGE_ID =
		block === 'checkout' ? CHECKOUT_PAGE_ID : CART_PAGE_ID;
	const settingName =
		block === 'checkout'
			? 'woocommerce_checkout_page_id'
			: 'woocommerce_cart_page_id';

	const noticeContent =
		block === 'checkout'
			? __(
					'If you would like to use this block as your default checkout, update your page settings',
					'woo-gutenberg-products-block'
			  )
			: __(
					'If you would like to use this block as your default cart, update your page settings',
					'woo-gutenberg-products-block'
			  );

	// Everything below works the same for Cart/Checkout
	const { saveEntityRecord } = useDispatch( coreStore );
	const { editPost, savePost } = useDispatch( editorStore );
	const { slug, isLoadingPage, postPublished, currentPostId } = useSelect(
		( select ) => {
			const { getEntityRecord, isResolving } = select( coreStore );
			const { isCurrentPostPublished, getCurrentPostId } =
				select( editorStore );
			return {
				slug:
					getEntityRecord( 'postType', 'page', ORIGINAL_PAGE_ID )
						?.slug || block,
				isLoadingPage: isResolving( 'getEntityRecord', [
					'postType',
					'page',
					ORIGINAL_PAGE_ID,
				] ),
				postPublished: isCurrentPostPublished(),
				currentPostId: getCurrentPostId(),
			};
		},
		[]
	);
	const [ settingStatus, setStatus ] = useState( 'pristine' );
	const updatePage = useCallback( () => {
		setStatus( 'updating' );
		Promise.resolve()
			.then( () =>
				triggerFetch( {
					path: `/wc/v3/settings/advanced/${ settingName }`,
					method: 'GET',
				} )
			)
			.catch( ( error ) => {
				if ( error.code === 'rest_setting_setting_invalid' ) {
					setStatus( 'error' );
				}
			} )
			.then( () => {
				if ( ! postPublished ) {
					editPost( { status: 'publish' } );
					return savePost();
				}
			} )
			.then( () =>
				// Make this page ID the default cart/checkout.
				triggerFetch( {
					path: `/wc/v3/settings/advanced/${ settingName }`,
					method: 'POST',
					data: {
						value: currentPostId.toString(),
					},
				} )
			)
			// Append `-2` to the original link so we can use it here.
			.then( () => {
				if ( ORIGINAL_PAGE_ID !== 0 ) {
					return saveEntityRecord( 'postType', 'page', {
						id: ORIGINAL_PAGE_ID,
						slug: `${ slug }-2`,
					} );
				}
			} )
			// Use the original link for this page.
			.then( () => editPost( { slug } ) )
			// Save page.
			.then( () => savePost() )
			.then( () => setStatus( 'updated' ) );
	}, [
		postPublished,
		editPost,
		savePost,
		settingName,
		currentPostId,
		ORIGINAL_PAGE_ID,
		saveEntityRecord,
		slug,
	] );
	if ( currentPostId === ORIGINAL_PAGE_ID || settingStatus === 'dismissed' ) {
		return null;
	}
	return (
		<Notice
			className="wc-default-page-notice"
			status={ settingStatus === 'updated' ? 'success' : 'warning' }
			onRemove={ () => setStatus( 'dismissed' ) }
			spokenMessage={
				settingStatus === 'updated'
					? __(
							'Page settings updated',
							'woo-gutenberg-products-block'
					  )
					: noticeContent
			}
		>
			{ settingStatus === 'updated' ? (
				__( 'Page settings updated', 'woo-gutenberg-products-block' )
			) : (
				<>
					<p>{ noticeContent }</p>
					<Button
						onClick={ updatePage }
						variant="secondary"
						isBusy={ settingStatus === 'updating' }
						disabled={ isLoadingPage }
						isSmall={ true }
					>
						{ __(
							'Update your page settings',
							'woo-gutenberg-products-block'
						) }
					</Button>
				</>
			) }
		</Notice>
	);
}
edit-product-link/index.tsx000064400000003011151550716220011750 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { Icon, external } from '@wordpress/icons';
import { ADMIN_URL } from '@woocommerce/settings';
import { InspectorControls } from '@wordpress/block-editor';
import { useProductDataContext } from '@woocommerce/shared-context';

interface EditProductLinkProps {
	id?: number | undefined;
	productId?: number | undefined;
}

/**
 * Component to render an edit product link in the sidebar.
 *
 * @param {Object} props Component props.
 */
const EditProductLink = ( props: EditProductLinkProps ): JSX.Element | null => {
	const productDataContext = useProductDataContext();
	const product = productDataContext.product || {};
	const productId = product.id || props.productId || 0;

	if ( ! productId || productId === 1 ) {
		return null;
	}

	return (
		<InspectorControls>
			<div className="wc-block-single-product__edit-card">
				<div className="wc-block-single-product__edit-card-title">
					<a
						href={ `${ ADMIN_URL }post.php?post=${ productId }&action=edit` }
						target="_blank"
						rel="noopener noreferrer"
					>
						{ __(
							"Edit this product's details",
							'woo-gutenberg-products-block'
						) }
						<Icon icon={ external } size={ 16 } />
					</a>
				</div>
				<div className="wc-block-single-product__edit-card-description">
					{ __(
						'Edit details such as title, price, description and more.',
						'woo-gutenberg-products-block'
					) }
				</div>
			</div>
		</InspectorControls>
	);
};

export default EditProductLink;
editable-button/index.tsx000064400000001467151550716220011511 0ustar00/**
 * External dependencies
 */
import Button, { ButtonProps } from '@woocommerce/base-components/button';
import { RichText } from '@wordpress/block-editor';

export interface EditableButtonProps
	extends Omit< ButtonProps, 'onChange' | 'placeholder' | 'value' > {
	/**
	 * On change callback.
	 */
	onChange: ( value: string ) => void;
	/**
	 * The placeholder of the editable button.
	 */
	placeholder?: string;
	/**
	 * The current value of the editable button.
	 */
	value: string;
}

const EditableButton = ( {
	onChange,
	placeholder,
	value,
	...props
}: EditableButtonProps ) => {
	return (
		<Button { ...props }>
			<RichText
				multiline={ false }
				allowedFormats={ [] }
				value={ value }
				placeholder={ placeholder }
				onChange={ onChange }
			/>
		</Button>
	);
};

export default EditableButton;
error-placeholder/editor.scss000064400000000361151550716220012344 0ustar00.wc-block-error-message {
	margin-bottom: 16px;
	margin-top: 8px;
}

.wc-block-api-error {
	.components-placeholder__fieldset {
		display: block;
	}

	.wc-block-error-message {
		margin-top: 0;
	}

	.components-spinner {
		float: none;
	}
}
error-placeholder/error-message.tsx000064400000002155151550716220013477 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { escapeHTML } from '@wordpress/escape-html';

/**
 * Internal dependencies
 */
import { ErrorObject } from '.';

export interface ErrorMessageProps {
	/**
	 * The error object.
	 */
	error: ErrorObject;
}

const getErrorMessage = ( { message, type }: ErrorObject ) => {
	if ( ! message ) {
		return __(
			'An error has prevented the block from being updated.',
			'woo-gutenberg-products-block'
		);
	}

	if ( type === 'general' ) {
		return (
			<span>
				{ __(
					'The following error was returned',
					'woo-gutenberg-products-block'
				) }
				<br />
				<code>{ escapeHTML( message ) }</code>
			</span>
		);
	}

	if ( type === 'api' ) {
		return (
			<span>
				{ __(
					'The following error was returned from the API',
					'woo-gutenberg-products-block'
				) }
				<br />
				<code>{ escapeHTML( message ) }</code>
			</span>
		);
	}

	return message;
};

const ErrorMessage = ( { error }: ErrorMessageProps ): JSX.Element => (
	<div className="wc-block-error-message">{ getErrorMessage( error ) }</div>
);

export default ErrorMessage;
error-placeholder/index.tsx000064400000003110151550716220012023 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { Icon, warning } from '@wordpress/icons';
import classNames from 'classnames';
import { Button, Placeholder, Spinner } from '@wordpress/components';

/**
 * Internal dependencies
 */
import ErrorMessage from './error-message';
import './editor.scss';

export interface ErrorObject {
	/**
	 * Human-readable error message to display.
	 */
	message: string;
	/**
	 * Context in which the error was triggered. That will determine how the error is displayed to the user.
	 */
	type: 'api' | 'general' | string;
}

export interface ErrorPlaceholderProps {
	/**
	 * Classname to add to placeholder in addition to the defaults.
	 */
	className?: string;
	/**
	 * The error object.
	 */
	error: ErrorObject;
	/**
	 * Whether there is a request running, so the 'Retry' button is hidden and
	 * a spinner is shown instead.
	 */
	isLoading: boolean;
	/**
	 * Callback to retry an action.
	 */
	onRetry?: () => void;
}

const ErrorPlaceholder = ( {
	className,
	error,
	isLoading = false,
	onRetry,
}: ErrorPlaceholderProps ): JSX.Element => (
	<Placeholder
		icon={ <Icon icon={ warning } /> }
		label={ __(
			'Sorry, an error occurred',
			'woo-gutenberg-products-block'
		) }
		className={ classNames( 'wc-block-api-error', className ) }
	>
		<ErrorMessage error={ error } />
		{ onRetry && (
			<>
				{ isLoading ? (
					<Spinner />
				) : (
					<Button isSecondary onClick={ onRetry }>
						{ __( 'Retry', 'woo-gutenberg-products-block' ) }
					</Button>
				) }
			</>
		) }
	</Placeholder>
);

export default ErrorPlaceholder;
error-placeholder/stories/error-message.tsx000064400000001203151550716220015160 0ustar00/**
 * External dependencies
 */
import type { Story, Meta } from '@storybook/react';

/**
 * Internal dependencies
 */
import ErrorMessage, { ErrorMessageProps } from '../error-message';

export default {
	title: 'WooCommerce Blocks/editor-components/Errors/Base Error Atom',
	component: ErrorMessage,
} as Meta< ErrorMessageProps >;

const Template: Story< ErrorMessageProps > = ( args ) => (
	<ErrorMessage { ...args } />
);

export const BaseErrorAtom = Template.bind( {} );
BaseErrorAtom.args = {
	error: {
		message:
			'A very generic and unhelpful error. Please try again later. Or contact support. Or not.',
		type: 'general',
	},
};
error-placeholder/stories/error-placeholder.tsx000064400000003000151550716220016013 0ustar00/**
 * External dependencies
 */
import type { Story, Meta } from '@storybook/react';
import { useArgs } from '@storybook/client-api';
import { INTERACTION_TIMEOUT } from '@woocommerce/storybook-controls';

/**
 * Internal dependencies
 */
import ErrorPlaceholder, { ErrorPlaceholderProps } from '..';

export default {
	title: 'WooCommerce Blocks/editor-components/Errors',
	component: ErrorPlaceholder,
} as Meta< ErrorPlaceholderProps >;

const Template: Story< ErrorPlaceholderProps > = ( args ) => {
	const [ { isLoading }, setArgs ] = useArgs();

	const onRetry = args.onRetry
		? () => {
				setArgs( { isLoading: true } );

				setTimeout(
					() => setArgs( { isLoading: false } ),
					INTERACTION_TIMEOUT
				);
		  }
		: undefined;

	return (
		<ErrorPlaceholder
			{ ...args }
			onRetry={ onRetry }
			isLoading={ isLoading }
		/>
	);
};

export const Default = Template.bind( {} );
Default.args = {
	error: {
		message:
			'A very generic and unhelpful error. Please try again later. Or contact support. Or not.',
		type: 'general',
	},
};

export const APIError = Template.bind( {} );
APIError.args = {
	error: {
		message: 'Server refuses to comply. It is a teapot.',
		type: 'api',
	},
};

export const UnknownError = Template.bind( {} );
UnknownError.args = {
	error: {
		message: '',
		type: 'general',
	},
};

export const NoRetry: Story< ErrorPlaceholderProps > = ( args ) => {
	return <ErrorPlaceholder { ...args } onRetry={ undefined } />;
};
NoRetry.args = {
	error: {
		message: '',
		type: 'general',
	},
};
expandable-search-list-item/expandable-search-list-item.tsx000064400000002106151550716220020035 0ustar00/**
 * External dependencies
 */
import { Spinner } from '@wordpress/components';
import { SearchListItem } from '@woocommerce/editor-components/search-list-control';
import { renderItemArgs } from '@woocommerce/editor-components/search-list-control/types';
import classNames from 'classnames';

interface ExpandableSearchListItemProps extends renderItemArgs {
	isLoading: boolean;
}

const ExpandableSearchListItem = ( {
	className,
	item,
	isSelected,
	isLoading,
	onSelect,
	disabled,
	...rest
}: ExpandableSearchListItemProps ): JSX.Element => {
	return (
		<>
			<SearchListItem
				{ ...rest }
				key={ item.id }
				className={ className }
				isSelected={ isSelected }
				item={ item }
				onSelect={ onSelect }
				disabled={ disabled }
			/>
			{ isSelected && isLoading && (
				<div
					key="loading"
					className={ classNames(
						'woocommerce-search-list__item',
						'woocommerce-product-attributes__item',
						'depth-1',
						'is-loading',
						'is-not-active'
					) }
				>
					<Spinner />
				</div>
			) }
		</>
	);
};

export default ExpandableSearchListItem;
external-link-card/editor.scss000064400000002003151550716220012412 0ustar00.wc-block-editor-components-external-link-card {
	display: flex;
	flex-direction: row;
	text-decoration: none;
	margin: $gap-large 0;
	color: inherit;
	align-items: flex-start;

	+ .wc-block-editor-components-external-link-card {
		margin-top: -($gap-large - $gap);
	}
	.wc-block-editor-components-external-link-card__content {
		flex: 1 1 0;
		padding-right: $gap;
	}
	.wc-block-editor-components-external-link-card__title {
		font-weight: 500;
		display: block;
	}
	.wc-block-editor-components-external-link-card__description {
		color: $gray-700;
		display: block;
		@include font-size(small);
		margin-top: 0.5em;
	}
	.wc-block-editor-components-external-link-card__icon {
		flex: 0 0 24px;
		margin: 0;
		text-align: right;
		color: inherit;
		vertical-align: top;
	}
	.wc-block-editor-components-external-link-card__warning {
		color: #cc1818;
		display: flex;
		align-items: flex-start;
		font-size: 0.875em;
		column-gap: 4px;
		margin-top: 0.5em;

		svg {
			width: 18px;
			height: 18px;
			min-width: 18px;
		}
	}
}
external-link-card/index.tsx000064400000003370151550716220012106 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { Icon, external } from '@wordpress/icons';
import { VisuallyHidden } from '@wordpress/components';
import { sanitizeHTML } from '@woocommerce/utils';
import { Alert } from '@woocommerce/icons';

/**
 * Internal dependencies
 */
import './editor.scss';

export interface ExternalLinkCardProps {
	href: string;
	title: string;
	description?: string;
	warning?: string;
}

/**
 * Show a link that displays a title, description, and an icon showing that the link is external.
 * Links are opened in a new tab.
 */
const ExternalLinkCard = ( {
	href,
	title,
	description,
	warning,
}: ExternalLinkCardProps ): JSX.Element => {
	return (
		<a
			href={ href }
			className="wc-block-editor-components-external-link-card"
			target="_blank"
			rel="noreferrer"
		>
			<span className="wc-block-editor-components-external-link-card__content">
				<strong className="wc-block-editor-components-external-link-card__title">
					{ title }
				</strong>
				{ description && (
					<span
						className="wc-block-editor-components-external-link-card__description"
						dangerouslySetInnerHTML={ {
							__html: sanitizeHTML( description ),
						} }
					></span>
				) }
				{ warning ? (
					<span className="wc-block-editor-components-external-link-card__warning">
						<Icon icon={ <Alert status="error" /> } />
						<span>{ warning }</span>
					</span>
				) : null }
			</span>
			<VisuallyHidden as="span">
				{
					/* translators: accessibility text */
					__( '(opens in a new tab)', 'woo-gutenberg-products-block' )
				}
			</VisuallyHidden>
			<Icon
				icon={ external }
				className="wc-block-editor-components-external-link-card__icon"
			/>
		</a>
	);
};

export default ExternalLinkCard;
external-link-card/stories/index.tsx000064400000001432151550716220013573 0ustar00/**
 * External dependencies
 */
import type { Story, Meta } from '@storybook/react';

/**
 * Internal dependencies
 */
import ExternalLinkCard, { ExternalLinkCardProps } from '..';

export default {
	title: 'WooCommerce Blocks/editor-components/ExternalLinkCard',
	component: ExternalLinkCard,
} as Meta< ExternalLinkCardProps >;

const Template: Story< ExternalLinkCardProps > = ( args ) => (
	<ExternalLinkCard { ...args } />
);

export const Default = Template.bind( {} );
Default.args = {
	description:
		'This is the description of the link, perhaps a bit of a longer paragraph or a summary of a blog post, or whatever could give more context',
	href: 'https://woocommerce.com/posts/seven-tips-to-extend-holiday-sales-momentum/',
	title: 'Seven tips to extend holiday sales momentum',
};
feedback-prompt/index.tsx000064400000006351151550716220011467 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { Icon, commentContent, external } from '@wordpress/icons';
import { useEffect, useState } from '@wordpress/element';

/**
 * Internal dependencies
 */
import './style.scss';
interface FeedbackPromptProps {
	text: string;
	title?: string;
	url?: string;
}
/**
 * Component to render a Feedback prompt in the sidebar.
 *
 * @param {Object} props       Incoming props for the component.
 * @param {string} props.text
 * @param {string} props.title
 * @param {string} props.url
 */
const FeedbackPrompt = ( {
	text,
	title = __( 'Feedback?', 'woo-gutenberg-products-block' ),
	url = 'https://ideas.woocommerce.com/forums/133476-woocommerce?category_id=384565',
}: FeedbackPromptProps ) => {
	// By returning false we ensure that this component is not entered into the InspectorControls
	// (which is a slot fill), children array on first render, on the second render when the state
	// gets updated this component does get put into the InspectorControls children array but as the
	// last item, ensuring it shows last in the sidebar.
	const [ isVisible, setIsVisible ] = useState( false );
	useEffect( () => {
		setIsVisible( true );
	}, [] );

	return (
		<>
			{ isVisible && (
				<div className="wc-block-feedback-prompt">
					<Icon icon={ commentContent } />
					<h2 className="wc-block-feedback-prompt__title">
						{ title }
					</h2>
					<p className="wc-block-feedback-prompt__text">{ text }</p>
					<a
						href={ url }
						className="wc-block-feedback-prompt__link"
						rel="noreferrer noopener"
						target="_blank"
					>
						{ __(
							'Give us your feedback.',
							'woo-gutenberg-products-block'
						) }
						<Icon icon={ external } size={ 16 } />
					</a>
				</div>
			) }
		</>
	);
};

export default FeedbackPrompt;

export const CartCheckoutFeedbackPrompt = () => (
	<FeedbackPrompt
		text={ __(
			'We are currently working on improving our cart and checkout blocks to provide merchants with the tools and customization options they need.',
			'woo-gutenberg-products-block'
		) }
		url="https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/new?template=--cart-checkout-feedback.md"
	/>
);

export const LegacyFeedbackPrompt = () => (
	<FeedbackPrompt
		text={ __(
			'We are working on a better editing experience that will replace classic blocks. Keep an eye out for updates!',
			'woo-gutenberg-products-block'
		) }
		url="https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/new?template=--classic-block-feedback.md"
	/>
);

export const ProductQueryFeedbackPrompt = () => (
	<FeedbackPrompt
		text={ __(
			'Thanks for trying out the Products block! Help us make it better by sharing your feedback.',
			'woo-gutenberg-products-block'
		) }
		title={ __( 'Share your feedback!', 'woo-gutenberg-products-block' ) }
		url={ 'https://airtable.com/shrFX5FAqmCY6hVYI' }
	/>
);

export const ProductCollectionFeedbackPrompt = () => (
	<FeedbackPrompt
		text={ __(
			'Thanks for trying out the Product Collection block! Help us make it better by sharing your feedback.',
			'woo-gutenberg-products-block'
		) }
		title={ __( 'Share your feedback!', 'woo-gutenberg-products-block' ) }
		url={ 'https://airtable.com/shrqsMSDPvAKoY99u' }
	/>
);
feedback-prompt/style.scss000064400000000513151550716220011647 0ustar00.wc-block-feedback-prompt {
	background-color: #f7f7f7;
	border-top: 1px solid $gray-200;
	margin: 0 -16px 0;
	padding: $gap-large;
	text-align: center;

	.wc-block-feedback-prompt__title {
		margin: 0 0 $gap-small;
	}

	.wc-block-feedback-prompt__link {
		color: inherit;

		> .gridicon {
			vertical-align: text-bottom;
		}
	}
}
grid-content-control/index.tsx000064400000003701151550716220012473 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { ToggleControl } from '@wordpress/components';

interface GridContentControlProps {
	onChange: ( settings: GridContentSettings ) => void;
	settings: GridContentSettings;
}

interface GridContentSettings {
	image: boolean;
	button: boolean;
	price: boolean;
	rating: boolean;
	title: boolean;
}
/**
 * A combination of toggle controls for content visibility in product grids.
 *
 * @param {Object}            props          Incoming props for the component.
 * @param {function(any):any} props.onChange
 * @param {Object}            props.settings
 */
const GridContentControl = ( {
	onChange,
	settings,
}: GridContentControlProps ) => {
	const { image, button, price, rating, title } = settings;
	// If `image` is undefined, that might be because it's a block that was
	// created before the `image` attribute existed, so we default to true.
	const imageIsVisible = image !== false;
	return (
		<>
			<ToggleControl
				label={ __( 'Product image', 'woo-gutenberg-products-block' ) }
				checked={ imageIsVisible }
				onChange={ () =>
					onChange( { ...settings, image: ! imageIsVisible } )
				}
			/>
			<ToggleControl
				label={ __( 'Product title', 'woo-gutenberg-products-block' ) }
				checked={ title }
				onChange={ () => onChange( { ...settings, title: ! title } ) }
			/>
			<ToggleControl
				label={ __( 'Product price', 'woo-gutenberg-products-block' ) }
				checked={ price }
				onChange={ () => onChange( { ...settings, price: ! price } ) }
			/>
			<ToggleControl
				label={ __( 'Product rating', 'woo-gutenberg-products-block' ) }
				checked={ rating }
				onChange={ () => onChange( { ...settings, rating: ! rating } ) }
			/>
			<ToggleControl
				label={ __(
					'Add to Cart button',
					'woo-gutenberg-products-block'
				) }
				checked={ button }
				onChange={ () => onChange( { ...settings, button: ! button } ) }
			/>
		</>
	);
};

export default GridContentControl;
grid-layout-control/index.tsx000064400000005336151550716220012344 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { RangeControl, ToggleControl } from '@wordpress/components';

interface ClampProps {
	( number: number, boundOne: number, boundTwo?: number ): number;
}

const clamp: ClampProps = ( number, boundOne, boundTwo ) => {
	if ( ! boundTwo ) {
		return Math.max( number, boundOne ) === boundOne ? number : boundOne;
	} else if ( Math.min( number, boundOne ) === number ) {
		return boundOne;
	} else if ( Math.max( number, boundTwo ) === number ) {
		return boundTwo;
	}
	return number;
};

interface GridLayoutControlProps {
	columns: number;
	rows: number;
	setAttributes: ( attributes: Record< string, unknown > ) => void;
	alignButtons: boolean;
	minColumns?: number;
	maxColumns?: number;
	minRows?: number;
	maxRows?: number;
}

/**
 * A combination of range controls for product grid layout settings.
 *
 * @param {Object}            props               Incoming props for the component.
 * @param {number}            props.columns
 * @param {number}            props.rows
 * @param {function(any):any} props.setAttributes Setter for block attributes.
 * @param {boolean}           props.alignButtons
 * @param {number}            props.minColumns
 * @param {number}            props.maxColumns
 * @param {number}            props.minRows
 * @param {number}            props.maxRows
 */
const GridLayoutControl = ( {
	columns,
	rows,
	setAttributes,
	alignButtons,
	minColumns = 1,
	maxColumns = 6,
	minRows = 1,
	maxRows = 6,
}: GridLayoutControlProps ) => {
	return (
		<>
			<RangeControl
				label={ __( 'Columns', 'woo-gutenberg-products-block' ) }
				value={ columns }
				onChange={ ( value: number ) => {
					const newValue = clamp( value, minColumns, maxColumns );
					setAttributes( {
						columns: Number.isNaN( newValue ) ? '' : newValue,
					} );
				} }
				min={ minColumns }
				max={ maxColumns }
			/>
			<RangeControl
				label={ __( 'Rows', 'woo-gutenberg-products-block' ) }
				value={ rows }
				onChange={ ( value: number ) => {
					const newValue = clamp( value, minRows, maxRows );
					setAttributes( {
						rows: Number.isNaN( newValue ) ? '' : newValue,
					} );
				} }
				min={ minRows }
				max={ maxRows }
			/>
			<ToggleControl
				label={ __(
					'Align the last block to the bottom',
					'woo-gutenberg-products-block'
				) }
				help={
					alignButtons
						? __(
								'Align the last block to the bottom.',
								'woo-gutenberg-products-block'
						  )
						: __(
								'The last inner block will follow other content.',
								'woo-gutenberg-products-block'
						  )
				}
				checked={ alignButtons }
				onChange={ () =>
					setAttributes( { alignButtons: ! alignButtons } )
				}
			/>
		</>
	);
};

export default GridLayoutControl;
heading-toolbar/heading-level-icon.js000064400000005040151550716220013576 0ustar00/**
 * External dependencies
 */
import { Path, SVG } from '@wordpress/primitives';

export default function HeadingLevelIcon( { level } ) {
	const levelToPath = {
		1: 'M9 5h2v10H9v-4H5v4H3V5h2v4h4V5zm6.6 0c-.6.9-1.5 1.7-2.6 2v1h2v7h2V5h-1.4z',
		2: 'M7 5h2v10H7v-4H3v4H1V5h2v4h4V5zm8 8c.5-.4.6-.6 1.1-1.1.4-.4.8-.8 1.2-1.3.3-.4.6-.8.9-1.3.2-.4.3-.8.3-1.3 0-.4-.1-.9-.3-1.3-.2-.4-.4-.7-.8-1-.3-.3-.7-.5-1.2-.6-.5-.2-1-.2-1.5-.2-.4 0-.7 0-1.1.1-.3.1-.7.2-1 .3-.3.1-.6.3-.9.5-.3.2-.6.4-.8.7l1.2 1.2c.3-.3.6-.5 1-.7.4-.2.7-.3 1.2-.3s.9.1 1.3.4c.3.3.5.7.5 1.1 0 .4-.1.8-.4 1.1-.3.5-.6.9-1 1.2-.4.4-1 .9-1.6 1.4-.6.5-1.4 1.1-2.2 1.6V15h8v-2H15z',
		3: 'M12.1 12.2c.4.3.8.5 1.2.7.4.2.9.3 1.4.3.5 0 1-.1 1.4-.3.3-.1.5-.5.5-.8 0-.2 0-.4-.1-.6-.1-.2-.3-.3-.5-.4-.3-.1-.7-.2-1-.3-.5-.1-1-.1-1.5-.1V9.1c.7.1 1.5-.1 2.2-.4.4-.2.6-.5.6-.9 0-.3-.1-.6-.4-.8-.3-.2-.7-.3-1.1-.3-.4 0-.8.1-1.1.3-.4.2-.7.4-1.1.6l-1.2-1.4c.5-.4 1.1-.7 1.6-.9.5-.2 1.2-.3 1.8-.3.5 0 1 .1 1.6.2.4.1.8.3 1.2.5.3.2.6.5.8.8.2.3.3.7.3 1.1 0 .5-.2.9-.5 1.3-.4.4-.9.7-1.5.9v.1c.6.1 1.2.4 1.6.8.4.4.7.9.7 1.5 0 .4-.1.8-.3 1.2-.2.4-.5.7-.9.9-.4.3-.9.4-1.3.5-.5.1-1 .2-1.6.2-.8 0-1.6-.1-2.3-.4-.6-.2-1.1-.6-1.6-1l1.1-1.4zM7 9H3V5H1v10h2v-4h4v4h2V5H7v4z',
		4: 'M9 15H7v-4H3v4H1V5h2v4h4V5h2v10zm10-2h-1v2h-2v-2h-5v-2l4-6h3v6h1v2zm-3-2V7l-2.8 4H16z',
		5: 'M12.1 12.2c.4.3.7.5 1.1.7.4.2.9.3 1.3.3.5 0 1-.1 1.4-.4.4-.3.6-.7.6-1.1 0-.4-.2-.9-.6-1.1-.4-.3-.9-.4-1.4-.4H14c-.1 0-.3 0-.4.1l-.4.1-.5.2-1-.6.3-5h6.4v1.9h-4.3L14 8.8c.2-.1.5-.1.7-.2.2 0 .5-.1.7-.1.5 0 .9.1 1.4.2.4.1.8.3 1.1.6.3.2.6.6.8.9.2.4.3.9.3 1.4 0 .5-.1 1-.3 1.4-.2.4-.5.8-.9 1.1-.4.3-.8.5-1.3.7-.5.2-1 .3-1.5.3-.8 0-1.6-.1-2.3-.4-.6-.2-1.1-.6-1.6-1-.1-.1 1-1.5 1-1.5zM9 15H7v-4H3v4H1V5h2v4h4V5h2v10z',
		6: 'M9 15H7v-4H3v4H1V5h2v4h4V5h2v10zm8.6-7.5c-.2-.2-.5-.4-.8-.5-.6-.2-1.3-.2-1.9 0-.3.1-.6.3-.8.5l-.6.9c-.2.5-.2.9-.2 1.4.4-.3.8-.6 1.2-.8.4-.2.8-.3 1.3-.3.4 0 .8 0 1.2.2.4.1.7.3 1 .6.3.3.5.6.7.9.2.4.3.8.3 1.3s-.1.9-.3 1.4c-.2.4-.5.7-.8 1-.4.3-.8.5-1.2.6-1 .3-2 .3-3 0-.5-.2-1-.5-1.4-.9-.4-.4-.8-.9-1-1.5-.2-.6-.3-1.3-.3-2.1s.1-1.6.4-2.3c.2-.6.6-1.2 1-1.6.4-.4.9-.7 1.4-.9.6-.3 1.1-.4 1.7-.4.7 0 1.4.1 2 .3.5.2 1 .5 1.4.8 0 .1-1.3 1.4-1.3 1.4zm-2.4 5.8c.2 0 .4 0 .6-.1.2 0 .4-.1.5-.2.1-.1.3-.3.4-.5.1-.2.1-.5.1-.7 0-.4-.1-.8-.4-1.1-.3-.2-.7-.3-1.1-.3-.3 0-.7.1-1 .2-.4.2-.7.4-1 .7 0 .3.1.7.3 1 .1.2.3.4.4.6.2.1.3.3.5.3.2.1.5.2.7.1z',
	};
	if ( ! levelToPath.hasOwnProperty( level ) ) {
		return null;
	}

	return (
		<SVG
			width="20"
			height="20"
			viewBox="0 0 20 20"
			xmlns="http://www.w3.org/2000/svg"
		>
			<Path d={ levelToPath[ level ] } />
		</SVG>
	);
}
heading-toolbar/index.js000064400000002415151550716220011256 0ustar00/**
 * External dependencies
 */
import { __, sprintf } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import { ToolbarGroup } from '@wordpress/components';

/**
 * Internal dependencies
 */
import HeadingLevelIcon from './heading-level-icon';

/**
 * HeadingToolbar component.
 *
 * Allows the heading level to be chosen for a title block.
 */
class HeadingToolbar extends Component {
	createLevelControl( targetLevel, selectedLevel, onChange ) {
		const isActive = targetLevel === selectedLevel;
		return {
			icon: <HeadingLevelIcon level={ targetLevel } />,
			title: sprintf(
				/* translators: %s: heading level e.g: "2", "3", "4" */
				__( 'Heading %d', 'woocommerce' ),
				targetLevel
			),
			isActive,
			onClick: () => onChange( targetLevel ),
		};
	}

	render() {
		const {
			isCollapsed = true,
			minLevel,
			maxLevel,
			selectedLevel,
			onChange,
		} = this.props;

		const levels = Array.from(
			{ length: maxLevel - minLevel + 1 },
			( _, i ) => i + minLevel
		);

		return (
			<ToolbarGroup
				isCollapsed={ isCollapsed }
				icon={ <HeadingLevelIcon level={ selectedLevel } /> }
				controls={ levels.map( ( index ) =>
					this.createLevelControl( index, selectedLevel, onChange )
				) }
			/>
		);
	}
}

export default HeadingToolbar;
incompatible-payment-gateways-notice/editor.scss000064400000001326151550716220016157 0ustar00.wc-blocks-incompatible-extensions-notice.is-dismissible {
	margin: 0;
	padding-right: 16px;
	.components-notice__dismiss {
		min-width: 24px;
	}
	.components-notice__content {
		margin: 4px 0;
	}
	svg {
		width: 16px;
		height: 16px;
	}
	.wc-blocks-incompatible-extensions-notice__content {
		display: flex;

		.wc-blocks-incompatible-extensions-notice__warning-icon {
			width: 24px;
			height: 24px;
			margin-right: 6px;
			min-width: max-content;
		}
	}
	.wc-blocks-incompatible-extensions-notice__element {
		display: flex;
		align-items: center;
		position: relative;

		&::before {
			content: "•";
			position: absolute;
			left: -13px;
			font-size: 1.2rem;
		}
	}
}

.wc-blocks-legacy-page-notice {
	margin: 0;
}
incompatible-payment-gateways-notice/index.tsx000064400000004431151550716220015643 0ustar00/**
 * External dependencies
 */
import { _n } from '@wordpress/i18n';
import { Notice, ExternalLink } from '@wordpress/components';
import { createInterpolateElement, useEffect } from '@wordpress/element';
import { Alert } from '@woocommerce/icons';
import { Icon } from '@wordpress/icons';
/**
 * Internal dependencies
 */
import { useIncompatiblePaymentGatewaysNotice } from './use-incompatible-payment-gateways-notice';
import './editor.scss';

interface PaymentGatewaysNoticeProps {
	toggleDismissedStatus: ( status: boolean ) => void;
	block: 'woocommerce/cart' | 'woocommerce/checkout';
}

export function IncompatiblePaymentGatewaysNotice( {
	toggleDismissedStatus,
	block,
}: PaymentGatewaysNoticeProps ) {
	const [
		isVisible,
		dismissNotice,
		incompatiblePaymentMethods,
		numberOfIncompatiblePaymentMethods,
	] = useIncompatiblePaymentGatewaysNotice( block );

	useEffect( () => {
		toggleDismissedStatus( ! isVisible );
	}, [ isVisible, toggleDismissedStatus ] );

	if ( ! isVisible ) {
		return null;
	}

	const noticeContent = createInterpolateElement(
		_n(
			'The following extension is incompatible with the block-based checkout. <a>Learn more</a>',
			'The following extensions are incompatible with the block-based checkout. <a>Learn more</a>',
			numberOfIncompatiblePaymentMethods,
			'woo-gutenberg-products-block'
		),
		{
			a: (
				// Suppress the warning as this <a> will be interpolated into the string with content.
				// eslint-disable-next-line jsx-a11y/anchor-has-content
				<ExternalLink href="https://woocommerce.com/document/cart-checkout-blocks-support-status/" />
			),
		}
	);

	return (
		<Notice
			className="wc-blocks-incompatible-extensions-notice"
			status={ 'warning' }
			onRemove={ dismissNotice }
			spokenMessage={ noticeContent }
		>
			<div className="wc-blocks-incompatible-extensions-notice__content">
				<Icon
					className="wc-blocks-incompatible-extensions-notice__warning-icon"
					icon={ <Alert /> }
				/>
				<div>
					<p>{ noticeContent }</p>
					<ul>
						{ Object.entries( incompatiblePaymentMethods ).map(
							( [ id, title ] ) => (
								<li
									key={ id }
									className="wc-blocks-incompatible-extensions-notice__element"
								>
									{ title }
								</li>
							)
						) }
					</ul>
				</div>
			</div>
		</Notice>
	);
}
incompatible-payment-gateways-notice/use-incompatible-payment-gateways-notice.ts000064400000005462151550716220024365 0ustar00/**
 * External dependencies
 */
import { useSelect } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import { useLocalStorageState } from '@woocommerce/base-hooks';

/**
 * Internal dependencies
 */
import { STORE_KEY as PAYMENT_STORE_KEY } from '../../data/payment/constants';

type StoredIncompatibleGateway = { [ k: string ]: string[] };
const initialDismissedNotices: React.SetStateAction<
	StoredIncompatibleGateway[]
> = [];

const areEqual = ( array1: string[], array2: string[] ) => {
	if ( array1.length !== array2.length ) {
		return false;
	}

	const uniqueCollectionValues = new Set( [ ...array1, ...array2 ] );

	return uniqueCollectionValues.size === array1.length;
};

export const useIncompatiblePaymentGatewaysNotice = (
	blockName: string
): [ boolean, () => void, { [ k: string ]: string }, number ] => {
	const [ dismissedNotices, setDismissedNotices ] = useLocalStorageState<
		StoredIncompatibleGateway[]
	>(
		`wc-blocks_dismissed_incompatible_payment_gateways_notices`,
		initialDismissedNotices
	);
	const [ isVisible, setIsVisible ] = useState( false );

	const { incompatiblePaymentMethods } = useSelect( ( select ) => {
		const { getIncompatiblePaymentMethods } = select( PAYMENT_STORE_KEY );
		return {
			incompatiblePaymentMethods: getIncompatiblePaymentMethods(),
		};
	}, [] );
	const incompatiblePaymentMethodsIDs = Object.keys(
		incompatiblePaymentMethods
	);
	const numberOfIncompatiblePaymentMethods =
		incompatiblePaymentMethodsIDs.length;

	const isDismissedNoticeUpToDate = dismissedNotices.some(
		( notice ) =>
			Object.keys( notice ).includes( blockName ) &&
			areEqual(
				notice[ blockName as keyof object ],
				incompatiblePaymentMethodsIDs
			)
	);

	const shouldBeDismissed =
		numberOfIncompatiblePaymentMethods === 0 || isDismissedNoticeUpToDate;
	const dismissNotice = () => {
		const dismissedNoticesSet = new Set( dismissedNotices );
		dismissedNoticesSet.add( {
			[ blockName ]: incompatiblePaymentMethodsIDs,
		} );
		setDismissedNotices( [ ...dismissedNoticesSet ] );
	};

	// This ensures the modal is not loaded on first render. This is required so
	// Gutenberg doesn't steal the focus from the Guide and focuses the block.
	useEffect( () => {
		setIsVisible( ! shouldBeDismissed );

		if ( ! shouldBeDismissed && ! isDismissedNoticeUpToDate ) {
			setDismissedNotices( ( previousDismissedNotices ) =>
				previousDismissedNotices.reduce(
					( acc: StoredIncompatibleGateway[], curr ) => {
						if ( Object.keys( curr ).includes( blockName ) ) {
							return acc;
						}
						acc.push( curr );

						return acc;
					},
					[]
				)
			);
		}
	}, [
		shouldBeDismissed,
		isDismissedNoticeUpToDate,
		setDismissedNotices,
		blockName,
	] );

	return [
		isVisible,
		dismissNotice,
		incompatiblePaymentMethods,
		numberOfIncompatiblePaymentMethods,
	];
};
no-payment-methods-notice/editor.scss000064400000000151151550716220013737 0ustar00.wc-blocks-no-payment-methods-notice {
	margin: 0;

	.components-notice__content {
		margin: 4px 0;
	}
}
no-payment-methods-notice/index.tsx000064400000001754151550716220013435 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { Notice, ExternalLink } from '@wordpress/components';
import { ADMIN_URL } from '@woocommerce/settings';

/**
 * Internal dependencies
 */
import './editor.scss';

export function NoPaymentMethodsNotice() {
	const noticeContent = __(
		'Your store does not have any payment methods that support the Checkout block. Once you have configured a compatible payment method it will be displayed here.',
		'woo-gutenberg-products-block'
	);

	return (
		<Notice
			className="wc-blocks-no-payment-methods-notice"
			status={ 'warning' }
			spokenMessage={ noticeContent }
			isDismissible={ false }
		>
			<div className="wc-blocks-no-payment-methods-notice__content">
				{ noticeContent }{ ' ' }
				<ExternalLink
					href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=checkout` }
				>
					{ __(
						'Configure Payment Methods',
						'woo-gutenberg-products-block'
					) }
				</ExternalLink>
			</div>
		</Notice>
	);
}
page-selector/index.js000064400000002064151550716220010751 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { PanelBody, SelectControl } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
/**
 * Internal dependencies
 */
import { formatTitle } from '../utils';

const PageSelector = ( { setPageId, pageId, labels } ) => {
	const pages =
		useSelect( ( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'page', {
				status: 'publish',
				orderby: 'title',
				order: 'asc',
				per_page: 100,
			} );
		}, [] ) || null;
	if ( pages ) {
		return (
			<PanelBody title={ labels.title }>
				<SelectControl
					label={ __( 'Link to', 'woocommerce' ) }
					value={ pageId }
					options={ [
						{
							label: labels.default,
							value: 0,
						},
						...pages.map( ( page ) => {
							return {
								label: formatTitle( page, pages ),
								value: parseInt( page.id, 10 ),
							};
						} ),
					] }
					onChange={ ( value ) => setPageId( parseInt( value, 10 ) ) }
				/>
			</PanelBody>
		);
	}
	return null;
};

export default PageSelector;
product-attribute-term-control/index.tsx000064400000013362151550716220014530 0ustar00/**
 * External dependencies
 */
import classNames from 'classnames';
import { __, _n, sprintf } from '@wordpress/i18n';
import {
	SearchListControl,
	SearchListItem,
} from '@woocommerce/editor-components/search-list-control';
import { SelectControl } from '@wordpress/components';
import { withInstanceId } from '@wordpress/compose';
import useProductAttributes from '@woocommerce/base-context/hooks/use-product-attributes';
import ErrorMessage from '@woocommerce/editor-components/error-placeholder/error-message';
import ExpandableSearchListItem from '@woocommerce/editor-components/expandable-search-list-item/expandable-search-list-item';
import {
	renderItemArgs,
	SearchListControlProps,
	SearchListItem as SearchListItemProps,
} from '@woocommerce/editor-components/search-list-control/types';
import { convertAttributeObjectToSearchItem } from '@woocommerce/utils';

/**
 * Internal dependencies
 */
import './style.scss';

interface Props
	extends Omit< SearchListControlProps, 'isSingle' | 'list' | 'selected' > {
	instanceId?: string;
	/**
	 * Callback to update the category operator. If not passed in, setting is not used.
	 */
	onOperatorChange?: () => void;
	/**
	 * Setting for whether products should match all or any selected categories.
	 */
	operator: 'all' | 'any';
	/**
	 * The list of currently selected attribute ids.
	 */
	selected: { id: number }[];
}

const ProductAttributeTermControl = ( {
	onChange,
	onOperatorChange,
	instanceId,
	isCompact = false,
	messages = {},
	operator = 'any',
	selected,
	type = 'text',
}: Props ) => {
	const { errorLoadingAttributes, isLoadingAttributes, productsAttributes } =
		useProductAttributes( true );

	const renderItem = ( args: renderItemArgs ) => {
		const { item, search, depth = 0 } = args;
		const count = item.count || 0;
		const classes = [
			'woocommerce-product-attributes__item',
			'woocommerce-search-list__item',
			{
				'is-searching': search.length > 0,
				'is-skip-level': depth === 0 && item.parent !== 0,
			},
		];

		if ( ! item.breadcrumbs.length ) {
			return (
				<ExpandableSearchListItem
					{ ...args }
					className={ classNames( classes ) }
					item={ item }
					isLoading={ isLoadingAttributes }
					disabled={ item.count === 0 }
					name={ `attributes-${ instanceId }` }
					countLabel={ sprintf(
						/* translators: %d is the count of terms. */
						_n(
							'%d term',
							'%d terms',
							count,
							'woo-gutenberg-products-block'
						),
						count
					) }
					aria-label={ sprintf(
						/* translators: %1$s is the item name, %2$d is the count of terms for the item. */
						_n(
							'%1$s, has %2$d term',
							'%1$s, has %2$d terms',
							count,
							'woo-gutenberg-products-block'
						),
						item.name,
						count
					) }
				/>
			);
		}

		const itemName = `${ item.breadcrumbs[ 0 ] }: ${ item.name }`;

		return (
			<SearchListItem
				{ ...args }
				name={ `terms-${ instanceId }` }
				className={ classNames( ...classes, 'has-count' ) }
				countLabel={ sprintf(
					/* translators: %d is the count of products. */
					_n(
						'%d product',
						'%d products',
						count,
						'woo-gutenberg-products-block'
					),
					count
				) }
				aria-label={ sprintf(
					/* translators: %1$s is the attribute name, %2$d is the count of products for that attribute. */
					_n(
						'%1$s, has %2$d product',
						'%1$s, has %2$d products',
						count,
						'woo-gutenberg-products-block'
					),
					itemName,
					count
				) }
			/>
		);
	};

	const list = productsAttributes.reduce( ( acc, curr ) => {
		const { terms, ...props } = curr;

		return [
			...acc,
			convertAttributeObjectToSearchItem( props ),
			...terms.map( convertAttributeObjectToSearchItem ),
		];
	}, [] as SearchListItemProps[] );

	messages = {
		clear: __(
			'Clear all product attributes',
			'woo-gutenberg-products-block'
		),
		noItems: __(
			"Your store doesn't have any product attributes.",
			'woo-gutenberg-products-block'
		),
		search: __(
			'Search for product attributes',
			'woo-gutenberg-products-block'
		),
		selected: ( n: number ) =>
			sprintf(
				/* translators: %d is the count of attributes selected. */
				_n(
					'%d attribute selected',
					'%d attributes selected',
					n,
					'woo-gutenberg-products-block'
				),
				n
			),
		updated: __(
			'Product attribute search results updated.',
			'woo-gutenberg-products-block'
		),
		...messages,
	};

	if ( errorLoadingAttributes ) {
		return <ErrorMessage error={ errorLoadingAttributes } />;
	}

	return (
		<>
			<SearchListControl
				className="woocommerce-product-attributes"
				isCompact={ isCompact }
				isHierarchical
				isLoading={ isLoadingAttributes }
				isSingle={ false }
				list={ list }
				messages={ messages }
				onChange={ onChange }
				renderItem={ renderItem }
				selected={
					selected
						.map( ( { id } ) =>
							list.find( ( term ) => term.id === id )
						)
						.filter( Boolean ) as SearchListItemProps[]
				}
				type={ type }
			/>
			{ !! onOperatorChange && (
				<div hidden={ selected.length < 2 }>
					<SelectControl
						className="woocommerce-product-attributes__operator"
						label={ __(
							'Display products matching',
							'woo-gutenberg-products-block'
						) }
						help={ __(
							'Pick at least two attributes to use this setting.',
							'woo-gutenberg-products-block'
						) }
						value={ operator }
						onChange={ onOperatorChange }
						options={ [
							{
								label: __(
									'Any selected attributes',
									'woo-gutenberg-products-block'
								),
								value: 'any',
							},
							{
								label: __(
									'All selected attributes',
									'woo-gutenberg-products-block'
								),
								value: 'all',
							},
						] }
					/>
				</div>
			) }
		</>
	);
};

export default withInstanceId( ProductAttributeTermControl );
product-attribute-term-control/style.scss000064400000001066151550716220014714 0ustar00.woocommerce-product-attributes__operator {
	.components-base-control__help {
		@include visually-hidden;
	}

	.components-base-control__label {
		margin-bottom: 0;
		margin-right: 0.5em;
	}
}

.woocommerce-search-list__item.woocommerce-product-attributes__item {
	&.is-searching,
	&.is-skip-level {
		.woocommerce-search-list__item-prefix::after {
			content: ":";
		}
	}

	&.is-not-active {
		&:hover,
		&:active,
		&:focus {
			background: $white;
		}
	}

	&.is-loading {
		justify-content: center;

		.components-spinner {
			margin-bottom: $gap-small;
		}
	}
}
product-category-control/index.js000064400000012270151550716220013170 0ustar00/**
 * External dependencies
 */
import { __, _n, sprintf } from '@wordpress/i18n';
import PropTypes from 'prop-types';
import {
	SearchListControl,
	SearchListItem,
} from '@woocommerce/editor-components/search-list-control';
import { SelectControl } from '@wordpress/components';
import { withCategories } from '@woocommerce/block-hocs';
import ErrorMessage from '@woocommerce/editor-components/error-placeholder/error-message';
import classNames from 'classnames';

/**
 * Internal dependencies
 */
import './style.scss';

/**
 * @param {Object}    props
 * @param {string=}   props.categories
 * @param {boolean=}  props.isLoading
 * @param {string=}   props.error
 * @param {Function}  props.onChange
 * @param {Function=} props.onOperatorChange
 * @param {string=}   props.operator
 * @param {number[]}  props.selected
 * @param {boolean=}  props.isCompact
 * @param {boolean=}  props.isSingle
 * @param {boolean=}  props.showReviewCount
 */
const ProductCategoryControl = ( {
	categories,
	error,
	isLoading,
	onChange,
	onOperatorChange,
	operator,
	selected,
	isCompact,
	isSingle,
	showReviewCount,
} ) => {
	const renderItem = ( args ) => {
		const { item, search, depth = 0 } = args;

		const accessibleName = ! item.breadcrumbs.length
			? item.name
			: `${ item.breadcrumbs.join( ', ' ) }, ${ item.name }`;

		const listItemAriaLabel = showReviewCount
			? sprintf(
					/* translators: %1$s is the item name, %2$d is the count of reviews for the item. */
					_n(
						'%1$s, has %2$d review',
						'%1$s, has %2$d reviews',
						item.review_count,
						'woocommerce'
					),
					accessibleName,
					item.review_count
			  )
			: sprintf(
					/* translators: %1$s is the item name, %2$d is the count of products for the item. */
					_n(
						'%1$s, has %2$d product',
						'%1$s, has %2$d products',
						item.count,
						'woocommerce'
					),
					accessibleName,
					item.count
			  );

		const listItemCountLabel = showReviewCount
			? sprintf(
					/* translators: %d is the count of reviews. */
					_n(
						'%d review',
						'%d reviews',
						item.review_count,
						'woocommerce'
					),
					item.review_count
			  )
			: sprintf(
					/* translators: %d is the count of products. */
					_n(
						'%d product',
						'%d products',
						item.count,
						'woocommerce'
					),
					item.count
			  );
		return (
			<SearchListItem
				className={ classNames(
					'woocommerce-product-categories__item',
					'has-count',
					{
						'is-searching': search.length > 0,
						'is-skip-level': depth === 0 && item.parent !== 0,
					}
				) }
				{ ...args }
				countLabel={ listItemCountLabel }
				aria-label={ listItemAriaLabel }
			/>
		);
	};

	const messages = {
		clear: __(
			'Clear all product categories',
			'woocommerce'
		),
		list: __( 'Product Categories', 'woocommerce' ),
		noItems: __(
			"Your store doesn't have any product categories.",
			'woocommerce'
		),
		search: __(
			'Search for product categories',
			'woocommerce'
		),
		selected: ( n ) =>
			sprintf(
				/* translators: %d is the count of selected categories. */
				_n(
					'%d category selected',
					'%d categories selected',
					n,
					'woocommerce'
				),
				n
			),
		updated: __(
			'Category search results updated.',
			'woocommerce'
		),
	};

	if ( error ) {
		return <ErrorMessage error={ error } />;
	}

	return (
		<>
			<SearchListControl
				className="woocommerce-product-categories"
				list={ categories }
				isLoading={ isLoading }
				selected={ selected
					.map( ( id ) =>
						categories.find( ( category ) => category.id === id )
					)
					.filter( Boolean ) }
				onChange={ onChange }
				renderItem={ renderItem }
				messages={ messages }
				isCompact={ isCompact }
				isHierarchical
				isSingle={ isSingle }
			/>
			{ !! onOperatorChange && (
				<div hidden={ selected.length < 2 }>
					<SelectControl
						className="woocommerce-product-categories__operator"
						label={ __(
							'Display products matching',
							'woocommerce'
						) }
						help={ __(
							'Pick at least two categories to use this setting.',
							'woocommerce'
						) }
						value={ operator }
						onChange={ onOperatorChange }
						options={ [
							{
								label: __(
									'Any selected categories',
									'woocommerce'
								),
								value: 'any',
							},
							{
								label: __(
									'All selected categories',
									'woocommerce'
								),
								value: 'all',
							},
						] }
					/>
				</div>
			) }
		</>
	);
};

ProductCategoryControl.propTypes = {
	/**
	 * Callback to update the selected product categories.
	 */
	onChange: PropTypes.func.isRequired,
	/**
	 * Callback to update the category operator. If not passed in, setting is not used.
	 */
	onOperatorChange: PropTypes.func,
	/**
	 * Setting for whether products should match all or any selected categories.
	 */
	operator: PropTypes.oneOf( [ 'all', 'any' ] ),
	/**
	 * The list of currently selected category IDs.
	 */
	selected: PropTypes.array.isRequired,
	isCompact: PropTypes.bool,
	/**
	 * Allow only a single selection. Defaults to false.
	 */
	isSingle: PropTypes.bool,
};

ProductCategoryControl.defaultProps = {
	operator: 'any',
	isCompact: false,
	isSingle: false,
};

export default withCategories( ProductCategoryControl );
product-category-control/style.scss000064400000000301151550716220013550 0ustar00.woocommerce-product-categories__operator {
	.components-base-control__help {
		@include visually-hidden;
	}

	.components-base-control__label {
		margin-bottom: 0;
		margin-right: 0.5em;
	}
}
product-control/index.tsx000064400000013360151550716220011560 0ustar00/**
 * External dependencies
 */
import { __, _n, sprintf } from '@wordpress/i18n';
import { isEmpty } from '@woocommerce/types';
import {
	SearchListControl,
	SearchListItem,
} from '@woocommerce/editor-components/search-list-control';
import type {
	SearchListControlProps,
	renderItemArgs,
} from '@woocommerce/editor-components/search-list-control/types';
import { withInstanceId } from '@wordpress/compose';
import {
	withProductVariations,
	withSearchedProducts,
	withTransformSingleSelectToMultipleSelect,
} from '@woocommerce/block-hocs';
import type {
	ProductResponseItem,
	WithInjectedInstanceId,
	WithInjectedProductVariations,
	WithInjectedSearchedProducts,
} from '@woocommerce/types';
import { convertProductResponseItemToSearchItem } from '@woocommerce/utils';
import ErrorMessage from '@woocommerce/editor-components/error-placeholder/error-message';
import classNames from 'classnames';
import ExpandableSearchListItem from '@woocommerce/editor-components/expandable-search-list-item/expandable-search-list-item';

/**
 * Internal dependencies
 */
import './style.scss';

interface ProductControlProps {
	/**
	 * Callback to update the selected products.
	 */
	onChange: () => void;
	isCompact?: boolean;
	/**
	 * The ID of the currently expanded product.
	 */
	expandedProduct: number | null;
	/**
	 * Callback to search products by their name.
	 */
	onSearch: () => void;
	/**
	 * Callback to render each item in the selection list, allows any custom object-type rendering.
	 */
	renderItem: SearchListControlProps[ 'renderItem' ] | null;
	/**
	 * The ID of the currently selected item (product or variation).
	 */
	selected: number[];
	/**
	 * Whether to show variations in the list of items available.
	 */
	showVariations?: boolean;
}

const messages = {
	list: __( 'Products', 'woo-gutenberg-products-block' ),
	noItems: __(
		"Your store doesn't have any products.",
		'woo-gutenberg-products-block'
	),
	search: __(
		'Search for a product to display',
		'woo-gutenberg-products-block'
	),
	updated: __(
		'Product search results updated.',
		'woo-gutenberg-products-block'
	),
};

const ProductControl = (
	props: ProductControlProps &
		WithInjectedSearchedProducts &
		WithInjectedProductVariations &
		WithInjectedInstanceId
) => {
	const {
		expandedProduct = null,
		error,
		instanceId,
		isCompact = false,
		isLoading,
		onChange,
		onSearch,
		products,
		renderItem,
		selected = [],
		showVariations = false,
		variations,
		variationsLoading,
	} = props;

	const renderItemWithVariations = (
		args: renderItemArgs< ProductResponseItem >
	) => {
		const { item, search, depth = 0, isSelected, onSelect } = args;
		const variationsCount =
			item.details?.variations && Array.isArray( item.details.variations )
				? item.details.variations.length
				: 0;
		const classes = classNames(
			'woocommerce-search-product__item',
			'woocommerce-search-list__item',
			`depth-${ depth }`,
			'has-count',
			{
				'is-searching': search.length > 0,
				'is-skip-level': depth === 0 && item.parent !== 0,
				'is-variable': variationsCount > 0,
			}
		);

		// Top level items custom rendering based on SearchListItem.
		if ( ! item.breadcrumbs.length ) {
			const hasVariations =
				item.details?.variations && item.details.variations.length > 0;

			return (
				<ExpandableSearchListItem
					{ ...args }
					className={ classNames( classes, {
						'is-selected': isSelected,
					} ) }
					isSelected={ isSelected }
					item={ item }
					onSelect={ () => {
						return () => {
							onSelect( item )();
						};
					} }
					isLoading={ isLoading || variationsLoading }
					countLabel={
						hasVariations
							? sprintf(
									/* translators: %1$d is the number of variations of a product product. */
									__(
										'%1$d variations',
										'woo-gutenberg-products-block'
									),
									item.details?.variations.length
							  )
							: null
					}
					name={ `products-${ instanceId }` }
					aria-label={
						hasVariations
							? sprintf(
									/* translators: %1$s is the product name, %2$d is the number of variations of that product. */
									_n(
										'%1$s, has %2$d variation',
										'%1$s, has %2$d variations',
										item.details?.variations
											?.length as number,
										'woo-gutenberg-products-block'
									),
									item.name,
									item.details?.variations.length
							  )
							: undefined
					}
				/>
			);
		}

		const itemArgs = isEmpty( item.details?.variation )
			? args
			: {
					...args,
					item: {
						...args.item,
						name: item.details?.variation as string,
					},
					'aria-label': `${ item.breadcrumbs[ 0 ] }: ${ item.details?.variation }`,
			  };

		return (
			<SearchListItem
				{ ...itemArgs }
				className={ classes }
				name={ `variations-${ instanceId }` }
			/>
		);
	};

	const getRenderItemFunc = () => {
		if ( renderItem ) {
			return renderItem;
		} else if ( showVariations ) {
			return renderItemWithVariations;
		}
		return () => null;
	};

	if ( error ) {
		return <ErrorMessage error={ error } />;
	}

	const currentVariations =
		variations && expandedProduct && variations[ expandedProduct ]
			? variations[ expandedProduct ]
			: [];
	const currentList = [ ...products, ...currentVariations ].map(
		convertProductResponseItemToSearchItem
	);

	return (
		<SearchListControl
			className="woocommerce-products"
			list={ currentList }
			isCompact={ isCompact }
			isLoading={ isLoading }
			isSingle
			selected={ currentList.filter( ( { id } ) =>
				selected.includes( Number( id ) )
			) }
			onChange={ onChange }
			renderItem={ getRenderItemFunc() }
			onSearch={ onSearch }
			messages={ messages }
			isHierarchical
		/>
	);
};

export default withTransformSingleSelectToMultipleSelect(
	withSearchedProducts(
		withProductVariations( withInstanceId( ProductControl ) )
	)
);
product-control/style.scss000064400000002220151550716220011737 0ustar00.woocommerce-search-product__item {
	.woocommerce-search-list__item-name {
		.description {
			display: block;
		}
	}

	&.is-searching,
	&.is-skip-level {
		.woocommerce-search-list__item-prefix::after {
			content: ":";
		}
	}

	&.is-not-active {
		&:hover,
		&:active,
		&:focus {
			background: $white;
		}
	}

	&.is-loading {
		justify-content: center;

		.components-spinner {
			margin-bottom: $gap-small;
		}
	}

	&.depth-0.is-variable::after {
		margin-left: $gap-smaller;
		content: "";
		height: $gap-large;
		width: $gap-large;
		background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" fill="#{encode-color($gray-700)}" /></svg>');
		background-repeat: no-repeat;
		background-position: center right;
		background-size: contain;
	}

	&.depth-0.is-variable.is-selected::after {
		background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" fill="#{encode-color($gray-700)}" /></svg>');
	}
}
product-orderby-control/index.tsx000064400000003260151550716220013222 0ustar00/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { SelectControl } from '@wordpress/components';

/**
 * Internal dependencies
 */
import type { ProductOrderbyControlProps } from './types';

/**
 * A pre-configured SelectControl for product orderby settings.
 *
 * @param {Object}            props               Incoming props for the component.
 * @param {string}            props.value
 * @param {function(any):any} props.setAttributes Setter for block attributes.
 */
const ProductOrderbyControl = ( {
	value,
	setAttributes,
}: ProductOrderbyControlProps ) => {
	return (
		<SelectControl
			label={ __( 'Order products by', 'woo-gutenberg-products-block' ) }
			value={ value }
			options={ [
				{
					label: __(
						'Newness - newest first',
						'woo-gutenberg-products-block'
					),
					value: 'date',
				},
				{
					label: __(
						'Price - low to high',
						'woo-gutenberg-products-block'
					),
					value: 'price_asc',
				},
				{
					label: __(
						'Price - high to low',
						'woo-gutenberg-products-block'
					),
					value: 'price_desc',
				},
				{
					label: __(
						'Rating - highest first',
						'woo-gutenberg-products-block'
					),
					value: 'rating',
				},
				{
					label: __(
						'Sales - most first',
						'woo-gutenberg-products-block'
					),
					value: 'popularity',
				},
				{
					label: __(
						'Title - alphabetical',
						'woo-gutenberg-products-block'
					),
					value: 'title',
				},
				{
					label: __( 'Menu Order', 'woo-gutenberg-products-block' ),
					value: 'menu_order',
				},
			] }
			onChange={ ( orderby ) => setAttributes( { orderby } ) }
		/>
	);
};

export default ProductOrderbyControl;
product-orderby-control/types.ts000064400000000203151550716220013061 0ustar00export interface ProductOrderbyControlProps {
	value: string;
	setAttributes: ( attributes: Record< string, unknown > ) => void;
}
product-stock-control/index.tsx000064400000006101151550716220012674 0ustar00/**
 * External dependencies
 */
import { __, sprintf } from '@wordpress/i18n';
import { getSetting } from '@woocommerce/settings';
import { useCallback, useState, useEffect } from '@wordpress/element';
import { ToggleControl } from '@wordpress/components';

export interface ProductStockControlProps {
	value: Array< string >;
	setAttributes: ( attributes: Record< string, unknown > ) => void;
}

// Look up whether or not out of stock items should be hidden globally.
const hideOutOfStockItems = getSetting( 'hideOutOfStockItems', false );

// Get the stock status options.
const allStockStatusOptions = getSetting( 'stockStatusOptions', {} );

/**
 * A pre-configured SelectControl for product stock settings.
 */
const ProductStockControl = ( {
	value,
	setAttributes,
}: ProductStockControlProps ): JSX.Element => {
	// Determine whether or not to use the out of stock status.
	const { outofstock, ...otherStockStatusOptions } = allStockStatusOptions;
	const stockStatusOptions = hideOutOfStockItems
		? otherStockStatusOptions
		: allStockStatusOptions;

	/**
	 * Valid options must be in an array of [ 'value' : 'mystatus', 'label' : 'My label' ] format.
	 * stockStatusOptions are returned as [ 'mystatus' : 'My label' ].
	 * Formatting is corrected here.
	 */
	const displayOptions = Object.entries( stockStatusOptions )
		.map( ( [ slug, name ] ) => ( { value: slug, label: name } ) )
		.filter( ( status ) => !! status.label );
	const defaultCheckedOptions = Object.keys( stockStatusOptions ).filter(
		( key: string ) => !! key
	);

	// Set the initial state to the default or saved value.
	const [ checkedOptions, setChecked ] = useState(
		value || defaultCheckedOptions
	);

	/**
	 * Set attributes when checked items change.
	 * Note: The blank stock status prevents all results returning when all options are unchecked.
	 */
	useEffect( () => {
		setAttributes( {
			stockStatus: [ '', ...checkedOptions ],
		} );
	}, [ checkedOptions, setAttributes ] );

	/**
	 * When a checkbox in the list changes, update state.
	 */
	const onChange = useCallback(
		( checkedValue: string ) => {
			const previouslyChecked = checkedOptions.includes( checkedValue );

			const newChecked = checkedOptions.filter(
				( filteredValue ) => filteredValue !== checkedValue
			);

			if ( ! previouslyChecked ) {
				newChecked.push( checkedValue );
				newChecked.sort();
			}

			setChecked( newChecked );
		},
		[ checkedOptions ]
	);

	return (
		<>
			{ displayOptions.map( ( option ) => {
				const helpText = checkedOptions.includes( option.value )
					? /* translators: %s stock status. */ __(
							'Stock status "%s" visible.',
							'woo-gutenberg-products-block'
					  )
					: /* translators: %s stock status. */ __(
							'Stock status "%s" hidden.',
							'woo-gutenberg-products-block'
					  );
				return (
					<ToggleControl
						label={ option.label }
						key={ option.value }
						help={ sprintf( helpText, option.label ) }
						checked={ checkedOptions.includes( option.value ) }
						onChange={ () => onChange( option.value ) }
					/>
				);
			} ) }
		</>
	);
};

export default ProductStockControl;
product-tag-control/index.tsx000064400000007114151550716220012331 0ustar00/**
 * External dependencies
 */
import { __, _n, sprintf } from '@wordpress/i18n';
import { useState, useEffect, useCallback, useMemo } from '@wordpress/element';
import { SearchListControl } from '@woocommerce/editor-components/search-list-control';
import { SelectControl } from '@wordpress/components';
import { getSetting } from '@woocommerce/settings';
import { useDebouncedCallback } from 'use-debounce';

/**
 * Internal dependencies
 */
import type { SearchListItem as SearchListItemProps } from '../search-list-control/types';
import ProductTagItem from './product-tag-item';
import type { ProductTagControlProps } from './types';
import { getProductTags } from '../utils';
import './style.scss';

/**
 * Component to handle searching and selecting product tags.
 */
const ProductTagControl = ( {
	isCompact = false,
	onChange,
	onOperatorChange,
	operator = 'any',
	selected,
}: ProductTagControlProps ): JSX.Element => {
	const [ list, setList ] = useState< SearchListItemProps[] >( [] );
	const [ loading, setLoading ] = useState( true );
	const [ isMounted, setIsMounted ] = useState( false );
	const limitTags = getSetting( 'limitTags', false );

	const selectedTags = useMemo< SearchListItemProps[] >( () => {
		return list.filter( ( item ) => selected.includes( item.id ) );
	}, [ list, selected ] );

	const onSearch = useCallback(
		( search: string ) => {
			setLoading( true );
			getProductTags( { selected, search } )
				.then( ( newList ) => {
					setList( newList );
					setLoading( false );
				} )
				.catch( () => {
					setLoading( false );
				} );
		},
		[ selected ]
	);

	// Load on mount.
	useEffect( () => {
		if ( isMounted ) {
			return;
		}
		onSearch( '' );
		setIsMounted( true );
	}, [ onSearch, isMounted ] );

	const debouncedOnSearch = useDebouncedCallback( onSearch, 400 );

	const messages = {
		clear: __( 'Clear all product tags', 'woo-gutenberg-products-block' ),
		list: __( 'Product Tags', 'woo-gutenberg-products-block' ),
		noItems: __(
			'You have not set up any product tags on your store.',
			'woo-gutenberg-products-block'
		),
		search: __( 'Search for product tags', 'woo-gutenberg-products-block' ),
		selected: ( n: number ) =>
			sprintf(
				/* translators: %d is the count of selected tags. */
				_n(
					'%d tag selected',
					'%d tags selected',
					n,
					'woo-gutenberg-products-block'
				),
				n
			),
		updated: __(
			'Tag search results updated.',
			'woo-gutenberg-products-block'
		),
	};

	return (
		<>
			<SearchListControl
				className="woocommerce-product-tags"
				list={ list }
				isLoading={ loading }
				selected={ selectedTags }
				onChange={ onChange }
				onSearch={ limitTags ? debouncedOnSearch : undefined }
				renderItem={ ProductTagItem }
				messages={ messages }
				isCompact={ isCompact }
				isHierarchical
				isSingle={ false }
			/>
			{ !! onOperatorChange && (
				<div hidden={ selected.length < 2 }>
					<SelectControl
						className="woocommerce-product-tags__operator"
						label={ __(
							'Display products matching',
							'woo-gutenberg-products-block'
						) }
						help={ __(
							'Pick at least two tags to use this setting.',
							'woo-gutenberg-products-block'
						) }
						value={ operator }
						onChange={ onOperatorChange }
						options={ [
							{
								label: __(
									'Any selected tags',
									'woo-gutenberg-products-block'
								),
								value: 'any',
							},
							{
								label: __(
									'All selected tags',
									'woo-gutenberg-products-block'
								),
								value: 'all',
							},
						] }
					/>
				</div>
			) }
		</>
	);
};

export default ProductTagControl;
product-tag-control/product-tag-item.tsx000064400000002220151550716220014400 0ustar00/**
 * External dependencies
 */
import { _n, sprintf } from '@wordpress/i18n';
import { SearchListItem } from '@woocommerce/editor-components/search-list-control';
import classNames from 'classnames';

/**
 * Internal dependencies
 */
import type { renderItemArgs } from '../search-list-control/types';

export const ProductTagItem = ( {
	item,
	search,
	depth = 0,
	...rest
}: renderItemArgs ): JSX.Element => {
	const accessibleName = ! item.breadcrumbs.length
		? item.name
		: `${ item.breadcrumbs.join( ', ' ) }, ${ item.name }`;

	return (
		<SearchListItem
			className={ classNames(
				'woocommerce-product-tags__item',
				'has-count',
				{
					'is-searching': search.length > 0,
					'is-skip-level': depth === 0 && item.parent !== 0,
				}
			) }
			item={ item }
			search={ search }
			depth={ depth }
			{ ...rest }
			ariaLabel={ sprintf(
				/* translators: %1$d is the count of products, %2$s is the name of the tag. */
				_n(
					'%1$d product tagged as %2$s',
					'%1$d products tagged as %2$s',
					item.count,
					'woo-gutenberg-products-block'
				),
				item.count,
				accessibleName
			) }
		/>
	);
};

export default ProductTagItem;
product-tag-control/style.scss000064400000000273151550716220012516 0ustar00.woocommerce-product-tags__operator {
	.components-base-control__help {
		@include visually-hidden;
	}

	.components-base-control__label {
		margin-bottom: 0;
		margin-right: 0.5em;
	}
}
product-tag-control/types.ts000064400000000563151550716220012177 0ustar00/**
 * Internal dependencies
 */
import type { SearchListItem as SearchListItemProps } from '../search-list-control/types';

export type ProductTagControlProps = {
	isCompact?: boolean;
	onChange: ( selected: SearchListItemProps[] ) => void;
	onOperatorChange?: ( operator: string ) => void;
	operator?: string;
	// Selected tag ids.
	selected: ( number | string )[];
};
products-control/index.js000064400000005326151550716220011544 0ustar00/**
 * External dependencies
 */
import { __, _n, sprintf } from '@wordpress/i18n';
import { SearchListControl } from '@woocommerce/editor-components/search-list-control';
import PropTypes from 'prop-types';
import { withSearchedProducts } from '@woocommerce/block-hocs';
import ErrorMessage from '@woocommerce/editor-components/error-placeholder/error-message';
import { decodeEntities } from '@wordpress/html-entities';

/**
 * The products control exposes a custom selector for searching and selecting
 * products.
 *
 * @param {Object}   props           Component props.
 * @param {string}   props.error
 * @param {Function} props.onChange  Callback fired when the selected item changes
 * @param {Function} props.onSearch  Callback fired when a search is triggered
 * @param {Array}    props.selected  An array of selected products.
 * @param {Array}    props.products  An array of products to select from.
 * @param {boolean}  props.isLoading Whether or not the products are being loaded.
 * @param {boolean}  props.isCompact Whether or not the control should have compact styles.
 *
 * @return {Function} A functional component.
 */
const ProductsControl = ( {
	error,
	onChange,
	onSearch,
	selected,
	products,
	isLoading,
	isCompact,
} ) => {
	const messages = {
		clear: __( 'Clear all products', 'woocommerce' ),
		list: __( 'Products', 'woocommerce' ),
		noItems: __(
			"Your store doesn't have any products.",
			'woocommerce'
		),
		search: __(
			'Search for products to display',
			'woocommerce'
		),
		selected: ( n ) =>
			sprintf(
				/* translators: %d is the number of selected products. */
				_n(
					'%d product selected',
					'%d products selected',
					n,
					'woocommerce'
				),
				n
			),
		updated: __(
			'Product search results updated.',
			'woocommerce'
		),
	};

	if ( error ) {
		return <ErrorMessage error={ error } />;
	}

	return (
		<SearchListControl
			className="woocommerce-products"
			list={ products.map( ( product ) => {
				const formattedSku = product.sku
					? ' (' + product.sku + ')'
					: '';
				return {
					...product,
					name: `${ decodeEntities(
						product.name
					) }${ formattedSku }`,
				};
			} ) }
			isCompact={ isCompact }
			isLoading={ isLoading }
			selected={ products.filter( ( { id } ) =>
				selected.includes( id )
			) }
			onSearch={ onSearch }
			onChange={ onChange }
			messages={ messages }
		/>
	);
};

ProductsControl.propTypes = {
	onChange: PropTypes.func.isRequired,
	onSearch: PropTypes.func,
	selected: PropTypes.array,
	products: PropTypes.array,
	isCompact: PropTypes.bool,
	isLoading: PropTypes.bool,
};

ProductsControl.defaultProps = {
	selected: [],
	products: [],
	isCompact: false,
	isLoading: true,
};

export default withSearchedProducts( ProductsControl );
search-list-control/index.ts000064400000000077151550716220012127 0ustar00export * from './search-list-control';
export * from './item';
search-list-control/item.tsx000064400000011677151550716220012156 0ustar00/**
 * External dependencies
 */
import classNames from 'classnames';
import { CheckboxControl } from '@wordpress/components';
import { useCallback } from '@wordpress/element';
import { arrayDifferenceBy, arrayUnionBy } from '@woocommerce/utils';
import { decodeEntities } from '@wordpress/html-entities';

/**
 * Internal dependencies
 */
import type {
	renderItemArgs,
	SearchListItem as SearchListItemProps,
} from './types';
import { getHighlightedName, getBreadcrumbsForDisplay } from './utils';

const Count = ( { label }: { label: string | React.ReactNode | number } ) => {
	return (
		<span className="woocommerce-search-list__item-count">{ label }</span>
	);
};

const ItemLabel = ( props: { item: SearchListItemProps; search: string } ) => {
	const { item, search } = props;
	const hasBreadcrumbs = item.breadcrumbs && item.breadcrumbs.length;

	return (
		<span className="woocommerce-search-list__item-label">
			{ hasBreadcrumbs ? (
				<span className="woocommerce-search-list__item-prefix">
					{ getBreadcrumbsForDisplay( item.breadcrumbs ) }
				</span>
			) : null }
			<span className="woocommerce-search-list__item-name">
				{ getHighlightedName( decodeEntities( item.name ), search ) }
			</span>
		</span>
	);
};

export const SearchListItem = < T extends object = object >( {
	countLabel,
	className,
	depth = 0,
	controlId = '',
	item,
	isSelected,
	isSingle,
	onSelect,
	search = '',
	selected,
	useExpandedPanelId,
	...props
}: renderItemArgs< T > ): JSX.Element => {
	const [ expandedPanelId, setExpandedPanelId ] = useExpandedPanelId;
	const showCount =
		countLabel !== undefined &&
		countLabel !== null &&
		item.count !== undefined &&
		item.count !== null;
	const hasBreadcrumbs = !! item.breadcrumbs?.length;
	const hasChildren = !! item.children?.length;
	const isExpanded = expandedPanelId === item.id;
	const classes = classNames(
		[ 'woocommerce-search-list__item', `depth-${ depth }`, className ],
		{
			'has-breadcrumbs': hasBreadcrumbs,
			'has-children': hasChildren,
			'has-count': showCount,
			'is-expanded': isExpanded,
			'is-radio-button': isSingle,
		}
	);

	const name = props.name || `search-list-item-${ controlId }`;
	const id = `${ name }-${ item.id }`;

	const togglePanel = useCallback( () => {
		setExpandedPanelId( isExpanded ? -1 : Number( item.id ) );
	}, [ isExpanded, item.id, setExpandedPanelId ] );

	return hasChildren ? (
		<div
			className={ classes }
			onClick={ togglePanel }
			onKeyDown={ ( e ) =>
				e.key === 'Enter' || e.key === ' ' ? togglePanel() : null
			}
			role="treeitem"
			tabIndex={ 0 }
		>
			{ isSingle ? (
				<>
					<input
						type="radio"
						id={ id }
						name={ name }
						value={ item.value }
						onChange={ onSelect( item ) }
						onClick={ ( e ) => e.stopPropagation() }
						checked={ isSelected }
						className="woocommerce-search-list__item-input"
						{ ...props }
					/>

					<ItemLabel item={ item } search={ search } />

					{ showCount ? (
						<Count label={ countLabel || item.count } />
					) : null }
				</>
			) : (
				<>
					<CheckboxControl
						className="woocommerce-search-list__item-input"
						checked={ isSelected }
						{ ...( ! isSelected &&
						// We know that `item.children` is not `undefined` because
						// we are here only if `hasChildren` is `true`.
						( item.children as SearchListItemProps[] ).some(
							( child ) =>
								selected.find(
									( selectedItem ) =>
										selectedItem.id === child.id
								)
						)
							? { indeterminate: true }
							: {} ) }
						label={ getHighlightedName(
							decodeEntities( item.name ),
							search
						) }
						onChange={ () => {
							if ( isSelected ) {
								onSelect(
									arrayDifferenceBy(
										selected,
										item.children as SearchListItemProps[],
										'id'
									)
								)();
							} else {
								onSelect(
									arrayUnionBy(
										selected,
										item.children as SearchListItemProps[],
										'id'
									)
								)();
							}
						} }
						onClick={ ( e ) => e.stopPropagation() }
					/>

					{ showCount ? (
						<Count label={ countLabel || item.count } />
					) : null }
				</>
			) }
		</div>
	) : (
		<label htmlFor={ id } className={ classes }>
			{ isSingle ? (
				<>
					<input
						{ ...props }
						type="radio"
						id={ id }
						name={ name }
						value={ item.value }
						onChange={ onSelect( item ) }
						checked={ isSelected }
						className="woocommerce-search-list__item-input"
					></input>

					<ItemLabel item={ item } search={ search } />
				</>
			) : (
				<CheckboxControl
					{ ...props }
					id={ id }
					name={ name }
					className="woocommerce-search-list__item-input"
					value={ decodeEntities( item.value ) }
					label={ getHighlightedName(
						decodeEntities( item.name ),
						search
					) }
					onChange={ onSelect( item ) }
					checked={ isSelected }
				/>
			) }

			{ showCount ? <Count label={ countLabel || item.count } /> : null }
		</label>
	);
};

export default SearchListItem;
search-list-control/search-list-control.tsx000064400000017723151550716220015112 0ustar00/**
 * External dependencies
 */
import { __, sprintf } from '@wordpress/i18n';
import {
	Button,
	FormTokenField,
	Spinner,
	TextControl,
	withSpokenMessages,
} from '@wordpress/components';
import {
	useState,
	useMemo,
	useEffect,
	useCallback,
	Fragment,
} from '@wordpress/element';
import { Icon, info } from '@wordpress/icons';
import classnames from 'classnames';
import { useInstanceId } from '@wordpress/compose';

/**
 * Internal dependencies
 */
import { getFilteredList, defaultMessages } from './utils';
import SearchListItem from './item';
import Tag from '../tag';
import type {
	SearchListItem as SearchListItemProps,
	SearchListControlProps,
	SearchListMessages,
	renderItemArgs,
	ListItemsProps,
	SearchListItemsContainerProps,
} from './types';
import './style.scss';

const defaultRenderListItem = ( args: renderItemArgs ): JSX.Element => {
	return <SearchListItem { ...args } />;
};

const ListItems = ( props: ListItemsProps ): JSX.Element | null => {
	const {
		list,
		selected,
		renderItem,
		depth = 0,
		onSelect,
		instanceId,
		isSingle,
		search,
		useExpandedPanelId,
	} = props;

	const [ expandedPanelId ] = useExpandedPanelId;

	if ( ! list ) {
		return null;
	}
	return (
		<>
			{ list.map( ( item ) => {
				const isSelected =
					item.children?.length && ! isSingle
						? item.children.every( ( { id } ) =>
								selected.find(
									( selectedItem ) => selectedItem.id === id
								)
						  )
						: !! selected.find( ( { id } ) => id === item.id );
				const isExpanded =
					item.children?.length && expandedPanelId === item.id;

				return (
					<Fragment key={ item.id }>
						<li>
							{ renderItem( {
								item,
								isSelected,
								onSelect,
								isSingle,
								selected,
								search,
								depth,
								useExpandedPanelId,
								controlId: instanceId,
							} ) }
						</li>
						{ isExpanded ? (
							<ListItems
								{ ...props }
								list={ item.children as SearchListItemProps[] }
								depth={ depth + 1 }
							/>
						) : null }
					</Fragment>
				);
			} ) }
		</>
	);
};

const SelectedListItems = < T extends object = object >( {
	isLoading,
	isSingle,
	selected,
	messages,
	onChange,
	onRemove,
}: SearchListControlProps< T > & {
	messages: SearchListMessages;
	onRemove: ( itemId: string | number ) => () => void;
} ) => {
	if ( isLoading || isSingle || ! selected ) {
		return null;
	}
	const selectedCount = selected.length;
	return (
		<div className="woocommerce-search-list__selected">
			<div className="woocommerce-search-list__selected-header">
				<strong>{ messages.selected( selectedCount ) }</strong>
				{ selectedCount > 0 ? (
					<Button
						isLink
						isDestructive
						onClick={ () => onChange( [] ) }
						aria-label={ messages.clear }
					>
						{ __( 'Clear all', 'woo-gutenberg-products-block' ) }
					</Button>
				) : null }
			</div>
			{ selectedCount > 0 ? (
				<ul>
					{ selected.map( ( item, i ) => (
						<li key={ i }>
							<Tag
								label={ item.name }
								id={ item.id }
								remove={ onRemove }
							/>
						</li>
					) ) }
				</ul>
			) : null }
		</div>
	);
};

const ListItemsContainer = < T extends object = object >( {
	filteredList,
	search,
	onSelect,
	instanceId,
	useExpandedPanelId,
	...props
}: SearchListItemsContainerProps< T > ) => {
	const { messages, renderItem, selected, isSingle } = props;
	const renderItemCallback = renderItem || defaultRenderListItem;

	if ( filteredList.length === 0 ) {
		return (
			<div className="woocommerce-search-list__list is-not-found">
				<span className="woocommerce-search-list__not-found-icon">
					<Icon icon={ info } />
				</span>
				<span className="woocommerce-search-list__not-found-text">
					{ search
						? // eslint-disable-next-line @wordpress/valid-sprintf
						  sprintf( messages.noResults, search )
						: messages.noItems }
				</span>
			</div>
		);
	}

	return (
		<ul className="woocommerce-search-list__list">
			<ListItems
				useExpandedPanelId={ useExpandedPanelId }
				list={ filteredList }
				selected={ selected }
				renderItem={ renderItemCallback }
				onSelect={ onSelect }
				instanceId={ instanceId }
				isSingle={ isSingle }
				search={ search }
			/>
		</ul>
	);
};

/**
 * Component to display a searchable, selectable list of items.
 */
export const SearchListControl = < T extends object = object >(
	props: SearchListControlProps< T >
) => {
	const {
		className = '',
		isCompact,
		isHierarchical,
		isLoading,
		isSingle,
		list,
		messages: customMessages = defaultMessages,
		onChange,
		onSearch,
		selected,
		type = 'text',
		debouncedSpeak,
	} = props;

	const [ search, setSearch ] = useState( '' );
	const useExpandedPanelId = useState< number >( -1 );
	const instanceId = useInstanceId( SearchListControl );
	const messages = useMemo(
		() => ( { ...defaultMessages, ...customMessages } ),
		[ customMessages ]
	);
	const filteredList = useMemo( () => {
		return getFilteredList( list, search, isHierarchical );
	}, [ list, search, isHierarchical ] );

	useEffect( () => {
		if ( debouncedSpeak ) {
			debouncedSpeak( messages.updated );
		}
	}, [ debouncedSpeak, messages ] );

	useEffect( () => {
		if ( typeof onSearch === 'function' ) {
			onSearch( search );
		}
	}, [ search, onSearch ] );

	const onRemove = useCallback(
		( itemId: string | number ) => () => {
			if ( isSingle ) {
				onChange( [] );
			}
			const i = selected.findIndex(
				( { id: selectedId } ) => selectedId === itemId
			);
			onChange( [
				...selected.slice( 0, i ),
				...selected.slice( i + 1 ),
			] );
		},
		[ isSingle, selected, onChange ]
	);

	const onSelect = useCallback(
		( item: SearchListItemProps< T > | SearchListItemProps< T >[] ) =>
			() => {
				if ( Array.isArray( item ) ) {
					onChange( item );
					return;
				}

				if (
					selected.findIndex( ( { id } ) => id === item.id ) !== -1
				) {
					onRemove( item.id )();
					return;
				}
				if ( isSingle ) {
					onChange( [ item ] );
				} else {
					onChange( [ ...selected, item ] );
				}
			},
		[ isSingle, onRemove, onChange, selected ]
	);

	const onRemoveToken = useCallback(
		( tokens: Array< SearchListItemProps & { value: string } > ) => {
			const [ removedItem ] = selected.filter(
				( item ) => ! tokens.find( ( token ) => item.id === token.id )
			);

			onRemove( removedItem.id )();
		},
		[ onRemove, selected ]
	);

	return (
		<div
			className={ classnames( 'woocommerce-search-list', className, {
				'is-compact': isCompact,
				'is-loading': isLoading,
				'is-token': type === 'token',
			} ) }
		>
			{ type === 'text' && (
				<SelectedListItems
					{ ...props }
					onRemove={ onRemove }
					messages={ messages }
				/>
			) }
			<div className="woocommerce-search-list__search">
				{ type === 'text' ? (
					<TextControl
						label={ messages.search }
						type="search"
						value={ search }
						onChange={ ( value ) => setSearch( value ) }
					/>
				) : (
					<FormTokenField
						disabled={ isLoading }
						label={ messages.search }
						onChange={ onRemoveToken }
						onInputChange={ ( value ) => setSearch( value ) }
						suggestions={ [] }
						// eslint-disable-next-line @typescript-eslint/ban-ts-comment
						// @ts-ignore - Ignoring because `__experimentalValidateInput` is not yet in the type definitions.
						__experimentalValidateInput={ () => false }
						value={
							isLoading
								? [
										__(
											'Loading…',
											'woo-gutenberg-products-block'
										),
								  ]
								: selected.map( ( token ) => ( {
										...token,
										value: token.name,
								  } ) )
						}
						__experimentalShowHowTo={ false }
					/>
				) }
			</div>
			{ isLoading ? (
				<div className="woocommerce-search-list__list">
					<Spinner />
				</div>
			) : (
				<ListItemsContainer
					{ ...props }
					search={ search }
					filteredList={ filteredList }
					messages={ messages }
					onSelect={ onSelect }
					instanceId={ instanceId }
					useExpandedPanelId={ useExpandedPanelId }
				/>
			) }
		</div>
	);
};

export default withSpokenMessages( SearchListControl );
search-list-control/style.scss000064400000013062151550716220012503 0ustar00.woocommerce-search-list {
	width: 100%;
	padding: 0 0 $gap;
	text-align: left;

	&.is-compact {
		.woocommerce-search-list__selected {
			margin: 0 0 $gap;
			padding: 0;
			border-top: none;
			// 54px is the height of 1 row of tags in the sidebar.
			min-height: 54px;
		}

		.woocommerce-search-list__search {
			margin: 0 0 $gap;
			padding: 0;
			border-top: none;

			&.is-token {
				margin-bottom: 0;
			}
		}
	}

	&.is-loading {
		.woocommerce-search-list__list {
			padding: $gap-small 0;
			text-align: center;
			border: none;
		}

		.components-form-token-field__remove-token {
			// We use a placeholder “Loading…” text when loading passed
			// as a value to the `FormTokenField`, so we hide the “X”.
			display: none;
		}
	}

	&.is-token {
		.woocommerce-search-list__list {
			border-top: 0;
		}

		.woocommerce-search-list__search {
			margin-bottom: 0;

			.components-form-token-field__input-container {
				border-bottom-left-radius: 0;
				border-bottom-right-radius: 0;
				margin-bottom: 0;
			}
		}
	}
}

.woocommerce-search-list__selected {
	margin: $gap 0;
	padding: $gap 0 0;
	// 76px is the height of 1 row of tags.
	min-height: 76px;
	border-top: 1px solid $gray-100;

	.woocommerce-search-list__selected-header {
		margin-bottom: $gap-smaller;

		button {
			margin-left: $gap-small;
		}
	}

	.woocommerce-tag__text {
		max-width: 13em;
	}

	ul {
		list-style: none;
		margin: 0;
		padding: 0;

		li {
			float: left;
		}
	}
}

.woocommerce-search-list__search {
	margin: $gap 0;
	padding: $gap 0 0;
	border-top: 1px solid $gray-100;

	.components-base-control__field {
		margin-bottom: $gap;
	}
}

.woocommerce-search-list__list {
	border: 1px solid $gray-200;
	margin: 0;
	padding: 0;
	max-height: 17em;
	overflow-x: hidden;
	overflow-y: auto;

	li {
		margin-bottom: 0;
	}

	&.is-not-found {
		padding: $gap-small 0;
		text-align: center;
		border: none;

		.woocommerce-search-list__not-found-icon,
		.woocommerce-search-list__not-found-text {
			display: inline-block;
		}

		.woocommerce-search-list__not-found-icon {
			margin-right: $gap;

			.gridicon {
				vertical-align: top;
				margin-top: -1px;
			}
		}
	}

	.components-spinner {
		float: none;
		margin: 0 auto;
	}

	.components-menu-group__label {
		@include visually-hidden;
	}

	> [role="menu"] {
		border: 1px solid $gray-100;
		border-bottom: none;
	}

	.woocommerce-search-list__item {
		display: flex;
		align-items: center;
		margin-bottom: 0;
		padding: $gap-small $gap;
		background: $studio-white;
		// !important to keep the border around on hover
		border-bottom: 1px solid $gray-100;
		color: $gray-700;

		&:hover,
		&:active,
		&:focus {
			background: $gray-100;
		}

		&:active,
		&:focus {
			box-shadow: none;
		}

		&.has-children {
			cursor: pointer;

			&::after {
				background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" fill="#{encode-color($gray-700)}" /></svg>');
				background-position: center right;
				background-repeat: no-repeat;
				background-size: contain;
				content: "";
				height: $gap-large;
				margin-left: $gap-smaller;
				width: $gap-large;
			}

			&[disabled]::after {
				background: none;
				margin-left: 0;
				width: auto;
			}

			&.is-expanded::after {
				background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" fill="#{encode-color($gray-700)}" /></svg>');
			}
		}

		.woocommerce-search-list__item-input {
			margin: 0;
		}

		.woocommerce-search-list__item-input[type="radio"] {
			margin-right: $gap-smaller;
		}

		.components-base-control__field {
			margin: 0;
		}

		.woocommerce-search-list__item-label {
			display: flex;
			flex: 1;
		}

		&.depth-0 + .depth-1 {
			// Hide the border on the preceding list item
			margin-top: -1px;
		}

		&:not(.depth-0) {
			border-bottom: 0 !important;
		}

		&:not(.depth-0) + .depth-0 {
			border-top: 1px solid $gray-100;
		}

		// Anything deeper than 5 levels will use this fallback depth
		&[class*="depth-"] .woocommerce-search-list__item-label::before {
			margin-right: $gap-smallest;
			content: str-repeat("— ", 5);
		}

		&.depth-0 .woocommerce-search-list__item-label::before {
			margin-right: 0;
			content: "";
		}

		@for $i from 1 to 5 {
			&.depth-#{$i} {
				padding-left: $gap * ( $i + 1 );
			}

			&.depth-#{$i} .woocommerce-search-list__item-label::before {
				content: str-repeat("— ", $i);
			}
		}

		.woocommerce-search-list__item-name {
			display: inline-block;
		}

		.woocommerce-search-list__item-prefix {
			display: none;
			color: $gray-700;
		}

		&.is-searching,
		&.is-skip-level {
			.woocommerce-search-list__item-label {
				// Un-flex the label, so the prefix (breadcrumbs) and name are aligned.
				display: inline-block;
			}

			.woocommerce-search-list__item-prefix {
				display: inline;

				&::after {
					margin-right: $gap-smallest;
					content: " ›";
				}
			}
		}

		&.is-searching {
			.woocommerce-search-list__item-name {
				color: $gray-900;
			}
		}

		&.has-count {
			> .components-menu-item__item {
				width: 100%;
			}
		}

		.woocommerce-search-list__item-count {
			flex: 0 1 auto;
			padding: math.div($gap-smallest, 2) $gap-smaller;
			border: 1px solid $gray-100;
			border-radius: 12px;
			font-size: 0.8em;
			line-height: 1.4;
			margin-left: auto;
			color: $gray-700;
			background: $studio-white;
			white-space: nowrap;
		}
	}

	li:last-child .woocommerce-search-list__item {
		border-bottom: none;
	}
}
search-list-control/test/__snapshots__/index.js.snap000064400000551305151550716220016657 0ustar00// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SearchListControl should render a search box and list of hierarchical options 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list is-compact"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-11"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-11"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <div
              class="woocommerce-search-list__item depth-0 has-children"
              role="treeitem"
              tabindex="0"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="inspector-checkbox-control-54"
                      type="checkbox"
                      value="1"
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-54"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </div>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-11-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-11-5"
                      name="search-list-item-11"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-55"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-11-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-11-6"
                      name="search-list-item-11"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-56"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list is-compact"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-11"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-11"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <div
            class="woocommerce-search-list__item depth-0 has-children"
            role="treeitem"
            tabindex="0"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="inspector-checkbox-control-54"
                    type="checkbox"
                    value="1"
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-54"
                >
                  Apricots
                </label>
              </div>
            </div>
          </div>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-11-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-11-5"
                    name="search-list-item-11"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-55"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-11-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-11-6"
                    name="search-list-item-11"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-56"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box and list of options 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-0"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-0"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-0-1"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-0-1"
                      name="search-list-item-0"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-0"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-0-2"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-0-2"
                      name="search-list-item-0"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-1"
                  >
                    Clementine
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-0-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-0-3"
                      name="search-list-item-0"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-2"
                  >
                    Elderberry
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-0-4"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-0-4"
                      name="search-list-item-0"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-3"
                  >
                    Guava
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-0-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-0-5"
                      name="search-list-item-0"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-4"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-0-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-0-6"
                      name="search-list-item-0"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-5"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-0"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-0"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-0-1"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-0-1"
                    name="search-list-item-0"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-0"
                >
                  Apricots
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-0-2"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-0-2"
                    name="search-list-item-0"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-1"
                >
                  Clementine
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-0-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-0-3"
                    name="search-list-item-0"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-2"
                >
                  Elderberry
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-0-4"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-0-4"
                    name="search-list-item-0"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-3"
                >
                  Guava
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-0-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-0-5"
                    name="search-list-item-0"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-4"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-0-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-0-6"
                    name="search-list-item-0"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-5"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box and list of options with a custom className 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list test-search"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-1"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-1"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-1-1"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-1-1"
                      name="search-list-item-1"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-6"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-1-2"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-1-2"
                      name="search-list-item-1"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-7"
                  >
                    Clementine
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-1-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-1-3"
                      name="search-list-item-1"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-8"
                  >
                    Elderberry
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-1-4"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-1-4"
                      name="search-list-item-1"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-9"
                  >
                    Guava
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-1-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-1-5"
                      name="search-list-item-1"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-10"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-1-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-1-6"
                      name="search-list-item-1"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-11"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list test-search"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-1"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-1"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-1-1"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-1-1"
                    name="search-list-item-1"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-6"
                >
                  Apricots
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-1-2"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-1-2"
                    name="search-list-item-1"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-7"
                >
                  Clementine
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-1-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-1-3"
                    name="search-list-item-1"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-8"
                >
                  Elderberry
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-1-4"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-1-4"
                    name="search-list-item-1"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-9"
                >
                  Guava
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-1-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-1-5"
                    name="search-list-item-1"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-10"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-1-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-1-6"
                    name="search-list-item-1"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-11"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box and list of options, with a custom render callback for each item 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-10"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-10"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <div>
              Apricots
              !
            </div>
          </li>
          <li>
            <div>
              Clementine
              !
            </div>
          </li>
          <li>
            <div>
              Elderberry
              !
            </div>
          </li>
          <li>
            <div>
              Guava
              !
            </div>
          </li>
          <li>
            <div>
              Lychee
              !
            </div>
          </li>
          <li>
            <div>
              Mulberry
              !
            </div>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-10"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-10"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <div>
            Apricots
            !
          </div>
        </li>
        <li>
          <div>
            Clementine
            !
          </div>
        </li>
        <li>
          <div>
            Elderberry
            !
          </div>
        </li>
        <li>
          <div>
            Guava
            !
          </div>
        </li>
        <li>
          <div>
            Lychee
            !
          </div>
        </li>
        <li>
          <div>
            Mulberry
            !
          </div>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box and list of options, with a custom search input message 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-9"
              >
                Testing search label
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-9"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-9-1"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-9-1"
                      name="search-list-item-9"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-48"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-9-2"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-9-2"
                      name="search-list-item-9"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-49"
                  >
                    Clementine
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-9-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-9-3"
                      name="search-list-item-9"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-50"
                  >
                    Elderberry
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-9-4"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-9-4"
                      name="search-list-item-9"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-51"
                  >
                    Guava
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-9-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-9-5"
                      name="search-list-item-9"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-52"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-9-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-9-6"
                      name="search-list-item-9"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-53"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-9"
            >
              Testing search label
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-9"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-9-1"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-9-1"
                    name="search-list-item-9"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-48"
                >
                  Apricots
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-9-2"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-9-2"
                    name="search-list-item-9"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-49"
                >
                  Clementine
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-9-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-9-3"
                    name="search-list-item-9"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-50"
                >
                  Elderberry
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-9-4"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-9-4"
                    name="search-list-item-9"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-51"
                >
                  Guava
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-9-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-9-5"
                    name="search-list-item-9"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-52"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-9-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-9-6"
                    name="search-list-item-9"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-53"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box and no options 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-4"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-4"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <div
          class="woocommerce-search-list__list is-not-found"
        >
          <span
            class="woocommerce-search-list__not-found-icon"
          >
            <svg
              aria-hidden="true"
              focusable="false"
              height="24"
              role="img"
              viewBox="0 0 24 24"
              width="24"
              xmlns="http://www.w3.org/2000/svg"
            >
              <path
                d="M12 3.2c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8 0-4.8-4-8.8-8.8-8.8zm0 16c-4 0-7.2-3.3-7.2-7.2C4.8 8 8 4.8 12 4.8s7.2 3.3 7.2 7.2c0 4-3.2 7.2-7.2 7.2zM11 17h2v-6h-2v6zm0-8h2V7h-2v2z"
              />
            </svg>
          </span>
          <span
            class="woocommerce-search-list__not-found-text"
          >
            No items found.
          </span>
        </div>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-4"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-4"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <div
        class="woocommerce-search-list__list is-not-found"
      >
        <span
          class="woocommerce-search-list__not-found-icon"
        >
          <svg
            aria-hidden="true"
            focusable="false"
            height="24"
            role="img"
            viewBox="0 0 24 24"
            width="24"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              d="M12 3.2c-4.8 0-8.8 3.9-8.8 8.8 0 4.8 3.9 8.8 8.8 8.8 4.8 0 8.8-3.9 8.8-8.8 0-4.8-4-8.8-8.8-8.8zm0 16c-4 0-7.2-3.3-7.2-7.2C4.8 8 8 4.8 12 4.8s7.2 3.3 7.2 7.2c0 4-3.2 7.2-7.2 7.2zM11 17h2v-6h-2v6zm0-8h2V7h-2v2z"
            />
          </svg>
        </span>
        <span
          class="woocommerce-search-list__not-found-text"
        >
          No items found.
        </span>
      </div>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box with a search term, and no matching options 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-8"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-8"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-8-1"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-8-1"
                      name="search-list-item-8"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-42"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-8-2"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-8-2"
                      name="search-list-item-8"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-43"
                  >
                    Clementine
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-8-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-8-3"
                      name="search-list-item-8"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-44"
                  >
                    Elderberry
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-8-4"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-8-4"
                      name="search-list-item-8"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-45"
                  >
                    Guava
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-8-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-8-5"
                      name="search-list-item-8"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-46"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-8-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-8-6"
                      name="search-list-item-8"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-47"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-8"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-8"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-8-1"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-8-1"
                    name="search-list-item-8"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-42"
                >
                  Apricots
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-8-2"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-8-2"
                    name="search-list-item-8"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-43"
                >
                  Clementine
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-8-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-8-3"
                    name="search-list-item-8"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-44"
                >
                  Elderberry
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-8-4"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-8-4"
                    name="search-list-item-8"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-45"
                >
                  Guava
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-8-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-8-5"
                    name="search-list-item-8"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-46"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-8-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-8-6"
                    name="search-list-item-8"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-47"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box with a search term, and only matching options 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-5"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-5"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-5-1"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-5-1"
                      name="search-list-item-5"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-24"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-5-2"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-5-2"
                      name="search-list-item-5"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-25"
                  >
                    Clementine
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-5-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-5-3"
                      name="search-list-item-5"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-26"
                  >
                    Elderberry
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-5-4"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-5-4"
                      name="search-list-item-5"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-27"
                  >
                    Guava
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-5-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-5-5"
                      name="search-list-item-5"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-28"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-5-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-5-6"
                      name="search-list-item-5"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-29"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-5"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-5"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-5-1"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-5-1"
                    name="search-list-item-5"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-24"
                >
                  Apricots
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-5-2"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-5-2"
                    name="search-list-item-5"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-25"
                >
                  Clementine
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-5-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-5-3"
                    name="search-list-item-5"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-26"
                >
                  Elderberry
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-5-4"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-5-4"
                    name="search-list-item-5"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-27"
                >
                  Guava
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-5-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-5-5"
                    name="search-list-item-5"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-28"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-5-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-5-6"
                    name="search-list-item-5"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-29"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box with a search term, and only matching options, regardless of case sensitivity 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              0 items selected
            </strong>
          </div>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-6"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-6"
                type="search"
                value="BeRrY"
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-6-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-6-3"
                      name="search-list-item-6"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-32"
                  >
                    Elder
                    <strong>
                      berry
                    </strong>
                    
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-6-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-6-6"
                      name="search-list-item-6"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-35"
                  >
                    Mul
                    <strong>
                      berry
                    </strong>
                    
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            0 items selected
          </strong>
        </div>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-6"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-6"
              type="search"
              value="BeRrY"
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-6-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-6-3"
                    name="search-list-item-6"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-32"
                >
                  Elder
                  <strong>
                    berry
                  </strong>
                  
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-6-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-6-6"
                    name="search-list-item-6"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-35"
                >
                  Mul
                  <strong>
                    berry
                  </strong>
                  
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box, a list of options, and 1 selected item 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              1 item selected
            </strong>
            <button
              aria-label="Clear all selected items"
              class="components-button is-link is-destructive"
              type="button"
            >
              Clear all
            </button>
          </div>
          <ul>
            <li>
              <span
                class="woocommerce-tag has-remove"
              >
                <span
                  class="woocommerce-tag__text"
                  id="woocommerce-tag__label-0"
                >
                  <span
                    class="screen-reader-text"
                  >
                    Clementine
                  </span>
                  <span
                    aria-hidden="true"
                  >
                    Clementine
                  </span>
                </span>
                <button
                  aria-describedby="woocommerce-tag__label-0"
                  aria-label="Remove Clementine"
                  class="components-button woocommerce-tag__remove"
                  type="button"
                >
                  <svg
                    aria-hidden="true"
                    class="clear-icon"
                    focusable="false"
                    height="20"
                    role="img"
                    viewBox="0 0 24 24"
                    width="20"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <path
                      d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
                    />
                  </svg>
                </button>
              </span>
            </li>
          </ul>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-2"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-2"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-2-1"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-2-1"
                      name="search-list-item-2"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-12"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-2-2"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      checked=""
                      class="components-checkbox-control__input"
                      id="search-list-item-2-2"
                      name="search-list-item-2"
                      type="checkbox"
                      value=""
                    />
                    <svg
                      aria-hidden="true"
                      class="components-checkbox-control__checked"
                      focusable="false"
                      height="24"
                      role="img"
                      viewBox="0 0 24 24"
                      width="24"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"
                      />
                    </svg>
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-13"
                  >
                    Clementine
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-2-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-2-3"
                      name="search-list-item-2"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-14"
                  >
                    Elderberry
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-2-4"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-2-4"
                      name="search-list-item-2"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-15"
                  >
                    Guava
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-2-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-2-5"
                      name="search-list-item-2"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-16"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-2-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-2-6"
                      name="search-list-item-2"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-17"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            1 item selected
          </strong>
          <button
            aria-label="Clear all selected items"
            class="components-button is-link is-destructive"
            type="button"
          >
            Clear all
          </button>
        </div>
        <ul>
          <li>
            <span
              class="woocommerce-tag has-remove"
            >
              <span
                class="woocommerce-tag__text"
                id="woocommerce-tag__label-0"
              >
                <span
                  class="screen-reader-text"
                >
                  Clementine
                </span>
                <span
                  aria-hidden="true"
                >
                  Clementine
                </span>
              </span>
              <button
                aria-describedby="woocommerce-tag__label-0"
                aria-label="Remove Clementine"
                class="components-button woocommerce-tag__remove"
                type="button"
              >
                <svg
                  aria-hidden="true"
                  class="clear-icon"
                  focusable="false"
                  height="20"
                  role="img"
                  viewBox="0 0 24 24"
                  width="20"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
                  />
                </svg>
              </button>
            </span>
          </li>
        </ul>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-2"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-2"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-2-1"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-2-1"
                    name="search-list-item-2"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-12"
                >
                  Apricots
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-2-2"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    checked=""
                    class="components-checkbox-control__input"
                    id="search-list-item-2-2"
                    name="search-list-item-2"
                    type="checkbox"
                    value=""
                  />
                  <svg
                    aria-hidden="true"
                    class="components-checkbox-control__checked"
                    focusable="false"
                    height="24"
                    role="img"
                    viewBox="0 0 24 24"
                    width="24"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <path
                      d="M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"
                    />
                  </svg>
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-13"
                >
                  Clementine
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-2-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-2-3"
                    name="search-list-item-2"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-14"
                >
                  Elderberry
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-2-4"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-2-4"
                    name="search-list-item-2"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-15"
                >
                  Guava
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-2-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-2-5"
                    name="search-list-item-2"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-16"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-2-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-2-6"
                    name="search-list-item-2"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-17"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`SearchListControl should render a search box, a list of options, and 2 selected item 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <div
        class="woocommerce-search-list"
      >
        <div
          class="woocommerce-search-list__selected"
        >
          <div
            class="woocommerce-search-list__selected-header"
          >
            <strong>
              2 items selected
            </strong>
            <button
              aria-label="Clear all selected items"
              class="components-button is-link is-destructive"
              type="button"
            >
              Clear all
            </button>
          </div>
          <ul>
            <li>
              <span
                class="woocommerce-tag has-remove"
              >
                <span
                  class="woocommerce-tag__text"
                  id="woocommerce-tag__label-1"
                >
                  <span
                    class="screen-reader-text"
                  >
                    Clementine
                  </span>
                  <span
                    aria-hidden="true"
                  >
                    Clementine
                  </span>
                </span>
                <button
                  aria-describedby="woocommerce-tag__label-1"
                  aria-label="Remove Clementine"
                  class="components-button woocommerce-tag__remove"
                  type="button"
                >
                  <svg
                    aria-hidden="true"
                    class="clear-icon"
                    focusable="false"
                    height="20"
                    role="img"
                    viewBox="0 0 24 24"
                    width="20"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <path
                      d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
                    />
                  </svg>
                </button>
              </span>
            </li>
            <li>
              <span
                class="woocommerce-tag has-remove"
              >
                <span
                  class="woocommerce-tag__text"
                  id="woocommerce-tag__label-2"
                >
                  <span
                    class="screen-reader-text"
                  >
                    Guava
                  </span>
                  <span
                    aria-hidden="true"
                  >
                    Guava
                  </span>
                </span>
                <button
                  aria-describedby="woocommerce-tag__label-2"
                  aria-label="Remove Guava"
                  class="components-button woocommerce-tag__remove"
                  type="button"
                >
                  <svg
                    aria-hidden="true"
                    class="clear-icon"
                    focusable="false"
                    height="20"
                    role="img"
                    viewBox="0 0 24 24"
                    width="20"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <path
                      d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
                    />
                  </svg>
                </button>
              </span>
            </li>
          </ul>
        </div>
        <div
          class="woocommerce-search-list__search"
        >
          <div
            class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
          >
            <div
              class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
            >
              <label
                class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
                for="inspector-text-control-3"
              >
                Search for items
              </label>
              <input
                class="components-text-control__input"
                id="inspector-text-control-3"
                type="search"
                value=""
              />
            </div>
          </div>
        </div>
        <ul
          class="woocommerce-search-list__list"
        >
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-3-1"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-3-1"
                      name="search-list-item-3"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-18"
                  >
                    Apricots
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-3-2"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      checked=""
                      class="components-checkbox-control__input"
                      id="search-list-item-3-2"
                      name="search-list-item-3"
                      type="checkbox"
                      value=""
                    />
                    <svg
                      aria-hidden="true"
                      class="components-checkbox-control__checked"
                      focusable="false"
                      height="24"
                      role="img"
                      viewBox="0 0 24 24"
                      width="24"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"
                      />
                    </svg>
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-19"
                  >
                    Clementine
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-3-3"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-3-3"
                      name="search-list-item-3"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-20"
                  >
                    Elderberry
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-3-4"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      checked=""
                      class="components-checkbox-control__input"
                      id="search-list-item-3-4"
                      name="search-list-item-3"
                      type="checkbox"
                      value=""
                    />
                    <svg
                      aria-hidden="true"
                      class="components-checkbox-control__checked"
                      focusable="false"
                      height="24"
                      role="img"
                      viewBox="0 0 24 24"
                      width="24"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <path
                        d="M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"
                      />
                    </svg>
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-21"
                  >
                    Guava
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-3-5"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-3-5"
                      name="search-list-item-3"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-22"
                  >
                    Lychee
                  </label>
                </div>
              </div>
            </label>
          </li>
          <li>
            <label
              class="woocommerce-search-list__item depth-0"
              for="search-list-item-3-6"
            >
              <div
                class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
              >
                <div
                  class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
                >
                  <span
                    class="components-checkbox-control__input-container"
                  >
                    <input
                      class="components-checkbox-control__input"
                      id="search-list-item-3-6"
                      name="search-list-item-3"
                      type="checkbox"
                      value=""
                    />
                  </span>
                  <label
                    class="components-checkbox-control__label"
                    for="inspector-checkbox-control-23"
                  >
                    Mulberry
                  </label>
                </div>
              </div>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </body>,
  "container": <div>
    <div
      class="woocommerce-search-list"
    >
      <div
        class="woocommerce-search-list__selected"
      >
        <div
          class="woocommerce-search-list__selected-header"
        >
          <strong>
            2 items selected
          </strong>
          <button
            aria-label="Clear all selected items"
            class="components-button is-link is-destructive"
            type="button"
          >
            Clear all
          </button>
        </div>
        <ul>
          <li>
            <span
              class="woocommerce-tag has-remove"
            >
              <span
                class="woocommerce-tag__text"
                id="woocommerce-tag__label-1"
              >
                <span
                  class="screen-reader-text"
                >
                  Clementine
                </span>
                <span
                  aria-hidden="true"
                >
                  Clementine
                </span>
              </span>
              <button
                aria-describedby="woocommerce-tag__label-1"
                aria-label="Remove Clementine"
                class="components-button woocommerce-tag__remove"
                type="button"
              >
                <svg
                  aria-hidden="true"
                  class="clear-icon"
                  focusable="false"
                  height="20"
                  role="img"
                  viewBox="0 0 24 24"
                  width="20"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
                  />
                </svg>
              </button>
            </span>
          </li>
          <li>
            <span
              class="woocommerce-tag has-remove"
            >
              <span
                class="woocommerce-tag__text"
                id="woocommerce-tag__label-2"
              >
                <span
                  class="screen-reader-text"
                >
                  Guava
                </span>
                <span
                  aria-hidden="true"
                >
                  Guava
                </span>
              </span>
              <button
                aria-describedby="woocommerce-tag__label-2"
                aria-label="Remove Guava"
                class="components-button woocommerce-tag__remove"
                type="button"
              >
                <svg
                  aria-hidden="true"
                  class="clear-icon"
                  focusable="false"
                  height="20"
                  role="img"
                  viewBox="0 0 24 24"
                  width="20"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
                  />
                </svg>
              </button>
            </span>
          </li>
        </ul>
      </div>
      <div
        class="woocommerce-search-list__search"
      >
        <div
          class="components-base-control css-wdf2ti-Wrapper e1puf3u3"
        >
          <div
            class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
          >
            <label
              class="components-base-control__label css-13ck15n-StyledLabel e1puf3u1"
              for="inspector-text-control-3"
            >
              Search for items
            </label>
            <input
              class="components-text-control__input"
              id="inspector-text-control-3"
              type="search"
              value=""
            />
          </div>
        </div>
      </div>
      <ul
        class="woocommerce-search-list__list"
      >
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-3-1"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-3-1"
                    name="search-list-item-3"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-18"
                >
                  Apricots
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-3-2"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    checked=""
                    class="components-checkbox-control__input"
                    id="search-list-item-3-2"
                    name="search-list-item-3"
                    type="checkbox"
                    value=""
                  />
                  <svg
                    aria-hidden="true"
                    class="components-checkbox-control__checked"
                    focusable="false"
                    height="24"
                    role="img"
                    viewBox="0 0 24 24"
                    width="24"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <path
                      d="M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"
                    />
                  </svg>
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-19"
                >
                  Clementine
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-3-3"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-3-3"
                    name="search-list-item-3"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-20"
                >
                  Elderberry
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-3-4"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    checked=""
                    class="components-checkbox-control__input"
                    id="search-list-item-3-4"
                    name="search-list-item-3"
                    type="checkbox"
                    value=""
                  />
                  <svg
                    aria-hidden="true"
                    class="components-checkbox-control__checked"
                    focusable="false"
                    height="24"
                    role="img"
                    viewBox="0 0 24 24"
                    width="24"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <path
                      d="M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"
                    />
                  </svg>
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-21"
                >
                  Guava
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-3-5"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-3-5"
                    name="search-list-item-3"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-22"
                >
                  Lychee
                </label>
              </div>
            </div>
          </label>
        </li>
        <li>
          <label
            class="woocommerce-search-list__item depth-0"
            for="search-list-item-3-6"
          >
            <div
              class="components-base-control components-checkbox-control woocommerce-search-list__item-input css-wdf2ti-Wrapper e1puf3u3"
            >
              <div
                class="components-base-control__field css-igk9ll-StyledField e1puf3u2"
              >
                <span
                  class="components-checkbox-control__input-container"
                >
                  <input
                    class="components-checkbox-control__input"
                    id="search-list-item-3-6"
                    name="search-list-item-3"
                    type="checkbox"
                    value=""
                  />
                </span>
                <label
                  class="components-checkbox-control__label"
                  for="inspector-checkbox-control-23"
                >
                  Mulberry
                </label>
              </div>
            </div>
          </label>
        </li>
      </ul>
    </div>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;
search-list-control/test/hierarchy.js000064400000007757151550716220013757 0ustar00/**
 * Internal dependencies
 */
import { buildTermsTree } from '../utils';

const list = [
	{ id: 1, name: 'Apricots', parent: 0 },
	{ id: 2, name: 'Clementine', parent: 0 },
	{ id: 3, name: 'Elderberry', parent: 2 },
	{ id: 4, name: 'Guava', parent: 2 },
	{ id: 5, name: 'Lychee', parent: 3 },
	{ id: 6, name: 'Mulberry', parent: 0 },
	{ id: 7, name: 'Tamarind', parent: 5 },
];

describe( 'buildTermsTree', () => {
	test( 'should return an empty array on empty input', () => {
		const tree = buildTermsTree( [] );
		expect( tree ).toEqual( [] );
	} );

	test( 'should return a flat array when there are no parent relationships', () => {
		const tree = buildTermsTree( [
			{ id: 1, name: 'Apricots', parent: 0 },
			{ id: 2, name: 'Clementine', parent: 0 },
		] );
		expect( tree ).toEqual( [
			{
				id: 1,
				name: 'Apricots',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
			{
				id: 2,
				name: 'Clementine',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
		] );
	} );

	test( 'should return a tree of items', () => {
		const tree = buildTermsTree( list );
		expect( tree ).toEqual( [
			{
				id: 1,
				name: 'Apricots',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
			{
				id: 2,
				name: 'Clementine',
				parent: 0,
				breadcrumbs: [],
				children: [
					{
						id: 3,
						name: 'Elderberry',
						parent: 2,
						breadcrumbs: [ 'Clementine' ],
						children: [
							{
								id: 5,
								name: 'Lychee',
								parent: 3,
								breadcrumbs: [ 'Clementine', 'Elderberry' ],
								children: [
									{
										id: 7,
										name: 'Tamarind',
										parent: 5,
										breadcrumbs: [
											'Clementine',
											'Elderberry',
											'Lychee',
										],
										children: [],
									},
								],
							},
						],
					},
					{
						id: 4,
						name: 'Guava',
						parent: 2,
						breadcrumbs: [ 'Clementine' ],
						children: [],
					},
				],
			},
			{
				id: 6,
				name: 'Mulberry',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
		] );
	} );

	test( 'should return a tree of items, with orphan categories appended to the end', () => {
		const filteredList = [
			{ id: 1, name: 'Apricots', parent: 0 },
			{ id: 2, name: 'Clementine', parent: 0 },
			{ id: 4, name: 'Guava', parent: 2 },
			{ id: 5, name: 'Lychee', parent: 3 },
			{ id: 6, name: 'Mulberry', parent: 0 },
		];
		const tree = buildTermsTree( filteredList, list );
		expect( tree ).toEqual( [
			{
				id: 1,
				name: 'Apricots',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
			{
				id: 2,
				name: 'Clementine',
				parent: 0,
				breadcrumbs: [],
				children: [
					{
						id: 4,
						name: 'Guava',
						parent: 2,
						breadcrumbs: [ 'Clementine' ],
						children: [],
					},
				],
			},
			{
				id: 6,
				name: 'Mulberry',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
			{
				id: 5,
				name: 'Lychee',
				parent: 3,
				breadcrumbs: [ 'Clementine', 'Elderberry' ],
				children: [],
			},
		] );
	} );

	test( 'should return a tree of items, with orphan categories appended to the end, with children of thier own', () => {
		const filteredList = [
			{ id: 1, name: 'Apricots', parent: 0 },
			{ id: 3, name: 'Elderberry', parent: 2 },
			{ id: 4, name: 'Guava', parent: 2 },
			{ id: 5, name: 'Lychee', parent: 3 },
			{ id: 6, name: 'Mulberry', parent: 0 },
		];
		const tree = buildTermsTree( filteredList, list );
		expect( tree ).toEqual( [
			{
				id: 1,
				name: 'Apricots',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
			{
				id: 6,
				name: 'Mulberry',
				parent: 0,
				breadcrumbs: [],
				children: [],
			},
			{
				id: 3,
				name: 'Elderberry',
				parent: 2,
				breadcrumbs: [ 'Clementine' ],
				children: [
					{
						id: 5,
						name: 'Lychee',
						parent: 3,
						breadcrumbs: [ 'Clementine', 'Elderberry' ],
						children: [],
					},
				],
			},
			{
				id: 4,
				name: 'Guava',
				parent: 2,
				breadcrumbs: [ 'Clementine' ],
				children: [],
			},
		] );
	} );
} );
search-list-control/test/index.js000064400000012423151550716220013072 0ustar00/**
 * External dependencies
 */
import { fireEvent, render } from '@testing-library/react';

/**
 * Internal dependencies
 */
import { SearchListControl } from '../';

const noop = () => {};

const SELECTORS = {
	listItems: '.woocommerce-search-list__list > li',
	searchInput: '.components-text-control__input[type="search"]',
};

const list = [
	{ id: 1, name: 'Apricots' },
	{ id: 2, name: 'Clementine' },
	{ id: 3, name: 'Elderberry' },
	{ id: 4, name: 'Guava' },
	{ id: 5, name: 'Lychee' },
	{ id: 6, name: 'Mulberry' },
];

const hierarchicalList = [
	{ id: 1, name: 'Apricots', parent: 0 },
	{ id: 2, name: 'Clementine', parent: 1 },
	{ id: 3, name: 'Elderberry', parent: 1 },
	{ id: 4, name: 'Guava', parent: 3 },
	{ id: 5, name: 'Lychee', parent: 0 },
	{ id: 6, name: 'Mulberry', parent: 0 },
];

describe( 'SearchListControl', () => {
	test( 'should render a search box and list of options', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				selected={ [] }
				onChange={ noop }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box and list of options with a custom className', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				className="test-search"
				list={ list }
				selected={ [] }
				onChange={ noop }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box, a list of options, and 1 selected item', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				selected={ [ list[ 1 ] ] }
				onChange={ noop }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box, a list of options, and 2 selected item', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				selected={ [ list[ 1 ], list[ 3 ] ] }
				onChange={ noop }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box and no options', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ [] }
				selected={ [] }
				onChange={ noop }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box with a search term, and only matching options', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				search="berry"
				selected={ [] }
				onChange={ noop }
				debouncedSpeak={ noop }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box with a search term, and only matching options, regardless of case sensitivity', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				selected={ [] }
				onChange={ noop }
				debouncedSpeak={ noop }
			/>
		);

		fireEvent.change(
			component.container.querySelector( SELECTORS.searchInput ),
			{ target: { value: 'BeRrY' } }
		);

		expect( component ).toMatchSnapshot();

		const $listItems = component.container.querySelectorAll(
			SELECTORS.listItems
		);

		expect( $listItems ).toHaveLength( 2 );
	} );

	// @see https://github.com/woocommerce/woocommerce-blocks/issues/6524
	test( "should render search results in their original case regardless of user's input case", () => {
		const EXPECTED = [ 'Elderberry', 'Mulberry' ];

		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				selected={ [] }
				onChange={ noop }
				debouncedSpeak={ noop }
			/>
		);

		fireEvent.change(
			component.container.querySelector( SELECTORS.searchInput ),
			{ target: { value: 'BeRrY' } }
		);

		const listItems = Array.from(
			component.container.querySelectorAll( SELECTORS.listItems )
		).map( ( $el ) => $el.textContent );

		expect( listItems ).toEqual( expect.arrayContaining( EXPECTED ) );
	} );

	test( 'should render a search box with a search term, and no matching options', () => {
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				search="no matches"
				selected={ [] }
				onChange={ noop }
				debouncedSpeak={ noop }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box and list of options, with a custom search input message', () => {
		const messages = { search: 'Testing search label' };
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				selected={ [] }
				onChange={ noop }
				messages={ messages }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box and list of options, with a custom render callback for each item', () => {
		const renderItem = ( { item } ) => (
			<div key={ item.id }>{ item.name }!</div>
		); // eslint-disable-line
		const component = render(
			<SearchListControl
				instanceId={ 1 }
				list={ list }
				selected={ [] }
				onChange={ noop }
				renderItem={ renderItem }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );

	test( 'should render a search box and list of hierarchical options', () => {
		const component = render(
			<SearchListControl
				isCompact
				isHierarchical
				instanceId={ 1 }
				isSingle={ false }
				list={ hierarchicalList }
				onChange={ noop }
				selected={ [] }
				type={ 'text' }
			/>
		);
		expect( component ).toMatchSnapshot();
	} );
} );
search-list-control/types.ts000064400000011743151550716220012166 0ustar00/**
 * External dependencies
 */
import type { InputHTMLAttributes, ReactNode } from 'react';
import { Require } from '@woocommerce/types';

interface ItemProps< T extends object = object > {
	// Depth, non-zero if the list is hierarchical.
	depth?: number;
	// Callback for selecting the item.
	onSelect: (
		item: SearchListItem< T > | SearchListItem< T >[]
	) => () => void;
	// Search string, used to highlight the substring in the item name.
	search: string;
	useExpandedPanelId: [
		number,
		React.Dispatch< React.SetStateAction< number > >
	];
}

interface SearchListProps< T extends object = object > {
	//Restrict selections to one item.
	isSingle: boolean;
	// A complete list of item objects, each with id, name properties. This is displayed as a clickable/keyboard-able list, and possibly filtered by the search term (searches name).
	list: SearchListItem< T >[];
	// Callback to render each item in the selection list, allows any custom object-type rendering.
	renderItem?: ( args: renderItemArgs< T > ) => JSX.Element;
	// The list of currently selected items.
	selected: SearchListItem< T >[];
}

export interface ListItemsProps
	extends Require< SearchListProps, 'renderItem' >,
		ItemProps {
	instanceId: string | number;
}

export type SearchListItem< T extends object = object > = {
	breadcrumbs: string[];
	children?: SearchListItem< T >[];
	count?: number;
	details?: T;
	id: string | number;
	name: string;
	parent: number;
	value: string;
};

export interface SearchListItemsContainerProps< T extends object = object >
	extends SearchListControlProps,
		ItemProps {
	instanceId: string | number;
	filteredList: SearchListItem< T >[];
	messages: SearchListMessages;
}

export interface SearchListMessages {
	// A more detailed label for the "Clear all" button, read to screen reader users.
	clear: string;
	// Message to display when the list is empty (implies nothing loaded from the server or parent component).
	noItems: string;
	// Message to display when no matching results are found. %s is the search term.
	noResults: string;
	// Label for the search input
	search: string;
	// Label for the selected items. This is actually a function, so that we can pass through the count of currently selected items.
	selected: ( n: number ) => string;
	// Label indicating that search results have changed, read to screen reader users.
	updated: string;
}

export interface renderItemArgs< T extends object = object >
	extends ItemProps,
		Partial<
			Omit<
				InputHTMLAttributes< HTMLInputElement >,
				'onChange' | 'onSelect'
			>
		> {
	// Additional CSS classes.
	className?: string;
	// Unique id of the parent control.
	controlId: string | number;
	// Label to display in the count bubble. Takes preference over `item.count`.
	countLabel?: ReactNode;
	// Whether the item is disabled.
	disabled?: boolean;
	// Current item to display.
	item: SearchListItem< T >;
	// Whether this item is selected.
	isSelected: boolean;
	// Whether this should only display a single item (controls radio vs checkbox icon).
	isSingle: boolean;
	// The list of currently selected items.
	selected: SearchListItem< T >[];
	/**
	 * Name of the inputs. Used to group input controls together. See:
	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-name
	 * If not provided, a default name will be generated using the controlId.
	 */
	name?: string;
	// Aria label for the input. If not provided, a default label will be generated using the item name.
	ariaLabel?: string;
}

export interface SearchListControlProps< T extends object = object > {
	// Additional CSS classes.
	className?: string;
	// Whether it should be displayed in a compact way, so it occupies less space.
	isCompact: boolean;
	// Whether the list of items is hierarchical or not. If true, each list item is expected to have a parent property.
	isHierarchical?: boolean;
	// Whether the list of items is still loading.
	isLoading?: boolean;
	//Restrict selections to one item.
	isSingle: boolean;
	// A complete list of item objects, each with id, name properties. This is displayed as a clickable/keyboard-able list, and possibly filtered by the search term (searches name).
	list: SearchListItem< T >[];
	// Messages displayed or read to the user. Configure these to reflect your object type.
	messages?: Partial< SearchListMessages >;
	// Callback fired when selected items change, whether added, cleared, or removed. Passed an array of item objects (as passed in via props.list).
	onChange: ( search: SearchListItem< T >[] ) => void;
	// Callback fired when the search field is used.
	onSearch?: ( ( search: string ) => void ) | undefined;
	// Callback to render each item in the selection list, allows any custom object-type rendering.
	renderItem?:
		| ( ( args: renderItemArgs< T > ) => JSX.Element | null )
		| undefined;
	// The list of currently selected items.
	selected: SearchListItem< T >[];
	// Whether to show a text field or a token field as search
	// Defaults to `'text'`
	type?: 'text' | 'token';
	// from withSpokenMessages
	debouncedSpeak?: ( message: string ) => void;
}
search-list-control/utils.tsx000064400000007657151550716220012363 0ustar00/**
 * External dependencies
 */
import { Fragment } from '@wordpress/element';
import { __, _n, sprintf } from '@wordpress/i18n';
import { keyBy } from '@woocommerce/base-utils';

/**
 * Internal dependencies
 */
import type { SearchListItem } from './types';

export const defaultMessages = {
	clear: __( 'Clear all selected items', 'woo-gutenberg-products-block' ),
	noItems: __( 'No items found.', 'woo-gutenberg-products-block' ),
	/* Translators: %s search term */
	noResults: __( 'No results for %s', 'woo-gutenberg-products-block' ),
	search: __( 'Search for items', 'woo-gutenberg-products-block' ),
	selected: ( n: number ): string =>
		sprintf(
			/* translators: Number of items selected from list. */
			_n(
				'%d item selected',
				'%d items selected',
				n,
				'woo-gutenberg-products-block'
			),
			n
		),
	updated: __( 'Search results updated.', 'woo-gutenberg-products-block' ),
};

/**
 * Returns terms in a tree form.
 *
 * @param {Array} filteredList Array of terms, possibly a subset of all terms, in flat format.
 * @param {Array} list         Array of the full list of terms, defaults to the filteredList.
 *
 * @return {Array} Array of terms in tree format.
 */
export const buildTermsTree = (
	filteredList: SearchListItem[],
	list = filteredList
): SearchListItem[] | [] => {
	const termsByParent = filteredList.reduce( ( acc, currentValue ) => {
		const key = currentValue.parent || 0;

		if ( ! acc[ key ] ) {
			acc[ key ] = [];
		}

		acc[ key ].push( currentValue );
		return acc;
	}, {} as Record< string, SearchListItem[] > );

	const listById = keyBy( list, 'id' );
	const builtParents = [ '0' ];

	const getParentsName = ( term = {} as SearchListItem ): string[] => {
		if ( ! term.parent ) {
			return term.name ? [ term.name ] : [];
		}

		const parentName = getParentsName( listById[ term.parent ] );
		return [ ...parentName, term.name ];
	};

	const fillWithChildren = ( terms: SearchListItem[] ): SearchListItem[] => {
		return terms.map( ( term ) => {
			const children = termsByParent[ term.id ];
			builtParents.push( '' + term.id );
			return {
				...term,
				breadcrumbs: getParentsName( listById[ term.parent ] ),
				children:
					children && children.length
						? fillWithChildren( children )
						: [],
			};
		} );
	};

	const tree = fillWithChildren( termsByParent[ '0' ] || [] );

	// Handle remaining items in termsByParent that have not been built (orphaned).
	Object.entries( termsByParent ).forEach( ( [ termId, terms ] ) => {
		if ( ! builtParents.includes( termId ) ) {
			tree.push( ...fillWithChildren( terms || [] ) );
		}
	} );

	return tree;
};

export const getFilteredList = (
	list: SearchListItem[],
	search: string,
	isHierarchical?: boolean | undefined
) => {
	if ( ! search ) {
		return isHierarchical ? buildTermsTree( list ) : list;
	}
	const re = new RegExp(
		search.replace( /[-\/\\^$*+?.()|[\]{}]/g, '\\$&' ),
		'i'
	);
	const filteredList = list
		.map( ( item ) => ( re.test( item.name ) ? item : false ) )
		.filter( Boolean ) as SearchListItem[];

	return isHierarchical ? buildTermsTree( filteredList, list ) : filteredList;
};

export const getHighlightedName = (
	name: string,
	search: string
): ( JSX.Element | string )[] | string => {
	if ( ! search ) {
		return name;
	}
	const re = new RegExp(
		// Escaping.
		`(${ search.replace( /[-\/\\^$*+?.()|[\]{}]/g, '\\$&' ) })`,
		'ig'
	);
	const nameParts = name.split( re );

	return nameParts.map( ( part, i ) => {
		return re.test( part ) ? (
			<strong key={ i }>{ part }</strong>
		) : (
			<Fragment key={ i }>{ part }</Fragment>
		);
	} );
};

export const getBreadcrumbsForDisplay = ( breadcrumbs: string[] ): string => {
	if ( breadcrumbs.length === 1 ) {
		return breadcrumbs.slice( 0, 1 ).toString();
	}
	if ( breadcrumbs.length === 2 ) {
		return (
			breadcrumbs.slice( 0, 1 ).toString() +
			' › ' +
			breadcrumbs.slice( -1 ).toString()
		);
	}
	return (
		breadcrumbs.slice( 0, 1 ).toString() +
		' … ' +
		breadcrumbs.slice( -1 ).toString()
	);
};
sidebar-compatibility-notice/editor.scss000064400000000421151550716220014467 0ustar00.wc-blocks-sidebar-compatibility-notice.is-dismissible {
	margin: 0;
	padding-right: 16px;
	.components-notice__dismiss {
		min-width: 24px;
	}
	.components-notice__content {
		margin: 4px 0;
	}
	svg {
		width: 16px;
		height: 16px;
	}
	&.is-hidden {
		display: none;
	}
}
sidebar-compatibility-notice/index.tsx000064400000002430151550716220014155 0ustar00/**
 * External dependencies
 */
import { Notice, ExternalLink } from '@wordpress/components';
import { createInterpolateElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import classnames from 'classnames';

/**
 * Internal dependencies
 */
import './editor.scss';
import { useCompatibilityNotice } from './use-compatibility-notice';

export const CartCheckoutSidebarCompatibilityNotice = ( {
	block,
}: {
	block: 'cart' | 'checkout';
} ) => {
	const [ isVisible, dismissNotice ] = useCompatibilityNotice( block );

	const noticeText = createInterpolateElement(
		__(
			'The Cart & Checkout Blocks are built to optimize for faster checkout. To make sure this feature is right for your store, <a>review the list of compatible extensions</a>.',
			'woo-gutenberg-products-block'
		),
		{
			a: (
				// Suppress the warning as this <a> will be interpolated into the string with content.
				// eslint-disable-next-line jsx-a11y/anchor-has-content
				<ExternalLink href="https://woocommerce.com/document/cart-checkout-blocks-support-status/#section-3" />
			),
		}
	);

	return (
		<Notice
			onRemove={ dismissNotice }
			className={ classnames( [
				'wc-blocks-sidebar-compatibility-notice',
				{ 'is-hidden': ! isVisible },
			] ) }
		>
			{ noticeText }
		</Notice>
	);
};
sidebar-compatibility-notice/use-compatibility-notice.ts000064400000002006151550716220017577 0ustar00/**
 * External dependencies
 */
import { useEffect, useState } from '@wordpress/element';
import { useLocalStorageState } from '@woocommerce/base-hooks';

const initialDismissedNotices: string[] = [];

export const useCompatibilityNotice = (
	blockName: string
): [ boolean, () => void ] => {
	const [ dismissedNotices, setDismissedNotices ] = useLocalStorageState(
		`wc-blocks_dismissed_sidebar_compatibility_notices`,
		initialDismissedNotices
	);
	const [ isVisible, setIsVisible ] = useState( false );

	const isDismissed = dismissedNotices.includes( blockName );
	const dismissNotice = () => {
		const dismissedNoticesSet = new Set( dismissedNotices );
		dismissedNoticesSet.add( blockName );
		setDismissedNotices( [ ...dismissedNoticesSet ] );
	};

	// This ensures the modal is not loaded on first render. This is required so
	// Gutenberg doesn't steal the focus from the Guide and focuses the block.
	useEffect( () => {
		setIsVisible( ! isDismissed );
	}, [ isDismissed ] );

	return [ isVisible, dismissNotice ];
};
tag/editor.scss000064400000001461151550716220007510 0ustar00.woocommerce-tag {
	display: inline-flex;
	margin: 1px 4px 1px 0;
	overflow: hidden;
	vertical-align: middle;

	.woocommerce-tag__text,
	.woocommerce-tag__remove {
		display: inline-block;
		line-height: 24px;
		background: $gray-100;
		transition: all 0.2s cubic-bezier(0.4, 1, 0.4, 1);
	}

	.woocommerce-tag__text {
		align-self: center;
		padding: 0 $gap-smaller;
		border-radius: 12px;
		color: $gray-700;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	&.has-remove .woocommerce-tag__text {
		padding: 0 $gap-smallest 0 $gap-smaller;
		border-radius: 12px 0 0 12px;
	}

	.woocommerce-tag__remove {
		cursor: pointer;
		padding: 0 2px;
		border-radius: 0 12px 12px 0;
		color: $gray-700;
		line-height: 10px;
		text-indent: 0;
		height: 24px;

		&:hover {
			color: $gray-900;
		}
	}
}
tag/index.tsx000064400000005267151550716220007204 0ustar00/**
 * External dependencies
 */
import { __, sprintf } from '@wordpress/i18n';
import classnames from 'classnames';
import { Button, Popover } from '@wordpress/components';
import { Icon, cancelCircleFilled } from '@wordpress/icons';
import { decodeEntities } from '@wordpress/html-entities';
import { useInstanceId } from '@wordpress/compose';
import { useState } from '@wordpress/element';

/**
 * Internal dependencies
 */
import './editor.scss';

/**
 * This component can be used to show an item styled as a "tag", optionally with an `X` + "remove"
 * or with a popover that is shown on click.
 */
const Tag = ( {
	id,
	label,
	popoverContents,
	remove,
	screenReaderLabel,
	className = '',
}: {
	// Additional CSS classes.
	className?: string;
	// The ID for this item, used in the remove function.
	id: string | number;
	// The name for this item, displayed as the tag's text.
	label: string;
	// Contents to display on click in a popover
	popoverContents?: JSX.Element;
	// A function called when the remove X is clicked. If not used, no X icon will display.
	remove?: ( id: string | number ) => () => void;
	// A more descriptive label for screen reader users. Defaults to the `name` prop.
	screenReaderLabel?: string;
} ): JSX.Element | null => {
	const [ isVisible, setIsVisible ] = useState( false );
	const instanceId = useInstanceId( Tag );
	screenReaderLabel = screenReaderLabel || label;
	if ( ! label ) {
		// A null label probably means something went wrong
		return null;
	}
	label = decodeEntities( label );
	const classes = classnames( 'woocommerce-tag', className, {
		'has-remove': !! remove,
	} );
	const labelId = `woocommerce-tag__label-${ instanceId }`;
	const labelTextNode = (
		<>
			<span className="screen-reader-text">{ screenReaderLabel }</span>
			<span aria-hidden="true">{ label }</span>
		</>
	);

	return (
		<span className={ classes }>
			{ popoverContents ? (
				<Button
					className="woocommerce-tag__text"
					id={ labelId }
					onClick={ () => setIsVisible( true ) }
				>
					{ labelTextNode }
				</Button>
			) : (
				<span className="woocommerce-tag__text" id={ labelId }>
					{ labelTextNode }
				</span>
			) }
			{ popoverContents && isVisible && (
				<Popover onClose={ () => setIsVisible( false ) }>
					{ popoverContents }
				</Popover>
			) }
			{ remove && (
				<Button
					className="woocommerce-tag__remove"
					onClick={ remove( id ) }
					label={ sprintf(
						// Translators: %s label.
						__( 'Remove %s', 'woo-gutenberg-products-block' ),
						label
					) }
					aria-describedby={ labelId }
				>
					<Icon
						icon={ cancelCircleFilled }
						size={ 20 }
						className="clear-icon"
					/>
				</Button>
			) }
		</span>
	);
};

export default Tag;
tag/test/__snapshots__/index.js.snap000064400000042106151550716220013530 0ustar00// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Tag <Tag label="foo" /> should render a tag with the label foo 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <span
        class="woocommerce-tag"
      >
        <span
          class="woocommerce-tag__text"
          id="woocommerce-tag__label-0"
        >
          <span
            class="screen-reader-text"
          >
            foo
          </span>
          <span
            aria-hidden="true"
          >
            foo
          </span>
        </span>
      </span>
    </div>
  </body>,
  "container": <div>
    <span
      class="woocommerce-tag"
    >
      <span
        class="woocommerce-tag__text"
        id="woocommerce-tag__label-0"
      >
        <span
          class="screen-reader-text"
        >
          foo
        </span>
        <span
          aria-hidden="true"
        >
          foo
        </span>
      </span>
    </span>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`Tag <Tag label="foo" popoverContents={ <p>This is a popover</p> } /> should render a tag with a popover 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <span
        class="woocommerce-tag"
      >
        <button
          class="components-button woocommerce-tag__text"
          id="woocommerce-tag__label-2"
          type="button"
        >
          <span
            class="screen-reader-text"
          >
            foo
          </span>
          <span
            aria-hidden="true"
          >
            foo
          </span>
        </button>
      </span>
    </div>
  </body>,
  "container": <div>
    <span
      class="woocommerce-tag"
    >
      <button
        class="components-button woocommerce-tag__text"
        id="woocommerce-tag__label-2"
        type="button"
      >
        <span
          class="screen-reader-text"
        >
          foo
        </span>
        <span
          aria-hidden="true"
        >
          foo
        </span>
      </button>
    </span>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`Tag <Tag label="foo" remove={ noop } /> should render a tag with a close button 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <span
        class="woocommerce-tag has-remove"
      >
        <span
          class="woocommerce-tag__text"
          id="woocommerce-tag__label-1"
        >
          <span
            class="screen-reader-text"
          >
            foo
          </span>
          <span
            aria-hidden="true"
          >
            foo
          </span>
        </span>
        <button
          aria-describedby="woocommerce-tag__label-1"
          aria-label="Remove foo"
          class="components-button woocommerce-tag__remove"
          type="button"
        >
          <svg
            aria-hidden="true"
            class="clear-icon"
            focusable="false"
            height="20"
            role="img"
            viewBox="0 0 24 24"
            width="20"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
            />
          </svg>
        </button>
      </span>
    </div>
  </body>,
  "container": <div>
    <span
      class="woocommerce-tag has-remove"
    >
      <span
        class="woocommerce-tag__text"
        id="woocommerce-tag__label-1"
      >
        <span
          class="screen-reader-text"
        >
          foo
        </span>
        <span
          aria-hidden="true"
        >
          foo
        </span>
      </span>
      <button
        aria-describedby="woocommerce-tag__label-1"
        aria-label="Remove foo"
        class="components-button woocommerce-tag__remove"
        type="button"
      >
        <svg
          aria-hidden="true"
          class="clear-icon"
          focusable="false"
          height="20"
          role="img"
          viewBox="0 0 24 24"
          width="20"
          xmlns="http://www.w3.org/2000/svg"
        >
          <path
            d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM15.5303 8.46967C15.8232 8.76256 15.8232 9.23744 15.5303 9.53033L13.0607 12L15.5303 14.4697C15.8232 14.7626 15.8232 15.2374 15.5303 15.5303C15.2374 15.8232 14.7626 15.8232 14.4697 15.5303L12 13.0607L9.53033 15.5303C9.23744 15.8232 8.76256 15.8232 8.46967 15.5303C8.17678 15.2374 8.17678 14.7626 8.46967 14.4697L10.9393 12L8.46967 9.53033C8.17678 9.23744 8.17678 8.76256 8.46967 8.46967C8.76256 8.17678 9.23744 8.17678 9.53033 8.46967L12 10.9393L14.4697 8.46967C14.7626 8.17678 15.2374 8.17678 15.5303 8.46967Z"
          />
        </svg>
      </button>
    </span>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;

exports[`Tag <Tag label="foo" screenReaderLabel="FooBar" /> should render a tag with a screen reader label 1`] = `
Object {
  "asFragment": [Function],
  "baseElement": <body>
    <p
      class="a11y-speak-intro-text"
      hidden="hidden"
      id="a11y-speak-intro-text"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    >
      Notifications
    </p>
    <div
      aria-atomic="true"
      aria-live="assertive"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-assertive"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div
      aria-atomic="true"
      aria-live="polite"
      aria-relevant="additions text"
      class="a11y-speak-region"
      id="a11y-speak-polite"
      style="position: absolute;margin: -1px;padding: 0;height: 1px;width: 1px;overflow: hidden;clip: rect(1px, 1px, 1px, 1px);-webkit-clip-path: inset(50%);clip-path: inset(50%);border: 0;word-wrap: normal !important;"
    />
    <div>
      <span
        class="woocommerce-tag"
      >
        <span
          class="woocommerce-tag__text"
          id="woocommerce-tag__label-3"
        >
          <span
            class="screen-reader-text"
          >
            FooBar
          </span>
          <span
            aria-hidden="true"
          >
            foo
          </span>
        </span>
      </span>
    </div>
  </body>,
  "container": <div>
    <span
      class="woocommerce-tag"
    >
      <span
        class="woocommerce-tag__text"
        id="woocommerce-tag__label-3"
      >
        <span
          class="screen-reader-text"
        >
          FooBar
        </span>
        <span
          aria-hidden="true"
        >
          foo
        </span>
      </span>
    </span>
  </div>,
  "debug": [Function],
  "findAllByAltText": [Function],
  "findAllByDisplayValue": [Function],
  "findAllByLabelText": [Function],
  "findAllByPlaceholderText": [Function],
  "findAllByRole": [Function],
  "findAllByTestId": [Function],
  "findAllByText": [Function],
  "findAllByTitle": [Function],
  "findByAltText": [Function],
  "findByDisplayValue": [Function],
  "findByLabelText": [Function],
  "findByPlaceholderText": [Function],
  "findByRole": [Function],
  "findByTestId": [Function],
  "findByText": [Function],
  "findByTitle": [Function],
  "getAllByAltText": [Function],
  "getAllByDisplayValue": [Function],
  "getAllByLabelText": [Function],
  "getAllByPlaceholderText": [Function],
  "getAllByRole": [Function],
  "getAllByTestId": [Function],
  "getAllByText": [Function],
  "getAllByTitle": [Function],
  "getByAltText": [Function],
  "getByDisplayValue": [Function],
  "getByLabelText": [Function],
  "getByPlaceholderText": [Function],
  "getByRole": [Function],
  "getByTestId": [Function],
  "getByText": [Function],
  "getByTitle": [Function],
  "queryAllByAltText": [Function],
  "queryAllByDisplayValue": [Function],
  "queryAllByLabelText": [Function],
  "queryAllByPlaceholderText": [Function],
  "queryAllByRole": [Function],
  "queryAllByTestId": [Function],
  "queryAllByText": [Function],
  "queryAllByTitle": [Function],
  "queryByAltText": [Function],
  "queryByDisplayValue": [Function],
  "queryByLabelText": [Function],
  "queryByPlaceholderText": [Function],
  "queryByRole": [Function],
  "queryByTestId": [Function],
  "queryByText": [Function],
  "queryByTitle": [Function],
  "rerender": [Function],
  "unmount": [Function],
}
`;
tag/test/index.js000064400000002100151550716220007740 0ustar00/**
 * External dependencies
 */
import { render } from '@testing-library/react';

/**
 * Internal dependencies
 */
import Tag from '../';

const noop = () => {};

describe( 'Tag', () => {
	test( '<Tag label="foo" /> should render a tag with the label foo', () => {
		const component = render( <Tag label="foo" /> );
		expect( component ).toMatchSnapshot();
	} );

	test( '<Tag label="foo" remove={ noop } /> should render a tag with a close button', () => {
		const component = render( <Tag label="foo" remove={ noop } /> );
		expect( component ).toMatchSnapshot();
	} );

	test( '<Tag label="foo" popoverContents={ <p>This is a popover</p> } /> should render a tag with a popover', () => {
		const component = render(
			<Tag label="foo" popoverContents={ <p>This is a popover</p> } />
		);
		expect( component ).toMatchSnapshot();
	} );

	test( '<Tag label="foo" screenReaderLabel="FooBar" /> should render a tag with a screen reader label', () => {
		const component = render(
			<Tag label="foo" screenReaderLabel="FooBar" />
		);
		expect( component ).toMatchSnapshot();
	} );
} );
template-notice/editor.scss000064400000000342151550716220012024 0ustar00.wc-default-template-notice.is-dismissible {
	margin: 0;
	padding-right: 16px;
	.components-notice__dismiss {
		min-width: 24px;
	}
	.components-notice__content {
		margin: 4px 0;
	}
	svg {
		width: 16px;
		height: 16px;
	}
}
template-notice/index.tsx000064400000002712151550716220011513 0ustar00/**
 * External dependencies
 */
import { __, sprintf } from '@wordpress/i18n';
import { Notice, Button } from '@wordpress/components';
import { useState } from '@wordpress/element';
import { isSiteEditorPage } from '@woocommerce/utils';
import { select } from '@wordpress/data';
import { getSetting } from '@woocommerce/settings';

/**
 * Internal dependencies
 */
import './editor.scss';

export function TemplateNotice( { block }: { block: string } ) {
	const [ settingStatus, setStatus ] = useState( 'pristine' );
	const store = select( 'core/edit-site' );

	if ( settingStatus === 'dismissed' || isSiteEditorPage( store ) ) {
		return null;
	}

	const editUrl = `${ getSetting(
		'adminUrl'
	) }site-editor.php?postType=wp_template&postId=woocommerce%2Fwoocommerce%2F%2F${ block }`;

	const noticeContent = sprintf(
		// translators: %s: cart or checkout page name.
		__(
			'The default %s can be customized in the Site Editor',
			'woo-gutenberg-products-block'
		),
		block === 'checkout'
			? __( 'checkout', 'woo-gutenberg-products-block' )
			: __( 'cart', 'woo-gutenberg-products-block' )
	);

	return (
		<Notice
			className="wc-default-template-notice"
			status={ 'warning' }
			onRemove={ () => setStatus( 'dismissed' ) }
			spokenMessage={ noticeContent }
		>
			<>
				<p>{ noticeContent }</p>
				<Button href={ editUrl } variant="secondary" isSmall={ true }>
					{ __( 'Edit template', 'woo-gutenberg-products-block' ) }
				</Button>
			</>
		</Notice>
	);
}
text-toolbar-button/index.js000064400000000623151550716220012153 0ustar00/**
 * External dependencies
 */
import { Button } from '@wordpress/components';
import classnames from 'classnames';

/**
 * Internal dependencies
 */
import './style.scss';

function TextToolbarButton( { className = '', ...props } ) {
	const classes = classnames( 'wc-block-text-toolbar-button', className );
	return <Button className={ classes } { ...props } />;
}

export default TextToolbarButton;
text-toolbar-button/style.scss000064400000000420151550716220012536 0ustar00.wc-block-text-toolbar-button {
	align-items: center;

	&.is-toggled,
	&.is-toggled:focus {
		background: $gray-700;
		color: $white;
	}
}
.block-editor-block-toolbar__slot {
	// prevents text toolbar items shrinking to avoid other buttons overlapping.
	flex-shrink: 0;
}
utils/index.js000064400000014430151550716220007357 0ustar00/**
 * External dependencies
 */
import { addQueryArgs } from '@wordpress/url';
import apiFetch from '@wordpress/api-fetch';
import { getSetting } from '@woocommerce/settings';
import { blocksConfig } from '@woocommerce/block-settings';

/**
 * Get product query requests for the Store API.
 *
 * @param {Object}                     request           A query object with the list of selected products and search term.
 * @param {number[]}                   request.selected  Currently selected products.
 * @param {string=}                    request.search    Search string.
 * @param {(Record<string, unknown>)=} request.queryArgs Query args to pass in.
 */
const getProductsRequests = ( {
	selected = [],
	search = '',
	queryArgs = {},
} ) => {
	const isLargeCatalog = blocksConfig.productCount > 100;
	const defaultArgs = {
		per_page: isLargeCatalog ? 100 : 0,
		catalog_visibility: 'any',
		search,
		orderby: 'title',
		order: 'asc',
	};
	const requests = [
		addQueryArgs( '/wc/store/v1/products', {
			...defaultArgs,
			...queryArgs,
		} ),
	];

	// If we have a large catalog, we might not get all selected products in the first page.
	if ( isLargeCatalog && selected.length ) {
		requests.push(
			addQueryArgs( '/wc/store/v1/products', {
				catalog_visibility: 'any',
				include: selected,
				per_page: 0,
			} )
		);
	}

	return requests;
};

const uniqBy = ( array, iteratee ) => {
	const seen = new Map();
	return array.filter( ( item ) => {
		const key = iteratee( item );
		if ( ! seen.has( key ) ) {
			seen.set( key, item );
			return true;
		}
		return false;
	} );
};

/**
 * Get a promise that resolves to a list of products from the Store API.
 *
 * @param {Object}                     request           A query object with the list of selected products and search term.
 * @param {number[]}                   request.selected  Currently selected products.
 * @param {string=}                    request.search    Search string.
 * @param {(Record<string, unknown>)=} request.queryArgs Query args to pass in.
 * @return {Promise<unknown>} Promise resolving to a Product list.
 * @throws Exception if there is an error.
 */
export const getProducts = ( {
	selected = [],
	search = '',
	queryArgs = {},
} ) => {
	const requests = getProductsRequests( { selected, search, queryArgs } );

	return Promise.all( requests.map( ( path ) => apiFetch( { path } ) ) )
		.then( ( data ) => {
			const flatData = data.flat();
			const products = uniqBy( flatData, ( item ) => item.id );
			const list = products.map( ( product ) => ( {
				...product,
				parent: 0,
			} ) );
			return list;
		} )
		.catch( ( e ) => {
			throw e;
		} );
};

/**
 * Get a promise that resolves to a product object from the Store API.
 *
 * @param {number} productId Id of the product to retrieve.
 */
export const getProduct = ( productId ) => {
	return apiFetch( {
		path: `/wc/store/v1/products/${ productId }`,
	} );
};

/**
 * Get a promise that resolves to a list of attribute objects from the Store API.
 */
export const getAttributes = () => {
	return apiFetch( {
		path: `wc/store/v1/products/attributes`,
	} );
};

/**
 * Get a promise that resolves to a list of attribute term objects from the Store API.
 *
 * @param {number} attribute Id of the attribute to retrieve terms for.
 */
export const getTerms = ( attribute ) => {
	return apiFetch( {
		path: `wc/store/v1/products/attributes/${ attribute }/terms`,
	} );
};

/**
 * Get product tag query requests for the Store API.
 *
 * @param {Object} request          A query object with the list of selected products and search term.
 * @param {Array}  request.selected Currently selected tags.
 * @param {string} request.search   Search string.
 */
const getProductTagsRequests = ( { selected = [], search } ) => {
	const limitTags = getSetting( 'limitTags', false );
	const requests = [
		addQueryArgs( `wc/store/v1/products/tags`, {
			per_page: limitTags ? 100 : 0,
			orderby: limitTags ? 'count' : 'name',
			order: limitTags ? 'desc' : 'asc',
			search,
		} ),
	];

	// If we have a large catalog, we might not get all selected products in the first page.
	if ( limitTags && selected.length ) {
		requests.push(
			addQueryArgs( `wc/store/v1/products/tags`, {
				include: selected,
			} )
		);
	}

	return requests;
};

/**
 * Get a promise that resolves to a list of tags from the Store API.
 *
 * @param {Object} props          A query object with the list of selected products and search term.
 * @param {Array}  props.selected
 * @param {string} props.search
 */
export const getProductTags = ( { selected = [], search } ) => {
	const requests = getProductTagsRequests( { selected, search } );

	return Promise.all( requests.map( ( path ) => apiFetch( { path } ) ) ).then(
		( data ) => {
			const flatData = data.flat();
			return uniqBy( flatData, ( item ) => item.id );
		}
	);
};

/**
 * Get a promise that resolves to a list of category objects from the Store API.
 *
 * @param {Object} queryArgs Query args to pass in.
 */
export const getCategories = ( queryArgs ) => {
	return apiFetch( {
		path: addQueryArgs( `wc/store/v1/products/categories`, {
			per_page: 0,
			...queryArgs,
		} ),
	} );
};

/**
 * Get a promise that resolves to a category object from the API.
 *
 * @param {number} categoryId Id of the product to retrieve.
 */
export const getCategory = ( categoryId ) => {
	return apiFetch( {
		path: `wc/store/v1/products/categories/${ categoryId }`,
	} );
};

/**
 * Get a promise that resolves to a list of variation objects from the Store API.
 *
 * @param {number} product Product ID.
 */
export const getProductVariations = ( product ) => {
	return apiFetch( {
		path: addQueryArgs( `wc/store/v1/products`, {
			per_page: 0,
			type: 'variation',
			parent: product,
		} ),
	} );
};

/**
 * Given a page object and an array of page, format the title.
 *
 * @param {Object} page           Page object.
 * @param {Object} page.title     Page title object.
 * @param {string} page.title.raw Page title.
 * @param {string} page.slug      Page slug.
 * @param {Array}  pages          Array of all pages.
 * @return {string}                Formatted page title to display.
 */
export const formatTitle = ( page, pages ) => {
	if ( ! page.title.raw ) {
		return page.slug;
	}
	const isUnique =
		pages.filter( ( p ) => p.title.raw === page.title.raw ).length === 1;
	return page.title.raw + ( ! isUnique ? ` - ${ page.slug }` : '' );
};