Skip to content

Commit 11105b1

Browse files
authored
fix: improve examples and add tests (#191)
* chore(deps): upgrade prettier-browser * simpler example * eslint is not bad * working on initial integration tests * Sync with Prettier * test * test * refactoring compute logic * tests work, but need cleanup * fixes all around * less annoying for cjs users * prepare more test cases * extract Expect component * cleanup * fix TS * cleanup a little more
1 parent 0cce588 commit 11105b1

File tree

24 files changed

+1458
-761
lines changed

24 files changed

+1458
-761
lines changed

.circleci/config.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ jobs:
2828
- checkout
2929
- restore-cache: *restore-cache
3030
- *install
31+
- run: yarn lint
3132
- run:
3233
name: scroll-into-view-if-needed
3334
command: yarn build:d.ts
@@ -73,14 +74,14 @@ jobs:
7374
- checkout
7475
- restore-cache: *restore-cache
7576
- *install
76-
- run:
77-
name: scroll-into-view-if-needed
78-
command: npx --no-install semantic-release -e semantic-release-monorepo
79-
working_directory: packages/scroll-into-view-if-needed
80-
- run:
81-
name: smooth-scroll-into-view-if-needed
82-
command: npx --no-install semantic-release -e semantic-release-monorepo
83-
working_directory: packages/smooth-scroll-into-view-if-needed
77+
#- run:
78+
# name: scroll-into-view-if-needed
79+
# command: npx --no-install semantic-release -e semantic-release-monorepo
80+
# working_directory: packages/scroll-into-view-if-needed
81+
#- run:
82+
# name: smooth-scroll-into-view-if-needed
83+
# command: npx --no-install semantic-release -e semantic-release-monorepo
84+
# working_directory: packages/smooth-scroll-into-view-if-needed
8485

8586
# Workflows enables us to run multiple jobs in parallel
8687
workflows:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
lerna-debug.log
3+
.next

integration-tests/.eslintrc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"parser": "babel-eslint",
3+
"env": {
4+
"browser": true,
5+
"node": true
6+
},
7+
"plugins": ["import", "react"],
8+
"extends": [
9+
"eslint:recommended",
10+
"prettier",
11+
"plugin:import/errors",
12+
"plugin:react/recommended"
13+
],
14+
"rules": {
15+
"react/react-jsx-in-scope": false,
16+
"react/display-name": false
17+
}
18+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import PropTypes from 'prop-types'
2+
import { Component, Fragment, createRef } from 'react'
3+
import scrollIntoView from 'scroll-into-view-if-needed'
4+
5+
export default class Expect extends Component {
6+
static propTypes = {
7+
children: PropTypes.func.isRequired,
8+
toBe: PropTypes.func.isRequired,
9+
options: PropTypes.object,
10+
}
11+
static defaultProps = {
12+
setup: () => {},
13+
}
14+
15+
target = createRef()
16+
17+
state = { test: undefined }
18+
19+
componentDidMount() {
20+
const node = this.target.current
21+
const { setup, options, toBe } = this.props
22+
23+
setup(node)
24+
scrollIntoView(node, options)
25+
this.setState({ test: toBe(node) ? 'pass' : 'fail' })
26+
}
27+
28+
render() {
29+
return this.props.children({
30+
target: (
31+
<div
32+
className="bulls-eye"
33+
ref={this.target}
34+
data-test={this.state.test}
35+
/>
36+
),
37+
})
38+
}
39+
}

integration-tests/core/next.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const withCSS = require('@zeit/next-css')
2+
3+
module.exports = withCSS()

integration-tests/core/package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"private": true,
3+
"name": "@integration-tests/core",
4+
"description": "Ensures the core functionality is correct",
5+
"version": "1.0.0",
6+
"main": "index.js",
7+
"scripts": {
8+
"build": "next build",
9+
"dev": "next",
10+
"start": "next start"
11+
},
12+
"dependencies": {
13+
"@zeit/next-css": "0.0.7",
14+
"next": "5.1.0",
15+
"react": "16.3.2",
16+
"react-dom": "16.3.2"
17+
}
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Document, { Head, Main, NextScript } from 'next/document'
2+
3+
export default class MyDocument extends Document {
4+
render() {
5+
return (
6+
<html>
7+
<Head>
8+
<link rel="stylesheet" href="/_next/static/style.css" />
9+
</Head>
10+
<body>
11+
<Main />
12+
<NextScript />
13+
</body>
14+
</html>
15+
)
16+
}
17+
}

integration-tests/core/pages/block.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import PropTypes from 'prop-types'
2+
import { Component, Fragment, createRef } from 'react'
3+
4+
import Expect from '../components/Expect'
5+
6+
import '../style.css'
7+
8+
const SIZE = 100
9+
10+
const tests = {
11+
start: () => (
12+
<Expect
13+
options={{ block: 'start' }}
14+
toBe={node => {
15+
const clientRect = node.getBoundingClientRect()
16+
return clientRect.top === 0
17+
}}
18+
>
19+
{({ target }) => (
20+
<Fragment>
21+
<div className="is-full-height align-center" />
22+
<div className="is-full-height align-center">{target}</div>
23+
<div className="is-full-height align-center" />
24+
</Fragment>
25+
)}
26+
</Expect>
27+
),
28+
center: () => (
29+
<Expect
30+
options={{ block: 'center' }}
31+
toBe={node => {
32+
const clientRect = node.getBoundingClientRect()
33+
return clientRect.top === window.innerHeight / 2 - SIZE / 2
34+
}}
35+
>
36+
{({ target }) => (
37+
<Fragment>
38+
<div className="is-full-height align-center" />
39+
<div className="is-full-height align-center">{target}</div>
40+
<div className="is-full-height align-center" />
41+
</Fragment>
42+
)}
43+
</Expect>
44+
),
45+
end: () => (
46+
<Expect
47+
options={{ block: 'end' }}
48+
toBe={node => {
49+
const clientRect = node.getBoundingClientRect()
50+
return clientRect.bottom === window.innerHeight
51+
}}
52+
>
53+
{({ target }) => (
54+
<Fragment>
55+
<div className="is-full-height align-center" />
56+
<div className="is-full-height align-center">{target}</div>
57+
<div className="is-full-height align-center" />
58+
</Fragment>
59+
)}
60+
</Expect>
61+
),
62+
}
63+
const keys = Object.keys(tests).sort()
64+
65+
export default class extends Component {
66+
state = { test: keys[0], mounted: false }
67+
68+
componentDidMount() {
69+
// @TODO Workaround annoying chrome behavior, implement event listeners like window.onload instead
70+
setTimeout(() => this.setState({ mounted: true }), 100)
71+
}
72+
73+
render() {
74+
const buttons = keys
75+
const ActiveTest = tests[this.state.test]
76+
return (
77+
<Fragment>
78+
<navbar className="test-switcher">
79+
{buttons.map(name => (
80+
<button key={name} onClick={() => this.setState({ test: name })}>
81+
{name}
82+
</button>
83+
))}
84+
</navbar>
85+
86+
{this.state.mounted ? (
87+
<ActiveTest key={this.state.test} />
88+
) : (
89+
'mounting…'
90+
)}
91+
</Fragment>
92+
)
93+
}
94+
}

integration-tests/core/pages/index.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Link from 'next/link'
2+
3+
const suites = ['block', 'inline', 'scrollMode', 'boundary']
4+
5+
export default () => (
6+
<div
7+
style={{
8+
display: 'grid',
9+
margin: '0 auto',
10+
gridTemplateRows: 'repeat(auto-fill, minmax(200px, 1fr))',
11+
gridAutoRows: 'minmax(150px, auto)',
12+
}}
13+
>
14+
{suites.map(suite => (
15+
<Link key={suite} href={`/${suite}`}>
16+
<a>{suite}</a>
17+
</Link>
18+
))}
19+
</div>
20+
)

integration-tests/core/style.css

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
*,
2+
*:before,
3+
*:after {
4+
box-sizing: border-box;
5+
}
6+
7+
body {
8+
margin: 0;
9+
padding: 0;
10+
display: flex;
11+
}
12+
13+
.test-switcher {
14+
position: fixed;
15+
top: 0;
16+
left: 0;
17+
right: 0;
18+
text-align: center;
19+
}
20+
21+
.example {
22+
font-size: 50px;
23+
color: papayawhip;
24+
}
25+
26+
.align-center {
27+
display: flex;
28+
align-items: center;
29+
justify-content: center;
30+
}
31+
32+
.is-full-height {
33+
height: 100vh;
34+
}
35+
36+
.bulls-eye {
37+
--size: 100px;
38+
background: #ffeb3b;
39+
height: var(--size);
40+
width: var(--size);
41+
}
42+
43+
[data-test='pass'] {
44+
background: #4caf50;
45+
}
46+
[data-test='fail'] {
47+
background: #f44336;
48+
}

0 commit comments

Comments
 (0)