Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intro: Consent items using checkbox instead toggle #832

Merged
merged 8 commits into from
Feb 17, 2025
1 change: 1 addition & 0 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import styles from './Button.less';
type Props = {
className?: string,
href?: string,
target?: string
title?: string,
disabled?: boolean,
tabIndex?: number,
Expand Down
83 changes: 83 additions & 0 deletions src/components/Checkbox/Checkbox.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (C) 2017-2025 Smart code 203358507

@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';

.checkbox {
display: flex;
align-items: center;
overflow: visible;

.label {
display: flex;
flex-direction: row;
align-items: center;
padding: 0.5rem 0;
cursor: pointer;

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.5rem;
height: 1.5rem;
border-radius: 0.3rem;
background-color: var(--overlay-color);
padding: 0.1rem;
display: flex;
flex: none;
margin: 0 1rem 0 0.3rem;
align-items: center;
justify-content: center;
transition: all 0.2s ease-in-out;
cursor: pointer;
outline: none;
user-select: none;
outline-width: var(--focus-outline-size);
outline-color: @color-surface-light5;
outline-offset: 2px;

input[type='checkbox'] {
opacity: 0;
width: 0;
height: 0;
position: absolute;
cursor: pointer;
}

.checkbox-icon {
width: 100%;
height: 100%;
color: var(--primary-foreground-color);
}

&.disabled {
cursor: not-allowed;
}

&.error {
border-color: var(--color-trakt);
}

&.checked {
background-color: var(--primary-accent-color);
}

&:hover, &:focus {
outline-style: solid;
}
}
}
97 changes: 97 additions & 0 deletions src/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// 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';
import Icon from '@stremio/stremio-icons/react';

type Props = {
ref?: RefCallback<HTMLInputElement>;
name: string;
disabled?: boolean;
checked?: boolean;
className?: string;
label?: string;
link?: string;
href?: string;
onChange?: (props: {
type: string;
checked: boolean;
reactEvent: KeyboardEvent<HTMLInputElement> | ChangeEvent<HTMLInputElement>;
nativeEvent: Event;
}) => 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<HTMLInputElement>) => {
if ((event.key === 'Enter' || event.key === ' ') && !disabled) {
onChange && onChange({
type: 'select',
checked: !checked,
reactEvent: event as KeyboardEvent<HTMLInputElement>,
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']}
/>
{
checked ?
<Icon name={'checkmark'} className={styles['checkbox-icon']} />
: null
}
</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 changes: 5 additions & 0 deletions src/components/Checkbox/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2017-2025 Smart code 203358507

import Checkbox from './Checkbox';

export default Checkbox;
2 changes: 2 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -31,6 +32,7 @@ export {
AddonDetailsModal,
BottomSheet,
Button,
Checkbox,
Chips,
ColorInput,
ContinueWatchingItem,
Expand Down
56 changes: 0 additions & 56 deletions src/routes/Intro/ConsentToggle/ConsentToggle.js

This file was deleted.

5 changes: 0 additions & 5 deletions src/routes/Intro/ConsentToggle/index.js

This file was deleted.

43 changes: 0 additions & 43 deletions src/routes/Intro/ConsentToggle/styles.less

This file was deleted.

18 changes: 7 additions & 11 deletions src/routes/Intro/Intro.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ const { default: Icon } = require('@stremio/stremio-icons/react');
const { Modal, useRouteFocused } = require('stremio-router');
const { useServices } = require('stremio/services');
const { useBinaryState } = require('stremio/common');
const { Button, Image } = require('stremio/components');
const { Button, Image, Checkbox } = require('stremio/components');
const CredentialsTextInput = require('./CredentialsTextInput');
const ConsentToggle = require('./ConsentToggle');
const PasswordResetModal = require('./PasswordResetModal');
const useFacebookLogin = require('./useFacebookLogin');
const styles = require('./styles');
Expand Down Expand Up @@ -308,30 +307,27 @@ const Intro = ({ queryParams }) => {
onChange={confirmPasswordOnChange}
onSubmit={confirmPasswordOnSubmit}
/>
<ConsentToggle
<Checkbox
ref={termsRef}
className={styles['consent-toggle']}
label={'I have read and agree with the Stremio'}
link={'Terms and conditions'}
href={'https://www.stremio.com/tos'}
checked={state.termsAccepted}
onToggle={toggleTermsAccepted}
onChange={toggleTermsAccepted}
/>
<ConsentToggle
<Checkbox
ref={privacyPolicyRef}
className={styles['consent-toggle']}
label={'I have read and agree with the Stremio'}
link={'Privacy Policy'}
href={'https://www.stremio.com/privacy'}
checked={state.privacyPolicyAccepted}
onToggle={togglePrivacyPolicyAccepted}
onChange={togglePrivacyPolicyAccepted}
/>
<ConsentToggle
<Checkbox
ref={marketingRef}
className={styles['consent-toggle']}
label={'I agree to receive marketing communications from Stremio'}
checked={state.marketingAccepted}
onToggle={toggleMarketingAccepted}
onChange={toggleMarketingAccepted}
/>
</React.Fragment>
:
Expand Down