refactor: checkbox component

This commit is contained in:
Timothy Z. 2024-11-29 12:22:20 +02:00
parent 7087033522
commit ccccce2be1
2 changed files with 18 additions and 36 deletions

View file

@ -1,65 +1,47 @@
// Copyright (C) 2017-2024 Smart code 203358507 // Copyright (C) 2017-2024 Smart code 203358507
import React, { useState, useEffect, useCallback, DetailedHTMLProps, HTMLAttributes } from 'react'; import React, { useCallback, DetailedHTMLProps, HTMLAttributes, ChangeEvent } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import styles from './Checkbox.less'; import styles from './Checkbox.less';
import Icon from '@stremio/stremio-icons/react'; import Icon from '@stremio/stremio-icons/react';
type Props = { type Props = {
disabled?: boolean; disabled?: boolean;
value?: boolean; checked?: boolean;
className?: string; className?: string;
onChange?: (checked: boolean) => void; onChange?: (checked: boolean) => void;
ariaLabel?: string; ariaLabel?: string;
error?: string; error?: string;
}; };
const Checkbox = ({ disabled, value, className, onChange, ariaLabel, error }: Props) => { const Checkbox = ({ disabled, checked, className, onChange, ariaLabel, error }: Props) => {
const [isChecked, setIsChecked] = useState(false);
const [isError, setIsError] = useState(false);
const [isDisabled, setIsDisabled] = useState(disabled);
const handleChangeCheckbox = useCallback(() => { const handleChangeCheckbox = useCallback(({ target }: ChangeEvent<HTMLInputElement>) => {
if (disabled) { onChange && onChange(target.checked);
return; }, [onChange]);
const onKeyDown = useCallback(({ key }: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => {
if ((key === 'Enter' || key === ' ') && !disabled) {
onChange && onChange(!checked);
} }
}, [disabled, checked, onChange]);
setIsChecked(!isChecked);
onChange && onChange(!isChecked);
}, [disabled]);
const handleEnterPress = useCallback((event: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => {
if ((event.key === 'Enter' || event.key === ' ') && !disabled) {
setIsChecked(!isChecked);
onChange && onChange(!isChecked);
}
}, [disabled]);
useEffect(() => setIsDisabled(disabled), [disabled]);
useEffect(() => setIsError(!!error), [error]);
useEffect(() => {
const checked = typeof value === 'boolean' ? value : false;
setIsChecked(checked);
}, [value]);
return ( return (
<div className={classNames(styles['checkbox'], className)}> <div className={classNames(styles['checkbox'], className)}>
<label> <label>
<div <div
className={classNames({ className={classNames({
[styles['checkbox-checked']]: isChecked, [styles['checkbox-checked']]: checked,
[styles['checkbox-unchecked']]: !isChecked, [styles['checkbox-unchecked']]: !checked,
[styles['checkbox-error']]: isError, [styles['checkbox-error']]: error,
[styles['checkbox-disabled']]: isDisabled, [styles['checkbox-disabled']]: disabled,
})} })}
> >
<div <div
className={styles['checkbox-container']} className={styles['checkbox-container']}
role={'input'} role={'input'}
tabIndex={0} tabIndex={0}
onKeyDown={handleEnterPress} onKeyDown={onKeyDown}
> >
<input <input
type={'checkbox'} type={'checkbox'}
@ -69,7 +51,7 @@ const Checkbox = ({ disabled, value, className, onChange, ariaLabel, error }: Pr
disabled={disabled} disabled={disabled}
/> />
{ {
isChecked ? checked ?
<Icon name={'checkmark'} className={styles['checkbox-icon']} /> <Icon name={'checkmark'} className={styles['checkbox-icon']} />
: null : null
} }

View file

@ -36,7 +36,7 @@ const Item = ({ url }: Props) => {
return ( return (
<div className={styles['item']}> <div className={styles['item']}>
<div className={styles['content']}> <div className={styles['content']}>
<Checkbox className={styles['check']} value={selected} onChange={handleSelect} disabled={selected} /> <Checkbox className={styles['check']} checked={selected} onChange={handleSelect} disabled={selected} />
<div className={styles['label']}>{url}</div> <div className={styles['label']}>{url}</div>
</div> </div>
<div className={styles['actions']}> <div className={styles['actions']}>