feat: init implementation of new checkbox

This commit is contained in:
Timothy Z. 2024-11-29 14:26:55 +02:00
parent 0372683484
commit 99efdf8136
7 changed files with 148 additions and 75 deletions

View file

@ -1,26 +0,0 @@
// Copyright (C) 2017-2023 Smart code 203358507
const React = require('react');
const PropTypes = require('prop-types');
const classnames = require('classnames');
const Button = require('stremio/common/Button');
const styles = require('./styles');
const Checkbox = React.forwardRef(({ className, checked, children, ...props }, ref) => {
return (
<Button {...props} ref={ref} className={classnames(className, styles['checkbox-container'], { 'checked': checked })}>
<div className={styles['toggle']} />
{children}
</Button>
);
});
Checkbox.displayName = 'Checkbox';
Checkbox.propTypes = {
className: PropTypes.string,
checked: PropTypes.bool,
children: PropTypes.node
};
module.exports = Checkbox;

View file

@ -0,0 +1,77 @@
// Copyright (C) 2017-2024 Smart code 203358507
.checkbox {
display: flex;
align-items: center;
label {
display: flex;
align-items: center;
cursor: pointer;
.checkbox-checked {
.checkbox-container {
background-color: var(--primary-accent-color);
border-color: var(--primary-accent-color);
}
.checkbox-icon {
color: var(--secondary-foreground-color);
}
}
.checkbox-unchecked {
.checkbox-container {
background-color: transparent;
border-color: var(--primary-accent-color);
}
}
.checkbox-disabled {
cursor: not-allowed;
.checkbox-container {
cursor: not-allowed;
}
}
.checkbox-error {
.checkbox-container {
border-color: var(--color-reddit);
}
}
.checkbox-container {
position: relative;
width: 1.25rem;
height: 1.25rem;
border: 2px solid var(--primary-accent-color);
border-radius: 0.25rem;
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;
&:focus {
outline: var(--focus-outline-size) solid var(--primary-accent-color);
outline-offset: 2px;
}
input[type='checkbox'] {
opacity: 0;
width: 0;
height: 0;
position: absolute;
}
.checkbox-icon {
color: var(--primary-background-color);
width: 1rem;
}
}
}
}

View file

@ -0,0 +1,65 @@
// Copyright (C) 2017-2024 Smart code 203358507
import React, { useCallback, DetailedHTMLProps, HTMLAttributes, ChangeEvent } from 'react';
import classNames from 'classnames';
import styles from './Checkbox.less';
import Icon from '@stremio/stremio-icons/react';
type Props = {
disabled?: boolean;
checked?: boolean;
className?: string;
onChange?: (checked: boolean) => void;
ariaLabel?: string;
error?: string;
};
const Checkbox = ({ disabled, checked, className, onChange, ariaLabel, error }: Props) => {
const handleChangeCheckbox = useCallback(({ target }: ChangeEvent<HTMLInputElement>) => {
onChange && onChange(target.checked);
}, [onChange]);
const onKeyDown = useCallback(({ key }: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => {
if ((key === 'Enter' || key === ' ') && !disabled) {
onChange && onChange(!checked);
}
}, [disabled, checked, onChange]);
return (
<div className={classNames(styles['checkbox'], className)}>
<label>
<div
className={classNames({
[styles['checkbox-checked']]: checked,
[styles['checkbox-unchecked']]: !checked,
[styles['checkbox-error']]: error,
[styles['checkbox-disabled']]: disabled,
})}
>
<div
className={styles['checkbox-container']}
role={'input'}
tabIndex={0}
onKeyDown={onKeyDown}
>
<input
type={'checkbox'}
onChange={handleChangeCheckbox}
aria-label={ariaLabel}
tabIndex={-1}
disabled={disabled}
/>
{
checked ?
<Icon name={'checkmark'} className={styles['checkbox-icon']} />
: null
}
</div>
</div>
</label>
</div>
);
};
export default Checkbox;

View file

@ -1,5 +0,0 @@
// Copyright (C) 2017-2023 Smart code 203358507
const Checkbox = require('./Checkbox');
module.exports = Checkbox;

View file

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

View file

@ -1,44 +0,0 @@
// Copyright (C) 2017-2023 Smart code 203358507
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
@height: 1.7rem;
@width: 3.2rem;
@thumb-margin: 0.5rem;
@thumb-size: calc(@height - @thumb-margin);
.checkbox-container {
position: relative;
.toggle {
position: relative;
width: @width;
height: @height;
border-radius: @height;
background-color: var(--overlay-color);
transition: background-color 0.1s ease-in-out;
&::before {
content: "";
position: absolute;
height: @thumb-size;
width: @thumb-size;
top: calc(@thumb-margin / 2);
left: calc(@thumb-margin / 2);
border-radius: 50%;
background-color: var(--primary-foreground-color);
transition: transform 0.1s ease-in-out;
}
}
&:global(.checked) {
.toggle {
background-color: var(--secondary-accent-color);
&::before {
transform: translateX(calc(@width - @thumb-size - @thumb-margin));
}
}
}
}

View file

@ -48,6 +48,7 @@ const useStreamingServer = require('./useStreamingServer');
const useTorrent = require('./useTorrent');
const useTranslate = require('./useTranslate');
const EventModal = require('./EventModal');
const { default: Checkbox } = require('./Checkbox');
module.exports = {
AddonDetailsModal,