Skip to content

Commit 80540c7

Browse files
authored
Merge pull request #40 from SeinopSys/v7
Sorry for the delay. I had been out for a while. Give me a while to try it out for myself and another time to update the README before publishing
2 parents f7b2859 + 54d1c76 commit 80540c7

18 files changed

+14085
-2339
lines changed

.babelrc

-8
This file was deleted.

.editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 2
7+
indent_style = space
8+
insert_final_newline = true
9+
max_line_length = 120
10+
trim_trailing_whitespace = true

.eslintignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
src/scrollchor-old.jsx
2+
lib/
3+
rollup.config.js

.eslintrc

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es6": true
5+
},
6+
"extends": [
7+
"plugin:react/recommended",
8+
"plugin:react-hooks/recommended",
9+
"airbnb",
10+
"plugin:import/typescript",
11+
"plugin:@typescript-eslint/eslint-recommended",
12+
"plugin:@typescript-eslint/recommended",
13+
"plugin:@typescript-eslint/recommended-requiring-type-checking"
14+
],
15+
"parser": "@typescript-eslint/parser",
16+
"parserOptions": {
17+
"ecmaFeatures": {
18+
"jsx": true
19+
},
20+
"ecmaVersion": 2018,
21+
"sourceType": "module",
22+
"project": "./tsconfig*.json"
23+
},
24+
"plugins": [
25+
"react",
26+
"@typescript-eslint",
27+
"import-newlines"
28+
],
29+
"rules": {
30+
"no-unused-vars": "off",
31+
"@typescript-eslint/no-unused-vars": "error",
32+
"react/prop-types": "off",
33+
"no-use-before-define": "off",
34+
"@typescript-eslint/no-use-before-define": "error",
35+
"import/extensions": [
36+
"error",
37+
"never"
38+
],
39+
"react/jsx-filename-extension": [
40+
"error",
41+
{
42+
"extensions": [
43+
".tsx"
44+
]
45+
}
46+
],
47+
"no-void": "off",
48+
"react/jsx-props-no-spreading": "off",
49+
"object-curly-newline": [
50+
"error",
51+
{
52+
"multiline": true,
53+
"minProperties": 5
54+
}
55+
],
56+
"import-newlines/enforce": [
57+
"error",
58+
4,
59+
100
60+
],
61+
"import/prefer-default-export": "off"
62+
},
63+
"settings": {
64+
"import/parsers": {
65+
"@typescript-eslint/parser": [
66+
".ts",
67+
".tsx"
68+
]
69+
},
70+
"import/resolver": {
71+
"typescript": {}
72+
},
73+
"react": {
74+
"version": "detect"
75+
}
76+
}
77+
}

.huskyrc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"hooks": {
3+
"pre-commit": "lint-staged",
4+
"pre-push": "npm run build"
5+
}
6+
}

.npmignore

+4
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ CHANGELOG.md
33
CONTRIBUTING.md
44
src
55
package-lock.json*
6+
.eslintrc
7+
.eslintignore
8+
tsconfig.json
9+
rollup.config.js

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
## master (unreleased)
22

3+
## 7.0.0
4+
5+
This new major version contains breaking changes.
6+
7+
- Everything has been rewritten in TypeScript, which brings with it published type definitions
8+
- The default export has been removed in favor of a named export; `import Scrollchor` must be replaced with `import { Scrollchor }`
9+
- The `simulateClick()` API has been removed entirely
10+
- Scrollchor is now a function component and makes use of hooks introduced in React v16.8, which necessitated a minimum version bump for this `peerDependency`
11+
- `animation.easing` configuration is now documented and compatible with all the easing functions provided by [jquery-easing](https://github.com/danro/jquery-easing/blob/master/jquery.easing.js)
12+
- Added two additional built-in easing types for _ease_ of use, borrowed from jQuery (`linear`, `swing`)
13+
314
## 6.0.0
415

516
`Scrollchor` React component now belong to `Some React Component` Organization Team. This move will ensure its future development and manteniance.

README.md

+77-105
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@
44
[![npm downloads](https://img.shields.io/npm/dm/react-scrollchor.svg?style=flat-square)](https://www.npmjs.com/package/react-scrollchor)
55
[![Donate](https://img.shields.io/badge/$-support-green.svg?style=flat-square)](https://paypal.me/bySabi/10)
66

7-
> A React component for scroll to `#hash` links with smooth animations.
7+
> A React component for scrolling to `#hash` links with smooth animations.
88
> Scrollchor is a mix of `Scroll` and `Anchor`, a joke name for a useful component.
99
1010
See it in action:
1111
* demo [video](https://github.com/some-react-components/react-scrollchor/blob/example/demo/scrollchor.webm?raw=true)
12-
* example [page](https://some-react-components.github.io/react-scrollchor/) and [source code](https://github.com/some-react-components/react-scrollchor/tree/example)
13-
14-
15-
`hash` is the `id` of a HTML tag on current page.
1612

13+
`hash` is the `id` attribute of an HTML tag on the current page.
1714

1815
## Installation
1916

@@ -23,17 +20,24 @@ See it in action:
2320
npm install react-scrollchor --save
2421
```
2522

23+
### yarn
24+
25+
```bash
26+
yarn add react-scrollchor
27+
```
28+
2629
### Dependencies
27-
* User should provide their own `React` package
30+
31+
You must have React (≥16.8.0) installed in your project before trying to use this component. This minimum version constraint represents the React version which [introduced hooks](https://reactjs.org/docs/hooks-intro.html).
2832

2933

3034
## Usage
3135

3236
```js
33-
import Scrollchor from 'react-scrollchor';
34-
```
35-
```js
36-
export default (props) => (
37+
import { Scrollchor } from 'react-scrollchor';
38+
import { Navbar, NavItem, Page, Section } from './components';
39+
40+
const LandingPage = (props) => (
3741
<Page>
3842

3943
<Navbar brand={brand} className="navbar-fixed-top">
@@ -44,128 +48,95 @@ export default (props) => (
4448
</Navbar>
4549

4650

47-
<Section id="sample-code">
51+
<Section id="sample-code">
52+
<div style={{ height: '100vh' }} />
53+
</Section>
4854

49-
</Section>
55+
<div id="features">
56+
<div style={{ height: '100vh' }} />
57+
</div>
5058

51-
<div id="features">
59+
<footer id="footer">
60+
<div style={{ height: '100vh' }} />
61+
</footer>
5262

53-
</div>
63+
</Page>
64+
);
5465

55-
<footer id="footer">
66+
export default LandingPage;
67+
```
5668

57-
</footer>
69+
## Props
5870

59-
</Page>
60-
```
71+
The package ships with TypeScript type definitions to help with IDE autocompletion, but the sections below should give you a quick rundown of each prop if you prefer this format. Any props not listed below are passed directly on to the underlying `<a>` tag, except for `href` and `onClick`.
6172

62-
## Prop types
63-
```js
64-
propTypes: {
65-
66-
/**
67-
* id attribute of the target DOM node
68-
* - `#` can be omitted
69-
* - let it blank, `to = ''`, for scroll to page top
70-
* - this prop is required
71-
*/
72-
to: PropTypes.string.isRequired,
73-
74-
/**
75-
* id attribute of the scrollable DOM node
76-
* - `#` can be omitted
77-
* - uses the root element of the document if omitted
78-
*/
79-
target: PropTypes.string,
80-
81-
/**
82-
* scroll smooth animation can be customized
83-
* Accepted options, Ex: (default)
84-
* { offset: 0, duration: 400, easing: easeOutQuad }
85-
*/
86-
animate: PropTypes.object,
87-
88-
/**
89-
* callback function triggered before scroll to #hash
90-
* @param1 Received click event
91-
*/
92-
beforeAnimate: PropTypes.func,
93-
94-
/**
95-
* callback function triggered after scroll to #hash
96-
* @param1 Received click event
97-
*/
98-
afterAnimate: PropTypes.func
99-
100-
/**
101-
* enable/disable update browser history with scroll behaviours
102-
* Default to `false`
103-
*/
104-
disableHistory: PropTypes.bool
105-
}
106-
```
107-
### Reactive `props`
108-
Update `props` will re-render `Scrollchor` element
73+
The `to` prop controls the final `href` prop, and `onClick` is used internally to perform the scrolling. If you need to run some code when the link is clicked use the `beforeAnimate` prop instead.
10974

110-
Example: [updating "to" prop](https://github.com/some-react-components/react-scrollchor/blob/example/src/App.js#L28)
75+
### `to: string`
11176

112-
## Custom animations
77+
The anchor (id) to which this link should scroll to. Any leading `#` will be stripped from this value.
11378

114-
Animation behavior can be customized:
79+
### `target?: string`
11580

116-
```js
117-
<Scrollchor to="#aboutus" animate={{offset: 20, duration: 600}} className="nav-link">Home</Scrollchor>
118-
```
81+
The element scrolling will be performed on when clicked. Leading `#` will be stripped here as well.
11982

120-
### default animation settings
121-
```js
122-
{ offset: 0, duration: 400, easing: easeOutQuad }
123-
```
124-
This setting is equivalent to default jQuery.animate `easing: swing`
83+
Scrollchor works within any scrollable parent container. If no target is provided (or the target element is not found on the page), the default is scrolling both the `<html>` and `<body>` elements simultaneously.
12584

126-
### more `Easing` functions
85+
### `animate?: Partial<AnimateConfig>`
12786

128-
* [jQuery easings](http://api.jqueryui.com/easings/)
129-
* [Robert Penner's Easing Functions](http://robertpenner.com/easing/)
130-
* [Javascript source code](https://github.com/danro/jquery-easing/blob/master/jquery.easing.js)
87+
The smooth scrolling animation can be customized using this prop. Three pre-defined easing functions are exported by the package: `easeOutQuad`, `swing`, `linear`. When not provided, the default looks like this:
13188

89+
```ts
90+
import { AnimateConfig, easeOutQuad } from 'react-scrollchor';
13291

133-
## `before` and `after` Animate callbacks
134-
Use these callbacks to trigger behaviors like: update state, load async stuff, etc.
135-
```js
136-
<Scrollchor to="#aboutus" afterAnimate={() => updateState(this)}>Home</Scrollchor>
92+
const defaultAnimate: AnimateConfig = {
93+
offset: 0,
94+
duration: 400,
95+
easing: easeOutQuad,
96+
};
13797
```
13898

139-
## Simulate click API
140-
Scrollchor includes a dedicate API to do animate scroll programmatically that works like normal click events using `simulateClick()`.
99+
* `offset?: number` &mdash; Additional pixels to scroll relative to the target element (supports negative values, e.g. for fixed position headers)
100+
* `duration?: number` &mdash; Length of the animation in milliseconds
101+
* `easing?: ScrollchorEasingFunction` &mdash; Easing function to calculate the animation steps. Pass a function that matches the exported interface for a custom easing.
141102

142-
Example: [using simulateClick](https://github.com/some-react-components/react-scrollchor/blob/example/src/App.js#L16)
103+
| # | Parameter | Meaning |
104+
|---|-----------|---------|
105+
|0|percent|Percent completed of the animation (decimal, `0.0` to `1.0`)|
106+
|1|elapsedTime|Time elapsed since the animation began, in ms|
107+
|2|startValue|Static value set to `0`|
108+
|3|valueChange|Static value set to `1`|
109+
|4|duration|Duration of the animation, in ms|
143110

144-
When used programmatically, some use-cases don't need `anchor tags`. On these cases use childless `Scrollchor`.
111+
Returns a decimal indicating how close the animation is to the end value (`0` = start, `1` = finished, `1.2` = 20% over the end value, think "bounce" effects)
145112

146-
### Childless `Scrollchor`
147-
This component will render `null` and the user is reponsible for storing the component [reference](https://facebook.github.io/react/docs/refs-and-the-dom.html), Ex: [childless](https://github.com/some-react-components/react-scrollchor/blob/example/src/App.js#L23)
148-
```js
149-
<Scrollchor ref={ref => (this._back = ref)} to="_back" />
150-
```
151-
Example: [calling `simulateClick()` on childless `ref`](https://github.com/some-react-components/react-scrollchor/blob/example/src/App.js#L16)
152-
```js
153-
_afterAnimate = () => {
154-
this.setState({ to: this._iterator.next().value });
155-
setTimeout(() => this._back.simulateClick(), 1000);
156-
};
113+
The default values can be customized all at once or individually by providing only the properties you want to override. For example:
114+
115+
```jsx
116+
import { Scrollchor, linear } from 'react-scrollchor';
117+
118+
const HomeLink = () => (
119+
<Scrollchor to="home" animate={{ duration: 1000, easing: linear }}>
120+
Home
121+
</Scrollchor>
122+
);
157123
```
158124

159-
## Scrollable ancestor container
160-
Scrollchor works within any scrollable parent container. The root element of the `document` will be choose if none is specified.
125+
You can find additional easing functions at these links:
126+
127+
* [Robert Penner's Easing Functions](http://robertpenner.com/easing/)
128+
* [Javascript source code](https://github.com/danro/jquery-easing/blob/master/jquery.easing.js)
129+
161130

162-
Hosted example show how to use a different container using prop `target`.
163-
* Click `Within scrollable container` checkbox: [hosted example](https://some-react-components.github.io/react-scrollchor/)(full example below)
131+
### `beforeAnimate: MouseEventHandler` / `afterAnimate: MouseEventHandler`
164132

133+
You can use these callbacks to trigger behaviors like: update state, load async stuff, etc. when either stage happens. The functions receive the originating `MouseEvent` as their only argument, the return value is not used.
165134

166-
## Full Example
135+
`beforeAnimate` is triggered before the animation starts, i.e. immediately when the link is clicked, while `afterAnimate` is called once the animation has finished.
167136

168-
[react-scrollchor--example](https://github.com/some-react-components/react-scrollchor/tree/example)
137+
```js
138+
<Scrollchor to="#aboutus" afterAnimate={() => setActive('home')}>Home</Scrollchor>
139+
```
169140

170141
## Credits
171142

@@ -174,6 +145,7 @@ Hosted example show how to use a different container using prop `target`.
174145

175146
### maintainers
176147
* xehpuk <> [@xehpuk](https://github.com/xehpuk)
148+
* SeinopSys <> [@SeinopSys](https://github.com/SeinopSys)
177149

178150
### contributors
179151
* Jean Chung <> [@jeanchung](https://github.com/jeanchung)

0 commit comments

Comments
 (0)