Skip to content

Commit d85cf0a

Browse files
committed
added startAt prop
1 parent c03a14b commit d85cf0a

12 files changed

+751
-372
lines changed

babel.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ module.exports = {
99
alias: {
1010
"lib/utils": "./src/lib/utils",
1111
"lib/styles": "./src/lib/styles",
12-
"lib/types": "./src/lib/types"
12+
"lib/types": "./src/lib/types",
13+
"lib/common": "./src/lib/common"
1314
},
1415
},
1516
],

index.d.ts

+17
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ type RenderPaginationProps = {
7676
onDotClick(index: number): void
7777
}
7878

79+
type StartAt = {
80+
/**
81+
Defines index of start element (scrolled to when componentDidMount)
82+
*/
83+
84+
startIndex: number,
85+
86+
/**
87+
Defines alignment of start element
88+
If set to true, target element will be centered
89+
*/
90+
91+
center?: boolean
92+
}
93+
7994
export type ReactSmartScrollerProps = {
8095
/**
8196
Default undefined.
@@ -133,6 +148,8 @@ export type ReactSmartScrollerProps = {
133148

134149
pagination?: boolean,
135150

151+
startAt?: StartAt,
152+
136153
paginationConfig?: PaginationConfig,
137154

138155
/**

package.json

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-smart-scroller",
3-
"version": "1.1.1",
3+
"version": "1.1.2",
44
"description": "React-smart-scroller is a library that allows you to create highly customizable horizontal or vertical scroller in easy way. You can modify track styles or pass your own thumb (own component)",
55
"main": "dist/index.js",
66
"module": "dist/react-smart-scroller.esm.js",
@@ -42,27 +42,27 @@
4242
},
4343
"homepage": "https://github.com/codegateinc/react-smart-slider#readme",
4444
"devDependencies": {
45-
"@types/enzyme": "3.1.15",
46-
"@types/enzyme-adapter-react-16": "1.0.3",
47-
"@types/jest": "24.0.13",
48-
"@types/react": "16.8.17",
49-
"@types/react-dom": "16.8.4",
50-
"@types/styled-components": "4.1.16",
45+
"@types/enzyme": "3.10.5",
46+
"@types/enzyme-adapter-react-16": "1.0.6",
47+
"@types/jest": "26.0.7",
48+
"@types/react": "16.9.43",
49+
"@types/react-dom": "16.9.8",
50+
"@types/styled-components": "5.1.1",
5151
"babel-plugin-module-resolver": "4.0.0",
52-
"coveralls": "3.0.4",
53-
"enzyme": "3.9.0",
54-
"enzyme-adapter-react-16": "1.9.1",
55-
"jsdom": "15.1.0",
56-
"react": "16.8.6",
57-
"react-dom": "16.8.6",
52+
"coveralls": "3.1.0",
53+
"enzyme": "3.11.0",
54+
"enzyme-adapter-react-16": "1.15.2",
55+
"jsdom": "16.3.0",
56+
"react": "16.13.1",
57+
"react-dom": "16.13.1",
5858
"react-scripts-ts": "4.0.8",
59-
"ts-loader": "7.0.0",
59+
"ts-loader": "8.0.1",
6060
"tsdx": "0.13.2",
61-
"tslint": "5.17.0",
62-
"typescript": "3.4.5"
61+
"tslint": "6.1.2",
62+
"typescript": "3.9.7"
6363
},
6464
"dependencies": {
65-
"styled-components": "4.3.1"
65+
"styled-components": "5.1.1"
6666
},
6767
"browserslist": [
6868
">0.2%",

src/components/ReactSmartScrollerHorizontal.tsx

+48-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import styled from 'styled-components'
33
import { colors } from 'lib/styles'
44
import { Padding, ReactSmartScrollerProps } from 'lib/types'
55
import { C, isMobile, isMacOs } from 'lib/utils'
6+
import { constants } from 'lib/common'
67

78
type ReactSmartScrollerHorizontalState = {
89
scrollContainerWidth: number,
@@ -12,7 +13,8 @@ type ReactSmartScrollerHorizontalState = {
1213
trackHeight: number,
1314
scrollWidth: number,
1415
scrollLeft: number,
15-
padding: Padding
16+
padding: Padding,
17+
ratio: number
1618
}
1719

1820
export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScrollerProps, ReactSmartScrollerHorizontalState> {
@@ -31,7 +33,8 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
3133
trackHeight: 0,
3234
scrollWidth: 0,
3335
scrollLeft: 0,
34-
padding: this.trackPadding
36+
padding: this.trackPadding,
37+
ratio: 1
3538
}
3639

3740
private overflowContainerRef: React.RefObject<HTMLDivElement> = React.createRef()
@@ -55,14 +58,17 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
5558
componentDidMount() {
5659
window.addEventListener('resize', this.measureContainers)
5760
window.addEventListener('mouseup', this.deleteMouseMoveEvent)
61+
window.addEventListener('transitionend', this.measureContainers)
5862
window.addEventListener('mouseup', this.deleteOverflowMouseMoveEvent)
59-
this.measureContainers()
63+
window.addEventListener('load', this.measureContainers)
6064
}
6165

6266
componentWillUnmount() {
6367
window.removeEventListener('resize', this.measureContainers)
6468
window.removeEventListener('mouseup', this.deleteMouseMoveEvent)
69+
window.removeEventListener('transitionend', this.measureContainers)
6570
window.removeEventListener('mouseup', this.deleteOverflowMouseMoveEvent)
71+
window.removeEventListener('load', this.measureContainers)
6672
}
6773

6874
get shouldRenderScrollbar() {
@@ -111,13 +117,37 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
111117
: 0
112118
}
113119

120+
get startElement() {
121+
if (this.props.startAt) {
122+
return document.getElementById(`${constants.reactSmartScrollerId}-${this.props.startAt.startIndex}`)
123+
}
124+
125+
return undefined
126+
}
127+
114128
scrollContainerReducedWidth(scrollContainerWidth: number) {
115129
const { padding } = this.state
116130

117131
return scrollContainerWidth - (padding.left + padding.right)
118132
}
119133

120-
measureContainers() {
134+
setStartPosition() {
135+
const { startAt } = this.props
136+
const overflowRef = this.overflowContainerRef.current as HTMLDivElement
137+
const startElement = this.startElement
138+
139+
this.measureContainers()
140+
141+
if (overflowRef && startElement) {
142+
const offset = startAt && startAt.center
143+
? (overflowRef.clientWidth - startElement.clientWidth) / 2
144+
: 0
145+
146+
overflowRef.scrollLeft = startElement.offsetLeft - offset
147+
}
148+
}
149+
150+
measureContainers(event?: Event) {
121151
const overflownRef = this.overflowContainerRef.current as HTMLDivElement
122152
const thumbRef = this.thumbRef.current as HTMLDivElement
123153
const trackRef = this.trackRef.current as HTMLDivElement
@@ -128,11 +158,20 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
128158
)
129159

130160
if (areRefsCurrent) {
161+
const scrollContainerWidth = this.scrollContainerReducedWidth(overflownRef.clientWidth)
162+
const maximumOffset = scrollContainerWidth - thumbRef.offsetWidth
163+
const ratio = maximumOffset / (overflownRef.scrollWidth - overflownRef.clientWidth)
164+
131165
this.setState({
132-
scrollContainerWidth: this.scrollContainerReducedWidth(overflownRef.clientWidth),
166+
scrollContainerWidth,
133167
thumbHeight: thumbRef.offsetHeight,
134168
trackHeight: trackRef.clientHeight,
135-
scrollWidth: overflownRef.scrollWidth
169+
scrollWidth: overflownRef.scrollWidth,
170+
ratio
171+
}, () => {
172+
if (event && event.type === 'load') {
173+
this.setStartPosition()
174+
}
136175
})
137176
}
138177

@@ -193,7 +232,7 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
193232

194233
onMouseDrag(event: DragEvent | MouseEvent) {
195234
const zero = 0
196-
const { deltaX, deltaXOrigin, scrollContainerWidth } = this.state
235+
const { deltaX, deltaXOrigin, scrollContainerWidth, ratio } = this.state
197236
const overflowRef = this.overflowContainerRef.current as HTMLDivElement
198237
const thumbRef = this.thumbRef.current as HTMLDivElement
199238
const maximumOffset = scrollContainerWidth - thumbRef.offsetWidth
@@ -215,22 +254,17 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
215254
}
216255

217256
if (areRefsCurrent && isBetweenClientWidth) {
218-
const ratio = (overflowRef.scrollWidth - overflowRef.clientWidth) / maximumOffset
219-
220257
overflowRef.scroll(ratio * offset, zero)
221258
thumbRef.style.left = `${offset}px`
222259
}
223260
}
224261

225262
onOverflowContentScroll() {
226-
const { scrollContainerWidth } = this.state
263+
const { ratio } = this.state
227264
const thumbRef = this.thumbRef.current as HTMLDivElement
228265
const overflowRef = this.overflowContainerRef.current
229266

230267
if (overflowRef && thumbRef) {
231-
const maximumOffset = scrollContainerWidth - thumbRef.offsetWidth
232-
const ratio = maximumOffset / (overflowRef.scrollWidth - overflowRef.clientWidth)
233-
234268
thumbRef.style.left = `${overflowRef.scrollLeft * ratio}px`
235269
}
236270
}
@@ -276,6 +310,7 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
276310

277311
return (
278312
<ChildrenWrapper
313+
id={`${constants.reactSmartScrollerId}-${index}`}
279314
style={{
280315
padding: `0 ${padding}px`,
281316
flexBasis,
@@ -348,7 +383,6 @@ export class ReactSmartScrollerHorizontal extends React.Component<ReactSmartScro
348383
<SecondWrapper
349384
ref={this.overflowContainerRef}
350385
onScroll={this.onOverflowContentScroll}
351-
onLoad={this.measureContainers}
352386
onMouseDown={draggable ? this.onOverflowContentMouseDown : C.noop}
353387
style={{ cursor }}
354388
>

0 commit comments

Comments
 (0)