mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-21 03:22:11 +00:00
feat: init implementation of new checkbox
This commit is contained in:
parent
0372683484
commit
99efdf8136
7 changed files with 148 additions and 75 deletions
|
|
@ -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;
|
|
||||||
77
src/common/Checkbox/Checkbox.less
Normal file
77
src/common/Checkbox/Checkbox.less
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
65
src/common/Checkbox/Checkbox.tsx
Normal file
65
src/common/Checkbox/Checkbox.tsx
Normal 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;
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
// Copyright (C) 2017-2023 Smart code 203358507
|
|
||||||
|
|
||||||
const Checkbox = require('./Checkbox');
|
|
||||||
|
|
||||||
module.exports = Checkbox;
|
|
||||||
5
src/common/Checkbox/index.ts
Normal file
5
src/common/Checkbox/index.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Copyright (C) 2017-2024 Smart code 203358507
|
||||||
|
|
||||||
|
import Checkbox from './Checkbox';
|
||||||
|
|
||||||
|
export default Checkbox;
|
||||||
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -48,6 +48,7 @@ const useStreamingServer = require('./useStreamingServer');
|
||||||
const useTorrent = require('./useTorrent');
|
const useTorrent = require('./useTorrent');
|
||||||
const useTranslate = require('./useTranslate');
|
const useTranslate = require('./useTranslate');
|
||||||
const EventModal = require('./EventModal');
|
const EventModal = require('./EventModal');
|
||||||
|
const { default: Checkbox } = require('./Checkbox');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
AddonDetailsModal,
|
AddonDetailsModal,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue