mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-08-19 18:48:17 +00:00
Discover adapted to the latest changes in common components
This commit is contained in:
parent
e8d81f6835
commit
1dabcc7a31
6 changed files with 193 additions and 188 deletions
|
|
@ -19,7 +19,7 @@ const Discover = ({ urlParams, queryParams }) => {
|
|||
<div className={styles['discover-content']}>
|
||||
<div className={styles['pickers-container']}>
|
||||
{pickers.map((picker) => (
|
||||
<PickerMenu {...picker} key={picker.name} />
|
||||
<PickerMenu {...picker} key={picker.name} className={'picker'} />
|
||||
))}
|
||||
</div>
|
||||
<div className={styles['meta-items-container']} tabIndex={-1}>
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const { Input, Popup, useBinaryState } = require('stremio/common');
|
||||
const styles = require('./styles');
|
||||
|
||||
const PickerMenu = ({ name, value, options, onChange }) => {
|
||||
const popupRef = React.useRef(null);
|
||||
const [open, onOpen, onClose] = useBinaryState(false);
|
||||
const label = typeof value === 'string' ? value : name;
|
||||
const optionOnClick = React.useCallback((event) => {
|
||||
if (popupRef.current !== null) {
|
||||
popupRef.current.close();
|
||||
}
|
||||
|
||||
onChange(event);
|
||||
}, [onChange]);
|
||||
return (
|
||||
<Popup ref={popupRef} onOpen={onOpen} onClose={onClose}>
|
||||
<Popup.Label>
|
||||
<Input className={classnames(styles['picker-button'], { 'active': open }, 'focusable-with-border')} title={label} type={'button'}>
|
||||
<div className={classnames(styles['picker-label'], { [styles['capitalized']]: name === 'type' })}>{label}</div>
|
||||
<Icon className={styles['picker-icon']} icon={'ic_arrow_down'} />
|
||||
</Input>
|
||||
</Popup.Label>
|
||||
<Popup.Menu className={styles['menu-container']}>
|
||||
<div className={styles['menu-content']}>
|
||||
{
|
||||
Array.isArray(options) ?
|
||||
options.map(({ value, label }) => (
|
||||
<Input key={value} className={classnames(styles['menu-item-container'], 'focusable-with-border')} title={label} data-name={name} data-value={value} type={'button'} onClick={optionOnClick}>
|
||||
<div className={classnames(styles['menu-label'], { [styles['capitalized']]: name === 'type' })}>{label}</div>
|
||||
</Input>
|
||||
))
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</Popup.Menu>
|
||||
</Popup>
|
||||
);
|
||||
};
|
||||
|
||||
PickerMenu.propTypes = {
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
options: PropTypes.arrayOf(PropTypes.shape({
|
||||
value: PropTypes.string,
|
||||
label: PropTypes.string
|
||||
})),
|
||||
onChange: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = PickerMenu;
|
||||
59
src/routes/Discover/PickerMenu/PickerMenu.js
Normal file
59
src/routes/Discover/PickerMenu/PickerMenu.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const { Button, Popup, useBinaryState } = require('stremio/common');
|
||||
require('./styles');
|
||||
|
||||
const PickerMenu = ({ className, name = '', value = '', options = [], onSelect }) => {
|
||||
const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false);
|
||||
const optionOnClick = React.useCallback((event) => {
|
||||
if (typeof onSelect === 'function') {
|
||||
onSelect(event);
|
||||
}
|
||||
|
||||
if (!event.nativeEvent.closeMenuPrevented) {
|
||||
closeMenu();
|
||||
}
|
||||
}, [onSelect]);
|
||||
return (
|
||||
<Popup
|
||||
open={menuOpen}
|
||||
menuMatchLabelWidth={true}
|
||||
onCloseRequest={closeMenu}
|
||||
renderLabel={(ref) => (
|
||||
<Button ref={ref} className={classnames(className, 'picker-label-container', { 'active': menuOpen })} title={name} onClick={toggleMenu}>
|
||||
<div className={'label'}>{typeof value === 'string' && value.length > 0 ? value : name}</div>
|
||||
<Icon className={'icon'} icon={'ic_arrow_down'} />
|
||||
</Button>
|
||||
)}
|
||||
renderMenu={() => (
|
||||
<div className={'discover-picker-menu-container'}>
|
||||
{
|
||||
Array.isArray(options) ?
|
||||
options.map(({ label, value }) => (
|
||||
<Button key={value} className={'picker-option-container'} title={label} data-name={name} data-value={value} onClick={optionOnClick}>
|
||||
<div className={'picker-option-label'}>{label}</div>
|
||||
</Button>
|
||||
))
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
PickerMenu.propTypes = {
|
||||
className: PropTypes.string,
|
||||
name: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
options: PropTypes.arrayOf(PropTypes.shape({
|
||||
label: PropTypes.string,
|
||||
value: PropTypes.string
|
||||
})),
|
||||
onSelect: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = PickerMenu;
|
||||
3
src/routes/Discover/PickerMenu/index.js
Normal file
3
src/routes/Discover/PickerMenu/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
const PickerMenu = require('./PickerMenu');
|
||||
|
||||
module.exports = PickerMenu;
|
||||
58
src/routes/Discover/PickerMenu/styles.less
Normal file
58
src/routes/Discover/PickerMenu/styles.less
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
.discover-container {
|
||||
.picker-label-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 0 0.8rem;
|
||||
background-color: var(--color-backgroundlighter);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-surfacedarker60);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: var(--color-surfacelight);
|
||||
|
||||
.label {
|
||||
color: var(--color-backgrounddarker);
|
||||
}
|
||||
|
||||
.icon {
|
||||
fill: var(--color-backgrounddarker);
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
flex: 1;
|
||||
font-size: 1.1rem;
|
||||
max-height: 2.4em;
|
||||
color: var(--color-surfacelighter);
|
||||
}
|
||||
|
||||
.icon {
|
||||
flex: none;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
margin-left: 0.8rem;
|
||||
fill: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.discover-picker-menu-container {
|
||||
width: 100%;
|
||||
background-color: var(--color-backgroundlighter);
|
||||
|
||||
.picker-option-container {
|
||||
padding: 0.8rem;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-surfacedarker60);
|
||||
}
|
||||
|
||||
.picker-option-label {
|
||||
color: var(--color-surfacelighter);
|
||||
max-height: 4.8em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
@import (reference) 'common/screen-sizes.less';
|
||||
|
||||
.discover-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -14,8 +16,8 @@
|
|||
flex: 1;
|
||||
align-self: stretch;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 26em;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-columns: 1fr 26rem;
|
||||
grid-template-rows: fit-content(13rem) 1fr;
|
||||
grid-template-areas:
|
||||
"pickers-area meta-preview-area"
|
||||
"meta-items-area meta-preview-area";
|
||||
|
|
@ -25,160 +27,98 @@
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-flow: wrap;
|
||||
padding: 0.6em;
|
||||
padding: 0.7rem;
|
||||
overflow-y: auto;
|
||||
|
||||
.picker-button {
|
||||
width: 18em;
|
||||
height: 3em;
|
||||
margin: 0.6em;
|
||||
padding: 0 0.8em;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: var(--color-backgroundlighter);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-surfacedarker60);
|
||||
}
|
||||
|
||||
&:global(.active) {
|
||||
background-color: var(--color-surfacelight);
|
||||
|
||||
.picker-label {
|
||||
color: var(--color-backgrounddarker);
|
||||
}
|
||||
|
||||
.picker-icon {
|
||||
fill: var(--color-backgrounddarker);
|
||||
}
|
||||
}
|
||||
|
||||
.picker-label {
|
||||
flex: 1;
|
||||
font-size: 1.1em;
|
||||
line-height: 1.2em;
|
||||
max-height: 2.4em;
|
||||
color: var(--color-surfacelighter);
|
||||
|
||||
&.capitalized {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
|
||||
.picker-icon {
|
||||
flex: none;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin-left: 0.8em;
|
||||
fill: var(--color-surfacelighter);
|
||||
}
|
||||
.picker {
|
||||
flex-basis: 17rem;
|
||||
height: 3rem;
|
||||
margin: 0.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.meta-items-container {
|
||||
grid-area: meta-items-area;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--items-per-row), auto);
|
||||
grid-auto-rows: max-content;
|
||||
grid-gap: 1.2em;
|
||||
grid-gap: 1.4rem;
|
||||
align-items: center;
|
||||
padding: var(--focusable-border-size) 1.2em 0;
|
||||
overflow-x: hidden;
|
||||
padding: 0 1.4rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.meta-preview-container {
|
||||
grid-area: meta-preview-area;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-container {
|
||||
--border-color: var(--color-backgroundlighter40);
|
||||
--box-shadow: -0.6em 0.6em 0.5em -0.1em var(--color-backgrounddark40);
|
||||
|
||||
.menu-content {
|
||||
width: 18em;
|
||||
background-color: var(--color-backgroundlighter);
|
||||
|
||||
.menu-item-container {
|
||||
padding: 0.8em;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-surfacedarker60);
|
||||
}
|
||||
|
||||
.menu-label {
|
||||
line-height: 1.2em;
|
||||
max-height: 2.4em;
|
||||
color: var(--color-surfacelighter);
|
||||
|
||||
&.capitalized {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
.discover-container, .menu-container {
|
||||
font-size: 14px;
|
||||
--items-per-row: 5;
|
||||
|
||||
@media only screen and (min-width: @xxlarge) {
|
||||
.discover-container {
|
||||
.discover-content {
|
||||
.meta-items-container {
|
||||
grid-template-columns: repeat(8, auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: @xxlarge) {
|
||||
.discover-container {
|
||||
.discover-content {
|
||||
.meta-items-container {
|
||||
grid-template-columns: repeat(7, auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: @normal) {
|
||||
.discover-container {
|
||||
.discover-content {
|
||||
.meta-items-container {
|
||||
grid-template-columns: repeat(6, auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: @medium) {
|
||||
.discover-container {
|
||||
.discover-content {
|
||||
.meta-items-container {
|
||||
grid-template-columns: repeat(5, auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: @small) {
|
||||
.discover-container {
|
||||
.discover-content {
|
||||
.meta-items-container {
|
||||
grid-template-columns: repeat(4, auto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: @xsmall) {
|
||||
.discover-container {
|
||||
.discover-content {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: fit-content(19rem) 1fr;
|
||||
grid-template-areas:
|
||||
"pickers-area pickers-area"
|
||||
"meta-items-area meta-items-area";
|
||||
"pickers-area"
|
||||
"meta-items-area";
|
||||
|
||||
.meta-items-container {
|
||||
grid-template-columns: repeat(5, auto);
|
||||
}
|
||||
|
||||
.meta-preview-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1000px) and (max-width: 1200px) {
|
||||
.discover-container, .menu-container {
|
||||
font-size: 14px;
|
||||
--items-per-row: 4;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1200px) and (max-width: 1400px) {
|
||||
.discover-container, .menu-container {
|
||||
font-size: 14px;
|
||||
--items-per-row: 5;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1400px) and (max-width: 1600px) {
|
||||
.discover-container, .menu-container {
|
||||
font-size: 14px;
|
||||
--items-per-row: 6;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1600px) and (max-width: 2000px) {
|
||||
.discover-container, .menu-container {
|
||||
font-size: 15px;
|
||||
--items-per-row: 7;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 2000px) and (max-width: 3000px) {
|
||||
.discover-container, .menu-container {
|
||||
font-size: 16px;
|
||||
--items-per-row: 8;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 3000px) {
|
||||
.discover-container, .menu-container {
|
||||
font-size: 18px;
|
||||
--items-per-row: 10;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue