mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-05-11 20:40:54 +00:00
refactor: checkbox component
This commit is contained in:
parent
7087033522
commit
ccccce2be1
2 changed files with 18 additions and 36 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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']}>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue