/**
* External dependencies
*/
import { __, _n, sprintf } from '@wordpress/i18n';
import { Fragment, useMemo, useState } from '@wordpress/element';
import clsx from 'clsx';
/**
* Internal dependencies
*/
import './style.scss';
import { CheckboxControl } from '../checkbox-control';
interface CheckboxListOptions {
label: React.ReactNode;
value: string;
}
export interface CheckboxListProps {
className?: string | undefined;
isLoading?: boolean | undefined;
isDisabled?: boolean | undefined;
limit?: number | undefined;
checked?: string[] | undefined;
onChange: ( value: string ) => void | undefined;
options?: CheckboxListOptions[] | undefined;
}
/**
* Component used to show a list of checkboxes in a group.
*
* @param {Object} props Incoming props for the component.
* @param {string} props.className CSS class used.
* @param {function(string):any} props.onChange Function called when inputs change.
* @param {Array} props.options Options for list.
* @param {Array} props.checked Which items are checked.
* @param {boolean} props.isLoading If loading or not.
* @param {boolean} props.isDisabled If inputs are disabled or not.
* @param {number} props.limit Whether to limit the number of inputs showing.
*/
const CheckboxList = ( {
className,
onChange,
options = [],
checked = [],
isLoading = false,
isDisabled = false,
limit = 10,
}: CheckboxListProps ): JSX.Element => {
const [ showExpanded, setShowExpanded ] = useState( false );
const placeholder = useMemo( () => {
return [ ...Array( 5 ) ].map( ( x, i ) => (
{ /* The is required to give the placeholder content and therefore height, without it the placeholder rows do not render */ }
) );
}, [] );
const renderedShowMore = useMemo( () => {
const optionCount = options.length;
const remainingOptionsCount = optionCount - limit;
return (
! showExpanded && (
)
);
}, [ options, limit, showExpanded ] );
const renderedShowLess = useMemo( () => {
return (
showExpanded && (
)
);
}, [ showExpanded ] );
const renderedOptions = useMemo( () => {
// Truncate options if > the limit + 5.
const optionCount = options.length;
const shouldTruncateOptions = optionCount > limit + 5;
return (
<>
{ options.map( ( option, index ) => (
= limit && { hidden: true } ) }
>
{
onChange( option.value );
} }
disabled={ isDisabled }
/>
{ shouldTruncateOptions &&
index === limit - 1 &&
renderedShowMore }
) ) }
{ shouldTruncateOptions && renderedShowLess }
>
);
}, [
options,
onChange,
checked,
showExpanded,
limit,
renderedShowLess,
renderedShowMore,
isDisabled,
] );
const classes = clsx(
'wc-block-checkbox-list',
'wc-block-components-checkbox-list',
{
'is-loading': isLoading,
},
className
);
return (
{ isLoading ? placeholder : renderedOptions }
);
};
export default CheckboxList;