cozy-ui 69.1.0 → 69.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/react/BottomDrawer/Readme.md +26 -17
- package/react/BottomDrawer/index.jsx +22 -20
- package/react/BottomDrawer/styles.styl +9 -8
- package/react/Overlay/index.jsx +8 -4
- package/transpiled/react/BottomDrawer/index.js +25 -18
- package/transpiled/react/Overlay/index.js +11 -5
- package/transpiled/react/stylesheet.css +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# [69.2.0](https://github.com/cozy/cozy-ui/compare/v69.1.0...v69.2.0) (2022-07-07)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **BottomDrawer:** Add possibility to use it with long content ([59296f0](https://github.com/cozy/cozy-ui/commit/59296f0))
|
|
7
|
+
* **Overlay:** Add ref propagation ([6a0b3f0](https://github.com/cozy/cozy-ui/commit/6a0b3f0))
|
|
8
|
+
|
|
1
9
|
# [69.1.0](https://github.com/cozy/cozy-ui/compare/v69.0.0...v69.1.0) (2022-07-05)
|
|
2
10
|
|
|
3
11
|
|
package/package.json
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
Displays content coming up from the bottom of the screen.
|
|
2
2
|
|
|
3
3
|
```jsx
|
|
4
|
-
import BottomDrawer from 'cozy-ui/transpiled/react/BottomDrawer'
|
|
5
|
-
import
|
|
6
|
-
import Button from 'cozy-ui/transpiled/react/
|
|
7
|
-
import Typography from "cozy-ui/transpiled/react/Typography"
|
|
4
|
+
import BottomDrawer from 'cozy-ui/transpiled/react/BottomDrawer'
|
|
5
|
+
import Paper from 'cozy-ui/transpiled/react/Paper'
|
|
6
|
+
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
7
|
+
import Typography from "cozy-ui/transpiled/react/Typography"
|
|
8
|
+
import Variants from 'cozy-ui/docs/components/Variants'
|
|
8
9
|
|
|
9
|
-
initialState = { isDrawerDisplayed: isTesting() }
|
|
10
|
+
const initialState = { isDrawerDisplayed: isTesting() }
|
|
11
|
+
const initialVariants = [{ longText: false }]
|
|
10
12
|
|
|
11
13
|
const showDrawer = () => setState({ isDrawerDisplayed: true });
|
|
12
|
-
const hideDrawer = () => setState({ isDrawerDisplayed: false })
|
|
14
|
+
const hideDrawer = () => setState({ isDrawerDisplayed: false })
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
</
|
|
16
|
+
;
|
|
17
|
+
|
|
18
|
+
<Variants initialVariants={initialVariants}>
|
|
19
|
+
{variant => (
|
|
20
|
+
<>
|
|
21
|
+
<Button variant="ghost" size="small" onClick={showDrawer} label="Open drawer" />
|
|
22
|
+
|
|
23
|
+
{state.isDrawerDisplayed &&
|
|
24
|
+
<BottomDrawer onClose={hideDrawer}>
|
|
25
|
+
<Paper className="u-p-1" style={{ borderRadius: '1rem 1rem 0 0' }}>
|
|
26
|
+
<Typography variant="h5" paragraph>This is a paper in a drawer</Typography>
|
|
27
|
+
<Typography paragraph>{variant.longText ? content.ada.long : content.ada.short}</Typography>
|
|
28
|
+
<Button label="Demo button" onClick={() => console.info('huhu')} />
|
|
29
|
+
</Paper>
|
|
30
|
+
</BottomDrawer>}
|
|
31
|
+
</>
|
|
32
|
+
)}
|
|
33
|
+
</Variants>
|
|
25
34
|
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { Component } from 'react'
|
|
1
|
+
import React, { Component, createRef } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import Hammer from 'hammerjs'
|
|
4
4
|
import once from 'lodash/once'
|
|
@@ -13,6 +13,8 @@ class BottomDrawer extends Component {
|
|
|
13
13
|
constructor(props) {
|
|
14
14
|
super(props)
|
|
15
15
|
this.state = { closing: false }
|
|
16
|
+
this.menuRef = createRef()
|
|
17
|
+
this.wrapperRef = createRef()
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
componentDidMount() {
|
|
@@ -22,7 +24,7 @@ class BottomDrawer extends Component {
|
|
|
22
24
|
|
|
23
25
|
componentWillUnmount() {
|
|
24
26
|
this.gesturesHandler.destroy()
|
|
25
|
-
this.
|
|
27
|
+
this.menuRef.current.style = '' // Drops the node style in case it gets recycled, see https://github.com/cozy/cozy-ui/pull/602
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
initialAppear() {
|
|
@@ -35,21 +37,21 @@ class BottomDrawer extends Component {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
turnTransitionsOn() {
|
|
38
|
-
this.
|
|
40
|
+
this.menuRef.current.classList.add(styles['with-transition'])
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
turnTransitionsOff() {
|
|
42
|
-
this.
|
|
44
|
+
this.menuRef.current.classList.remove(styles['with-transition'])
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
attachEvents() {
|
|
46
|
-
this.gesturesHandler = new Hammer.Manager(this.
|
|
48
|
+
this.gesturesHandler = new Hammer.Manager(this.wrapperRef.current, {
|
|
47
49
|
recognizers: [[Hammer.Pan, { direction: Hammer.DIRECTION_VERTICAL }]]
|
|
48
50
|
})
|
|
49
51
|
|
|
50
52
|
// to be completely accurate, `maximumGestureDelta` should be the difference between the top of the menu and the
|
|
51
53
|
// bottom of the page; but using the height is much easier to compute and accurate enough.
|
|
52
|
-
const maximumGestureDistance = this.
|
|
54
|
+
const maximumGestureDistance = this.menuRef.current.getBoundingClientRect()
|
|
53
55
|
.height
|
|
54
56
|
// between 0 and 1, how far down the gesture must be to be considered complete upon release
|
|
55
57
|
const minimumCloseDistance = 0.6
|
|
@@ -97,47 +99,47 @@ class BottomDrawer extends Component {
|
|
|
97
99
|
applyTransformation(progress) {
|
|
98
100
|
// constrain between 0 and 1.1 (go a bit further than 1 to be hidden completely)
|
|
99
101
|
const progressToApply = Math.min(1.1, Math.max(0, progress))
|
|
100
|
-
this.
|
|
102
|
+
this.menuRef.current.style.transform =
|
|
101
103
|
'translateY(' + progressToApply * 100 + '%)'
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
animateClose = () => {
|
|
107
|
+
const { current: menuNode } = this.menuRef
|
|
105
108
|
this.setState({ closing: true })
|
|
106
109
|
|
|
107
110
|
// we need to transition the menu to the bottom before dismissing it
|
|
108
|
-
const close =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
const close = menuNode =>
|
|
112
|
+
once(() => {
|
|
113
|
+
menuNode?.removeEventListener('transitionend', close(menuNode))
|
|
114
|
+
this.close()
|
|
115
|
+
})
|
|
113
116
|
|
|
114
|
-
|
|
115
|
-
this.menuNode.current.addEventListener('transitionend', close, false)
|
|
117
|
+
menuNode?.addEventListener('transitionend', close(menuNode), false)
|
|
116
118
|
// in case transitionend is not called, for example if the element is removed
|
|
117
|
-
setTimeout(close, TRANSITION_DURATION)
|
|
119
|
+
setTimeout(close(menuNode), TRANSITION_DURATION)
|
|
118
120
|
|
|
119
121
|
this.applyTransformation(1.1)
|
|
120
122
|
}
|
|
121
123
|
|
|
122
124
|
close = () => {
|
|
125
|
+
const { onClose } = this.props
|
|
123
126
|
this.setState({ closing: true })
|
|
124
|
-
|
|
127
|
+
onClose && onClose()
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
render() {
|
|
128
131
|
const { children } = this.props
|
|
129
132
|
const { closing } = this.state
|
|
130
|
-
|
|
131
|
-
this.wrapperNode = React.createRef()
|
|
133
|
+
|
|
132
134
|
return (
|
|
133
135
|
<RemoveScroll>
|
|
134
|
-
<div ref={this.
|
|
136
|
+
<div ref={this.wrapperRef}>
|
|
135
137
|
<Overlay
|
|
136
138
|
style={{ opacity: closing ? 0 : 1 }}
|
|
137
139
|
onClick={this.animateClose}
|
|
138
140
|
onEscape={this.animateClose}
|
|
139
141
|
>
|
|
140
|
-
<div ref={this.
|
|
142
|
+
<div ref={this.menuRef} className={styles['BottomDrawer-content']}>
|
|
141
143
|
{children}
|
|
142
144
|
</div>
|
|
143
145
|
</Overlay>
|
|
@@ -8,11 +8,12 @@
|
|
|
8
8
|
@extends $transition-transform-ease-out
|
|
9
9
|
|
|
10
10
|
.BottomDrawer-content
|
|
11
|
-
z-index
|
|
12
|
-
position
|
|
13
|
-
bottom
|
|
14
|
-
left
|
|
15
|
-
right
|
|
16
|
-
width
|
|
17
|
-
margin
|
|
18
|
-
|
|
11
|
+
z-index $drawer-index
|
|
12
|
+
position fixed
|
|
13
|
+
bottom 0
|
|
14
|
+
left 0
|
|
15
|
+
right 0
|
|
16
|
+
width 100%
|
|
17
|
+
margin 0
|
|
18
|
+
max-height 100vh
|
|
19
|
+
overflow-y auto
|
package/react/Overlay/index.jsx
CHANGED
|
@@ -7,7 +7,7 @@ import { RemoveScroll } from 'react-remove-scroll'
|
|
|
7
7
|
|
|
8
8
|
const ESC_KEYCODE = 27
|
|
9
9
|
|
|
10
|
-
const nonDOMProps = ['onEscape', 'children', 'className']
|
|
10
|
+
const nonDOMProps = ['onEscape', 'children', 'className', 'innerRef']
|
|
11
11
|
|
|
12
12
|
const bodyTallerThanWindow = () => {
|
|
13
13
|
return document.body.getBoundingClientRect().height > window.innerHeight
|
|
@@ -45,7 +45,7 @@ class Overlay extends Component {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
render() {
|
|
48
|
-
const { children, className } = this.props
|
|
48
|
+
const { children, className, innerRef } = this.props
|
|
49
49
|
const domProps = omit(this.props, nonDOMProps)
|
|
50
50
|
// We use Overlay when opening an ActionMenu.
|
|
51
51
|
// We don't want to block the scroll on Desktop if the ActionMenu
|
|
@@ -53,10 +53,12 @@ class Overlay extends Component {
|
|
|
53
53
|
// @todo Overlay should not RemoveScroll by itself. It should
|
|
54
54
|
// be done by lower component (like ActionMenu / Dialog / Modal...)
|
|
55
55
|
const Wrapper = bodyTallerThanWindow() ? React.Fragment : RemoveScroll
|
|
56
|
+
|
|
56
57
|
return (
|
|
57
58
|
<div
|
|
58
|
-
|
|
59
|
+
ref={innerRef}
|
|
59
60
|
className={cx(styles['c-overlay'], className)}
|
|
61
|
+
onClick={this.handleClick}
|
|
60
62
|
{...domProps}
|
|
61
63
|
>
|
|
62
64
|
<Wrapper>{children}</Wrapper>
|
|
@@ -71,4 +73,6 @@ Overlay.propTypes = {
|
|
|
71
73
|
onEscape: PropTypes.func
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
export default
|
|
76
|
+
export default React.forwardRef((props, ref) => (
|
|
77
|
+
<Overlay innerRef={ref} {...props} />
|
|
78
|
+
))
|
|
@@ -10,7 +10,7 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
|
|
|
10
10
|
|
|
11
11
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
12
12
|
|
|
13
|
-
import React, { Component } from 'react';
|
|
13
|
+
import React, { Component, createRef } from 'react';
|
|
14
14
|
import PropTypes from 'prop-types';
|
|
15
15
|
import Hammer from 'hammerjs';
|
|
16
16
|
import once from 'lodash/once';
|
|
@@ -37,34 +37,43 @@ var BottomDrawer = /*#__PURE__*/function (_Component) {
|
|
|
37
37
|
_this = _super.call(this, props);
|
|
38
38
|
|
|
39
39
|
_defineProperty(_assertThisInitialized(_this), "animateClose", function () {
|
|
40
|
+
var menuNode = _this.menuRef.current;
|
|
41
|
+
|
|
40
42
|
_this.setState({
|
|
41
43
|
closing: true
|
|
42
44
|
}); // we need to transition the menu to the bottom before dismissing it
|
|
43
45
|
|
|
44
46
|
|
|
45
|
-
var close =
|
|
46
|
-
|
|
47
|
+
var close = function close(menuNode) {
|
|
48
|
+
return once(function () {
|
|
49
|
+
menuNode === null || menuNode === void 0 ? void 0 : menuNode.removeEventListener('transitionend', close(menuNode));
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
_this.close();
|
|
52
|
+
});
|
|
53
|
+
};
|
|
51
54
|
|
|
52
|
-
|
|
55
|
+
menuNode === null || menuNode === void 0 ? void 0 : menuNode.addEventListener('transitionend', close(menuNode), false); // in case transitionend is not called, for example if the element is removed
|
|
56
|
+
|
|
57
|
+
setTimeout(close(menuNode), TRANSITION_DURATION);
|
|
53
58
|
|
|
54
59
|
_this.applyTransformation(1.1);
|
|
55
60
|
});
|
|
56
61
|
|
|
57
62
|
_defineProperty(_assertThisInitialized(_this), "close", function () {
|
|
63
|
+
var onClose = _this.props.onClose;
|
|
64
|
+
|
|
58
65
|
_this.setState({
|
|
59
66
|
closing: true
|
|
60
67
|
});
|
|
61
68
|
|
|
62
|
-
|
|
69
|
+
onClose && onClose();
|
|
63
70
|
});
|
|
64
71
|
|
|
65
72
|
_this.state = {
|
|
66
73
|
closing: false
|
|
67
74
|
};
|
|
75
|
+
_this.menuRef = /*#__PURE__*/createRef();
|
|
76
|
+
_this.wrapperRef = /*#__PURE__*/createRef();
|
|
68
77
|
return _this;
|
|
69
78
|
}
|
|
70
79
|
|
|
@@ -78,7 +87,7 @@ var BottomDrawer = /*#__PURE__*/function (_Component) {
|
|
|
78
87
|
key: "componentWillUnmount",
|
|
79
88
|
value: function componentWillUnmount() {
|
|
80
89
|
this.gesturesHandler.destroy();
|
|
81
|
-
this.
|
|
90
|
+
this.menuRef.current.style = ''; // Drops the node style in case it gets recycled, see https://github.com/cozy/cozy-ui/pull/602
|
|
82
91
|
}
|
|
83
92
|
}, {
|
|
84
93
|
key: "initialAppear",
|
|
@@ -96,26 +105,26 @@ var BottomDrawer = /*#__PURE__*/function (_Component) {
|
|
|
96
105
|
}, {
|
|
97
106
|
key: "turnTransitionsOn",
|
|
98
107
|
value: function turnTransitionsOn() {
|
|
99
|
-
this.
|
|
108
|
+
this.menuRef.current.classList.add(styles['with-transition']);
|
|
100
109
|
}
|
|
101
110
|
}, {
|
|
102
111
|
key: "turnTransitionsOff",
|
|
103
112
|
value: function turnTransitionsOff() {
|
|
104
|
-
this.
|
|
113
|
+
this.menuRef.current.classList.remove(styles['with-transition']);
|
|
105
114
|
}
|
|
106
115
|
}, {
|
|
107
116
|
key: "attachEvents",
|
|
108
117
|
value: function attachEvents() {
|
|
109
118
|
var _this3 = this;
|
|
110
119
|
|
|
111
|
-
this.gesturesHandler = new Hammer.Manager(this.
|
|
120
|
+
this.gesturesHandler = new Hammer.Manager(this.wrapperRef.current, {
|
|
112
121
|
recognizers: [[Hammer.Pan, {
|
|
113
122
|
direction: Hammer.DIRECTION_VERTICAL
|
|
114
123
|
}]]
|
|
115
124
|
}); // to be completely accurate, `maximumGestureDelta` should be the difference between the top of the menu and the
|
|
116
125
|
// bottom of the page; but using the height is much easier to compute and accurate enough.
|
|
117
126
|
|
|
118
|
-
var maximumGestureDistance = this.
|
|
127
|
+
var maximumGestureDistance = this.menuRef.current.getBoundingClientRect().height; // between 0 and 1, how far down the gesture must be to be considered complete upon release
|
|
119
128
|
|
|
120
129
|
var minimumCloseDistance = 0.6; // a gesture faster than this will dismiss the menu, regardless of distance traveled
|
|
121
130
|
|
|
@@ -162,17 +171,15 @@ var BottomDrawer = /*#__PURE__*/function (_Component) {
|
|
|
162
171
|
value: function applyTransformation(progress) {
|
|
163
172
|
// constrain between 0 and 1.1 (go a bit further than 1 to be hidden completely)
|
|
164
173
|
var progressToApply = Math.min(1.1, Math.max(0, progress));
|
|
165
|
-
this.
|
|
174
|
+
this.menuRef.current.style.transform = 'translateY(' + progressToApply * 100 + '%)';
|
|
166
175
|
}
|
|
167
176
|
}, {
|
|
168
177
|
key: "render",
|
|
169
178
|
value: function render() {
|
|
170
179
|
var children = this.props.children;
|
|
171
180
|
var closing = this.state.closing;
|
|
172
|
-
this.menuNode = /*#__PURE__*/React.createRef();
|
|
173
|
-
this.wrapperNode = /*#__PURE__*/React.createRef();
|
|
174
181
|
return /*#__PURE__*/React.createElement(RemoveScroll, null, /*#__PURE__*/React.createElement("div", {
|
|
175
|
-
ref: this.
|
|
182
|
+
ref: this.wrapperRef
|
|
176
183
|
}, /*#__PURE__*/React.createElement(Overlay, {
|
|
177
184
|
style: {
|
|
178
185
|
opacity: closing ? 0 : 1
|
|
@@ -180,7 +187,7 @@ var BottomDrawer = /*#__PURE__*/function (_Component) {
|
|
|
180
187
|
onClick: this.animateClose,
|
|
181
188
|
onEscape: this.animateClose
|
|
182
189
|
}, /*#__PURE__*/React.createElement("div", {
|
|
183
|
-
ref: this.
|
|
190
|
+
ref: this.menuRef,
|
|
184
191
|
className: styles['BottomDrawer-content']
|
|
185
192
|
}, children))));
|
|
186
193
|
}
|
|
@@ -20,7 +20,7 @@ import omit from 'lodash/omit';
|
|
|
20
20
|
import PropTypes from 'prop-types';
|
|
21
21
|
import { RemoveScroll } from 'react-remove-scroll';
|
|
22
22
|
var ESC_KEYCODE = 27;
|
|
23
|
-
var nonDOMProps = ['onEscape', 'children', 'className'];
|
|
23
|
+
var nonDOMProps = ['onEscape', 'children', 'className', 'innerRef'];
|
|
24
24
|
|
|
25
25
|
var bodyTallerThanWindow = function bodyTallerThanWindow() {
|
|
26
26
|
return document.body.getBoundingClientRect().height > window.innerHeight;
|
|
@@ -83,7 +83,8 @@ var Overlay = /*#__PURE__*/function (_Component) {
|
|
|
83
83
|
value: function render() {
|
|
84
84
|
var _this$props = this.props,
|
|
85
85
|
children = _this$props.children,
|
|
86
|
-
className = _this$props.className
|
|
86
|
+
className = _this$props.className,
|
|
87
|
+
innerRef = _this$props.innerRef;
|
|
87
88
|
var domProps = omit(this.props, nonDOMProps); // We use Overlay when opening an ActionMenu.
|
|
88
89
|
// We don't want to block the scroll on Desktop if the ActionMenu
|
|
89
90
|
// is displayed. So no RemoveScroll if the content is too small
|
|
@@ -92,8 +93,9 @@ var Overlay = /*#__PURE__*/function (_Component) {
|
|
|
92
93
|
|
|
93
94
|
var Wrapper = bodyTallerThanWindow() ? React.Fragment : RemoveScroll;
|
|
94
95
|
return /*#__PURE__*/React.createElement("div", _extends({
|
|
95
|
-
|
|
96
|
-
className: cx(styles['c-overlay'], className)
|
|
96
|
+
ref: innerRef,
|
|
97
|
+
className: cx(styles['c-overlay'], className),
|
|
98
|
+
onClick: this.handleClick
|
|
97
99
|
}, domProps), /*#__PURE__*/React.createElement(Wrapper, null, children));
|
|
98
100
|
}
|
|
99
101
|
}]);
|
|
@@ -106,4 +108,8 @@ Overlay.propTypes = {
|
|
|
106
108
|
children: PropTypes.node,
|
|
107
109
|
onEscape: PropTypes.func
|
|
108
110
|
};
|
|
109
|
-
export default
|
|
111
|
+
export default /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
112
|
+
return /*#__PURE__*/React.createElement(Overlay, _extends({
|
|
113
|
+
innerRef: ref
|
|
114
|
+
}, props));
|
|
115
|
+
});
|