diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index f4b059bd3..f97e1ba82 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -8,6 +8,7 @@ import styles from './Button.less'; type Props = { className?: string, href?: string, + target?: string title?: string, disabled?: boolean, tabIndex?: number, diff --git a/src/components/Checkbox/Checkbox.less b/src/components/Checkbox/Checkbox.less new file mode 100644 index 000000000..718a7b129 --- /dev/null +++ b/src/components/Checkbox/Checkbox.less @@ -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; + } + } +} diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx new file mode 100644 index 000000000..da4ae33eb --- /dev/null +++ b/src/components/Checkbox/Checkbox.tsx @@ -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; + name: string; + disabled?: boolean; + checked?: boolean; + className?: string; + label?: string; + link?: string; + href?: string; + onChange?: (props: { + type: string; + checked: boolean; + reactEvent: KeyboardEvent | ChangeEvent; + nativeEvent: Event; + }) => void; + error?: string; +}; + +const Checkbox = React.forwardRef(({ name, disabled, className, label, href, link, onChange, error, checked }, ref) => { + + const handleSelect = useCallback((event: ChangeEvent) => { + if (!disabled && onChange) { + onChange({ + type: 'select', + checked: event.target.checked, + reactEvent: event, + nativeEvent: event.nativeEvent, + }); + } + }, [disabled, onChange]); + + const onKeyDown = useCallback((event: KeyboardEvent) => { + if ((event.key === 'Enter' || event.key === ' ') && !disabled) { + onChange && onChange({ + type: 'select', + checked: !checked, + reactEvent: event as KeyboardEvent, + nativeEvent: event.nativeEvent, + }); + } + }, [disabled, checked, onChange]); + + return ( +
+ +
+ ); +}); + +export default Checkbox; diff --git a/src/components/Checkbox/index.ts b/src/components/Checkbox/index.ts new file mode 100644 index 000000000..fa5739580 --- /dev/null +++ b/src/components/Checkbox/index.ts @@ -0,0 +1,5 @@ +// Copyright (C) 2017-2025 Smart code 203358507 + +import Checkbox from './Checkbox'; + +export default Checkbox; diff --git a/src/components/Slider/styles.less b/src/components/Slider/styles.less index 66ad267c7..421826ea6 100644 --- a/src/components/Slider/styles.less +++ b/src/components/Slider/styles.less @@ -39,7 +39,8 @@ html.active-slider-within { flex: 1; height: var(--track-size); border-radius: var(--track-size); - background-color: var(--overlay-color); + background-color: var(--primary-accent-color); + opacity: 0.2; } .track-before { diff --git a/src/components/index.ts b/src/components/index.ts index f65d66f81..7ef75f888 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -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, diff --git a/src/routes/Calendar/List/Item/Item.less b/src/routes/Calendar/List/Item/Item.less index aba6bba09..b11feda2a 100644 --- a/src/routes/Calendar/List/Item/Item.less +++ b/src/routes/Calendar/List/Item/Item.less @@ -95,4 +95,4 @@ &:not(.active):hover { border-color: var(--overlay-color); } -} +} \ No newline at end of file diff --git a/src/routes/Calendar/List/List.less b/src/routes/Calendar/List/List.less index f63078680..9f2dfd774 100644 --- a/src/routes/Calendar/List/List.less +++ b/src/routes/Calendar/List/List.less @@ -10,6 +10,10 @@ width: 20rem; padding: 0 1rem; overflow-y: auto; + + @supports (scroll-padding-block-start: 0.15rem) { + scroll-padding-block-start: 0.15rem; + } } @media only screen and (max-width: @small) and (orientation: portrait) { @@ -34,4 +38,4 @@ .list { display: none; } -} +} \ No newline at end of file diff --git a/src/routes/Intro/ConsentToggle/ConsentToggle.js b/src/routes/Intro/ConsentToggle/ConsentToggle.js deleted file mode 100644 index 9a0210607..000000000 --- a/src/routes/Intro/ConsentToggle/ConsentToggle.js +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2017-2023 Smart code 203358507 - -const React = require('react'); -const PropTypes = require('prop-types'); -const classnames = require('classnames'); -const { Button, Toggle } = require('stremio/components'); -const styles = require('./styles'); - -const ConsentToggle = React.forwardRef(({ className, label, link, href, onToggle, ...props }, ref) => { - const toggleOnClick = React.useCallback((event) => { - if (typeof props.onClick === 'function') { - props.onClick(event); - } - - if (!event.nativeEvent.togglePrevented && typeof onToggle === 'function') { - onToggle({ - type: 'toggle', - reactEvent: event, - nativeEvent: event.nativeEvent - }); - } - }, [onToggle, props.onClick]); - const linkOnClick = React.useCallback((event) => { - event.nativeEvent.togglePrevented = true; - }, []); - return ( - -
- {label} - {' '} - { - typeof link === 'string' && link.length > 0 && typeof href === 'string' && href.length > 0 ? - - : - null - } -
-
- ); -}); - -ConsentToggle.displayName = 'ConsentToggle'; - -ConsentToggle.propTypes = { - className: PropTypes.string, - checked: PropTypes.bool, - label: PropTypes.string, - link: PropTypes.string, - href: PropTypes.string, - onToggle: PropTypes.func, - onClick: PropTypes.func -}; - -module.exports = ConsentToggle; diff --git a/src/routes/Intro/ConsentToggle/index.js b/src/routes/Intro/ConsentToggle/index.js deleted file mode 100644 index 8edfe4a27..000000000 --- a/src/routes/Intro/ConsentToggle/index.js +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (C) 2017-2023 Smart code 203358507 - -const ConsentToggle = require('./ConsentToggle'); - -module.exports = ConsentToggle; diff --git a/src/routes/Intro/ConsentToggle/styles.less b/src/routes/Intro/ConsentToggle/styles.less deleted file mode 100644 index e8229e244..000000000 --- a/src/routes/Intro/ConsentToggle/styles.less +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2017-2023 Smart code 203358507 - -@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; - -:import('~stremio/components/Toggle/styles.less') { - checkbox-icon: icon; -} - -.consent-toggle-container { - display: flex; - flex-direction: row; - align-items: center; - padding: 0.5rem 0; - border-radius: var(--border-radius); - - &:focus { - outline: none; - background-color: var(--overlay-color); - } - - &:global(.checked) { - .label { - opacity: 1; - } - } - - .label { - flex: 1; - margin-left: 1rem; - 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; - } - } - } -} \ No newline at end of file diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index fc98fe5cf..989e6febd 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -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'); @@ -308,30 +307,27 @@ const Intro = ({ queryParams }) => { onChange={confirmPasswordOnChange} onSubmit={confirmPasswordOnSubmit} /> - - - :