Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/createListComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ export default function createListComponent({
itemStyleCache[index] = style = {
position: 'absolute',
left: direction === 'horizontal' ? offset : 0,
right: direction === 'horizontal' ? offset : 0,
top: direction === 'vertical' ? offset : 0,
height: direction === 'vertical' ? size : '100%',
width: direction === 'horizontal' ? size : '100%',
Expand Down Expand Up @@ -448,7 +449,7 @@ export default function createListComponent({
}

_onScrollHorizontal = (event: ScrollEvent): void => {
const { scrollLeft } = event.currentTarget;
const { scrollLeft, scrollWidth, clientWidth } = event.currentTarget;
this.setState(prevState => {
if (prevState.scrollOffset === scrollLeft) {
// Scroll position may have been updated by cDM/cDU,
Expand All @@ -457,11 +458,15 @@ export default function createListComponent({
return null;
}

const isRtl = this.props.style && this.props.style.direction === 'rtl';

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about parsing the style in this way. Seems like RTL pages will likely have a direction: rtl on the level of the body rather than the list. Normally I'd say an explicit direction prop would be better, but that's already used in the list to differentiate between "horizontal" and "vertical". Hmm...

@bvaughn bvaughn Mar 3, 2019

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In CSS this is called direction but that's already in use for lists. Ideally I would have maybe used "layout" or something but that ship has sailed, and I'm not really willing to do a major release just to rename this property.

There's a related HTML attribute called dir but that doesn't really follow the prop naming convention.

I briefly considered maybe using direction anyway and just expanding it to be "vertical", "horizontal", or "rtl" (which would be horizontal with RTL direction) but that's maybe...not the most intuitive.

I am currently leaning toward an isRTL boolean attribute, even though...that's a bit weird too.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe direction can accept multiple values, e.g. "vertical ltr" (default), "horizontal ltr", "horizontal rtl", etc.

@bvaughn bvaughn Mar 3, 2019

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe I should just add a new layout prop and deprecate direction (with a DEV warning) for now. I think this is maybe the best long-term option.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my use case I saw the usage of direction (CSS) in an isolated fashion (component biased). But in a real scenario is true that this can be affected by parent styles. Definitely the last approach seems the way to go.


return {
isScrolling: true,
scrollDirection:
prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
scrollOffset: scrollLeft,
scrollOffset: isRtl
? scrollWidth - clientWidth - scrollLeft
: scrollLeft,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if this is right. Why should we invert the element's scrollLeft? That seems...wrong. Am I thinking about this wrong?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. I think I was mistaken.

scrollUpdateWasRequested: false,
};
}, this._resetIsScrollingDebounced);
Expand Down
6 changes: 6 additions & 0 deletions website/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import FixedSizeGridApi from './routes/api/FixedSizeGrid';
import FixedSizeListApi from './routes/api/FixedSizeList';
import FixedSizeGridExample from './routes/examples/FixedSizeGrid';
import FixedSizeListExample from './routes/examples/FixedSizeList';
import FixedSizeListExampleRtl from './routes/examples/FixedSizeListRtl';
import ListWithScrollingIndicatorExample from './routes/examples/ListWithScrollingIndicator';
import ScrollToItemExample from './routes/examples/ScrollToItem';
import MemoizedListItemsExample from './routes/examples/MemoizedListItemsExample';
Expand Down Expand Up @@ -95,6 +96,11 @@ const EXAMPLE_ROUTES = [
title: 'Memoized List items',
component: MemoizedListItemsExample,
},
{
path: '/examples/list/fixed-size-rtl',
title: 'Fixed Size List RTL',
component: FixedSizeListExampleRtl,
},
];

const COMPONENTS_ROUTES = [
Expand Down
18 changes: 18 additions & 0 deletions website/src/code/FixedSizeListHorizontalRtl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { FixedSizeList as List } from 'react-window';

const Column = ({ index, style }) => (
<div style={style}>Column {index}</div>
);

const Example = () => (
<List
direction="horizontal"
height={75}
itemCount={1000}
itemSize={100}
width={300}
style={{ direction: "rtl" }}
>
{Column}
</List>
);
17 changes: 17 additions & 0 deletions website/src/code/FixedSizeListVerticalRtl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FixedSizeList as List } from 'react-window';

const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);

const Example = () => (
<List
height={150}
itemCount={1000}
itemSize={35}
width={300}
style={{ direction: "rtl" }}
>
{Row}
</List>
);
75 changes: 75 additions & 0 deletions website/src/routes/examples/FixedSizeListRtl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { PureComponent } from 'react';
import { FixedSizeList } from 'react-window';
import CodeBlock from '../../components/CodeBlock';
import ProfiledExample from '../../components/ProfiledExample';

import CODE_HORIZONTAL from '../../code/FixedSizeListHorizontalRtl.js';
import CODE_VERTICAL from '../../code/FixedSizeListVerticalRtl.js';

import styles from './shared.module.css';

class Item extends PureComponent {
render() {
const { data, index, style } = this.props;

return (
<div
className={index % 2 ? styles.ListItemOdd : styles.ListItemEven}
style={style}
>
{data} {index}
</div>
);
}
}

export default function() {
return (
<div className={styles.ExampleWrapper}>
<h1 className={styles.ExampleHeader}>Basic List</h1>
<div className={styles.Example}>
<ProfiledExample
className={styles.ExampleDemo}
sandbox="fixed-size-list-vertical"
>
<FixedSizeList
className={styles.List}
height={150}
itemCount={1000}
itemData="صف"
itemSize={35}
width={300}
style={{ direction: "rtl" }}
>
{Item}
</FixedSizeList>
</ProfiledExample>
<div className={styles.ExampleCode}>
<CodeBlock value={CODE_VERTICAL} />
</div>
</div>
<div className={styles.Example}>
<ProfiledExample
className={styles.ExampleDemo}
sandbox="fixed-size-list-horizontal"
>
<FixedSizeList
className={styles.List}
direction="horizontal"
height={75}
itemCount={1000}
itemData="عمود"
itemSize={100}
width={300}
style={{ direction: "rtl" }}
>
{Item}
</FixedSizeList>
</ProfiledExample>
<div className={styles.ExampleCode}>
<CodeBlock value={CODE_HORIZONTAL} />
</div>
</div>
</div>
);
}