Skip to content

Commit 5413022

Browse files
feat(popperjs): use popperjs instead of tether (#561)
Add tests Update existing tests (jest has been upgraded) improve code coverage Breaking change: getRef has been renamed to innerRef to line up with other libraries. Breaking change: tether props have been removed.
1 parent f12057d commit 5413022

56 files changed

Lines changed: 1382 additions & 1419 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ var rules = {
3333
'prefer-const': 0,
3434
'react/jsx-filename-extension': 0,
3535
'linebreak-style': 0,
36-
'react/require-extension': 0
36+
'react/require-extension': 0,
37+
'react/no-children-prop': 0,
38+
'react/require-default-props': 0,
39+
'react/forbid-prop-types': 0,
40+
'jsx-a11y/no-noninteractive-element-interactions': 1
3741
};
3842

3943
module.exports = {
@@ -55,6 +59,5 @@ module.exports = {
5559
'ecmaFeatures': ecmaFeatures
5660
},
5761
'ecmaFeatures': ecmaFeatures,
58-
rules: rules,
59-
extensions: ['', '.js', '.jsx']
62+
rules: rules
6063
};

docs/lib/Components/ButtonDropdownPage.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export default class ButtonDropdownPage extends React.Component {
5151
group: PropTypes.bool,
5252
isOpen: PropTypes.bool,
5353
tag: PropTypes.string,
54-
tether: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
5554
toggle: PropTypes.func
5655
};
5756

docs/lib/Components/DropdownsPage.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ export default class DropdownPage extends React.Component {
4141
<p>
4242
The <code>Dropdown</code> component is used to pass the <code>isOpen</code> & <code>toggle</code> props via context to the following components: <code>DropdownToggle</code>, <code>DropdownMenu</code>. The <code>DropdownToggle</code> uses the <code>Button</code> component internally, meaning it also accepts all the props the <Link to="/components/buttons/">Button component</Link> accepts.
4343
</p>
44-
<h4>Advanced Positioning</h4>
45-
<p>
46-
The <code>DropdownMenu</code> can automatically be flipped (dropup vs dropdown) according to space available in the viewport by passing the <code>tether</code> prop to Dropdown <code>{`<Dropdown tether />`}</code>. For full customization, an object with <a href="http://tether.io/#options">Tether options</a> can be used instead.
47-
</p>
4844
<div className="docs-example">
4945
<DropdownExample />
5046
</div>
@@ -62,7 +58,6 @@ export default class DropdownPage extends React.Component {
6258
group: PropTypes.bool,
6359
isOpen: PropTypes.bool,
6460
tag: PropTypes.string, // default: 'div'
65-
tether: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
6661
toggle: PropTypes.func
6762
};
6863
@@ -78,16 +73,25 @@ DropdownToggle.propTypes = {
7873
nav: PropTypes.bool,
7974
// Defaults to Button component
8075
tag: PropTypes.any
76+
};
77+
78+
DropdownMenu.propTypes = {
79+
tag: PropTypes.string,
80+
children: PropTypes.node.isRequired,
81+
right: PropTypes.bool,
82+
flip: PropTypes.bool, // default: true,
83+
className: PropTypes.string,
84+
cssModule: PropTypes.object,
8185
};`}
8286
</PrismCode>
8387
</pre>
8488
<h3>Alignment</h3>
85-
<p>To align the <code>DropdownMenu</code> to the right, add a <code>right</code> prop to it.</p>
89+
<p>To align the <code>DropdownMenu</code> to the right, add a <code>right</code> prop to <code>Dropdown</code>.</p>
8690
<div className="docs-example">
8791
<div style={{ display: 'inline-block' }}>
8892
<Dropdown isOpen={this.state.example2} toggle={this.toggleExample2}>
8993
<DropdownToggle caret>
90-
Dropdown
94+
This dropdown's menu is right-aligned
9195
</DropdownToggle>
9296
<DropdownMenu right>
9397
<DropdownItem header>Header</DropdownItem>
@@ -103,7 +107,7 @@ DropdownToggle.propTypes = {
103107
<PrismCode className="language-jsx">
104108
{`<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
105109
<DropdownToggle caret>
106-
Dropdown
110+
This dropdown's menu is right-aligned
107111
</DropdownToggle>
108112
<DropdownMenu right>
109113
<DropdownItem header>Header</DropdownItem>

docs/lib/Components/NavsPage.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ export default class NavssPage extends React.Component {
7171
group: PropTypes.bool,
7272
isOpen: PropTypes.bool,
7373
tag: PropTypes.string,
74-
tether: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
7574
toggle: PropTypes.func
7675
};`}
7776
</PrismCode>

docs/lib/Components/PopoversPage.js

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default class PopoversPage extends React.Component {
1313
<div>
1414
<Helmet title="Popovers" />
1515
<h3>Popovers</h3>
16-
<p>Popovers are built with <a href="http://tether.io/">http://tether.io</a>.</p>
16+
<p>Popovers are built with <a href="https://popper.js.org/">https://popper.js.org/</a> via <a href="https://github.com/souporserious/react-popper">https://github.com/souporserious/react-popper</a>.</p>
1717
<div className="docs-example">
1818
<PopoverExample />
1919
</div>
@@ -30,32 +30,34 @@ export default class PopoversPage extends React.Component {
3030
// boolean to control the state of the popover
3131
toggle: PropTypes.func,
3232
// callback for toggling isOpen in the controlling component
33-
target: PropTypes.string.isRequired,
34-
// target div ID, popover is attached to this element
35-
tether: PropTypes.object,
36-
// optionally overide tether config http://tether.io/#options
37-
tetherRef: PropType.function,
38-
// function which is passed a reference to the instance of tether for manually \`position()\`ing
33+
target: PropTypes.oneOfType([
34+
PropTypes.string,
35+
PropTypes.func,
36+
DOMElement, // instanceof Element (https://developer.mozilla.org/en-US/docs/Web/API/Element)
37+
]).isRequired,
38+
disabled: PropTypes.bool,
39+
placementPrefix: PropTypes.string,
40+
delay: PropTypes.oneOfType([
41+
PropTypes.shape({ show: PropTypes.number, hide: PropTypes.number }),
42+
PropTypes.number,
43+
]),
3944
placement: PropTypes.oneOf([
45+
'auto',
46+
'auto-start',
47+
'auto-end',
4048
'top',
49+
'top-start',
50+
'top-end',
51+
'right',
52+
'right-start',
53+
'right-end',
4154
'bottom',
55+
'bottom-start',
56+
'bottom-end',
4257
'left',
43-
'right',
44-
'top left',
45-
'top center',
46-
'top right',
47-
'right top',
48-
'right middle',
49-
'right bottom',
50-
'bottom right',
51-
'bottom center',
52-
'bottom left',
53-
'left top',
54-
'left middle',
55-
'left bottom'
58+
'left-start',
59+
'left-end',
5660
])
57-
// convenience attachments for popover
58-
// examples http://github.hubspot.com/tooltip/docs/welcome/
5961
}`}
6062
</PrismCode>
6163
</pre>

docs/lib/Components/TooltipsPage.js

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default class TooltipsPage extends React.Component {
1717
<div>
1818
<Helmet title="Tooltips" />
1919
<h3>Tooltips</h3>
20-
<p>Tooltips are built with <a href="http://tether.io/">http://tether.io</a>.</p>
20+
<p>Tooltips are built with <a href="https://popper.js.org/">https://popper.js.org/</a> via <a href="https://github.com/souporserious/react-popper">https://github.com/souporserious/react-popper</a>.</p>
2121
<div className="docs-example">
2222
<TooltipExample />
2323
</div>
@@ -39,10 +39,6 @@ export default class TooltipsPage extends React.Component {
3939
PropTypes.object
4040
]).isRequired,
4141
// target element or element ID, popover is attached to this element
42-
tether: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
43-
// optionally overide tether config http://tether.io/#options
44-
tetherRef: PropType.function,
45-
// function which is passed a reference to the instance of tether for manually \`position()\`ing
4642
delay: PropTypes.oneOfType([
4743
PropTypes.shape({ show: PropTypes.number, hide: PropTypes.number }),
4844
PropTypes.number
@@ -51,22 +47,21 @@ export default class TooltipsPage extends React.Component {
5147
autohide: PropTypes.bool,
5248
// optionally hide tooltip when hovering over tooltip content - default true
5349
placement: PropTypes.oneOf([
50+
'auto',
51+
'auto-start',
52+
'auto-end',
5453
'top',
54+
'top-start',
55+
'top-end',
56+
'right',
57+
'right-start',
58+
'right-end',
5559
'bottom',
60+
'bottom-start',
61+
'bottom-end',
5662
'left',
57-
'right',
58-
'top left',
59-
'top center',
60-
'top right',
61-
'right top',
62-
'right middle',
63-
'right bottom',
64-
'bottom right',
65-
'bottom center',
66-
'bottom left',
67-
'left top',
68-
'left middle',
69-
'left bottom'
63+
'left-start',
64+
'left-end',
7065
])
7166
// convenience attachments for popover
7267
// examples http://github.hubspot.com/tooltip/docs/welcome/

docs/lib/Home/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ npm install --save reactstrap react-addons-transition-group react-addons-css-tra
100100
<p>Check out the demo <a href="http://output.jsbin.com/dimive/latest">here</a></p>
101101
<h2 className="mt-5">About the Project</h2>
102102
<hr />
103-
<p>This library contains React Bootstrap 4 components that favor composition and control. The library does not depend on jQuery or Bootstrap javascript. However, <a href="http://tether.io/" target="_blank">Tether</a> is relied upon for advanced positioning of content like Tooltips, Popovers, and auto-flipping Dropdowns.</p>
103+
<p>This library contains React Bootstrap 4 components that favor composition and control. The library does not depend on jQuery or Bootstrap javascript. However, <a href="https://popper.js.org/">https://popper.js.org/</a> via <a href="https://github.com/souporserious/react-popper">https://github.com/souporserious/react-popper</a> is relied upon for advanced positioning of content like Tooltips, Popovers, and auto-flipping Dropdowns.</p>
104104
<p>There are a few core concepts to understand in order to make the most out of this library.</p>
105105
<p>1) Your content is expected to be composed via props.children rather than using named props to pass in Components.</p>
106106
<pre>
@@ -126,7 +126,7 @@ const PreferredExample = (props) => {
126126
</PrismCode>
127127
</pre>
128128
<p>
129-
2) Attributes in this library are used to pass in state, conveniently apply modifier classes, enable advanced functionality (like tether), or automatically include non-content based elements.
129+
2) Attributes in this library are used to pass in state, conveniently apply modifier classes, enable advanced functionality (like popperjs), or automatically include non-content based elements.
130130
</p>
131131
<p>Examples:</p>
132132
<ul>

docs/lib/examples/CustomDropdown.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Dropdown, DropdownMenu } from 'reactstrap';
2+
import { Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap';
33

44
export default class Example extends React.Component {
55
constructor(props) {
@@ -20,14 +20,15 @@ export default class Example extends React.Component {
2020
render() {
2121
return (
2222
<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
23-
<span
23+
<DropdownToggle
24+
tag="span"
2425
onClick={this.toggle}
2526
data-toggle="dropdown"
2627
aria-haspopup="true"
2728
aria-expanded={this.state.dropdownOpen}
2829
>
2930
Custom Dropdown Content
30-
</span>
31+
</DropdownToggle>
3132
<DropdownMenu>
3233
<div onClick={this.toggle}>Custom dropdown item</div>
3334
<div onClick={this.toggle}>Custom dropdown item</div>

package.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@
9090
"lodash.isfunction": "^3.0.8",
9191
"lodash.isobject": "^3.0.2",
9292
"lodash.tonumber": "^4.0.3",
93+
"popper.js": "^1.10.8",
9394
"prop-types": "^15.5.8",
95+
"react-popper": "^0.7.2",
9496
"reactstrap-tether": "1.3.4"
9597
},
9698
"peerDependencies": {
@@ -115,11 +117,11 @@
115117
"css-loader": "^0.25.0",
116118
"ejs": "^2.5.1",
117119
"enzyme": "^2.8.2",
118-
"eslint": "^3.2.2",
119-
"eslint-config-airbnb": "^10.0.0",
120-
"eslint-plugin-import": "^1.12.0",
121-
"eslint-plugin-jsx-a11y": "^2.0.1",
122-
"eslint-plugin-react": "^6.0.0",
120+
"eslint": "^4.1.1",
121+
"eslint-config-airbnb": "^15.1.0",
122+
"eslint-plugin-import": "^2.6.0",
123+
"eslint-plugin-jsx-a11y": "^5.1.1",
124+
"eslint-plugin-react": "^7.1.0",
123125
"eslint-plugin-standard": "^2.0.0",
124126
"extract-text-webpack-plugin": "^1.0.1",
125127
"history": "^3.0.0",
@@ -132,7 +134,7 @@
132134
"react-helmet": "^5.0.3",
133135
"react-prism": "^4.1.0",
134136
"react-router": "^2.6.1",
135-
"react-scripts": "^0.9.5",
137+
"react-scripts": "^1.0.12",
136138
"react-test-renderer": "^15.5.4",
137139
"react-transition-group": "^1.1.2",
138140
"rollup": "^0.43.0",

src/Button.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const propTypes = {
1010
disabled: PropTypes.bool,
1111
outline: PropTypes.bool,
1212
tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
13-
getRef: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
13+
innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
1414
onClick: PropTypes.func,
1515
size: PropTypes.string,
1616
children: PropTypes.node,
@@ -51,7 +51,7 @@ class Button extends React.Component {
5151
outline,
5252
size,
5353
tag: Tag,
54-
getRef,
54+
innerRef,
5555
...attributes
5656
} = this.props;
5757

@@ -73,7 +73,7 @@ class Button extends React.Component {
7373
type={(Tag === 'button' && attributes.onClick) ? 'button' : undefined}
7474
{...attributes}
7575
className={classes}
76-
ref={getRef}
76+
ref={innerRef}
7777
onClick={this.onClick}
7878
/>
7979
);

0 commit comments

Comments
 (0)