mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
feat(Checkbox): added Checkbox component
This commit is contained in:
parent
d05488feb6
commit
1b2fe21044
4 changed files with 189 additions and 0 deletions
95
src/components/Checkbox/Checkbox.less
Normal file
95
src/components/Checkbox/Checkbox.less
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright (C) 2017-2025 Smart code 203358507
|
||||
|
||||
.checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: visible;
|
||||
|
||||
.label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 0.5rem 0;
|
||||
|
||||
span {
|
||||
font-size: 0.9rem;
|
||||
color: var(--primary-foreground-color);
|
||||
opacity: 0.6;
|
||||
}
|
||||
.link {
|
||||
font-size: 0.9rem;
|
||||
color: var(--primary-accent-color);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox-container {
|
||||
position: relative;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
border: 0.2rem solid var(--color-placeholder);
|
||||
border-radius: 0.5rem;
|
||||
background-color: transparent;
|
||||
display: flex;
|
||||
flex: none;
|
||||
margin-right: 1rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.2s ease-in-out;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
user-select: none;
|
||||
|
||||
input[type='checkbox'] {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.checkmark {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
background-color: transparent;
|
||||
opacity: 0;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0.45rem;
|
||||
top: 0.2rem;
|
||||
width: 0.2rem;
|
||||
height: 0.5rem;
|
||||
border: solid var(--primary-foreground-color);
|
||||
border-width: 0 0.2rem 0.2rem 0;
|
||||
-webkit-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.error {
|
||||
border-color: var(--color-trakt);
|
||||
}
|
||||
|
||||
&.checked {
|
||||
border: 3px solid var(--secondary-accent-color);
|
||||
background-color: var(--secondary-accent-color);
|
||||
.checkmark {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
src/components/Checkbox/Checkbox.tsx
Normal file
87
src/components/Checkbox/Checkbox.tsx
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (C) 2017-2025 Smart code 203358507
|
||||
|
||||
import React, { useCallback, ChangeEvent, KeyboardEvent, RefCallback } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import styles from './Checkbox.less';
|
||||
import Button from '../Button';
|
||||
|
||||
type Props = {
|
||||
ref?: RefCallback<HTMLInputElement>;
|
||||
name: string;
|
||||
disabled?: boolean;
|
||||
checked?: boolean;
|
||||
className?: string;
|
||||
label?: string;
|
||||
link?: string;
|
||||
href?: string;
|
||||
onChange?: (props: any) => void;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
const Checkbox = React.forwardRef<HTMLInputElement, Props>(({ name, disabled, className, label, href, link, onChange, error, checked }, ref) => {
|
||||
|
||||
const handleSelect = useCallback((event: ChangeEvent<HTMLInputElement>) => {
|
||||
if (!disabled && onChange) {
|
||||
onChange({
|
||||
type: 'select',
|
||||
checked: event.target.checked,
|
||||
reactEvent: event,
|
||||
nativeEvent: event.nativeEvent,
|
||||
});
|
||||
}
|
||||
}, [disabled, onChange]);
|
||||
|
||||
const onKeyDown = useCallback((event: KeyboardEvent<HTMLDivElement>) => {
|
||||
if ((event.key === 'Enter' || event.key === ' ') && !disabled) {
|
||||
onChange && onChange({
|
||||
type: 'select',
|
||||
checked: event.target.checked,
|
||||
reactEvent: event,
|
||||
nativeEvent: event.nativeEvent,
|
||||
});
|
||||
}
|
||||
}, [disabled, checked, onChange]);
|
||||
|
||||
return (
|
||||
<div className={classNames(styles['checkbox'], className)}>
|
||||
<label className={styles['label']} htmlFor={name}>
|
||||
<div
|
||||
className={classNames(
|
||||
styles['checkbox-container'],
|
||||
{ [styles['checked']]: checked },
|
||||
{ [styles['disabled']]: disabled },
|
||||
{ [styles['error']]: error }
|
||||
)}
|
||||
role={'checkbox'}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
aria-checked={checked}
|
||||
onKeyDown={onKeyDown}
|
||||
>
|
||||
<input
|
||||
ref={ref}
|
||||
id={name}
|
||||
type={'checkbox'}
|
||||
checked={checked}
|
||||
disabled={disabled}
|
||||
onChange={handleSelect}
|
||||
className={styles['input']}
|
||||
/>
|
||||
<span className={styles['checkmark']} />
|
||||
</div>
|
||||
<div>
|
||||
<span>{label}</span>
|
||||
{' '}
|
||||
{
|
||||
href && link ?
|
||||
<Button className={styles['link']} href={href} target={'_blank'} tabIndex={-1}>
|
||||
{link}
|
||||
</Button>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Checkbox;
|
||||
5
src/components/Checkbox/index.ts
Normal file
5
src/components/Checkbox/index.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// Copyright (C) 2017-2025 Smart code 203358507
|
||||
|
||||
import Checkbox from './Checkbox';
|
||||
|
||||
export default Checkbox;
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import AddonDetailsModal from './AddonDetailsModal';
|
||||
import BottomSheet from './BottomSheet';
|
||||
import Button from './Button';
|
||||
import Checkbox from './Checkbox';
|
||||
import Chips from './Chips';
|
||||
import ColorInput from './ColorInput';
|
||||
import ContinueWatchingItem from './ContinueWatchingItem';
|
||||
|
|
@ -31,6 +32,7 @@ export {
|
|||
AddonDetailsModal,
|
||||
BottomSheet,
|
||||
Button,
|
||||
Checkbox,
|
||||
Chips,
|
||||
ColorInput,
|
||||
ContinueWatchingItem,
|
||||
|
|
|
|||
Loading…
Reference in a new issue