refactor: use a radio button on the item instead

This commit is contained in:
Timothy Z. 2024-11-29 14:18:57 +02:00
parent ccde5971f8
commit a09332e101
5 changed files with 142 additions and 3 deletions

View file

@ -0,0 +1,72 @@
// Copyright (C) 2017-2024 Smart code 203358507
.radio-button {
display: flex;
align-items: center;
overflow: visible;
label {
display: flex;
align-items: center;
cursor: pointer;
.disabled {
cursor: not-allowed;
.radio-container {
cursor: not-allowed;
}
}
.error {
.radio-container {
border-color: var(--color-trakt);
}
}
.not-selected {
background-color: transparent;
border-color: var(--color-placeholder);
.radio-container .inner-circle {
background-color: transparent;
opacity: 0;
}
}
.radio-container {
position: relative;
width: 1.75rem;
height: 1.75rem;
border: 3px solid var(--color-placeholder);
border-radius: 1rem;
background-color: transparent;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease-in-out;
cursor: pointer;
outline: none;
user-select: none;
margin-right: 0.75rem;
input[type='radio'] {
opacity: 0;
width: 0;
height: 0;
position: absolute;
cursor: pointer;
}
.inner-circle {
width: 1.25rem;
height: 1.25rem;
background-color: var(--primary-accent-color);
border-radius: 0.675rem;
border: 2px solid var(--secondary-background-color);
transition: opacity 0.2s ease-in-out;
opacity: 1;
}
}
}
}

View file

@ -0,0 +1,62 @@
// Copyright (C) 2017-2024 Smart code 203358507
import React, { useCallback, ChangeEvent, KeyboardEvent } from 'react';
import classNames from 'classnames';
import styles from './RadioButton.less';
type Props = {
disabled?: boolean;
selected?: boolean;
className?: string;
onChange?: (checked: boolean) => void;
error?: string;
};
const RadioButton = ({ disabled, selected, className, onChange, error }: Props) => {
const handleSelect = useCallback(({ target }: ChangeEvent<HTMLInputElement>) => {
if (!disabled && onChange) {
onChange(target.checked);
}
}, [disabled, onChange]);
const onKeyDown = useCallback(({ key }: KeyboardEvent<HTMLDivElement>) => {
if ((key === 'Enter' || key === ' ') && !disabled) {
onChange && onChange(!selected);
}
}, [disabled, selected, onChange]);
return (
<div className={classNames(styles['radio-button'], className)}>
<label>
<div
className={classNames({
[styles['selected']]: selected,
[styles['not-selected']]: !selected,
[styles['error']]: error,
[styles['disabled']]: disabled,
})}
>
<div
className={styles['radio-container']}
role={'radio'}
tabIndex={disabled ? -1 : 0}
aria-checked={selected}
onKeyDown={onKeyDown}
>
<input
type={'radio'}
checked={selected}
disabled={disabled}
onChange={handleSelect}
className={styles['input']}
/>
<span className={styles['inner-circle']} />
</div>
</div>
</label>
</div>
);
};
export default RadioButton;

View file

@ -0,0 +1,5 @@
// Copyright (C) 2017-2024 Smart code 203358507
import RadioButton from './RadioButton';
export default RadioButton;

View file

@ -19,7 +19,7 @@
justify-content: center;
max-width: 60%;
.check {
.selectable {
overflow: visible;
}

View file

@ -9,7 +9,7 @@ import useStreamingServer from 'stremio/common/useStreamingServer';
import Icon from '@stremio/stremio-icons/react';
import styles from './Item.less';
import classNames from 'classnames';
import Checkbox from 'stremio/common/Checkbox';
import RadioButton from 'stremio/common/RadioButton/RadioButton';
import useStreamingServerUrls from '../useStreamingServerUrls';
type Props = {
@ -37,7 +37,7 @@ const Item = ({ url }: Props) => {
return (
<div className={styles['item']}>
<div className={styles['content']}>
<Checkbox className={styles['check']} checked={selected} onChange={handleSelect} disabled={selected} />
<RadioButton className={styles['selectable']} selected={selected} onChange={handleSelect} disabled={selected} />
<div className={styles['label']}>{url}</div>
</div>
<div className={styles['actions']}>