All files / app/ui/form ChecklistItem.tsx

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88111x   111x 111x   111x   111x 111x 111x                   111x 176x 176x 176x 176x 176x 176x   176x   231x                                     176x 8x 4x       176x 184x 184x 184x                         176x                               111x  
import { memoizeOne } from '@bigcommerce/memoize';
import { FieldProps } from 'formik';
import { kebabCase } from 'lodash';
import React, { memo, useCallback, useContext, FunctionComponent, ReactNode } from 'react';
 
import { AccordionItem, AccordionItemHeaderProps } from '../accordion';
 
import BasicFormField from './BasicFormField';
import { ChecklistContext } from './Checklist';
import ChecklistItemInput from './ChecklistItemInput';
 
export interface ChecklistItemProps {
    content?: ReactNode;
    htmlId?: string;
    isDisabled?: boolean;
    label: ReactNode | ((isSelected: boolean) => ReactNode);
    value: string;
}
 
const ChecklistItem: FunctionComponent<ChecklistItemProps> = ({
    isDisabled,
    value,
    content,
    htmlId = kebabCase(value),
    label,
    ...rest
}) => {
    const { name = '' } = useContext(ChecklistContext) || {};
 
    const renderInput = useCallback(memoizeOne((isSelected: boolean) => ({ field }: FieldProps) => (
        <ChecklistItemInput
            { ...field }
            disabled={ isDisabled }
            id={ htmlId }
            isSelected={ field.value === value }
            value={ value }
        >
            { label instanceof Function ?
                label(isSelected) :
                label }
        </ChecklistItemInput>
    )), [
        htmlId,
        isDisabled,
        label,
        value,
    ]);
 
    const handleChange = useCallback(memoizeOne((onToggle: (id: string) => void) => (selectedValue: string) => {
        if (value === selectedValue) {
            onToggle(value);
        }
    }), []);
 
    const renderHeaderContent = useCallback(({
        isSelected,
        onToggle,
    }: AccordionItemHeaderProps) => (
        <BasicFormField
            className="form-checklist-option"
            name={ name }
            onChange={ handleChange(onToggle) }
            render={ renderInput(isSelected) }
        />
    ), [
        handleChange,
        name,
        renderInput,
    ]);
 
    return (
        <AccordionItem
            { ...rest }
            bodyClassName="form-checklist-body"
            className="form-checklist-item optimizedCheckout-form-checklist-item"
            classNameSelected="form-checklist-item--selected optimizedCheckout-form-checklist-item--selected"
            headerClassName="form-checklist-header"
            headerClassNameSelected="form-checklist-header--selected"
            headerContent={ renderHeaderContent }
            itemId={ value }
        >
            { content }
        </AccordionItem>
    );
};
 
export default memo(ChecklistItem);