mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
PaginateInput simplified
This commit is contained in:
parent
7a1bf0f838
commit
34bf588c3c
7 changed files with 59 additions and 79 deletions
|
|
@ -3,90 +3,29 @@ const PropTypes = require('prop-types');
|
|||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const Button = require('stremio/common/Button');
|
||||
const Multiselect = require('stremio/common/Multiselect');
|
||||
const styles = require('./styles');
|
||||
|
||||
const PaginateInput = ({ className, options, selected, dataset, onSelect }) => {
|
||||
const selectedLabelText = React.useMemo(() => {
|
||||
if (Array.isArray(options)) {
|
||||
const selectedOption = options.find(({ value }) => {
|
||||
return selected === value;
|
||||
});
|
||||
if (selectedOption && typeof selectedOption.label === 'string') {
|
||||
return selectedOption.label;
|
||||
}
|
||||
}
|
||||
|
||||
return selected;
|
||||
}, [options, selected]);
|
||||
const PaginateInput = ({ className, label, dataset, onSelect, ...props }) => {
|
||||
const prevNextButtonOnClick = React.useCallback((event) => {
|
||||
if (typeof onSelect === 'function') {
|
||||
if (Array.isArray(options) && options.length > 0) {
|
||||
const selectedValueIndex = options.findIndex(({ value }) => {
|
||||
return selected === value;
|
||||
});
|
||||
const nextSelectedIndex = event.currentTarget.dataset.button === 'next' ?
|
||||
Math.min(selectedValueIndex + 1, options.length - 1)
|
||||
:
|
||||
Math.max(selectedValueIndex - 1, 0);
|
||||
const nextSelectedValue = options[nextSelectedIndex].value;
|
||||
onSelect({
|
||||
type: 'select',
|
||||
value: nextSelectedValue,
|
||||
dataset: dataset,
|
||||
reactEvent: event,
|
||||
nativeEvent: event.nativeEvent
|
||||
});
|
||||
} else {
|
||||
const nextSelectedValue = event.currentTarget.dataset.button === 'next' ?
|
||||
selected + 1
|
||||
:
|
||||
Math.max(selected - 1, 1);
|
||||
onSelect({
|
||||
type: 'select',
|
||||
value: nextSelectedValue,
|
||||
dataset: dataset,
|
||||
reactEvent: event,
|
||||
nativeEvent: event.nativeEvent
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [options, selected, dataset, onSelect]);
|
||||
const optionOnSelect = React.useCallback((event) => {
|
||||
const page = parseInt(event.value);
|
||||
if (!isNaN(page) && typeof onSelect === 'function') {
|
||||
onSelect({
|
||||
type: 'select',
|
||||
value: page,
|
||||
type: 'change-page',
|
||||
value: event.currentTarget.dataset.value,
|
||||
dataset: dataset,
|
||||
reactEvent: event.reactEvent,
|
||||
reactEvent: event,
|
||||
nativeEvent: event.nativeEvent
|
||||
});
|
||||
}
|
||||
}, [dataset, onSelect]);
|
||||
return (
|
||||
<div className={classnames(className, styles['paginate-input-container'])} title={selected}>
|
||||
<Button className={styles['prev-button-container']} data-button={'prev'} onClick={prevNextButtonOnClick}>
|
||||
<div {...props} className={classnames(className, styles['paginate-input-container'])} >
|
||||
<Button className={styles['prev-button-container']} title={'Previous page'} data-value={'prev'} onClick={prevNextButtonOnClick}>
|
||||
<Icon className={styles['icon']} icon={'ic_arrow_left'} />
|
||||
</Button>
|
||||
<Multiselect
|
||||
className={styles['multiselect-label-container']}
|
||||
renderLabelContent={() => (
|
||||
<div className={styles['multiselect-label']}>{selectedLabelText}</div>
|
||||
)}
|
||||
options={
|
||||
Array.isArray(options) ?
|
||||
options.map(({ value, label }) => ({
|
||||
value: String(value),
|
||||
label
|
||||
}))
|
||||
:
|
||||
null
|
||||
}
|
||||
disabled={!Array.isArray(options) || options.length === 0}
|
||||
onSelect={optionOnSelect}
|
||||
/>
|
||||
<Button className={styles['next-button-container']} data-button={'next'} onClick={prevNextButtonOnClick}>
|
||||
<div className={styles['label-container']} title={label}>
|
||||
<div className={styles['label']}>{label}</div>
|
||||
</div>
|
||||
<Button className={styles['next-button-container']} title={'Next page'} data-value={'next'} onClick={prevNextButtonOnClick}>
|
||||
<Icon className={styles['icon']} icon={'ic_arrow_right'} />
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -95,11 +34,7 @@ const PaginateInput = ({ className, options, selected, dataset, onSelect }) => {
|
|||
|
||||
PaginateInput.propTypes = {
|
||||
className: PropTypes.string,
|
||||
options: PropTypes.arrayOf(PropTypes.shape({
|
||||
value: PropTypes.number.isRequired,
|
||||
label: PropTypes.string
|
||||
})),
|
||||
selected: PropTypes.number.isRequired,
|
||||
label: PropTypes.string,
|
||||
onSelect: PropTypes.func
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
.paginate-input-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: visible;
|
||||
|
||||
.prev-button-container, .next-button-container {
|
||||
flex: none;
|
||||
|
|
@ -17,15 +16,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
.multiselect-label-container {
|
||||
.label-container {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.multiselect-label {
|
||||
.label {
|
||||
flex: none;
|
||||
max-width: 3rem;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
color: var(--color-surfacelighter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
const React = require('react');
|
||||
const { storiesOf } = require('@storybook/react');
|
||||
const { action } = require('@storybook/addon-actions');
|
||||
const { PaginateInput } = require('stremio/common');
|
||||
const styles = require('./styles');
|
||||
|
||||
storiesOf('PaginateInput', module).add('SimplePaginateInput', () => {
|
||||
const domEventHandler = React.useCallback((event) => {
|
||||
action('domEventHandler')(event.currentTarget.dataset);
|
||||
}, []);
|
||||
return (
|
||||
<PaginateInput
|
||||
className={styles['paginate-input']}
|
||||
label={'5'}
|
||||
dataset={{ 'dataset-prop': 'dataset-value' }}
|
||||
data-prop={'data-value'}
|
||||
onSelect={action('onSelect')}
|
||||
onClick={domEventHandler}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
@ -0,0 +1 @@
|
|||
require('./SimplePaginateInput');
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
:import('~stremio/common/PaginateInput/styles.less') {
|
||||
paginate-prev-button-container: prev-button-container;
|
||||
paginate-next-button-container: next-button-container;
|
||||
}
|
||||
|
||||
.paginate-input {
|
||||
flex: none;
|
||||
align-self: flex-start;
|
||||
display: flex;
|
||||
min-width: 8rem;
|
||||
max-width: 10rem;
|
||||
margin: 1rem;
|
||||
background-color: var(--color-backgroundlighter);
|
||||
|
||||
.paginate-prev-button-container, .paginate-next-button-container {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
}
|
||||
}
|
||||
1
storybook/stories/PaginateInput/index.js
Normal file
1
storybook/stories/PaginateInput/index.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
require('./SimplePaginateInput');
|
||||
|
|
@ -6,6 +6,7 @@ require('./MetaItem');
|
|||
require('./ModalDialog');
|
||||
require('./Multiselect');
|
||||
require('./Notification');
|
||||
require('./PaginateInput');
|
||||
require('./Popup');
|
||||
require('./SeasonsBar');
|
||||
require('./SharePrompt');
|
||||
|
|
|
|||
Loading…
Reference in a new issue