Skip to content

Commit b6884fa

Browse files
committed
add startAt prop support
1 parent 87b7cce commit b6884fa

File tree

5 files changed

+62
-16
lines changed

5 files changed

+62
-16
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ The `overflow` default value of `auto` is applied via `style`. So, if you want t
2727
- `overflow` - You can set this to `auto` or `scroll` ("auto" is the default).
2828
- `row` - Your row component.
2929
- `rowHeight` - Starting row height (100 by default) - it starts with this as an estimate for all rows, and then measures and caches the actual height of each row is as you scroll.
30+
- `startAt` - You can pass an index to start the list at (0 by default).
3031
- `style` - A style object applied to the component if you prefer using inline styling instead of css.
3132
- `...rowProps` - Any additional props you pass will be applied to your row components, for example `onClick`.
3233

@@ -38,6 +39,7 @@ import ReactSmartScroll from 'react-smart-scroll';
3839
data={data}
3940
overflow="scroll"
4041
row={TestRow}
42+
startAt={5}
4143
onClick={() => console.log('Hello!')} // passed to row components
4244
label="My text is: " // passed to row components
4345
/>
@@ -67,9 +69,7 @@ Unlike other virtual scrolling components/libraries out there, there are no unne
6769
#### Firefox Note
6870
The latest version of Firefox doesn't seem to keep up with React's rendering speed with `useLayoutEffect()` or `useEffect()`, so if you grab the scrollbar and scroll up and down really fast, you'll see blank space momentarily. Other browsers don't appear to have this problem. Using the mouse wheel to scroll looks good in all browsers.
6971

70-
## Future Stuff
71-
I'm working on the ability to scroll to a specific row in the list programmatically.
72-
72+
## Closing Note
7373
I hope you enjoy using this component as much as I enjoyed making it!
7474

7575
Follow me:

demo/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const Demo = () => {
1212
<div>
1313
<h1>React Smart Scroll Demo</h1>
1414
<div className="click-status">{clicked}</div>
15-
<ReactSmartScroll className="demo-smart-scroll" data={data} onClick={onClick} row={TestRow}/>
15+
<ReactSmartScroll className="demo-smart-scroll" data={data} onClick={onClick} row={TestRow} startAt={10}/>
1616
</div>
1717
);
1818
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-smart-scroll",
3-
"version": "1.0.5",
3+
"version": "1.0.6",
44
"description": "Smart Scroll React Component for long lists",
55
"author": "Steven Sacks",
66
"homepage": "https://github.com/stevensacks/react-smart-scroll",

src/ReactSmartScroll/index.js

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
1-
import {calcEndIndex, calcStartIndex} from './utils';
1+
import {calcEndIndex, calcStartIndex, sumRange} from './utils';
22
import React, {
33
useEffect,
44
useLayoutEffect,
5+
useReducer,
56
useRef,
67
useState,
7-
useReducer,
88
} from 'react';
99
import ReactSmartScrollRow from './ReactSmartScrollRow';
10-
import {sumRange} from './utils';
1110
import useComponentRect from '../hooks/useComponentRect';
1211
import useScroll from '../hooks/useScroll';
1312
import useScrollToTop from '../hooks/useScrollToTop';
1413

1514
const ReactSmartScroll = props => {
16-
const {className, data, overflow, row, rowHeight, style, ...rowProps} = props;
15+
const {
16+
className,
17+
data,
18+
overflow,
19+
row,
20+
rowHeight,
21+
startAt,
22+
style,
23+
...rowProps
24+
} = props;
25+
26+
const [start, setStart] = useState(0);
1727

1828
const [actualHeights, setActualHeights] = useReducer((state, action) => {
1929
if (!action.reset) {
@@ -43,7 +53,10 @@ const ReactSmartScroll = props => {
4353
// useEffect with this has considerable redraw lag
4454
useLayoutEffect(() => {
4555
if (visible.height) {
46-
const startIndex = calcStartIndex(actualHeights, scroll.top);
56+
const startIndex =
57+
start !== startAt
58+
? startAt
59+
: calcStartIndex(actualHeights, scroll.top);
4760
const endIndex = calcEndIndex(
4861
actualHeights,
4962
visible.height,
@@ -73,23 +86,49 @@ const ReactSmartScroll = props => {
7386
contentHeight,
7487
};
7588
setMeasurements(measurements);
89+
if (start !== startAt) {
90+
scrollRef.current.scrollTop = paddingTop;
91+
defer(() => {
92+
setStart(startAt);
93+
if (data[startAt]) {
94+
const el = document.querySelector(
95+
`[data-id="${data[startAt].id}"]`
96+
);
97+
98+
if (el) el.scrollIntoView();
99+
}
100+
});
101+
}
76102
}
77-
}, [actualHeights, scroll.top, setMeasurements, visible.height]);
103+
}, [
104+
actualHeights,
105+
data,
106+
scroll.top,
107+
setMeasurements,
108+
setStart,
109+
start,
110+
startAt,
111+
visible.height,
112+
]);
78113

79114
const {endIndex, paddingBottom, paddingTop, startIndex} = measurements;
80115

81116
return (
82-
<div ref={scrollRef} className={className || ''} style={{overflow, ...style}}>
83-
<div style={{paddingBottom, paddingTop: paddingTop}}>
117+
<div
118+
ref={scrollRef}
119+
className={className || ''}
120+
style={{overflow, ...style}}
121+
>
122+
<div style={{paddingBottom, paddingTop}}>
84123
{data.slice(startIndex, endIndex + 1).map((item, i) => (
85124
<ReactSmartScrollRow
86125
key={item.id || startIndex + i}
87126
Component={row}
88127
data={item}
89128
onUpdate={setActualHeights}
90-
rowProps={rowProps}
91129
rowHeight={actualHeights[startIndex + i]}
92130
rowIndex={startIndex + i}
131+
rowProps={rowProps}
93132
/>
94133
))}
95134
</div>
@@ -103,6 +142,7 @@ ReactSmartScroll.defaultProps = {
103142
overflow: 'auto',
104143
row: () => null,
105144
rowHeight: 100,
145+
startAt: 0,
106146
style: {},
107147
};
108148

src/ReactSmartScroll/utils.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,11 @@ export const calcEndIndex = (actualHeights, visibleHeight, startIndex) => {
2424
return len - 1;
2525
};
2626

27-
export const sumRange = (array, start, end) =>
28-
array.slice(start, end + 1).reduce((acc, val) => acc + val, 0);
27+
export const sumRange = (array, start, end) => {
28+
let result = 0;
29+
const e = end + 1;
30+
for (let i = start; i < e; i++) {
31+
result += array[i] || 0;
32+
}
33+
return result;
34+
};

0 commit comments

Comments
 (0)