Return

All tests / src/components/IconWithName index.tsx

100% Statements 8/8
66.66% Branches 2/3
100% Functions 1/1
100% Lines 7/7

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 661x 1x 1x                                                 1x 1x                               1x                                       1x  
import Image from 'next/image';
import styles from './icon.module.css';
import { clx } from '@/helpers';
 
type Props = {
    icon: string;
    alt: string;
    name: string;
    horizontal?: boolean;
    onClick?: () => void;
    /** Reflects on/off state to assistive tech when this acts as a toggle (e.g. the theme switch). */
    pressed?: boolean;
};
 
/**
 * @example
 *     <IconWithName icon="/images/icons/terminal.svg" alt="Terminal" name="Terminal" />;
 *     <IconWithName icon="/images/icons/terminal.svg" alt="Terminal" name="Terminal" horizontal />;
 *
 * @param {string} icon - The path to the icon
 * @param {string} alt - The alt text for the icon
 * @param {string} name - Text to display
 * @param {boolean} horizontal - If true, the icon will be displayed horizontally
 * @param {Function} onClick - Makes this a button; omit it for a static tile
 * @param {boolean} pressed - Toggle state, forwarded as aria-pressed
 * @returns {JSX.Element}
 */
const IconWithName = ({ icon, alt, name, horizontal, onClick, pressed }: Props) => {
    const className = clx(styles.option, horizontal ? styles.horizontal : '');
    const content = (
        <>
            <Image src={icon} alt={alt} width={44} height={44} />
            <p className={styles.optionText}>{name}</p>
        </>
    );
 
    /**
     * SDD-L05: a `<div onClick>` with no role, tabIndex or key handler. It backs the theme and language
     * tiles on /settings — the two things that page exists to do — so neither could be operated without
     * a mouse.
     *
     * A `<button>` only when there is something to activate: a static tile should not take a tab stop
     * or announce itself as pressable.
     */
    if (!onClick) {
        return (
            <div data-testid="icon-with-name" className={className}>
                {content}
            </div>
        );
    }
 
    return (
        <button
            type="button"
            data-testid="icon-with-name"
            className={className}
            onClick={onClick}
            aria-pressed={pressed}
        >
            {content}
        </button>
    );
};
export default IconWithName;